Loading libs/hwui/Android.mk +4 −4 Original line number Diff line number Diff line Loading @@ -109,8 +109,8 @@ ifeq (true, $(HWUI_NEW_OPS)) BakedOpDispatcher.cpp \ BakedOpRenderer.cpp \ BakedOpState.cpp \ FrameReorderer.cpp \ LayerReorderer.cpp \ FrameBuilder.cpp \ LayerBuilder.cpp \ RecordingCanvas.cpp hwui_cflags += -DHWUI_NEW_OPS Loading Loading @@ -237,7 +237,7 @@ LOCAL_SRC_FILES += \ ifeq (true, $(HWUI_NEW_OPS)) LOCAL_SRC_FILES += \ tests/unit/BakedOpStateTests.cpp \ tests/unit/FrameReordererTests.cpp \ tests/unit/FrameBuilderTests.cpp \ tests/unit/RecordingCanvasTests.cpp endif Loading Loading @@ -299,7 +299,7 @@ LOCAL_SRC_FILES += \ ifeq (true, $(HWUI_NEW_OPS)) LOCAL_SRC_FILES += \ tests/microbench/FrameReordererBench.cpp tests/microbench/FrameBuilderBench.cpp endif include $(BUILD_EXECUTABLE) libs/hwui/FrameReorderer.cpp→libs/hwui/FrameBuilder.cpp +49 −49 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ #include "FrameReorderer.h" #include "FrameBuilder.h" #include "LayerUpdateQueue.h" #include "RenderNode.h" Loading @@ -30,25 +30,25 @@ namespace android { namespace uirenderer { FrameReorderer::FrameReorderer(const LayerUpdateQueue& layers, const SkRect& clip, FrameBuilder::FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter) : mCanvasState(*this) { ATRACE_NAME("prepare drawing commands"); mLayerReorderers.reserve(layers.entries().size()); mLayerBuilders.reserve(layers.entries().size()); mLayerStack.reserve(layers.entries().size()); // Prepare to defer Fbo0 auto fbo0 = mAllocator.create<LayerReorderer>(viewportWidth, viewportHeight, Rect(clip)); mLayerReorderers.push_back(fbo0); auto fbo0 = mAllocator.create<LayerBuilder>(viewportWidth, viewportHeight, Rect(clip)); mLayerBuilders.push_back(fbo0); mLayerStack.push_back(0); mCanvasState.initializeSaveStack(viewportWidth, viewportHeight, clip.fLeft, clip.fTop, clip.fRight, clip.fBottom, 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) // updated in the order they're passed in (mLayerBuilders are issued to Renderer in reverse) for (int i = layers.entries().size() - 1; i >= 0; i--) { RenderNode* layerNode = layers.entries()[i].renderNode; const Rect& layerDamage = layers.entries()[i].damage; Loading Loading @@ -78,11 +78,11 @@ FrameReorderer::FrameReorderer(const LayerUpdateQueue& layers, const SkRect& cli } } void FrameReorderer::onViewportInitialized() {} void FrameBuilder::onViewportInitialized() {} void FrameReorderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {} void FrameBuilder::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {} void FrameReorderer::deferNodePropsAndOps(RenderNode& node) { void FrameBuilder::deferNodePropsAndOps(RenderNode& node) { const RenderProperties& properties = node.properties(); const Outline& outline = properties.getOutline(); if (properties.getAlpha() <= 0 Loading Loading @@ -214,7 +214,7 @@ static size_t findNonNegativeIndex(const V& zTranslatedNodes) { } template <typename V> void FrameReorderer::defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedNodes) { void FrameBuilder::defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedNodes) { const int size = zTranslatedNodes.size(); if (size == 0 || (mode == ChildrenSelectMode::Negative&& zTranslatedNodes[0].key > 0.0f) Loading Loading @@ -264,7 +264,7 @@ void FrameReorderer::defer3dChildren(ChildrenSelectMode mode, const V& zTranslat } } void FrameReorderer::deferShadow(const RenderNodeOp& casterNodeOp) { void FrameBuilder::deferShadow(const RenderNodeOp& casterNodeOp) { auto& node = *casterNodeOp.renderNode; auto& properties = node.properties(); Loading Loading @@ -320,7 +320,7 @@ void FrameReorderer::deferShadow(const RenderNodeOp& casterNodeOp) { } } void FrameReorderer::deferProjectedChildren(const RenderNode& renderNode) { void FrameBuilder::deferProjectedChildren(const RenderNode& renderNode) { const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath(); int count = mCanvasState.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); Loading Loading @@ -353,15 +353,15 @@ void FrameReorderer::deferProjectedChildren(const RenderNode& renderNode) { } /** * Used to define a list of lambdas referencing private FrameReorderer::onXX::defer() methods. * Used to define a list of lambdas referencing private FrameBuilder::onXX::defer() 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 FrameReorderer::onBitmapOp(const BitmapOp&) * E.g. a BitmapOp op then would be dispatched to FrameBuilder::onBitmapOp(const BitmapOp&) */ #define OP_RECEIVER(Type) \ [](FrameReorderer& reorderer, const RecordedOp& op) { reorderer.defer##Type(static_cast<const Type&>(op)); }, void FrameReorderer::deferNodeOps(const RenderNode& renderNode) { typedef void (*OpDispatcher) (FrameReorderer& reorderer, const RecordedOp& op); [](FrameBuilder& frameBuilder, const RecordedOp& op) { frameBuilder.defer##Type(static_cast<const Type&>(op)); }, void FrameBuilder::deferNodeOps(const RenderNode& renderNode) { typedef void (*OpDispatcher) (FrameBuilder& frameBuilder, const RecordedOp& op); static OpDispatcher receivers[] = BUILD_DEFERRABLE_OP_LUT(OP_RECEIVER); // can't be null, since DL=null node rejection happens before deferNodePropsAndOps Loading @@ -385,7 +385,7 @@ void FrameReorderer::deferNodeOps(const RenderNode& renderNode) { } } void FrameReorderer::deferRenderNodeOpImpl(const RenderNodeOp& op) { void FrameBuilder::deferRenderNodeOpImpl(const RenderNodeOp& op) { if (op.renderNode->nothingToDraw()) return; int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag); Loading @@ -400,7 +400,7 @@ void FrameReorderer::deferRenderNodeOpImpl(const RenderNodeOp& op) { mCanvasState.restoreToCount(count); } void FrameReorderer::deferRenderNodeOp(const RenderNodeOp& op) { void FrameBuilder::deferRenderNodeOp(const RenderNodeOp& op) { if (!op.skipInOrderDraw) { deferRenderNodeOpImpl(op); } Loading @@ -410,7 +410,7 @@ void FrameReorderer::deferRenderNodeOp(const RenderNodeOp& op) { * Defers an unmergeable, strokeable op, accounting correctly * for paint's style on the bounds being computed. */ void FrameReorderer::deferStrokeableOp(const RecordedOp& op, batchid_t batchId, void FrameBuilder::deferStrokeableOp(const RecordedOp& op, batchid_t batchId, BakedOpState::StrokeBehavior strokeBehavior) { // Note: here we account for stroke when baking the op BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct( Loading @@ -432,7 +432,7 @@ static batchid_t tessBatchId(const RecordedOp& op) { : (paint.isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices); } void FrameReorderer::deferArcOp(const ArcOp& op) { void FrameBuilder::deferArcOp(const ArcOp& op) { deferStrokeableOp(op, tessBatchId(op)); } Loading @@ -441,7 +441,7 @@ static bool hasMergeableClip(const BakedOpState& state) { || state.computedState.clipState->mode == ClipMode::Rectangle; } void FrameReorderer::deferBitmapOp(const BitmapOp& op) { void FrameBuilder::deferBitmapOp(const BitmapOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -461,19 +461,19 @@ void FrameReorderer::deferBitmapOp(const BitmapOp& op) { } } void FrameReorderer::deferBitmapMeshOp(const BitmapMeshOp& op) { void FrameBuilder::deferBitmapMeshOp(const BitmapMeshOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap); } void FrameReorderer::deferBitmapRectOp(const BitmapRectOp& op) { void FrameBuilder::deferBitmapRectOp(const BitmapRectOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap); } void FrameReorderer::deferCirclePropsOp(const CirclePropsOp& op) { void FrameBuilder::deferCirclePropsOp(const CirclePropsOp& op) { // allocate a temporary oval op (with mAllocator, so it persists until render), so the // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple. float x = *(op.x); Loading @@ -488,22 +488,22 @@ void FrameReorderer::deferCirclePropsOp(const CirclePropsOp& op) { deferOvalOp(*resolvedOp); } void FrameReorderer::deferFunctorOp(const FunctorOp& op) { void FrameBuilder::deferFunctorOp(const FunctorOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Functor); } void FrameReorderer::deferLinesOp(const LinesOp& op) { void FrameBuilder::deferLinesOp(const LinesOp& op) { batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices; deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); } void FrameReorderer::deferOvalOp(const OvalOp& op) { void FrameBuilder::deferOvalOp(const OvalOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void FrameReorderer::deferPatchOp(const PatchOp& op) { void FrameBuilder::deferPatchOp(const PatchOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -521,24 +521,24 @@ void FrameReorderer::deferPatchOp(const PatchOp& op) { } } void FrameReorderer::deferPathOp(const PathOp& op) { void FrameBuilder::deferPathOp(const PathOp& op) { deferStrokeableOp(op, OpBatchType::Bitmap); } void FrameReorderer::deferPointsOp(const PointsOp& op) { void FrameBuilder::deferPointsOp(const PointsOp& op) { batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices; deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); } void FrameReorderer::deferRectOp(const RectOp& op) { void FrameBuilder::deferRectOp(const RectOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void FrameReorderer::deferRoundRectOp(const RoundRectOp& op) { void FrameBuilder::deferRoundRectOp(const RoundRectOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void FrameReorderer::deferRoundRectPropsOp(const RoundRectPropsOp& op) { void FrameBuilder::deferRoundRectPropsOp(const RoundRectPropsOp& op) { // allocate a temporary round rect op (with mAllocator, so it persists until render), so the // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple. const RoundRectOp* resolvedOp = new (mAllocator) RoundRectOp( Loading @@ -549,7 +549,7 @@ void FrameReorderer::deferRoundRectPropsOp(const RoundRectPropsOp& op) { deferRoundRectOp(*resolvedOp); } void FrameReorderer::deferSimpleRectsOp(const SimpleRectsOp& op) { void FrameBuilder::deferSimpleRectsOp(const SimpleRectsOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices); Loading @@ -560,7 +560,7 @@ static batchid_t textBatchId(const SkPaint& paint) { return paint.getColor() == SK_ColorBLACK ? OpBatchType::Text : OpBatchType::ColorText; } void FrameReorderer::deferTextOp(const TextOp& op) { void FrameBuilder::deferTextOp(const TextOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -575,19 +575,19 @@ void FrameReorderer::deferTextOp(const TextOp& op) { } } void FrameReorderer::deferTextOnPathOp(const TextOnPathOp& op) { void FrameBuilder::deferTextOnPathOp(const TextOnPathOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, textBatchId(*(op.paint))); } void FrameReorderer::deferTextureLayerOp(const TextureLayerOp& op) { void FrameBuilder::deferTextureLayerOp(const TextureLayerOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::TextureLayer); } void FrameReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, void FrameBuilder::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, float contentTranslateX, float contentTranslateY, const Rect& repaintRect, const Vector3& lightCenter, Loading @@ -602,13 +602,13 @@ void FrameReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, repaintRect.left, repaintRect.top, repaintRect.right, repaintRect.bottom); // create a new layer repaint, and push its index on the stack mLayerStack.push_back(mLayerReorderers.size()); auto newFbo = mAllocator.create<LayerReorderer>(layerWidth, layerHeight, mLayerStack.push_back(mLayerBuilders.size()); auto newFbo = mAllocator.create<LayerBuilder>(layerWidth, layerHeight, repaintRect, beginLayerOp, renderNode); mLayerReorderers.push_back(newFbo); mLayerBuilders.push_back(newFbo); } void FrameReorderer::restoreForLayer() { void FrameBuilder::restoreForLayer() { // restore canvas, and pop finished layer off of the stack mCanvasState.restore(); mLayerStack.pop_back(); Loading @@ -616,7 +616,7 @@ void FrameReorderer::restoreForLayer() { // TODO: defer time rejection (when bounds become empty) + tests // Option - just skip layers with no bounds at playback + defer? void FrameReorderer::deferBeginLayerOp(const BeginLayerOp& op) { void FrameBuilder::deferBeginLayerOp(const BeginLayerOp& op) { uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth(); uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight(); Loading Loading @@ -661,7 +661,7 @@ void FrameReorderer::deferBeginLayerOp(const BeginLayerOp& op) { &op, nullptr); } void FrameReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) { void FrameBuilder::deferEndLayerOp(const EndLayerOp& /* ignored */) { const BeginLayerOp& beginLayerOp = *currentLayer().beginLayerOp; int finishedLayerIndex = mLayerStack.back(); Loading @@ -674,7 +674,7 @@ void FrameReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) { beginLayerOp.localMatrix, beginLayerOp.localClip, beginLayerOp.paint, &(mLayerReorderers[finishedLayerIndex]->offscreenBuffer)); &(mLayerBuilders[finishedLayerIndex]->offscreenBuffer)); BakedOpState* bakedOpState = tryBakeOpState(*drawLayerOp); if (bakedOpState) { Loading @@ -684,12 +684,12 @@ void FrameReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) { // Layer won't be drawn - delete its drawing batches to prevent it from doing any work // TODO: need to prevent any render work from being done // - create layerop earlier for reject purposes? mLayerReorderers[finishedLayerIndex]->clear(); mLayerBuilders[finishedLayerIndex]->clear(); return; } } void FrameReorderer::deferBeginUnclippedLayerOp(const BeginUnclippedLayerOp& op) { void FrameBuilder::deferBeginUnclippedLayerOp(const BeginUnclippedLayerOp& op) { Matrix4 boundsTransform(*(mCanvasState.currentSnapshot()->transform)); boundsTransform.multiply(op.localMatrix); Loading Loading @@ -724,7 +724,7 @@ void FrameReorderer::deferBeginUnclippedLayerOp(const BeginUnclippedLayerOp& op) currentLayer().activeUnclippedSaveLayers.push_back(bakedState); } void FrameReorderer::deferEndUnclippedLayerOp(const EndUnclippedLayerOp& /* ignored */) { void FrameBuilder::deferEndUnclippedLayerOp(const EndUnclippedLayerOp& /* ignored */) { LOG_ALWAYS_FATAL_IF(currentLayer().activeUnclippedSaveLayers.empty(), "no layer to end!"); BakedOpState* copyFromLayerOp = currentLayer().activeUnclippedSaveLayers.back(); Loading libs/hwui/FrameReorderer.h→libs/hwui/FrameBuilder.h +15 −15 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ #include "BakedOpState.h" #include "CanvasState.h" #include "DisplayList.h" #include "LayerReorderer.h" #include "LayerBuilder.h" #include "RecordedOp.h" #include <vector> Loading @@ -42,7 +42,7 @@ class Rect; * Resolves final drawing state for each operation (including clip, alpha and matrix), and then * reorder and merge each op as it is resolved for drawing efficiency. Each layer of content (either * from the LayerUpdateQueue, or temporary layers created by saveLayer operations in the * draw stream) will create different reorder contexts, each in its own LayerReorderer. * draw stream) will create different reorder contexts, each in its own LayerBuilder. * * Then the prepared or 'baked' drawing commands can be issued by calling the templated * replayBakedOps() function, which will dispatch them (including any created merged op collections) Loading @@ -52,13 +52,13 @@ class Rect; * This class is also the authoritative source for traversing RenderNodes, both for standard op * traversal within a DisplayList, and for out of order RenderNode traversal for Z and projection. */ class FrameReorderer : public CanvasStateClient { class FrameBuilder : public CanvasStateClient { public: FrameReorderer(const LayerUpdateQueue& layers, const SkRect& clip, FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter); virtual ~FrameReorderer() {} virtual ~FrameBuilder() {} /** * replayBakedOps() is templated based on what class will receive ops being replayed. Loading Loading @@ -98,8 +98,8 @@ public: // Relay through layers in reverse order, since layers // later in the list will be drawn by earlier ones for (int i = mLayerReorderers.size() - 1; i >= 1; i--) { LayerReorderer& layer = *(mLayerReorderers[i]); for (int i = mLayerBuilders.size() - 1; i >= 1; i--) { LayerBuilder& layer = *(mLayerBuilders[i]); if (layer.renderNode) { // cached HW layer - can't skip layer if empty renderer.startRepaintLayer(layer.offscreenBuffer, layer.repaintRect); Loading @@ -112,14 +112,14 @@ public: } } const LayerReorderer& fbo0 = *(mLayerReorderers[0]); const LayerBuilder& fbo0 = *(mLayerBuilders[0]); renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect); fbo0.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers); renderer.endFrame(fbo0.repaintRect); } void dump() const { for (auto&& layer : mLayerReorderers) { for (auto&& layer : mLayerBuilders) { layer->dump(); } } Loading @@ -143,7 +143,7 @@ private: const BeginLayerOp* beginLayerOp, RenderNode* renderNode); void restoreForLayer(); LayerReorderer& currentLayer() { return *(mLayerReorderers[mLayerStack.back()]); } LayerBuilder& currentLayer() { return *(mLayerBuilders[mLayerStack.back()]); } BakedOpState* tryBakeOpState(const RecordedOp& recordedOp) { return BakedOpState::tryConstruct(mAllocator, *mCanvasState.writableSnapshot(), recordedOp); Loading Loading @@ -173,7 +173,7 @@ private: BakedOpState::StrokeBehavior strokeBehavior = BakedOpState::StrokeBehavior::StyleDefined); /** * Declares all FrameReorderer::deferXXXXOp() methods for every RecordedOp type. * Declares all FrameBuilder::deferXXXXOp() methods for every RecordedOp type. * * These private methods are called from within deferImpl to defer each individual op * type differently. Loading @@ -183,17 +183,17 @@ private: #undef X // List of every deferred layer's render state. Replayed in reverse order to render a frame. std::vector<LayerReorderer*> mLayerReorderers; std::vector<LayerBuilder*> mLayerBuilders; /* * Stack of indices within mLayerReorderers representing currently active layers. If drawing * Stack of indices within mLayerBuilders representing currently active layers. If drawing * layerA within a layerB, will contain, in order: * - 0 (representing FBO 0, always present) * - layerB's index * - layerA's index * * Note that this doesn't vector doesn't always map onto all values of mLayerReorderers. When a * layer is finished deferring, it will still be represented in mLayerReorderers, but it's index * Note that this doesn't vector doesn't always map onto all values of mLayerBuilders. When a * layer is finished deferring, it will still be represented in mLayerBuilders, but it's index * won't be in mLayerStack. This is because it can be replayed, but can't have any more drawing * ops added to it. */ Loading libs/hwui/LayerReorderer.cpp→libs/hwui/LayerBuilder.cpp +10 −10 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ #include "LayerReorderer.h" #include "LayerBuilder.h" #include "BakedOpState.h" #include "RenderNode.h" Loading Loading @@ -202,7 +202,7 @@ private: int mClipSideFlags; }; LayerReorderer::LayerReorderer(uint32_t width, uint32_t height, LayerBuilder::LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode) : width(width) , height(height) Loading @@ -214,7 +214,7 @@ LayerReorderer::LayerReorderer(uint32_t width, uint32_t height, // 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 void LayerReorderer::locateInsertIndex(int batchId, const Rect& clippedBounds, void LayerBuilder::locateInsertIndex(int batchId, const Rect& clippedBounds, BatchBase** targetBatch, size_t* insertBatchIndex) const { for (int i = mBatches.size() - 1; i >= 0; i--) { BatchBase* overBatch = mBatches[i]; Loading @@ -237,11 +237,11 @@ void LayerReorderer::locateInsertIndex(int batchId, const Rect& clippedBounds, } } void LayerReorderer::deferLayerClear(const Rect& rect) { void LayerBuilder::deferLayerClear(const Rect& rect) { mClearRects.push_back(rect); } void LayerReorderer::flushLayerClears(LinearAllocator& allocator) { void LayerBuilder::flushLayerClears(LinearAllocator& allocator) { if (CC_UNLIKELY(!mClearRects.empty())) { const int vertCount = mClearRects.size() * 4; // put the verts in the frame allocator, since Loading Loading @@ -273,7 +273,7 @@ void LayerReorderer::flushLayerClears(LinearAllocator& allocator) { } } void LayerReorderer::deferUnmergeableOp(LinearAllocator& allocator, void LayerBuilder::deferUnmergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId) { if (batchId != OpBatchType::CopyToLayer) { // if first op after one or more unclipped saveLayers, flush the layer clears Loading @@ -298,7 +298,7 @@ void LayerReorderer::deferUnmergeableOp(LinearAllocator& allocator, } } void LayerReorderer::deferMergeableOp(LinearAllocator& allocator, void LayerBuilder::deferMergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId, mergeid_t mergeId) { if (batchId != OpBatchType::CopyToLayer) { // if first op after one or more unclipped saveLayers, flush the layer clears Loading Loading @@ -330,7 +330,7 @@ void LayerReorderer::deferMergeableOp(LinearAllocator& allocator, } } void LayerReorderer::replayBakedOpsImpl(void* arg, void LayerBuilder::replayBakedOpsImpl(void* arg, BakedOpReceiver* unmergedReceivers, MergedOpReceiver* mergedReceivers) const { ATRACE_NAME("flush drawing commands"); for (const BatchBase* batch : mBatches) { Loading @@ -353,8 +353,8 @@ void LayerReorderer::replayBakedOpsImpl(void* arg, } } void LayerReorderer::dump() const { ALOGD("LayerReorderer %p, %ux%u buffer %p, blo %p, rn %p", void LayerBuilder::dump() const { ALOGD("LayerBuilder %p, %ux%u buffer %p, blo %p, rn %p", this, width, height, offscreenBuffer, beginLayerOp, renderNode); for (const BatchBase* batch : mBatches) { batch->dump(); Loading libs/hwui/LayerReorderer.h→libs/hwui/LayerBuilder.h +7 −7 Original line number Diff line number Diff line Loading @@ -67,17 +67,17 @@ typedef void (*MergedOpReceiver)(void*, const MergedBakedOpList& opList); * Stores the deferred render operations and state used to compute ordering * for a single FBO/layer. */ class LayerReorderer { class LayerBuilder { // Prevent copy/assign because users may stash pointer to offscreenBuffer and viewportClip PREVENT_COPY_AND_ASSIGN(LayerReorderer); PREVENT_COPY_AND_ASSIGN(LayerBuilder); public: // Create LayerReorderer for Fbo0 LayerReorderer(uint32_t width, uint32_t height, const Rect& repaintRect) : LayerReorderer(width, height, repaintRect, nullptr, nullptr) {}; // Create LayerBuilder for Fbo0 LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect) : LayerBuilder(width, height, repaintRect, nullptr, nullptr) {}; // Create LayerReorderer for an offscreen layer, where beginLayerOp is present for a // Create LayerBuilder 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, LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); // iterate back toward target to see if anything drawn since should overlap the new op Loading Loading
libs/hwui/Android.mk +4 −4 Original line number Diff line number Diff line Loading @@ -109,8 +109,8 @@ ifeq (true, $(HWUI_NEW_OPS)) BakedOpDispatcher.cpp \ BakedOpRenderer.cpp \ BakedOpState.cpp \ FrameReorderer.cpp \ LayerReorderer.cpp \ FrameBuilder.cpp \ LayerBuilder.cpp \ RecordingCanvas.cpp hwui_cflags += -DHWUI_NEW_OPS Loading Loading @@ -237,7 +237,7 @@ LOCAL_SRC_FILES += \ ifeq (true, $(HWUI_NEW_OPS)) LOCAL_SRC_FILES += \ tests/unit/BakedOpStateTests.cpp \ tests/unit/FrameReordererTests.cpp \ tests/unit/FrameBuilderTests.cpp \ tests/unit/RecordingCanvasTests.cpp endif Loading Loading @@ -299,7 +299,7 @@ LOCAL_SRC_FILES += \ ifeq (true, $(HWUI_NEW_OPS)) LOCAL_SRC_FILES += \ tests/microbench/FrameReordererBench.cpp tests/microbench/FrameBuilderBench.cpp endif include $(BUILD_EXECUTABLE)
libs/hwui/FrameReorderer.cpp→libs/hwui/FrameBuilder.cpp +49 −49 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ #include "FrameReorderer.h" #include "FrameBuilder.h" #include "LayerUpdateQueue.h" #include "RenderNode.h" Loading @@ -30,25 +30,25 @@ namespace android { namespace uirenderer { FrameReorderer::FrameReorderer(const LayerUpdateQueue& layers, const SkRect& clip, FrameBuilder::FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter) : mCanvasState(*this) { ATRACE_NAME("prepare drawing commands"); mLayerReorderers.reserve(layers.entries().size()); mLayerBuilders.reserve(layers.entries().size()); mLayerStack.reserve(layers.entries().size()); // Prepare to defer Fbo0 auto fbo0 = mAllocator.create<LayerReorderer>(viewportWidth, viewportHeight, Rect(clip)); mLayerReorderers.push_back(fbo0); auto fbo0 = mAllocator.create<LayerBuilder>(viewportWidth, viewportHeight, Rect(clip)); mLayerBuilders.push_back(fbo0); mLayerStack.push_back(0); mCanvasState.initializeSaveStack(viewportWidth, viewportHeight, clip.fLeft, clip.fTop, clip.fRight, clip.fBottom, 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) // updated in the order they're passed in (mLayerBuilders are issued to Renderer in reverse) for (int i = layers.entries().size() - 1; i >= 0; i--) { RenderNode* layerNode = layers.entries()[i].renderNode; const Rect& layerDamage = layers.entries()[i].damage; Loading Loading @@ -78,11 +78,11 @@ FrameReorderer::FrameReorderer(const LayerUpdateQueue& layers, const SkRect& cli } } void FrameReorderer::onViewportInitialized() {} void FrameBuilder::onViewportInitialized() {} void FrameReorderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {} void FrameBuilder::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {} void FrameReorderer::deferNodePropsAndOps(RenderNode& node) { void FrameBuilder::deferNodePropsAndOps(RenderNode& node) { const RenderProperties& properties = node.properties(); const Outline& outline = properties.getOutline(); if (properties.getAlpha() <= 0 Loading Loading @@ -214,7 +214,7 @@ static size_t findNonNegativeIndex(const V& zTranslatedNodes) { } template <typename V> void FrameReorderer::defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedNodes) { void FrameBuilder::defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedNodes) { const int size = zTranslatedNodes.size(); if (size == 0 || (mode == ChildrenSelectMode::Negative&& zTranslatedNodes[0].key > 0.0f) Loading Loading @@ -264,7 +264,7 @@ void FrameReorderer::defer3dChildren(ChildrenSelectMode mode, const V& zTranslat } } void FrameReorderer::deferShadow(const RenderNodeOp& casterNodeOp) { void FrameBuilder::deferShadow(const RenderNodeOp& casterNodeOp) { auto& node = *casterNodeOp.renderNode; auto& properties = node.properties(); Loading Loading @@ -320,7 +320,7 @@ void FrameReorderer::deferShadow(const RenderNodeOp& casterNodeOp) { } } void FrameReorderer::deferProjectedChildren(const RenderNode& renderNode) { void FrameBuilder::deferProjectedChildren(const RenderNode& renderNode) { const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath(); int count = mCanvasState.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); Loading Loading @@ -353,15 +353,15 @@ void FrameReorderer::deferProjectedChildren(const RenderNode& renderNode) { } /** * Used to define a list of lambdas referencing private FrameReorderer::onXX::defer() methods. * Used to define a list of lambdas referencing private FrameBuilder::onXX::defer() 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 FrameReorderer::onBitmapOp(const BitmapOp&) * E.g. a BitmapOp op then would be dispatched to FrameBuilder::onBitmapOp(const BitmapOp&) */ #define OP_RECEIVER(Type) \ [](FrameReorderer& reorderer, const RecordedOp& op) { reorderer.defer##Type(static_cast<const Type&>(op)); }, void FrameReorderer::deferNodeOps(const RenderNode& renderNode) { typedef void (*OpDispatcher) (FrameReorderer& reorderer, const RecordedOp& op); [](FrameBuilder& frameBuilder, const RecordedOp& op) { frameBuilder.defer##Type(static_cast<const Type&>(op)); }, void FrameBuilder::deferNodeOps(const RenderNode& renderNode) { typedef void (*OpDispatcher) (FrameBuilder& frameBuilder, const RecordedOp& op); static OpDispatcher receivers[] = BUILD_DEFERRABLE_OP_LUT(OP_RECEIVER); // can't be null, since DL=null node rejection happens before deferNodePropsAndOps Loading @@ -385,7 +385,7 @@ void FrameReorderer::deferNodeOps(const RenderNode& renderNode) { } } void FrameReorderer::deferRenderNodeOpImpl(const RenderNodeOp& op) { void FrameBuilder::deferRenderNodeOpImpl(const RenderNodeOp& op) { if (op.renderNode->nothingToDraw()) return; int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag); Loading @@ -400,7 +400,7 @@ void FrameReorderer::deferRenderNodeOpImpl(const RenderNodeOp& op) { mCanvasState.restoreToCount(count); } void FrameReorderer::deferRenderNodeOp(const RenderNodeOp& op) { void FrameBuilder::deferRenderNodeOp(const RenderNodeOp& op) { if (!op.skipInOrderDraw) { deferRenderNodeOpImpl(op); } Loading @@ -410,7 +410,7 @@ void FrameReorderer::deferRenderNodeOp(const RenderNodeOp& op) { * Defers an unmergeable, strokeable op, accounting correctly * for paint's style on the bounds being computed. */ void FrameReorderer::deferStrokeableOp(const RecordedOp& op, batchid_t batchId, void FrameBuilder::deferStrokeableOp(const RecordedOp& op, batchid_t batchId, BakedOpState::StrokeBehavior strokeBehavior) { // Note: here we account for stroke when baking the op BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct( Loading @@ -432,7 +432,7 @@ static batchid_t tessBatchId(const RecordedOp& op) { : (paint.isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices); } void FrameReorderer::deferArcOp(const ArcOp& op) { void FrameBuilder::deferArcOp(const ArcOp& op) { deferStrokeableOp(op, tessBatchId(op)); } Loading @@ -441,7 +441,7 @@ static bool hasMergeableClip(const BakedOpState& state) { || state.computedState.clipState->mode == ClipMode::Rectangle; } void FrameReorderer::deferBitmapOp(const BitmapOp& op) { void FrameBuilder::deferBitmapOp(const BitmapOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -461,19 +461,19 @@ void FrameReorderer::deferBitmapOp(const BitmapOp& op) { } } void FrameReorderer::deferBitmapMeshOp(const BitmapMeshOp& op) { void FrameBuilder::deferBitmapMeshOp(const BitmapMeshOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap); } void FrameReorderer::deferBitmapRectOp(const BitmapRectOp& op) { void FrameBuilder::deferBitmapRectOp(const BitmapRectOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap); } void FrameReorderer::deferCirclePropsOp(const CirclePropsOp& op) { void FrameBuilder::deferCirclePropsOp(const CirclePropsOp& op) { // allocate a temporary oval op (with mAllocator, so it persists until render), so the // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple. float x = *(op.x); Loading @@ -488,22 +488,22 @@ void FrameReorderer::deferCirclePropsOp(const CirclePropsOp& op) { deferOvalOp(*resolvedOp); } void FrameReorderer::deferFunctorOp(const FunctorOp& op) { void FrameBuilder::deferFunctorOp(const FunctorOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Functor); } void FrameReorderer::deferLinesOp(const LinesOp& op) { void FrameBuilder::deferLinesOp(const LinesOp& op) { batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices; deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); } void FrameReorderer::deferOvalOp(const OvalOp& op) { void FrameBuilder::deferOvalOp(const OvalOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void FrameReorderer::deferPatchOp(const PatchOp& op) { void FrameBuilder::deferPatchOp(const PatchOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -521,24 +521,24 @@ void FrameReorderer::deferPatchOp(const PatchOp& op) { } } void FrameReorderer::deferPathOp(const PathOp& op) { void FrameBuilder::deferPathOp(const PathOp& op) { deferStrokeableOp(op, OpBatchType::Bitmap); } void FrameReorderer::deferPointsOp(const PointsOp& op) { void FrameBuilder::deferPointsOp(const PointsOp& op) { batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices; deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); } void FrameReorderer::deferRectOp(const RectOp& op) { void FrameBuilder::deferRectOp(const RectOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void FrameReorderer::deferRoundRectOp(const RoundRectOp& op) { void FrameBuilder::deferRoundRectOp(const RoundRectOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void FrameReorderer::deferRoundRectPropsOp(const RoundRectPropsOp& op) { void FrameBuilder::deferRoundRectPropsOp(const RoundRectPropsOp& op) { // allocate a temporary round rect op (with mAllocator, so it persists until render), so the // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple. const RoundRectOp* resolvedOp = new (mAllocator) RoundRectOp( Loading @@ -549,7 +549,7 @@ void FrameReorderer::deferRoundRectPropsOp(const RoundRectPropsOp& op) { deferRoundRectOp(*resolvedOp); } void FrameReorderer::deferSimpleRectsOp(const SimpleRectsOp& op) { void FrameBuilder::deferSimpleRectsOp(const SimpleRectsOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices); Loading @@ -560,7 +560,7 @@ static batchid_t textBatchId(const SkPaint& paint) { return paint.getColor() == SK_ColorBLACK ? OpBatchType::Text : OpBatchType::ColorText; } void FrameReorderer::deferTextOp(const TextOp& op) { void FrameBuilder::deferTextOp(const TextOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -575,19 +575,19 @@ void FrameReorderer::deferTextOp(const TextOp& op) { } } void FrameReorderer::deferTextOnPathOp(const TextOnPathOp& op) { void FrameBuilder::deferTextOnPathOp(const TextOnPathOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, textBatchId(*(op.paint))); } void FrameReorderer::deferTextureLayerOp(const TextureLayerOp& op) { void FrameBuilder::deferTextureLayerOp(const TextureLayerOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::TextureLayer); } void FrameReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, void FrameBuilder::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, float contentTranslateX, float contentTranslateY, const Rect& repaintRect, const Vector3& lightCenter, Loading @@ -602,13 +602,13 @@ void FrameReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, repaintRect.left, repaintRect.top, repaintRect.right, repaintRect.bottom); // create a new layer repaint, and push its index on the stack mLayerStack.push_back(mLayerReorderers.size()); auto newFbo = mAllocator.create<LayerReorderer>(layerWidth, layerHeight, mLayerStack.push_back(mLayerBuilders.size()); auto newFbo = mAllocator.create<LayerBuilder>(layerWidth, layerHeight, repaintRect, beginLayerOp, renderNode); mLayerReorderers.push_back(newFbo); mLayerBuilders.push_back(newFbo); } void FrameReorderer::restoreForLayer() { void FrameBuilder::restoreForLayer() { // restore canvas, and pop finished layer off of the stack mCanvasState.restore(); mLayerStack.pop_back(); Loading @@ -616,7 +616,7 @@ void FrameReorderer::restoreForLayer() { // TODO: defer time rejection (when bounds become empty) + tests // Option - just skip layers with no bounds at playback + defer? void FrameReorderer::deferBeginLayerOp(const BeginLayerOp& op) { void FrameBuilder::deferBeginLayerOp(const BeginLayerOp& op) { uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth(); uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight(); Loading Loading @@ -661,7 +661,7 @@ void FrameReorderer::deferBeginLayerOp(const BeginLayerOp& op) { &op, nullptr); } void FrameReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) { void FrameBuilder::deferEndLayerOp(const EndLayerOp& /* ignored */) { const BeginLayerOp& beginLayerOp = *currentLayer().beginLayerOp; int finishedLayerIndex = mLayerStack.back(); Loading @@ -674,7 +674,7 @@ void FrameReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) { beginLayerOp.localMatrix, beginLayerOp.localClip, beginLayerOp.paint, &(mLayerReorderers[finishedLayerIndex]->offscreenBuffer)); &(mLayerBuilders[finishedLayerIndex]->offscreenBuffer)); BakedOpState* bakedOpState = tryBakeOpState(*drawLayerOp); if (bakedOpState) { Loading @@ -684,12 +684,12 @@ void FrameReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) { // Layer won't be drawn - delete its drawing batches to prevent it from doing any work // TODO: need to prevent any render work from being done // - create layerop earlier for reject purposes? mLayerReorderers[finishedLayerIndex]->clear(); mLayerBuilders[finishedLayerIndex]->clear(); return; } } void FrameReorderer::deferBeginUnclippedLayerOp(const BeginUnclippedLayerOp& op) { void FrameBuilder::deferBeginUnclippedLayerOp(const BeginUnclippedLayerOp& op) { Matrix4 boundsTransform(*(mCanvasState.currentSnapshot()->transform)); boundsTransform.multiply(op.localMatrix); Loading Loading @@ -724,7 +724,7 @@ void FrameReorderer::deferBeginUnclippedLayerOp(const BeginUnclippedLayerOp& op) currentLayer().activeUnclippedSaveLayers.push_back(bakedState); } void FrameReorderer::deferEndUnclippedLayerOp(const EndUnclippedLayerOp& /* ignored */) { void FrameBuilder::deferEndUnclippedLayerOp(const EndUnclippedLayerOp& /* ignored */) { LOG_ALWAYS_FATAL_IF(currentLayer().activeUnclippedSaveLayers.empty(), "no layer to end!"); BakedOpState* copyFromLayerOp = currentLayer().activeUnclippedSaveLayers.back(); Loading
libs/hwui/FrameReorderer.h→libs/hwui/FrameBuilder.h +15 −15 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ #include "BakedOpState.h" #include "CanvasState.h" #include "DisplayList.h" #include "LayerReorderer.h" #include "LayerBuilder.h" #include "RecordedOp.h" #include <vector> Loading @@ -42,7 +42,7 @@ class Rect; * Resolves final drawing state for each operation (including clip, alpha and matrix), and then * reorder and merge each op as it is resolved for drawing efficiency. Each layer of content (either * from the LayerUpdateQueue, or temporary layers created by saveLayer operations in the * draw stream) will create different reorder contexts, each in its own LayerReorderer. * draw stream) will create different reorder contexts, each in its own LayerBuilder. * * Then the prepared or 'baked' drawing commands can be issued by calling the templated * replayBakedOps() function, which will dispatch them (including any created merged op collections) Loading @@ -52,13 +52,13 @@ class Rect; * This class is also the authoritative source for traversing RenderNodes, both for standard op * traversal within a DisplayList, and for out of order RenderNode traversal for Z and projection. */ class FrameReorderer : public CanvasStateClient { class FrameBuilder : public CanvasStateClient { public: FrameReorderer(const LayerUpdateQueue& layers, const SkRect& clip, FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter); virtual ~FrameReorderer() {} virtual ~FrameBuilder() {} /** * replayBakedOps() is templated based on what class will receive ops being replayed. Loading Loading @@ -98,8 +98,8 @@ public: // Relay through layers in reverse order, since layers // later in the list will be drawn by earlier ones for (int i = mLayerReorderers.size() - 1; i >= 1; i--) { LayerReorderer& layer = *(mLayerReorderers[i]); for (int i = mLayerBuilders.size() - 1; i >= 1; i--) { LayerBuilder& layer = *(mLayerBuilders[i]); if (layer.renderNode) { // cached HW layer - can't skip layer if empty renderer.startRepaintLayer(layer.offscreenBuffer, layer.repaintRect); Loading @@ -112,14 +112,14 @@ public: } } const LayerReorderer& fbo0 = *(mLayerReorderers[0]); const LayerBuilder& fbo0 = *(mLayerBuilders[0]); renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect); fbo0.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers); renderer.endFrame(fbo0.repaintRect); } void dump() const { for (auto&& layer : mLayerReorderers) { for (auto&& layer : mLayerBuilders) { layer->dump(); } } Loading @@ -143,7 +143,7 @@ private: const BeginLayerOp* beginLayerOp, RenderNode* renderNode); void restoreForLayer(); LayerReorderer& currentLayer() { return *(mLayerReorderers[mLayerStack.back()]); } LayerBuilder& currentLayer() { return *(mLayerBuilders[mLayerStack.back()]); } BakedOpState* tryBakeOpState(const RecordedOp& recordedOp) { return BakedOpState::tryConstruct(mAllocator, *mCanvasState.writableSnapshot(), recordedOp); Loading Loading @@ -173,7 +173,7 @@ private: BakedOpState::StrokeBehavior strokeBehavior = BakedOpState::StrokeBehavior::StyleDefined); /** * Declares all FrameReorderer::deferXXXXOp() methods for every RecordedOp type. * Declares all FrameBuilder::deferXXXXOp() methods for every RecordedOp type. * * These private methods are called from within deferImpl to defer each individual op * type differently. Loading @@ -183,17 +183,17 @@ private: #undef X // List of every deferred layer's render state. Replayed in reverse order to render a frame. std::vector<LayerReorderer*> mLayerReorderers; std::vector<LayerBuilder*> mLayerBuilders; /* * Stack of indices within mLayerReorderers representing currently active layers. If drawing * Stack of indices within mLayerBuilders representing currently active layers. If drawing * layerA within a layerB, will contain, in order: * - 0 (representing FBO 0, always present) * - layerB's index * - layerA's index * * Note that this doesn't vector doesn't always map onto all values of mLayerReorderers. When a * layer is finished deferring, it will still be represented in mLayerReorderers, but it's index * Note that this doesn't vector doesn't always map onto all values of mLayerBuilders. When a * layer is finished deferring, it will still be represented in mLayerBuilders, but it's index * won't be in mLayerStack. This is because it can be replayed, but can't have any more drawing * ops added to it. */ Loading
libs/hwui/LayerReorderer.cpp→libs/hwui/LayerBuilder.cpp +10 −10 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ #include "LayerReorderer.h" #include "LayerBuilder.h" #include "BakedOpState.h" #include "RenderNode.h" Loading Loading @@ -202,7 +202,7 @@ private: int mClipSideFlags; }; LayerReorderer::LayerReorderer(uint32_t width, uint32_t height, LayerBuilder::LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode) : width(width) , height(height) Loading @@ -214,7 +214,7 @@ LayerReorderer::LayerReorderer(uint32_t width, uint32_t height, // 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 void LayerReorderer::locateInsertIndex(int batchId, const Rect& clippedBounds, void LayerBuilder::locateInsertIndex(int batchId, const Rect& clippedBounds, BatchBase** targetBatch, size_t* insertBatchIndex) const { for (int i = mBatches.size() - 1; i >= 0; i--) { BatchBase* overBatch = mBatches[i]; Loading @@ -237,11 +237,11 @@ void LayerReorderer::locateInsertIndex(int batchId, const Rect& clippedBounds, } } void LayerReorderer::deferLayerClear(const Rect& rect) { void LayerBuilder::deferLayerClear(const Rect& rect) { mClearRects.push_back(rect); } void LayerReorderer::flushLayerClears(LinearAllocator& allocator) { void LayerBuilder::flushLayerClears(LinearAllocator& allocator) { if (CC_UNLIKELY(!mClearRects.empty())) { const int vertCount = mClearRects.size() * 4; // put the verts in the frame allocator, since Loading Loading @@ -273,7 +273,7 @@ void LayerReorderer::flushLayerClears(LinearAllocator& allocator) { } } void LayerReorderer::deferUnmergeableOp(LinearAllocator& allocator, void LayerBuilder::deferUnmergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId) { if (batchId != OpBatchType::CopyToLayer) { // if first op after one or more unclipped saveLayers, flush the layer clears Loading @@ -298,7 +298,7 @@ void LayerReorderer::deferUnmergeableOp(LinearAllocator& allocator, } } void LayerReorderer::deferMergeableOp(LinearAllocator& allocator, void LayerBuilder::deferMergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId, mergeid_t mergeId) { if (batchId != OpBatchType::CopyToLayer) { // if first op after one or more unclipped saveLayers, flush the layer clears Loading Loading @@ -330,7 +330,7 @@ void LayerReorderer::deferMergeableOp(LinearAllocator& allocator, } } void LayerReorderer::replayBakedOpsImpl(void* arg, void LayerBuilder::replayBakedOpsImpl(void* arg, BakedOpReceiver* unmergedReceivers, MergedOpReceiver* mergedReceivers) const { ATRACE_NAME("flush drawing commands"); for (const BatchBase* batch : mBatches) { Loading @@ -353,8 +353,8 @@ void LayerReorderer::replayBakedOpsImpl(void* arg, } } void LayerReorderer::dump() const { ALOGD("LayerReorderer %p, %ux%u buffer %p, blo %p, rn %p", void LayerBuilder::dump() const { ALOGD("LayerBuilder %p, %ux%u buffer %p, blo %p, rn %p", this, width, height, offscreenBuffer, beginLayerOp, renderNode); for (const BatchBase* batch : mBatches) { batch->dump(); Loading
libs/hwui/LayerReorderer.h→libs/hwui/LayerBuilder.h +7 −7 Original line number Diff line number Diff line Loading @@ -67,17 +67,17 @@ typedef void (*MergedOpReceiver)(void*, const MergedBakedOpList& opList); * Stores the deferred render operations and state used to compute ordering * for a single FBO/layer. */ class LayerReorderer { class LayerBuilder { // Prevent copy/assign because users may stash pointer to offscreenBuffer and viewportClip PREVENT_COPY_AND_ASSIGN(LayerReorderer); PREVENT_COPY_AND_ASSIGN(LayerBuilder); public: // Create LayerReorderer for Fbo0 LayerReorderer(uint32_t width, uint32_t height, const Rect& repaintRect) : LayerReorderer(width, height, repaintRect, nullptr, nullptr) {}; // Create LayerBuilder for Fbo0 LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect) : LayerBuilder(width, height, repaintRect, nullptr, nullptr) {}; // Create LayerReorderer for an offscreen layer, where beginLayerOp is present for a // Create LayerBuilder 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, LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode); // iterate back toward target to see if anything drawn since should overlap the new op Loading