diff options
24 files changed, 219 insertions, 81 deletions
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp index d154730058ee..df2b35b39aa8 100644 --- a/libs/hwui/BakedOpRenderer.cpp +++ b/libs/hwui/BakedOpRenderer.cpp @@ -32,7 +32,8 @@ namespace uirenderer { OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t height) { LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); - OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height); + OffscreenBuffer* buffer = mRenderState.layerPool().get( + mRenderState, width, height, mWideColorGamut); startRepaintLayer(buffer, Rect(width, height)); return buffer; } @@ -103,7 +104,8 @@ void BakedOpRenderer::endLayer() { OffscreenBuffer* BakedOpRenderer::copyToLayer(const Rect& area) { const uint32_t width = area.getWidth(); const uint32_t height = area.getHeight(); - OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height); + OffscreenBuffer* buffer = mRenderState.layerPool().get( + mRenderState, width, height, mWideColorGamut); if (!area.isEmpty() && width != 0 && height != 0) { mCaches.textureState().activateTexture(0); mCaches.textureState().bindTexture(buffer->texture.id()); diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h index 4d76a3df7a62..01ca36742d24 100644 --- a/libs/hwui/BakedOpRenderer.h +++ b/libs/hwui/BakedOpRenderer.h @@ -54,12 +54,13 @@ public: uint8_t spotShadowAlpha; }; - BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, + BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, bool wideColorGamut, const LightInfo& lightInfo) : mGlopReceiver(DefaultGlopReceiver) , mRenderState(renderState) , mCaches(caches) , mOpaque(opaque) + , mWideColorGamut(wideColorGamut) , mLightInfo(lightInfo) { } @@ -118,6 +119,7 @@ private: RenderState& mRenderState; Caches& mCaches; bool mOpaque; + bool mWideColorGamut; bool mHasDrawn = false; // render target state - setup by start/end layer/frame diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp index 959059fede0c..4ef31d59271e 100644 --- a/libs/hwui/Texture.cpp +++ b/libs/hwui/Texture.cpp @@ -120,6 +120,10 @@ void Texture::resetCachedParams() { void Texture::upload(GLint internalFormat, uint32_t width, uint32_t height, GLenum format, GLenum type, const void* pixels) { GL_CHECKPOINT(MODERATE); + + // We don't have color space information, we assume the data is gamma encoded + mIsLinear = false; + bool needsAlloc = updateLayout(width, height, internalFormat, format, GL_TEXTURE_2D); if (!mId) { glGenTextures(1, &mId); @@ -309,11 +313,16 @@ void Texture::upload(Bitmap& bitmap) { bool rgba16fNeedsConversion = bitmap.colorType() == kRGBA_F16_SkColorType && internalFormat != GL_RGBA16F; + // RGBA16F is always linear extended sRGB + if (internalFormat == GL_RGBA16F) { + mIsLinear = true; + } + mConnector.reset(); - // RGBA16F is always extended sRGB, alpha masks don't have color profiles + // Alpha masks don't have color profiles // If an RGBA16F bitmap needs conversion, we know the target will be sRGB - if (internalFormat != GL_RGBA16F && internalFormat != GL_ALPHA && !rgba16fNeedsConversion) { + if (!mIsLinear && internalFormat != GL_ALPHA && !rgba16fNeedsConversion) { SkColorSpace* colorSpace = bitmap.info().colorSpace(); // If the bitmap is sRGB we don't need conversion if (colorSpace != nullptr && !colorSpace->isSRGB()) { diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index 55b74ed9e234..7f742e604838 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -88,7 +88,8 @@ public: * The image data is undefined after calling this. */ void resize(uint32_t width, uint32_t height, GLint internalFormat, GLint format) { - upload(internalFormat, width, height, format, GL_UNSIGNED_BYTE, nullptr); + upload(internalFormat, width, height, format, + internalFormat == GL_RGBA16F ? GL_HALF_FLOAT : GL_UNSIGNED_BYTE, nullptr); } /** @@ -155,7 +156,7 @@ public: * Returns true if this texture uses a linear encoding format. */ constexpr bool isLinear() const { - return mInternalFormat == GL_RGBA16F; + return mIsLinear; } /** @@ -219,6 +220,9 @@ private: GLenum mMinFilter = GL_NEAREST_MIPMAP_LINEAR; GLenum mMagFilter = GL_LINEAR; + // Indicates whether the content of the texture is in linear space + bool mIsLinear = false; + Caches& mCaches; std::unique_ptr<ColorSpaceConnector> mConnector; diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp index 095d32e75911..6d5ef1d4ff1f 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -61,7 +61,7 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty, const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, - const Rect& contentDrawBounds, bool opaque, + const Rect& contentDrawBounds, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo, const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) { @@ -85,7 +85,8 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, mRenderThread.getGrContext(), renderTargetDesc, &props)); SkiaPipeline::updateLighting(lightGeometry, lightInfo); - renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface); + renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, wideColorGamut, + contentDrawBounds, surface); layerUpdateQueue->clear(); // Draw visual debugging features diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h index d5471de06aa3..aa29c8e3babc 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h @@ -35,7 +35,7 @@ public: bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty, const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, - const Rect& contentDrawBounds, bool opaque, + const Rect& contentDrawBounds, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo, const std::vector< sp<RenderNode> >& renderNodes, FrameInfoVisualizer* profiler) override; diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index bbbbd5ce51b2..0bab7932432c 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -72,16 +72,18 @@ void SkiaPipeline::unpinImages() { } void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry, - LayerUpdateQueue* layerUpdateQueue, bool opaque, + LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo) { updateLighting(lightGeometry, lightInfo); ATRACE_NAME("draw layers"); renderVectorDrawableCache(); - renderLayersImpl(*layerUpdateQueue, opaque); + renderLayersImpl(*layerUpdateQueue, opaque, wideColorGamut); layerUpdateQueue->clear(); } -void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) { +void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, + bool opaque, bool wideColorGamut) { + // TODO: Handle wide color gamut // Render all layers that need to be updated, in order. for (size_t i = 0; i < layers.entries().size(); i++) { RenderNode* layerNode = layers.entries()[i].renderNode.get(); @@ -129,12 +131,13 @@ void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) } bool SkiaPipeline::createOrUpdateLayer(RenderNode* node, - const DamageAccumulator& damageAccumulator) { + const DamageAccumulator& damageAccumulator, bool wideColorGamut) { SkSurface* layer = node->getLayerSurface(); if (!layer || layer->width() != node->getWidth() || layer->height() != node->getHeight()) { SkImageInfo info = SkImageInfo::MakeN32Premul(node->getWidth(), node->getHeight()); SkSurfaceProps props(0, kUnknown_SkPixelGeometry); SkASSERT(mRenderThread.getGrContext() != nullptr); + // TODO: Handle wide color gamut requests node->setLayerSurface( SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes, info, 0, &props)); @@ -203,13 +206,13 @@ void SkiaPipeline::renderVectorDrawableCache() { } void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip, - const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds, - sk_sp<SkSurface> surface) { + const std::vector<sp<RenderNode>>& nodes, bool opaque, bool wideColorGamut, + const Rect &contentDrawBounds, sk_sp<SkSurface> surface) { renderVectorDrawableCache(); // draw all layers up front - renderLayersImpl(layers, opaque); + renderLayersImpl(layers, opaque, wideColorGamut); // initialize the canvas for the current frame SkCanvas* canvas = surface->getCanvas(); @@ -227,7 +230,7 @@ void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& cli } } - renderFrameImpl(layers, clip, nodes, opaque, contentDrawBounds, canvas); + renderFrameImpl(layers, clip, nodes, opaque, wideColorGamut, contentDrawBounds, canvas); if (skpCaptureEnabled() && recordingPicture) { sk_sp<SkPicture> picture = recorder->finishRecordingAsPicture(); @@ -260,8 +263,8 @@ static Rect nodeBounds(RenderNode& node) { } void SkiaPipeline::renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip, - const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds, - SkCanvas* canvas) { + const std::vector<sp<RenderNode>>& nodes, bool opaque, bool wideColorGamut, + const Rect &contentDrawBounds, SkCanvas* canvas) { SkAutoCanvasRestore saver(canvas, true); canvas->androidFramework_setDeviceClipRestriction(clip.roundOut()); @@ -388,7 +391,7 @@ void SkiaPipeline::renderOverdraw(const LayerUpdateQueue& layers, const SkRect& // each time a pixel would have been drawn. // Pass true for opaque so we skip the clear - the overdrawCanvas is already zero // initialized. - renderFrameImpl(layers, clip, nodes, true, contentDrawBounds, &overdrawCanvas); + renderFrameImpl(layers, clip, nodes, true, false, contentDrawBounds, &overdrawCanvas); sk_sp<SkImage> counts = offscreen->makeImageSnapshot(); // Draw overdraw colors to the canvas. The color filter will convert counts to colors. diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h index 6f5e719fc2c2..19ffc463c121 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaPipeline.h @@ -39,15 +39,15 @@ public: void unpinImages() override; void renderLayers(const FrameBuilder::LightGeometry& lightGeometry, - LayerUpdateQueue* layerUpdateQueue, bool opaque, + LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo) override; bool createOrUpdateLayer(RenderNode* node, - const DamageAccumulator& damageAccumulator) override; + const DamageAccumulator& damageAccumulator, bool wideColorGamut) override; void renderFrame(const LayerUpdateQueue& layers, const SkRect& clip, - const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds, - sk_sp<SkSurface> surface); + const std::vector< sp<RenderNode> >& nodes, bool opaque, bool wideColorGamut, + const Rect &contentDrawBounds, sk_sp<SkSurface> surface); std::vector<VectorDrawableRoot*>* getVectorDrawables() { return &mVectorDrawables; } @@ -55,7 +55,7 @@ public: static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap); - static void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque); + static void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque, bool wideColorGamut); static bool skpCaptureEnabled() { return false; } @@ -110,8 +110,8 @@ protected: private: void renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip, - const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds, - SkCanvas* canvas); + const std::vector< sp<RenderNode> >& nodes, bool opaque, bool wideColorGamut, + const Rect &contentDrawBounds, SkCanvas* canvas); /** * Debugging feature. Draws a semi-transparent overlay on each pixel, indicating diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index f1ef9e60f997..e1ef71f7d3ab 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -66,7 +66,7 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty, const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, - const Rect& contentDrawBounds, bool opaque, + const Rect& contentDrawBounds, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo, const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) { @@ -76,7 +76,8 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, return false; } SkiaPipeline::updateLighting(lightGeometry, lightInfo); - renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer); + renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, wideColorGamut, + contentDrawBounds, backBuffer); layerUpdateQueue->clear(); // Draw visual debugging features diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h index 3481312d3b21..263206d97571 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h @@ -33,7 +33,7 @@ public: bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty, const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, - const Rect& contentDrawBounds, bool opaque, + const Rect& contentDrawBounds, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo, const std::vector< sp<RenderNode> >& renderNodes, FrameInfoVisualizer* profiler) override; diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp index a9bbb273dbb5..90b27c8d8fb0 100644 --- a/libs/hwui/renderstate/OffscreenBufferPool.cpp +++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp @@ -35,17 +35,19 @@ namespace uirenderer { //////////////////////////////////////////////////////////////////////////////// OffscreenBuffer::OffscreenBuffer(RenderState& renderState, Caches& caches, - uint32_t viewportWidth, uint32_t viewportHeight) + uint32_t viewportWidth, uint32_t viewportHeight, bool wideColorGamut) : GpuMemoryTracker(GpuObjectType::OffscreenBuffer) , renderState(renderState) , viewportWidth(viewportWidth) , viewportHeight(viewportHeight) - , texture(caches) { + , texture(caches) + , wideColorGamut(wideColorGamut) { uint32_t width = computeIdealDimension(viewportWidth); uint32_t height = computeIdealDimension(viewportHeight); ATRACE_FORMAT("Allocate %ux%u HW Layer", width, height); caches.textureState().activateTexture(0); - texture.resize(width, height, caches.rgbaInternalFormat(), GL_RGBA); + texture.resize(width, height, + wideColorGamut ? GL_RGBA16F : caches.rgbaInternalFormat(), GL_RGBA); texture.blend = true; texture.setWrap(GL_CLAMP_TO_EDGE); // not setting filter on texture, since it's set when drawing, based on transform @@ -127,7 +129,10 @@ int OffscreenBufferPool::Entry::compare(const Entry& lhs, const Entry& rhs) { int deltaInt = int(lhs.width) - int(rhs.width); if (deltaInt != 0) return deltaInt; - return int(lhs.height) - int(rhs.height); + deltaInt = int(lhs.height) - int(rhs.height); + if (deltaInt != 0) return deltaInt; + + return int(lhs.wideColorGamut) - int(rhs.wideColorGamut); } void OffscreenBufferPool::clear() { @@ -139,10 +144,10 @@ void OffscreenBufferPool::clear() { } OffscreenBuffer* OffscreenBufferPool::get(RenderState& renderState, - const uint32_t width, const uint32_t height) { + const uint32_t width, const uint32_t height, bool wideColorGamut) { OffscreenBuffer* layer = nullptr; - Entry entry(width, height); + Entry entry(width, height, wideColorGamut); auto iter = mPool.find(entry); if (iter != mPool.end()) { @@ -154,7 +159,8 @@ OffscreenBuffer* OffscreenBufferPool::get(RenderState& renderState, layer->viewportHeight = height; mSize -= layer->getSizeInBytes(); } else { - layer = new OffscreenBuffer(renderState, Caches::getInstance(), width, height); + layer = new OffscreenBuffer(renderState, Caches::getInstance(), + width, height, wideColorGamut); } return layer; @@ -174,7 +180,7 @@ OffscreenBuffer* OffscreenBufferPool::resize(OffscreenBuffer* layer, return layer; } putOrDelete(layer); - return get(renderState, width, height); + return get(renderState, width, height, layer->wideColorGamut); } void OffscreenBufferPool::dump() { diff --git a/libs/hwui/renderstate/OffscreenBufferPool.h b/libs/hwui/renderstate/OffscreenBufferPool.h index 26d4e3654a48..d9422c9edd69 100644 --- a/libs/hwui/renderstate/OffscreenBufferPool.h +++ b/libs/hwui/renderstate/OffscreenBufferPool.h @@ -43,7 +43,7 @@ class RenderState; class OffscreenBuffer : GpuMemoryTracker { public: OffscreenBuffer(RenderState& renderState, Caches& caches, - uint32_t viewportWidth, uint32_t viewportHeight); + uint32_t viewportWidth, uint32_t viewportHeight, bool wideColorGamut = false); ~OffscreenBuffer(); Rect getTextureCoordinates(); @@ -68,6 +68,8 @@ public: uint32_t viewportHeight; Texture texture; + bool wideColorGamut = false; + // Portion of layer that has been drawn to. Used to minimize drawing area when // drawing back to screen / parent FBO. Region region; @@ -90,7 +92,7 @@ public: ~OffscreenBufferPool(); WARN_UNUSED_RESULT OffscreenBuffer* get(RenderState& renderState, - const uint32_t width, const uint32_t height); + const uint32_t width, const uint32_t height, bool wideColorGamut = false); WARN_UNUSED_RESULT OffscreenBuffer* resize(OffscreenBuffer* layer, const uint32_t width, const uint32_t height); @@ -122,14 +124,16 @@ private: struct Entry { Entry() {} - Entry(const uint32_t layerWidth, const uint32_t layerHeight) + Entry(const uint32_t layerWidth, const uint32_t layerHeight, bool wideColorGamut) : width(OffscreenBuffer::computeIdealDimension(layerWidth)) - , height(OffscreenBuffer::computeIdealDimension(layerHeight)) {} + , height(OffscreenBuffer::computeIdealDimension(layerHeight)) + , wideColorGamut(wideColorGamut) {} explicit Entry(OffscreenBuffer* layer) : layer(layer) , width(layer->texture.width()) - , height(layer->texture.height()) { + , height(layer->texture.height()) + , wideColorGamut(layer->wideColorGamut) { } static int compare(const Entry& lhs, const Entry& rhs); @@ -149,6 +153,7 @@ private: OffscreenBuffer* layer = nullptr; uint32_t width = 0; uint32_t height = 0; + bool wideColorGamut = false; }; // struct Entry std::multiset<Entry> mPool; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index a79bf359913b..779924883016 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -421,7 +421,7 @@ void CanvasContext::draw() { SkRect windowDirty = computeDirtyRect(frame, &dirty); bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue, - mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes, &(profiler())); + mContentDrawBounds, mOpaque, mWideColorGamut, mLightInfo, mRenderNodes, &(profiler())); waitOnFences(); @@ -563,7 +563,8 @@ void CanvasContext::buildLayer(RenderNode* node) { // purposes when the frame is actually drawn node->setPropertyFieldsDirty(RenderNode::GENERIC); - mRenderPipeline->renderLayers(mLightGeometry, &mLayerUpdateQueue, mOpaque, mLightInfo); + mRenderPipeline->renderLayers(mLightGeometry, &mLayerUpdateQueue, + mOpaque, mWideColorGamut, mLightInfo); node->incStrong(nullptr); mPrefetchedLayers.insert(node); diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 76623f9ae954..b1f405040a59 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -76,7 +76,7 @@ public: * @return true if the layer has been created or updated */ bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& dmgAccumulator) { - return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator); + return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator, mWideColorGamut); } /** diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h index 46ac0d23637d..f9b6e384d211 100644 --- a/libs/hwui/renderthread/IRenderPipeline.h +++ b/libs/hwui/renderthread/IRenderPipeline.h @@ -59,7 +59,7 @@ public: virtual bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty, const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, - const Rect& contentDrawBounds, bool opaque, + const Rect& contentDrawBounds, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo, const std::vector< sp<RenderNode> >& renderNodes, FrameInfoVisualizer* profiler) = 0; @@ -73,11 +73,11 @@ public: virtual bool isContextReady() = 0; virtual void onDestroyHardwareResources() = 0; virtual void renderLayers(const FrameBuilder::LightGeometry& lightGeometry, - LayerUpdateQueue* layerUpdateQueue, bool opaque, + LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo) = 0; virtual TaskManager* getTaskManager() = 0; virtual bool createOrUpdateLayer(RenderNode* node, - const DamageAccumulator& damageAccumulator) = 0; + const DamageAccumulator& damageAccumulator, bool wideColorGamut) = 0; virtual bool pinImages(std::vector<SkImage*>& mutableImages) = 0; virtual bool pinImages(LsaVector<sk_sp<Bitmap>>& images) = 0; virtual void unpinImages() = 0; diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp index e15d0eb33403..7283eb123d6a 100644 --- a/libs/hwui/renderthread/OpenGLPipeline.cpp +++ b/libs/hwui/renderthread/OpenGLPipeline.cpp @@ -58,7 +58,7 @@ Frame OpenGLPipeline::getFrame() { bool OpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty, const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, - const Rect& contentDrawBounds, bool opaque, + const Rect& contentDrawBounds, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo, const std::vector< sp<RenderNode> >& renderNodes, FrameInfoVisualizer* profiler) { @@ -77,7 +77,7 @@ bool OpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const S frameBuilder.deferRenderNodeScene(renderNodes, contentDrawBounds); BakedOpRenderer renderer(caches, mRenderThread.renderState(), - opaque, lightInfo); + opaque, wideColorGamut, lightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); ProfileRenderer profileRenderer(renderer); profiler->draw(profileRenderer); @@ -184,14 +184,14 @@ void OpenGLPipeline::onDestroyHardwareResources() { } void OpenGLPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry, - LayerUpdateQueue* layerUpdateQueue, bool opaque, + LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo) { static const std::vector< sp<RenderNode> > emptyNodeList; auto& caches = Caches::getInstance(); FrameBuilder frameBuilder(*layerUpdateQueue, lightGeometry, caches); layerUpdateQueue->clear(); - BakedOpRenderer renderer(caches, mRenderThread.renderState(), - opaque, lightInfo); + // TODO: Handle wide color gamut contexts + BakedOpRenderer renderer(caches, mRenderThread.renderState(), opaque, wideColorGamut, lightInfo); LOG_ALWAYS_FATAL_IF(renderer.didDraw(), "shouldn't draw in buildlayer case"); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); } @@ -205,12 +205,13 @@ static bool layerMatchesWH(OffscreenBuffer* layer, int width, int height) { } bool OpenGLPipeline::createOrUpdateLayer(RenderNode* node, - const DamageAccumulator& damageAccumulator) { + const DamageAccumulator& damageAccumulator, bool wideColorGamut) { RenderState& renderState = mRenderThread.renderState(); OffscreenBufferPool& layerPool = renderState.layerPool(); bool transformUpdateNeeded = false; if (node->getLayer() == nullptr) { - node->setLayer(layerPool.get(renderState, node->getWidth(), node->getHeight())); + node->setLayer(layerPool.get(renderState, + node->getWidth(), node->getHeight(), wideColorGamut)); transformUpdateNeeded = true; } else if (!layerMatchesWH(node->getLayer(), node->getWidth(), node->getHeight())) { // TODO: remove now irrelevant, currently enqueued damage (respecting damage ordering) diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h index 0e8c3f553bc7..4ca19fb6245c 100644 --- a/libs/hwui/renderthread/OpenGLPipeline.h +++ b/libs/hwui/renderthread/OpenGLPipeline.h @@ -36,7 +36,7 @@ public: bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty, const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, - const Rect& contentDrawBounds, bool opaque, + const Rect& contentDrawBounds, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo, const std::vector< sp<RenderNode> >& renderNodes, FrameInfoVisualizer* profiler) override; @@ -50,11 +50,11 @@ public: bool isContextReady() override; void onDestroyHardwareResources() override; void renderLayers(const FrameBuilder::LightGeometry& lightGeometry, - LayerUpdateQueue* layerUpdateQueue, bool opaque, + LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo) override; TaskManager* getTaskManager() override; bool createOrUpdateLayer(RenderNode* node, - const DamageAccumulator& damageAccumulator) override; + const DamageAccumulator& damageAccumulator, bool wideColorGamut) override; bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; } bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override; void unpinImages() override; diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp index 398e7a89be1e..a5e85df22c8e 100644 --- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp +++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp @@ -83,7 +83,7 @@ void BM_FrameBuilder_deferAndRender(benchmark::State& state) { sLightGeometry, caches); frameBuilder.deferRenderNode(*node); - BakedOpRenderer renderer(caches, renderState, true, sLightInfo); + BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); benchmark::DoNotOptimize(&renderer); } @@ -142,7 +142,7 @@ void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) { sLightGeometry, Caches::getInstance()); frameBuilder.deferRenderNode(*node); - BakedOpRenderer renderer(caches, renderState, true, sLightInfo); + BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); benchmark::DoNotOptimize(&renderer); } diff --git a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp index c46592c8867a..b0ef11f26bdd 100644 --- a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp +++ b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp @@ -37,7 +37,7 @@ const FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50}; class ValidatingBakedOpRenderer : public BakedOpRenderer { public: ValidatingBakedOpRenderer(RenderState& renderState, std::function<void(const Glop& glop)> validator) - : BakedOpRenderer(Caches::getInstance(), renderState, true, sLightInfo) + : BakedOpRenderer(Caches::getInstance(), renderState, true, false, sLightInfo) , mValidator(validator) { mGlopReceiver = ValidatingGlopReceiver; } diff --git a/libs/hwui/tests/unit/BakedOpRendererTests.cpp b/libs/hwui/tests/unit/BakedOpRendererTests.cpp index 380062a36d45..603599ceb88a 100644 --- a/libs/hwui/tests/unit/BakedOpRendererTests.cpp +++ b/libs/hwui/tests/unit/BakedOpRendererTests.cpp @@ -24,7 +24,8 @@ using namespace android::uirenderer; const BakedOpRenderer::LightInfo sLightInfo = { 128, 128 }; RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpRenderer, startRepaintLayer_clear) { - BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(), true, sLightInfo); + BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(), + true, false, sLightInfo); OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 200u, 200u); layer.dirty(Rect(200, 200)); diff --git a/libs/hwui/tests/unit/LeakCheckTests.cpp b/libs/hwui/tests/unit/LeakCheckTests.cpp index 6c42ca1f2c2e..19d7ef59e397 100644 --- a/libs/hwui/tests/unit/LeakCheckTests.cpp +++ b/libs/hwui/tests/unit/LeakCheckTests.cpp @@ -45,7 +45,7 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(LeakCheck, saveLayer_overdrawRejection) { FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometery, Caches::getInstance()); frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node)); - BakedOpRenderer renderer(caches, renderState, true, sLightInfo); + BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); } @@ -62,6 +62,6 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(LeakCheck, saveLayerUnclipped_simple) { FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometery, Caches::getInstance()); frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node)); - BakedOpRenderer renderer(caches, renderState, true, sLightInfo); + BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); } diff --git a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp index 6cd595af6d2f..919852f6b2d7 100644 --- a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp +++ b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp @@ -41,6 +41,19 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, construct) { EXPECT_EQ(64u * 192u * 4u, layer.getSizeInBytes()); } +RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, constructWideColorGamut) { + OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 49u, 149u, true); + EXPECT_EQ(49u, layer.viewportWidth); + EXPECT_EQ(149u, layer.viewportHeight); + + EXPECT_EQ(64u, layer.texture.width()); + EXPECT_EQ(192u, layer.texture.height()); + + EXPECT_TRUE(layer.wideColorGamut); + + EXPECT_EQ(64u * 192u * 8u, layer.getSizeInBytes()); +} + RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, getTextureCoordinates) { OffscreenBuffer layerAligned(renderThread.renderState(), Caches::getInstance(), 256u, 256u); EXPECT_EQ(Rect(0, 1, 1, 0), @@ -88,6 +101,47 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, getPutClear) { EXPECT_EQ(0u, pool.getCount()); } +RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, getPutClearWideColorGamut) { + OffscreenBufferPool pool; + + auto layer = pool.get(renderThread.renderState(), 100u, 200u, true); + EXPECT_EQ(100u, layer->viewportWidth); + EXPECT_EQ(200u, layer->viewportHeight); + EXPECT_TRUE(layer->wideColorGamut); + + ASSERT_LT(layer->getSizeInBytes(), pool.getMaxSize()); + + pool.putOrDelete(layer); + ASSERT_EQ(layer->getSizeInBytes(), pool.getSize()); + + auto layer2 = pool.get(renderThread.renderState(), 102u, 202u, true); + EXPECT_EQ(layer, layer2) << "layer should be recycled"; + ASSERT_EQ(0u, pool.getSize()) << "pool should have been emptied by removing only layer"; + + pool.putOrDelete(layer2); + EXPECT_EQ(1u, pool.getCount()); + pool.clear(); + EXPECT_EQ(0u, pool.getSize()); + EXPECT_EQ(0u, pool.getCount()); + + // add non wide gamut layer + auto layer3 = pool.get(renderThread.renderState(), 100u, 200u); + EXPECT_FALSE(layer3->wideColorGamut); + pool.putOrDelete(layer3); + EXPECT_EQ(1u, pool.getCount()); + + auto layer4 = pool.get(renderThread.renderState(), 100u, 200u, true); + EXPECT_TRUE(layer4->wideColorGamut); + EXPECT_EQ(1u, pool.getCount()); + ASSERT_NE(layer3, layer4); + + pool.putOrDelete(layer4); + + pool.clear(); + EXPECT_EQ(0u, pool.getSize()); + EXPECT_EQ(0u, pool.getCount()); +} + RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resize) { OffscreenBufferPool pool; @@ -123,6 +177,43 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resize) { pool.putOrDelete(layer2); } +RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resizeWideColorGamut) { + OffscreenBufferPool pool; + + auto layer = pool.get(renderThread.renderState(), 64u, 64u, true); + + // resize in place + ASSERT_EQ(layer, pool.resize(layer, 60u, 55u)); + EXPECT_EQ(60u, layer->viewportWidth); + EXPECT_EQ(55u, layer->viewportHeight); + EXPECT_EQ(64u, layer->texture.width()); + EXPECT_EQ(64u, layer->texture.height()); + + EXPECT_TRUE(layer->wideColorGamut); + EXPECT_EQ(64u * 64u * 8u, layer->getSizeInBytes()); + + // resized to use different object in pool + auto layer2 = pool.get(renderThread.renderState(), 128u, 128u, true); + pool.putOrDelete(layer2); + ASSERT_EQ(1u, pool.getCount()); + + // add a non-wide gamut layer + auto layer3 = pool.get(renderThread.renderState(), 128u, 128u); + pool.putOrDelete(layer3); + ASSERT_EQ(2u, pool.getCount()); + + ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u)); + EXPECT_EQ(120u, layer2->viewportWidth); + EXPECT_EQ(125u, layer2->viewportHeight); + EXPECT_EQ(128u, layer2->texture.width()); + EXPECT_EQ(128u, layer2->texture.height()); + + EXPECT_TRUE(layer2->wideColorGamut); + EXPECT_EQ(128u * 128u * 8u, layer2->getSizeInBytes()); + + pool.putOrDelete(layer2); +} + RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, putAndDestroy) { OffscreenBufferPool pool; // layer too big to return to the pool @@ -153,3 +244,4 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, clear) { EXPECT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer)); } + diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp index 686d06f9cd85..4c3e182ced2f 100644 --- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp +++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp @@ -450,7 +450,7 @@ RENDERTHREAD_TEST(RenderNodeDrawable, projectionHwLayer) { LayerUpdateQueue layerUpdateQueue; layerUpdateQueue.enqueueLayerWithDamage(child.get(), android::uirenderer::Rect(LAYER_WIDTH, LAYER_HEIGHT)); - SkiaPipeline::renderLayersImpl(layerUpdateQueue, true); + SkiaPipeline::renderLayersImpl(layerUpdateQueue, true, false); EXPECT_EQ(1, drawCounter); //assert index 0 is drawn on the layer RenderNodeDrawable drawable(parent.get(), surfaceLayer1->getCanvas(), true); diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp index a895cbad838e..b397b151ad76 100644 --- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp +++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp @@ -51,7 +51,8 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrame) { auto surface = SkSurface::MakeRasterN32Premul(1, 1); surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, + opaque, false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED); } @@ -72,10 +73,12 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckOpaque) { auto surface = SkSurface::MakeRasterN32Premul(2, 2); surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, + true, false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN); - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, false, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, + false, false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned int)SK_ColorTRANSPARENT); ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN); } @@ -94,7 +97,8 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckDirtyRect) { auto surface = SkSurface::MakeRasterN32Premul(2, 2); surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, + true, false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); ASSERT_EQ(TestUtils::getColor(surface, 1, 0), SK_ColorBLUE); ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorRED); @@ -135,7 +139,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderLayer) { lightGeometry.center = { 0.0f, 0.0f, 0.0f }; BakedOpRenderer::LightInfo lightInfo; auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); - pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, lightInfo); + pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, false, lightInfo); ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorRED); ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorBLUE); ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 1), SK_ColorWHITE); @@ -166,32 +170,38 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderOverdraw) { ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); // Single draw, should be white. - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, + false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE); // 1 Overdraw, should be blue blended onto white. renderNodes.push_back(whiteNode); - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, + false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffd0d0ff); // 2 Overdraw, should be green blended onto white renderNodes.push_back(whiteNode); - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, + false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffd0ffd0); // 3 Overdraw, should be pink blended onto white. renderNodes.push_back(whiteNode); - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, + false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffffc0c0); // 4 Overdraw, should be red blended onto white. renderNodes.push_back(whiteNode); - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, + false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffff8080); // 5 Overdraw, should be red blended onto white. renderNodes.push_back(whiteNode); - pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, + false, contentDrawBounds, surface); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffff8080); } @@ -278,7 +288,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, deferRenderNodeScene) { SkRect dirty = SkRect::MakeWH(800, 600); auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); sk_sp<DeferLayer<DeferTestCanvas>> surface(new DeferLayer<DeferTestCanvas>()); - pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, contentDrawBounds, surface); + pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false, contentDrawBounds, surface); EXPECT_EQ(4, surface->canvas()->mDrawCounter); } @@ -308,7 +318,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped) { SkRect dirty = SkRect::MakeLTRB(10, 20, 30, 40); auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); sk_sp<DeferLayer<ClippedTestCanvas>> surface(new DeferLayer<ClippedTestCanvas>()); - pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, + pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false, SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface); EXPECT_EQ(1, surface->canvas()->mDrawCounter); } @@ -339,7 +349,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clip_replace) { SkRect dirty = SkRect::MakeLTRB(10, 10, 40, 40); auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); sk_sp<DeferLayer<ClipReplaceTestCanvas>> surface(new DeferLayer<ClipReplaceTestCanvas>()); - pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, + pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false, SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface); EXPECT_EQ(1, surface->canvas()->mDrawCounter); } |