Loading libs/hwui/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -275,7 +275,9 @@ LOCAL_MULTILIB := both LOCAL_MODULE_STEM_32 := hwuimicro LOCAL_MODULE_STEM_64 := hwuimicro64 LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries) LOCAL_CFLAGS := $(hwui_cflags) LOCAL_CFLAGS := \ $(hwui_cflags) \ -DHWUI_NULL_GPU LOCAL_C_INCLUDES += bionic/benchmarks/ LOCAL_WHOLE_STATIC_LIBRARIES := libhwui_static_null_gpu Loading libs/hwui/DisplayList.h +1 −1 Original line number Diff line number Diff line Loading @@ -132,7 +132,7 @@ public: DisplayList(); ~DisplayList(); // index of DisplayListOp restore, after which projected descendents should be drawn // index of DisplayListOp restore, after which projected descendants should be drawn int projectionReceiveIndex; const LsaVector<Chunk>& getChunks() const { return chunks; } Loading libs/hwui/DisplayListCanvas.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ class DeferredDisplayList; class DeferredLayerUpdater; class DisplayListOp; class DrawOp; class DrawRenderNodeOp; class RenderNode; class StateOp; Loading libs/hwui/DisplayListOp.h +7 −7 Original line number Diff line number Diff line Loading @@ -1386,19 +1386,19 @@ public: : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr) , renderNode(renderNode) , mRecordedWithPotentialStencilClip(!clipIsSimple || !transformFromParent.isSimple()) , mTransformFromParent(transformFromParent) , mSkipInOrderDraw(false) {} , localMatrix(transformFromParent) , skipInOrderDraw(false) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, bool useQuickReject) override { if (renderNode->isRenderable() && !mSkipInOrderDraw) { if (renderNode->isRenderable() && !skipInOrderDraw) { renderNode->defer(deferStruct, level + 1); } } virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, bool useQuickReject) override { if (renderNode->isRenderable() && !mSkipInOrderDraw) { if (renderNode->isRenderable() && !skipInOrderDraw) { renderNode->replay(replayStruct, level + 1); } } Loading Loading @@ -1439,7 +1439,7 @@ private: /** * Records transform vs parent, used for computing total transform without rerunning DL contents */ const mat4 mTransformFromParent; const mat4 localMatrix; /** * Holds the transformation between the projection surface ViewGroup and this RenderNode Loading @@ -1449,8 +1449,8 @@ private: * * Note: doesn't include transformation within the RenderNode, or its properties. */ mat4 mTransformFromCompositingAncestor; bool mSkipInOrderDraw; mat4 transformFromCompositingAncestor; bool skipInOrderDraw; }; /** Loading libs/hwui/OpReorderer.cpp +49 −20 Original line number Diff line number Diff line Loading @@ -330,6 +330,7 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, for (int i = layers.entries().size() - 1; i >= 0; i--) { RenderNode* layerNode = layers.entries()[i].renderNode; const Rect& layerDamage = layers.entries()[i].damage; layerNode->computeOrdering(); // map current light center into RenderNode's coordinate space Vector3 lightCenter = mCanvasState.currentSnapshot()->getRelativeLightCenter(); Loading @@ -339,7 +340,7 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, layerDamage, lightCenter, nullptr, layerNode); if (layerNode->getDisplayList()) { deferDisplayList(*(layerNode->getDisplayList())); deferNodeOps(*layerNode); } restoreForLayer(); } Loading @@ -347,6 +348,7 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, // Defer Fbo0 for (const sp<RenderNode>& node : nodes) { if (node->nothingToDraw()) continue; node->computeOrdering(); int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag); deferNodePropsAndOps(*node); Loading @@ -354,20 +356,6 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, } } OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList, const Vector3& lightCenter) : mCanvasState(*this) { ATRACE_NAME("prepare drawing commands"); // Prepare to defer Fbo0 mLayerReorderers.emplace_back(viewportWidth, viewportHeight, Rect(viewportWidth, viewportHeight)); mLayerStack.push_back(0); mCanvasState.initializeSaveStack(viewportWidth, viewportHeight, 0, 0, viewportWidth, viewportHeight, lightCenter); deferDisplayList(displayList); } void OpReorderer::onViewportInitialized() {} void OpReorderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {} Loading Loading @@ -462,10 +450,10 @@ void OpReorderer::deferNodePropsAndOps(RenderNode& node) { Matrix4::identity(), saveLayerBounds, &saveLayerPaint)); deferDisplayList(*(node.getDisplayList())); deferNodeOps(node); onEndLayerOp(*new (mAllocator) EndLayerOp()); } else { deferDisplayList(*(node.getDisplayList())); deferNodeOps(node); } } } Loading Loading @@ -610,18 +598,53 @@ void OpReorderer::deferShadow(const RenderNodeOp& casterNodeOp) { } } void OpReorderer::deferProjectedChildren(const RenderNode& renderNode) { const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath(); int count = mCanvasState.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); // can't be null, since DL=null node rejection happens before deferNodePropsAndOps const DisplayList& displayList = *(renderNode.getDisplayList()); const RecordedOp* op = (displayList.getOps()[displayList.projectionReceiveIndex]); const RenderNodeOp* backgroundOp = static_cast<const RenderNodeOp*>(op); const RenderProperties& backgroundProps = backgroundOp->renderNode->properties(); // Transform renderer to match background we're projecting onto // (by offsetting canvas by translationX/Y of background rendernode, since only those are set) mCanvasState.translate(backgroundProps.getTranslationX(), backgroundProps.getTranslationY()); // If the projection receiver has an outline, we mask projected content to it // (which we know, apriori, are all tessellated paths) mCanvasState.setProjectionPathMask(mAllocator, projectionReceiverOutline); // draw projected nodes for (size_t i = 0; i < renderNode.mProjectedNodes.size(); i++) { RenderNodeOp* childOp = renderNode.mProjectedNodes[i]; int restoreTo = mCanvasState.save(SkCanvas::kMatrix_SaveFlag); mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor); deferRenderNodeOp(*childOp); mCanvasState.restoreToCount(restoreTo); } mCanvasState.restoreToCount(count); } /** * Used to define a list of lambdas referencing private OpReorderer::onXXXXOp() methods. * * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas. E.g. a * BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&) * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas. * E.g. a BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&) */ #define OP_RECEIVER(Type) \ [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.on##Type(static_cast<const Type&>(op)); }, void OpReorderer::deferDisplayList(const DisplayList& displayList) { void OpReorderer::deferNodeOps(const RenderNode& renderNode) { static std::function<void(OpReorderer& reorderer, const RecordedOp&)> receivers[] = { MAP_OPS(OP_RECEIVER) }; // can't be null, since DL=null node rejection happens before deferNodePropsAndOps const DisplayList& displayList = *(renderNode.getDisplayList()); for (const DisplayList::Chunk& chunk : displayList.getChunks()) { FatVector<ZRenderNodeOpPair, 16> zTranslatedNodes; buildZSortedChildList(&zTranslatedNodes, displayList, chunk); Loading @@ -630,6 +653,12 @@ void OpReorderer::deferDisplayList(const DisplayList& displayList) { for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) { const RecordedOp* op = displayList.getOps()[opIndex]; receivers[op->opId](*this, *op); if (CC_UNLIKELY(!renderNode.mProjectedNodes.empty() && displayList.projectionReceiveIndex >= 0 && static_cast<int>(opIndex) == displayList.projectionReceiveIndex)) { deferProjectedChildren(renderNode); } } defer3dChildren(ChildrenSelectMode::Positive, zTranslatedNodes); } Loading Loading
libs/hwui/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -275,7 +275,9 @@ LOCAL_MULTILIB := both LOCAL_MODULE_STEM_32 := hwuimicro LOCAL_MODULE_STEM_64 := hwuimicro64 LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries) LOCAL_CFLAGS := $(hwui_cflags) LOCAL_CFLAGS := \ $(hwui_cflags) \ -DHWUI_NULL_GPU LOCAL_C_INCLUDES += bionic/benchmarks/ LOCAL_WHOLE_STATIC_LIBRARIES := libhwui_static_null_gpu Loading
libs/hwui/DisplayList.h +1 −1 Original line number Diff line number Diff line Loading @@ -132,7 +132,7 @@ public: DisplayList(); ~DisplayList(); // index of DisplayListOp restore, after which projected descendents should be drawn // index of DisplayListOp restore, after which projected descendants should be drawn int projectionReceiveIndex; const LsaVector<Chunk>& getChunks() const { return chunks; } Loading
libs/hwui/DisplayListCanvas.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ class DeferredDisplayList; class DeferredLayerUpdater; class DisplayListOp; class DrawOp; class DrawRenderNodeOp; class RenderNode; class StateOp; Loading
libs/hwui/DisplayListOp.h +7 −7 Original line number Diff line number Diff line Loading @@ -1386,19 +1386,19 @@ public: : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr) , renderNode(renderNode) , mRecordedWithPotentialStencilClip(!clipIsSimple || !transformFromParent.isSimple()) , mTransformFromParent(transformFromParent) , mSkipInOrderDraw(false) {} , localMatrix(transformFromParent) , skipInOrderDraw(false) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, bool useQuickReject) override { if (renderNode->isRenderable() && !mSkipInOrderDraw) { if (renderNode->isRenderable() && !skipInOrderDraw) { renderNode->defer(deferStruct, level + 1); } } virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, bool useQuickReject) override { if (renderNode->isRenderable() && !mSkipInOrderDraw) { if (renderNode->isRenderable() && !skipInOrderDraw) { renderNode->replay(replayStruct, level + 1); } } Loading Loading @@ -1439,7 +1439,7 @@ private: /** * Records transform vs parent, used for computing total transform without rerunning DL contents */ const mat4 mTransformFromParent; const mat4 localMatrix; /** * Holds the transformation between the projection surface ViewGroup and this RenderNode Loading @@ -1449,8 +1449,8 @@ private: * * Note: doesn't include transformation within the RenderNode, or its properties. */ mat4 mTransformFromCompositingAncestor; bool mSkipInOrderDraw; mat4 transformFromCompositingAncestor; bool skipInOrderDraw; }; /** Loading
libs/hwui/OpReorderer.cpp +49 −20 Original line number Diff line number Diff line Loading @@ -330,6 +330,7 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, for (int i = layers.entries().size() - 1; i >= 0; i--) { RenderNode* layerNode = layers.entries()[i].renderNode; const Rect& layerDamage = layers.entries()[i].damage; layerNode->computeOrdering(); // map current light center into RenderNode's coordinate space Vector3 lightCenter = mCanvasState.currentSnapshot()->getRelativeLightCenter(); Loading @@ -339,7 +340,7 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, layerDamage, lightCenter, nullptr, layerNode); if (layerNode->getDisplayList()) { deferDisplayList(*(layerNode->getDisplayList())); deferNodeOps(*layerNode); } restoreForLayer(); } Loading @@ -347,6 +348,7 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, // Defer Fbo0 for (const sp<RenderNode>& node : nodes) { if (node->nothingToDraw()) continue; node->computeOrdering(); int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag); deferNodePropsAndOps(*node); Loading @@ -354,20 +356,6 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip, } } OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList, const Vector3& lightCenter) : mCanvasState(*this) { ATRACE_NAME("prepare drawing commands"); // Prepare to defer Fbo0 mLayerReorderers.emplace_back(viewportWidth, viewportHeight, Rect(viewportWidth, viewportHeight)); mLayerStack.push_back(0); mCanvasState.initializeSaveStack(viewportWidth, viewportHeight, 0, 0, viewportWidth, viewportHeight, lightCenter); deferDisplayList(displayList); } void OpReorderer::onViewportInitialized() {} void OpReorderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {} Loading Loading @@ -462,10 +450,10 @@ void OpReorderer::deferNodePropsAndOps(RenderNode& node) { Matrix4::identity(), saveLayerBounds, &saveLayerPaint)); deferDisplayList(*(node.getDisplayList())); deferNodeOps(node); onEndLayerOp(*new (mAllocator) EndLayerOp()); } else { deferDisplayList(*(node.getDisplayList())); deferNodeOps(node); } } } Loading Loading @@ -610,18 +598,53 @@ void OpReorderer::deferShadow(const RenderNodeOp& casterNodeOp) { } } void OpReorderer::deferProjectedChildren(const RenderNode& renderNode) { const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath(); int count = mCanvasState.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); // can't be null, since DL=null node rejection happens before deferNodePropsAndOps const DisplayList& displayList = *(renderNode.getDisplayList()); const RecordedOp* op = (displayList.getOps()[displayList.projectionReceiveIndex]); const RenderNodeOp* backgroundOp = static_cast<const RenderNodeOp*>(op); const RenderProperties& backgroundProps = backgroundOp->renderNode->properties(); // Transform renderer to match background we're projecting onto // (by offsetting canvas by translationX/Y of background rendernode, since only those are set) mCanvasState.translate(backgroundProps.getTranslationX(), backgroundProps.getTranslationY()); // If the projection receiver has an outline, we mask projected content to it // (which we know, apriori, are all tessellated paths) mCanvasState.setProjectionPathMask(mAllocator, projectionReceiverOutline); // draw projected nodes for (size_t i = 0; i < renderNode.mProjectedNodes.size(); i++) { RenderNodeOp* childOp = renderNode.mProjectedNodes[i]; int restoreTo = mCanvasState.save(SkCanvas::kMatrix_SaveFlag); mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor); deferRenderNodeOp(*childOp); mCanvasState.restoreToCount(restoreTo); } mCanvasState.restoreToCount(count); } /** * Used to define a list of lambdas referencing private OpReorderer::onXXXXOp() methods. * * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas. E.g. a * BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&) * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas. * E.g. a BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&) */ #define OP_RECEIVER(Type) \ [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.on##Type(static_cast<const Type&>(op)); }, void OpReorderer::deferDisplayList(const DisplayList& displayList) { void OpReorderer::deferNodeOps(const RenderNode& renderNode) { static std::function<void(OpReorderer& reorderer, const RecordedOp&)> receivers[] = { MAP_OPS(OP_RECEIVER) }; // can't be null, since DL=null node rejection happens before deferNodePropsAndOps const DisplayList& displayList = *(renderNode.getDisplayList()); for (const DisplayList::Chunk& chunk : displayList.getChunks()) { FatVector<ZRenderNodeOpPair, 16> zTranslatedNodes; buildZSortedChildList(&zTranslatedNodes, displayList, chunk); Loading @@ -630,6 +653,12 @@ void OpReorderer::deferDisplayList(const DisplayList& displayList) { for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) { const RecordedOp* op = displayList.getOps()[opIndex]; receivers[op->opId](*this, *op); if (CC_UNLIKELY(!renderNode.mProjectedNodes.empty() && displayList.projectionReceiveIndex >= 0 && static_cast<int>(opIndex) == displayList.projectionReceiveIndex)) { deferProjectedChildren(renderNode); } } defer3dChildren(ChildrenSelectMode::Positive, zTranslatedNodes); } Loading