Loading libs/hwui/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -206,7 +206,9 @@ LOCAL_MODULE := hwui_unit_tests LOCAL_MODULE_TAGS := tests LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries) LOCAL_STATIC_LIBRARIES := libhwui_static_null_gpu LOCAL_CFLAGS := $(hwui_cflags) LOCAL_CFLAGS := \ $(hwui_cflags) \ -DHWUI_NULL_GPU LOCAL_SRC_FILES += \ unit_tests/CanvasStateTests.cpp \ Loading libs/hwui/BakedOpRenderer.cpp +25 −18 Original line number Diff line number Diff line Loading @@ -35,11 +35,11 @@ OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t h LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height); startRepaintLayer(buffer); startRepaintLayer(buffer, Rect(width, height)); return buffer; } void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer) { void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) { LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); mRenderTarget.offscreenBuffer = offscreenBuffer; Loading @@ -55,12 +55,10 @@ void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer) { LOG_ALWAYS_FATAL_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "framebuffer incomplete!"); // Clear the FBO mRenderState.scissor().setEnabled(false); glClear(GL_COLOR_BUFFER_BIT); // Change the viewport & ortho projection setViewport(offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight); clearColorBuffer(repaintRect); } void BakedOpRenderer::endLayer() { Loading @@ -74,16 +72,13 @@ void BakedOpRenderer::endLayer() { mRenderTarget.frameBufferId = -1; } void BakedOpRenderer::startFrame(uint32_t width, uint32_t height) { void BakedOpRenderer::startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) { mRenderState.bindFramebuffer(0); setViewport(width, height); mCaches.clearGarbage(); if (!mOpaque) { // TODO: partial invalidate! mRenderState.scissor().setEnabled(false); glClear(GL_COLOR_BUFFER_BIT); mHasDrawn = true; clearColorBuffer(repaintRect); } } Loading Loading @@ -113,6 +108,20 @@ void BakedOpRenderer::setViewport(uint32_t width, uint32_t height) { mRenderState.blend().syncEnabled(); } void BakedOpRenderer::clearColorBuffer(const Rect& rect) { if (Rect(mRenderTarget.viewportWidth, mRenderTarget.viewportHeight).contains(rect)) { // Full viewport is being cleared - disable scissor mRenderState.scissor().setEnabled(false); } else { // Requested rect is subset of viewport - scissor to it to avoid over-clearing mRenderState.scissor().setEnabled(true); mRenderState.scissor().set(rect.left, mRenderTarget.viewportHeight - rect.bottom, rect.getWidth(), rect.getHeight()); } glClear(GL_COLOR_BUFFER_BIT); if (!mRenderTarget.frameBufferId) mHasDrawn = true; } Texture* BakedOpRenderer::getTexture(const SkBitmap* bitmap) { Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap); if (!texture) { Loading @@ -136,7 +145,7 @@ void BakedOpRenderer::renderGlop(const BakedOpState& state, const Glop& glop) { mRenderTarget.offscreenBuffer->region.orSelf(dirty); } mRenderState.render(glop, mRenderTarget.orthoMatrix); mHasDrawn = true; if (!mRenderTarget.frameBufferId) mHasDrawn = true; } //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -217,7 +226,7 @@ static void renderShadow(BakedOpRenderer& renderer, const BakedOpState& state, f paint.setAntiAlias(true); // want to use AlphaVertex // The caller has made sure casterAlpha > 0. uint8_t ambientShadowAlpha = 128u; //TODO: mAmbientShadowAlpha; uint8_t ambientShadowAlpha = renderer.getLightInfo().ambientShadowAlpha; if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) { ambientShadowAlpha = Properties::overrideAmbientShadowStrength; } Loading @@ -227,7 +236,7 @@ static void renderShadow(BakedOpRenderer& renderer, const BakedOpState& state, f paint, VertexBufferRenderFlags::ShadowInterp); } uint8_t spotShadowAlpha = 128u; //TODO: mSpotShadowAlpha; uint8_t spotShadowAlpha = renderer.getLightInfo().spotShadowAlpha; if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) { spotShadowAlpha = Properties::overrideSpotShadowStrength; } Loading @@ -240,12 +249,10 @@ static void renderShadow(BakedOpRenderer& renderer, const BakedOpState& state, f void BakedOpDispatcher::onShadowOp(BakedOpRenderer& renderer, const ShadowOp& op, const BakedOpState& state) { TessellationCache::vertexBuffer_pair_t buffers; Vector3 lightCenter = { 300, 300, 300 }; // TODO! float lightRadius = 150; // TODO! renderer.caches().tessellationCache.getShadowBuffers(&state.computedState.transform, op.localClipRect, op.casterAlpha >= 1.0f, op.casterPath, &op.shadowMatrixXY, &op.shadowMatrixZ, lightCenter, lightRadius, &op.shadowMatrixXY, &op.shadowMatrixZ, op.lightCenter, renderer.getLightInfo().lightRadius, buffers); renderShadow(renderer, state, op.casterAlpha, buffers.first, buffers.second); Loading libs/hwui/BakedOpRenderer.h +18 −4 Original line number Diff line number Diff line Loading @@ -39,27 +39,39 @@ class RenderState; */ class BakedOpRenderer { public: BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque) /** * Position agnostic shadow lighting info. Used with all shadow ops in scene. */ struct LightInfo { float lightRadius = 0; uint8_t ambientShadowAlpha = 0; uint8_t spotShadowAlpha = 0; }; BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, const LightInfo& lightInfo) : mRenderState(renderState) , mCaches(caches) , mOpaque(opaque) { , mOpaque(opaque) , mLightInfo(lightInfo) { } RenderState& renderState() { return mRenderState; } Caches& caches() { return mCaches; } void startFrame(uint32_t width, uint32_t height); void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect); void endFrame(); OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height); void startRepaintLayer(OffscreenBuffer* offscreenBuffer); void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect); void endLayer(); Texture* getTexture(const SkBitmap* bitmap); const LightInfo& getLightInfo() { return mLightInfo; } void renderGlop(const BakedOpState& state, const Glop& glop); bool didDraw() { return mHasDrawn; } private: void setViewport(uint32_t width, uint32_t height); void clearColorBuffer(const Rect& clearRect); RenderState& mRenderState; Caches& mCaches; Loading @@ -75,6 +87,8 @@ private: uint32_t viewportHeight = 0; Matrix4 orthoMatrix; } mRenderTarget; const LightInfo mLightInfo; }; /** Loading libs/hwui/OpReorderer.cpp +46 −16 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include "LayerUpdateQueue.h" #include "RenderNode.h" #include "renderstate/OffscreenBufferPool.h" #include "utils/FatVector.h" #include "utils/PaintUtils.h" Loading Loading @@ -207,9 +208,10 @@ private: }; OpReorderer::LayerReorderer::LayerReorderer(uint32_t width, uint32_t height, const BeginLayerOp* beginLayerOp, RenderNode* renderNode) const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode) : width(width) , height(height) , repaintRect(repaintRect) , offscreenBuffer(renderNode ? renderNode->getLayer() : nullptr) , beginLayerOp(beginLayerOp) , renderNode(renderNode) {} Loading Loading @@ -309,15 +311,19 @@ void OpReorderer::LayerReorderer::dump() const { OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes) const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter) : mCanvasState(*this) { ATRACE_NAME("prepare drawing commands"); mLayerReorderers.emplace_back(viewportWidth, viewportHeight); mLayerStack.push_back(0); mLayerReorderers.reserve(layers.entries().size()); mLayerStack.reserve(layers.entries().size()); // Prepare to defer Fbo0 mLayerReorderers.emplace_back(viewportWidth, viewportHeight, Rect(clip)); mLayerStack.push_back(0); mCanvasState.initializeSaveStack(viewportWidth, viewportHeight, clip.fLeft, clip.fTop, clip.fRight, clip.fBottom, Vector3()); lightCenter); // Render all layers to be updated, in order. Defer in reverse order, so that they'll be // updated in the order they're passed in (mLayerReorderers are issued to Renderer in reverse) Loading @@ -325,7 +331,8 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, RenderNode* layerNode = layers.entries()[i].renderNode; const Rect& layerDamage = layers.entries()[i].damage; saveForLayer(layerNode->getWidth(), layerNode->getHeight(), nullptr, layerNode); saveForLayer(layerNode->getWidth(), layerNode->getHeight(), layerDamage, nullptr, layerNode); mCanvasState.writableSnapshot()->setClip( layerDamage.left, layerDamage.top, layerDamage.right, layerDamage.bottom); Loading @@ -345,14 +352,17 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, } } OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList) OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList, const Vector3& lightCenter) : mCanvasState(*this) { ATRACE_NAME("prepare drawing commands"); mLayerReorderers.emplace_back(viewportWidth, viewportHeight); // Prepare to defer Fbo0 mLayerReorderers.emplace_back(viewportWidth, viewportHeight, Rect(viewportWidth, viewportHeight)); mLayerStack.push_back(0); mCanvasState.initializeSaveStack(viewportWidth, viewportHeight, 0, 0, viewportWidth, viewportHeight, Vector3()); 0, 0, viewportWidth, viewportHeight, lightCenter); deferImpl(displayList); } Loading Loading @@ -508,7 +518,8 @@ void OpReorderer::deferShadow(const RenderNodeOp& casterNodeOp) { } ShadowOp* shadowOp = new (mAllocator) ShadowOp(casterNodeOp, casterAlpha, casterPath, mCanvasState.getLocalClipBounds()); mCanvasState.getLocalClipBounds(), mCanvasState.currentSnapshot()->getRelativeLightCenter()); BakedOpState* bakedOpState = BakedOpState::tryShadowOpConstruct( mAllocator, *mCanvasState.currentSnapshot(), shadowOp); if (CC_LIKELY(bakedOpState)) { Loading Loading @@ -589,17 +600,36 @@ void OpReorderer::onSimpleRectsOp(const SimpleRectsOp& op) { currentLayer().deferUnmergeableOp(mAllocator, bakedStateOp, OpBatchType::Vertices); } void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode) { auto previous = mCanvasState.currentSnapshot(); mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag); mCanvasState.writableSnapshot()->transform->loadIdentity(); mCanvasState.writableSnapshot()->initializeViewport(layerWidth, layerHeight); mCanvasState.writableSnapshot()->roundRectClipState = nullptr; Vector3 lightCenter = previous->getRelativeLightCenter(); if (renderNode) { Matrix4& inverse = renderNode->getLayer()->inverseTransformInWindow; inverse.mapPoint3d(lightCenter); } else { // Combine all transforms used to present saveLayer content: // parent content transform * canvas transform * bounds offset Matrix4 contentTransform(*previous->transform); contentTransform.multiply(beginLayerOp->localMatrix); contentTransform.translate(beginLayerOp->unmappedBounds.left, beginLayerOp->unmappedBounds.top); // inverse the total transform, to map light center into layer-relative space Matrix4 inverse; inverse.loadInverse(contentTransform); inverse.mapPoint3d(lightCenter); } mCanvasState.writableSnapshot()->setRelativeLightCenter(lightCenter); // create a new layer, and push its index on the stack mLayerStack.push_back(mLayerReorderers.size()); mLayerReorderers.emplace_back(layerWidth, layerHeight, beginLayerOp, renderNode); mLayerReorderers.emplace_back(layerWidth, layerHeight, repaintRect, beginLayerOp, renderNode); } void OpReorderer::restoreForLayer() { Loading @@ -612,7 +642,7 @@ void OpReorderer::restoreForLayer() { void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) { const uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth(); const uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight(); saveForLayer(layerWidth, layerHeight, &op, nullptr); saveForLayer(layerWidth, layerHeight, Rect(layerWidth, layerHeight), &op, nullptr); } void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) { Loading libs/hwui/OpReorderer.h +11 −9 Original line number Diff line number Diff line Loading @@ -67,13 +67,13 @@ class OpReorderer : public CanvasStateClient { class LayerReorderer { public: // Create LayerReorderer for Fbo0 LayerReorderer(uint32_t width, uint32_t height) : LayerReorderer(width, height, nullptr, nullptr) {}; LayerReorderer(uint32_t width, uint32_t height, const Rect& repaintRect) : LayerReorderer(width, height, repaintRect, nullptr, nullptr) {}; // Create LayerReorderer for an offscreen layer, where beginLayerOp is present for a // saveLayer, renderNode is present for a HW layer. LayerReorderer(uint32_t width, uint32_t height, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); // iterate back toward target to see if anything drawn since should overlap the new op // if no target, merging ops still iterate to find similar batch to insert after Loading Loading @@ -101,6 +101,7 @@ class OpReorderer : public CanvasStateClient { const uint32_t width; const uint32_t height; const Rect repaintRect; OffscreenBuffer* offscreenBuffer; const BeginLayerOp* beginLayerOp; const RenderNode* renderNode; Loading @@ -116,14 +117,15 @@ class OpReorderer : public CanvasStateClient { // Maps batch ids to the most recent *non-merging* batch of that id OpBatch* mBatchLookup[OpBatchType::Count] = { nullptr }; }; public: OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes); const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter); OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList); OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList, const Vector3& lightCenter); virtual ~OpReorderer() {} Loading Loading @@ -153,7 +155,7 @@ public: LayerReorderer& layer = mLayerReorderers[i]; if (layer.renderNode) { // cached HW layer - can't skip layer if empty renderer.startRepaintLayer(layer.offscreenBuffer); renderer.startRepaintLayer(layer.offscreenBuffer, layer.repaintRect); layer.replayBakedOpsImpl((void*)&renderer, receivers); renderer.endLayer(); } else if (!layer.empty()) { // save layer - skip entire layer if empty Loading @@ -164,7 +166,7 @@ public: } const LayerReorderer& fbo0 = mLayerReorderers[0]; renderer.startFrame(fbo0.width, fbo0.height); renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect); fbo0.replayBakedOpsImpl((void*)&renderer, receivers); renderer.endFrame(); } Loading @@ -188,7 +190,7 @@ private: Positive }; void saveForLayer(uint32_t layerWidth, uint32_t layerHeight, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); void restoreForLayer(); LayerReorderer& currentLayer() { return mLayerReorderers[mLayerStack.back()]; } Loading Loading
libs/hwui/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -206,7 +206,9 @@ LOCAL_MODULE := hwui_unit_tests LOCAL_MODULE_TAGS := tests LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries) LOCAL_STATIC_LIBRARIES := libhwui_static_null_gpu LOCAL_CFLAGS := $(hwui_cflags) LOCAL_CFLAGS := \ $(hwui_cflags) \ -DHWUI_NULL_GPU LOCAL_SRC_FILES += \ unit_tests/CanvasStateTests.cpp \ Loading
libs/hwui/BakedOpRenderer.cpp +25 −18 Original line number Diff line number Diff line Loading @@ -35,11 +35,11 @@ OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t h LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height); startRepaintLayer(buffer); startRepaintLayer(buffer, Rect(width, height)); return buffer; } void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer) { void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) { LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); mRenderTarget.offscreenBuffer = offscreenBuffer; Loading @@ -55,12 +55,10 @@ void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer) { LOG_ALWAYS_FATAL_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "framebuffer incomplete!"); // Clear the FBO mRenderState.scissor().setEnabled(false); glClear(GL_COLOR_BUFFER_BIT); // Change the viewport & ortho projection setViewport(offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight); clearColorBuffer(repaintRect); } void BakedOpRenderer::endLayer() { Loading @@ -74,16 +72,13 @@ void BakedOpRenderer::endLayer() { mRenderTarget.frameBufferId = -1; } void BakedOpRenderer::startFrame(uint32_t width, uint32_t height) { void BakedOpRenderer::startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) { mRenderState.bindFramebuffer(0); setViewport(width, height); mCaches.clearGarbage(); if (!mOpaque) { // TODO: partial invalidate! mRenderState.scissor().setEnabled(false); glClear(GL_COLOR_BUFFER_BIT); mHasDrawn = true; clearColorBuffer(repaintRect); } } Loading Loading @@ -113,6 +108,20 @@ void BakedOpRenderer::setViewport(uint32_t width, uint32_t height) { mRenderState.blend().syncEnabled(); } void BakedOpRenderer::clearColorBuffer(const Rect& rect) { if (Rect(mRenderTarget.viewportWidth, mRenderTarget.viewportHeight).contains(rect)) { // Full viewport is being cleared - disable scissor mRenderState.scissor().setEnabled(false); } else { // Requested rect is subset of viewport - scissor to it to avoid over-clearing mRenderState.scissor().setEnabled(true); mRenderState.scissor().set(rect.left, mRenderTarget.viewportHeight - rect.bottom, rect.getWidth(), rect.getHeight()); } glClear(GL_COLOR_BUFFER_BIT); if (!mRenderTarget.frameBufferId) mHasDrawn = true; } Texture* BakedOpRenderer::getTexture(const SkBitmap* bitmap) { Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap); if (!texture) { Loading @@ -136,7 +145,7 @@ void BakedOpRenderer::renderGlop(const BakedOpState& state, const Glop& glop) { mRenderTarget.offscreenBuffer->region.orSelf(dirty); } mRenderState.render(glop, mRenderTarget.orthoMatrix); mHasDrawn = true; if (!mRenderTarget.frameBufferId) mHasDrawn = true; } //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -217,7 +226,7 @@ static void renderShadow(BakedOpRenderer& renderer, const BakedOpState& state, f paint.setAntiAlias(true); // want to use AlphaVertex // The caller has made sure casterAlpha > 0. uint8_t ambientShadowAlpha = 128u; //TODO: mAmbientShadowAlpha; uint8_t ambientShadowAlpha = renderer.getLightInfo().ambientShadowAlpha; if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) { ambientShadowAlpha = Properties::overrideAmbientShadowStrength; } Loading @@ -227,7 +236,7 @@ static void renderShadow(BakedOpRenderer& renderer, const BakedOpState& state, f paint, VertexBufferRenderFlags::ShadowInterp); } uint8_t spotShadowAlpha = 128u; //TODO: mSpotShadowAlpha; uint8_t spotShadowAlpha = renderer.getLightInfo().spotShadowAlpha; if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) { spotShadowAlpha = Properties::overrideSpotShadowStrength; } Loading @@ -240,12 +249,10 @@ static void renderShadow(BakedOpRenderer& renderer, const BakedOpState& state, f void BakedOpDispatcher::onShadowOp(BakedOpRenderer& renderer, const ShadowOp& op, const BakedOpState& state) { TessellationCache::vertexBuffer_pair_t buffers; Vector3 lightCenter = { 300, 300, 300 }; // TODO! float lightRadius = 150; // TODO! renderer.caches().tessellationCache.getShadowBuffers(&state.computedState.transform, op.localClipRect, op.casterAlpha >= 1.0f, op.casterPath, &op.shadowMatrixXY, &op.shadowMatrixZ, lightCenter, lightRadius, &op.shadowMatrixXY, &op.shadowMatrixZ, op.lightCenter, renderer.getLightInfo().lightRadius, buffers); renderShadow(renderer, state, op.casterAlpha, buffers.first, buffers.second); Loading
libs/hwui/BakedOpRenderer.h +18 −4 Original line number Diff line number Diff line Loading @@ -39,27 +39,39 @@ class RenderState; */ class BakedOpRenderer { public: BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque) /** * Position agnostic shadow lighting info. Used with all shadow ops in scene. */ struct LightInfo { float lightRadius = 0; uint8_t ambientShadowAlpha = 0; uint8_t spotShadowAlpha = 0; }; BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, const LightInfo& lightInfo) : mRenderState(renderState) , mCaches(caches) , mOpaque(opaque) { , mOpaque(opaque) , mLightInfo(lightInfo) { } RenderState& renderState() { return mRenderState; } Caches& caches() { return mCaches; } void startFrame(uint32_t width, uint32_t height); void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect); void endFrame(); OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height); void startRepaintLayer(OffscreenBuffer* offscreenBuffer); void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect); void endLayer(); Texture* getTexture(const SkBitmap* bitmap); const LightInfo& getLightInfo() { return mLightInfo; } void renderGlop(const BakedOpState& state, const Glop& glop); bool didDraw() { return mHasDrawn; } private: void setViewport(uint32_t width, uint32_t height); void clearColorBuffer(const Rect& clearRect); RenderState& mRenderState; Caches& mCaches; Loading @@ -75,6 +87,8 @@ private: uint32_t viewportHeight = 0; Matrix4 orthoMatrix; } mRenderTarget; const LightInfo mLightInfo; }; /** Loading
libs/hwui/OpReorderer.cpp +46 −16 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include "LayerUpdateQueue.h" #include "RenderNode.h" #include "renderstate/OffscreenBufferPool.h" #include "utils/FatVector.h" #include "utils/PaintUtils.h" Loading Loading @@ -207,9 +208,10 @@ private: }; OpReorderer::LayerReorderer::LayerReorderer(uint32_t width, uint32_t height, const BeginLayerOp* beginLayerOp, RenderNode* renderNode) const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode) : width(width) , height(height) , repaintRect(repaintRect) , offscreenBuffer(renderNode ? renderNode->getLayer() : nullptr) , beginLayerOp(beginLayerOp) , renderNode(renderNode) {} Loading Loading @@ -309,15 +311,19 @@ void OpReorderer::LayerReorderer::dump() const { OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes) const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter) : mCanvasState(*this) { ATRACE_NAME("prepare drawing commands"); mLayerReorderers.emplace_back(viewportWidth, viewportHeight); mLayerStack.push_back(0); mLayerReorderers.reserve(layers.entries().size()); mLayerStack.reserve(layers.entries().size()); // Prepare to defer Fbo0 mLayerReorderers.emplace_back(viewportWidth, viewportHeight, Rect(clip)); mLayerStack.push_back(0); mCanvasState.initializeSaveStack(viewportWidth, viewportHeight, clip.fLeft, clip.fTop, clip.fRight, clip.fBottom, Vector3()); lightCenter); // Render all layers to be updated, in order. Defer in reverse order, so that they'll be // updated in the order they're passed in (mLayerReorderers are issued to Renderer in reverse) Loading @@ -325,7 +331,8 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, RenderNode* layerNode = layers.entries()[i].renderNode; const Rect& layerDamage = layers.entries()[i].damage; saveForLayer(layerNode->getWidth(), layerNode->getHeight(), nullptr, layerNode); saveForLayer(layerNode->getWidth(), layerNode->getHeight(), layerDamage, nullptr, layerNode); mCanvasState.writableSnapshot()->setClip( layerDamage.left, layerDamage.top, layerDamage.right, layerDamage.bottom); Loading @@ -345,14 +352,17 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, } } OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList) OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList, const Vector3& lightCenter) : mCanvasState(*this) { ATRACE_NAME("prepare drawing commands"); mLayerReorderers.emplace_back(viewportWidth, viewportHeight); // Prepare to defer Fbo0 mLayerReorderers.emplace_back(viewportWidth, viewportHeight, Rect(viewportWidth, viewportHeight)); mLayerStack.push_back(0); mCanvasState.initializeSaveStack(viewportWidth, viewportHeight, 0, 0, viewportWidth, viewportHeight, Vector3()); 0, 0, viewportWidth, viewportHeight, lightCenter); deferImpl(displayList); } Loading Loading @@ -508,7 +518,8 @@ void OpReorderer::deferShadow(const RenderNodeOp& casterNodeOp) { } ShadowOp* shadowOp = new (mAllocator) ShadowOp(casterNodeOp, casterAlpha, casterPath, mCanvasState.getLocalClipBounds()); mCanvasState.getLocalClipBounds(), mCanvasState.currentSnapshot()->getRelativeLightCenter()); BakedOpState* bakedOpState = BakedOpState::tryShadowOpConstruct( mAllocator, *mCanvasState.currentSnapshot(), shadowOp); if (CC_LIKELY(bakedOpState)) { Loading Loading @@ -589,17 +600,36 @@ void OpReorderer::onSimpleRectsOp(const SimpleRectsOp& op) { currentLayer().deferUnmergeableOp(mAllocator, bakedStateOp, OpBatchType::Vertices); } void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode) { auto previous = mCanvasState.currentSnapshot(); mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag); mCanvasState.writableSnapshot()->transform->loadIdentity(); mCanvasState.writableSnapshot()->initializeViewport(layerWidth, layerHeight); mCanvasState.writableSnapshot()->roundRectClipState = nullptr; Vector3 lightCenter = previous->getRelativeLightCenter(); if (renderNode) { Matrix4& inverse = renderNode->getLayer()->inverseTransformInWindow; inverse.mapPoint3d(lightCenter); } else { // Combine all transforms used to present saveLayer content: // parent content transform * canvas transform * bounds offset Matrix4 contentTransform(*previous->transform); contentTransform.multiply(beginLayerOp->localMatrix); contentTransform.translate(beginLayerOp->unmappedBounds.left, beginLayerOp->unmappedBounds.top); // inverse the total transform, to map light center into layer-relative space Matrix4 inverse; inverse.loadInverse(contentTransform); inverse.mapPoint3d(lightCenter); } mCanvasState.writableSnapshot()->setRelativeLightCenter(lightCenter); // create a new layer, and push its index on the stack mLayerStack.push_back(mLayerReorderers.size()); mLayerReorderers.emplace_back(layerWidth, layerHeight, beginLayerOp, renderNode); mLayerReorderers.emplace_back(layerWidth, layerHeight, repaintRect, beginLayerOp, renderNode); } void OpReorderer::restoreForLayer() { Loading @@ -612,7 +642,7 @@ void OpReorderer::restoreForLayer() { void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) { const uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth(); const uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight(); saveForLayer(layerWidth, layerHeight, &op, nullptr); saveForLayer(layerWidth, layerHeight, Rect(layerWidth, layerHeight), &op, nullptr); } void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) { Loading
libs/hwui/OpReorderer.h +11 −9 Original line number Diff line number Diff line Loading @@ -67,13 +67,13 @@ class OpReorderer : public CanvasStateClient { class LayerReorderer { public: // Create LayerReorderer for Fbo0 LayerReorderer(uint32_t width, uint32_t height) : LayerReorderer(width, height, nullptr, nullptr) {}; LayerReorderer(uint32_t width, uint32_t height, const Rect& repaintRect) : LayerReorderer(width, height, repaintRect, nullptr, nullptr) {}; // Create LayerReorderer for an offscreen layer, where beginLayerOp is present for a // saveLayer, renderNode is present for a HW layer. LayerReorderer(uint32_t width, uint32_t height, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); // iterate back toward target to see if anything drawn since should overlap the new op // if no target, merging ops still iterate to find similar batch to insert after Loading Loading @@ -101,6 +101,7 @@ class OpReorderer : public CanvasStateClient { const uint32_t width; const uint32_t height; const Rect repaintRect; OffscreenBuffer* offscreenBuffer; const BeginLayerOp* beginLayerOp; const RenderNode* renderNode; Loading @@ -116,14 +117,15 @@ class OpReorderer : public CanvasStateClient { // Maps batch ids to the most recent *non-merging* batch of that id OpBatch* mBatchLookup[OpBatchType::Count] = { nullptr }; }; public: OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes); const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter); OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList); OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList, const Vector3& lightCenter); virtual ~OpReorderer() {} Loading Loading @@ -153,7 +155,7 @@ public: LayerReorderer& layer = mLayerReorderers[i]; if (layer.renderNode) { // cached HW layer - can't skip layer if empty renderer.startRepaintLayer(layer.offscreenBuffer); renderer.startRepaintLayer(layer.offscreenBuffer, layer.repaintRect); layer.replayBakedOpsImpl((void*)&renderer, receivers); renderer.endLayer(); } else if (!layer.empty()) { // save layer - skip entire layer if empty Loading @@ -164,7 +166,7 @@ public: } const LayerReorderer& fbo0 = mLayerReorderers[0]; renderer.startFrame(fbo0.width, fbo0.height); renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect); fbo0.replayBakedOpsImpl((void*)&renderer, receivers); renderer.endFrame(); } Loading @@ -188,7 +190,7 @@ private: Positive }; void saveForLayer(uint32_t layerWidth, uint32_t layerHeight, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); void restoreForLayer(); LayerReorderer& currentLayer() { return mLayerReorderers[mLayerStack.back()]; } Loading