diff options
author | 2021-01-13 22:39:32 -0500 | |
---|---|---|
committer | 2021-01-14 03:55:58 +0000 | |
commit | be67195c44163c03d88af43b9d58b7e22139c0a9 (patch) | |
tree | 07d5f55ece853636eea9d7273b84fc2d7080dd2b | |
parent | 844516c4946fa200afab9575cb154a962779b74f (diff) |
Convert DisplayList to a value-type wrapper
Make DisplayList its own type instead of an alias,
pushing the Skia aspect behind it mostly. Removes a bunch
of manual memory management and opens the door to DisplayList
being a union type with multiple implementations
Test: builds (somehow), boots, hwuiunit passes, CtsUiRendering passes
Change-Id: I1d7806aa3afc5d9ece08b06959920078a5814c59
21 files changed, 200 insertions, 95 deletions
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index dc63e5db4a70..3aa5b4bf72f8 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -18,6 +18,8 @@ #include "pipeline/skia/SkiaDisplayList.h" +#include <memory> + namespace android { namespace uirenderer { @@ -29,7 +31,119 @@ typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot; /** * Data structure that holds the list of commands used in display list stream */ -using DisplayList = skiapipeline::SkiaDisplayList; +//using DisplayList = skiapipeline::SkiaDisplayList; +class DisplayList { +public: + // Constructs an empty (invalid) DisplayList + explicit DisplayList() {} + + // Constructs a DisplayList from a SkiaDisplayList + explicit DisplayList(std::unique_ptr<skiapipeline::SkiaDisplayList> impl) + : mImpl(std::move(impl)) {} + + // Move support + DisplayList(DisplayList&& other) : mImpl(std::move(other.mImpl)) {} + DisplayList& operator=(DisplayList&& other) { + mImpl = std::move(other.mImpl); + return *this; + } + + // No copy support + DisplayList(const DisplayList& other) = delete; + DisplayList& operator=(const DisplayList&) = delete; + + void updateChildren(std::function<void(RenderNode*)> updateFn) { + mImpl->updateChildren(std::move(updateFn)); + } + + [[nodiscard]] explicit operator bool() const { + return mImpl.get() != nullptr; + } + + // If true this DisplayList contains a backing content, even if that content is empty + // If false, there this DisplayList is in an "empty" state + [[nodiscard]] bool isValid() const { + return mImpl.get() != nullptr; + } + + [[nodiscard]] bool isEmpty() const { + return !hasContent(); + } + + [[nodiscard]] bool hasContent() const { + return mImpl && !(mImpl->isEmpty()); + } + + [[nodiscard]] bool containsProjectionReceiver() const { + return mImpl && mImpl->containsProjectionReceiver(); + } + + [[nodiscard]] skiapipeline::SkiaDisplayList* asSkiaDl() { + return mImpl.get(); + } + + [[nodiscard]] const skiapipeline::SkiaDisplayList* asSkiaDl() const { + return mImpl.get(); + } + + [[nodiscard]] bool hasVectorDrawables() const { + return mImpl && mImpl->hasVectorDrawables(); + } + + void clear(RenderNode* owningNode = nullptr) { + if (mImpl && owningNode && mImpl->reuseDisplayList(owningNode)) { + // TODO: This is a bit sketchy to have a unique_ptr temporarily owned twice + // Do something to cleanup reuseDisplayList passing itself to the RenderNode + mImpl.release(); + } else { + mImpl = nullptr; + } + } + + [[nodiscard]] size_t getUsedSize() const { + return mImpl ? mImpl->getUsedSize() : 0; + } + + [[nodiscard]] size_t getAllocatedSize() const { + return mImpl ? mImpl->getAllocatedSize() : 0; + } + + void output(std::ostream& output, uint32_t level) const { + if (mImpl) { + mImpl->output(output, level); + } + } + + [[nodiscard]] bool hasFunctor() const { + return mImpl && mImpl->hasFunctor(); + } + + bool prepareListAndChildren( + TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer, + std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) { + return mImpl && mImpl->prepareListAndChildren( + observer, info, functorsNeedLayer, std::move(childFn)); + } + + void syncContents(const WebViewSyncData& data) { + if (mImpl) { + mImpl->syncContents(data); + } + } + + [[nodiscard]] bool hasText() const { + return mImpl && mImpl->hasText(); + } + + void applyColorTransform(ColorTransform transform) { + if (mImpl) { + mImpl->mDisplayList.applyColorTransform(transform); + } + } + +private: + std::unique_ptr<skiapipeline::SkiaDisplayList> mImpl; +}; } // namespace uirenderer } // namespace android diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index c4189da99563..a6a7b12ba658 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -28,7 +28,6 @@ #include "SkPaint.h" #include "SkPath.h" #include "SkRect.h" -#include "SkTemplates.h" #include <vector> diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 1c78eede376d..44f54eef458f 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -70,19 +70,17 @@ RenderNode::RenderNode() RenderNode::~RenderNode() { ImmediateRemoved observer(nullptr); deleteDisplayList(observer); - delete mStagingDisplayList; LOG_ALWAYS_FATAL_IF(hasLayer(), "layer missed detachment!"); } -void RenderNode::setStagingDisplayList(DisplayList* displayList) { - mValid = (displayList != nullptr); +void RenderNode::setStagingDisplayList(DisplayList&& newData) { + mValid = newData.isValid(); mNeedsDisplayListSync = true; - delete mStagingDisplayList; - mStagingDisplayList = displayList; + mStagingDisplayList = std::move(newData); } void RenderNode::discardStagingDisplayList() { - setStagingDisplayList(nullptr); + setStagingDisplayList(DisplayList()); } /** @@ -105,32 +103,22 @@ void RenderNode::output(std::ostream& output, uint32_t level) { properties().debugOutputProperties(output, level + 1); - if (mDisplayList) { - mDisplayList->output(output, level); - } + mDisplayList.output(output, level); output << std::string(level * 2, ' ') << "/RenderNode(" << getName() << " " << this << ")"; output << std::endl; } int RenderNode::getUsageSize() { int size = sizeof(RenderNode); - if (mStagingDisplayList) { - size += mStagingDisplayList->getUsedSize(); - } - if (mDisplayList && mDisplayList != mStagingDisplayList) { - size += mDisplayList->getUsedSize(); - } + size += mStagingDisplayList.getUsedSize(); + size += mDisplayList.getUsedSize(); return size; } int RenderNode::getAllocatedSize() { int size = sizeof(RenderNode); - if (mStagingDisplayList) { - size += mStagingDisplayList->getAllocatedSize(); - } - if (mDisplayList && mDisplayList != mStagingDisplayList) { - size += mDisplayList->getAllocatedSize(); - } + size += mStagingDisplayList.getAllocatedSize(); + size += mDisplayList.getAllocatedSize(); return size; } @@ -246,9 +234,9 @@ void RenderNode::prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool fu bool willHaveFunctor = false; if (info.mode == TreeInfo::MODE_FULL && mStagingDisplayList) { - willHaveFunctor = mStagingDisplayList->hasFunctor(); + willHaveFunctor = mStagingDisplayList.hasFunctor(); } else if (mDisplayList) { - willHaveFunctor = mDisplayList->hasFunctor(); + willHaveFunctor = mDisplayList.hasFunctor(); } bool childFunctorsNeedLayer = mProperties.prepareForFunctorPresence(willHaveFunctor, functorsNeedLayer); @@ -263,8 +251,8 @@ void RenderNode::prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool fu } if (mDisplayList) { - info.out.hasFunctors |= mDisplayList->hasFunctor(); - bool isDirty = mDisplayList->prepareListAndChildren( + info.out.hasFunctors |= mDisplayList.hasFunctor(); + bool isDirty = mDisplayList.prepareListAndChildren( observer, info, childFunctorsNeedLayer, [](RenderNode* child, TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer) { @@ -318,16 +306,15 @@ void RenderNode::syncDisplayList(TreeObserver& observer, TreeInfo* info) { // Make sure we inc first so that we don't fluctuate between 0 and 1, // which would thrash the layer cache if (mStagingDisplayList) { - mStagingDisplayList->updateChildren([](RenderNode* child) { child->incParentRefCount(); }); + mStagingDisplayList.updateChildren([](RenderNode* child) { child->incParentRefCount(); }); } deleteDisplayList(observer, info); - mDisplayList = mStagingDisplayList; - mStagingDisplayList = nullptr; + mDisplayList = std::move(mStagingDisplayList); if (mDisplayList) { WebViewSyncData syncData { .applyForceDark = info && !info->disableForceDark }; - mDisplayList->syncContents(syncData); + mDisplayList.syncContents(syncData); handleForceDark(info); } } @@ -337,15 +324,18 @@ void RenderNode::handleForceDark(android::uirenderer::TreeInfo *info) { return; } auto usage = usageHint(); - const auto& children = mDisplayList->mChildNodes; - if (mDisplayList->hasText()) { + FatVector<RenderNode*, 6> children; + mDisplayList.updateChildren([&children](RenderNode* node) { + children.push_back(node); + }); + if (mDisplayList.hasText()) { usage = UsageHint::Foreground; } if (usage == UsageHint::Unknown) { if (children.size() > 1) { usage = UsageHint::Background; } else if (children.size() == 1 && - children.front().getRenderNode()->usageHint() != + children.front()->usageHint() != UsageHint::Background) { usage = UsageHint::Background; } @@ -354,7 +344,7 @@ void RenderNode::handleForceDark(android::uirenderer::TreeInfo *info) { // Crude overlap check SkRect drawn = SkRect::MakeEmpty(); for (auto iter = children.rbegin(); iter != children.rend(); ++iter) { - const auto& child = iter->getRenderNode(); + const auto& child = *iter; // We use stagingProperties here because we haven't yet sync'd the children SkRect bounds = SkRect::MakeXYWH(child->stagingProperties().getX(), child->stagingProperties().getY(), child->stagingProperties().getWidth(), child->stagingProperties().getHeight()); @@ -365,7 +355,7 @@ void RenderNode::handleForceDark(android::uirenderer::TreeInfo *info) { drawn.join(bounds); } } - mDisplayList->mDisplayList.applyColorTransform( + mDisplayList.applyColorTransform( usage == UsageHint::Background ? ColorTransform::Dark : ColorTransform::Light); } @@ -382,20 +372,17 @@ void RenderNode::pushStagingDisplayListChanges(TreeObserver& observer, TreeInfo& void RenderNode::deleteDisplayList(TreeObserver& observer, TreeInfo* info) { if (mDisplayList) { - mDisplayList->updateChildren( + mDisplayList.updateChildren( [&observer, info](RenderNode* child) { child->decParentRefCount(observer, info); }); - if (!mDisplayList->reuseDisplayList(this)) { - delete mDisplayList; - } + mDisplayList.clear(this); } - mDisplayList = nullptr; } void RenderNode::destroyHardwareResources(TreeInfo* info) { if (hasLayer()) { this->setLayerSurface(nullptr); } - setStagingDisplayList(nullptr); + discardStagingDisplayList(); ImmediateRemoved observer(info); deleteDisplayList(observer, info); @@ -406,7 +393,7 @@ void RenderNode::destroyLayers() { this->setLayerSurface(nullptr); } if (mDisplayList) { - mDisplayList->updateChildren([](RenderNode* child) { child->destroyLayers(); }); + mDisplayList.updateChildren([](RenderNode* child) { child->destroyLayers(); }); } } diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index 1eaf0d425818..39ea53b6e3b3 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -100,17 +100,17 @@ public: // See flags defined in DisplayList.java enum ReplayFlag { kReplayFlag_ClipChildren = 0x1 }; - void setStagingDisplayList(DisplayList* newData); + void setStagingDisplayList(DisplayList&& newData); void discardStagingDisplayList(); void output(); int getUsageSize(); int getAllocatedSize(); - bool isRenderable() const { return mDisplayList && !mDisplayList->isEmpty(); } + bool isRenderable() const { return mDisplayList.hasContent(); } bool hasProjectionReceiver() const { - return mDisplayList && mDisplayList->containsProjectionReceiver(); + return mDisplayList.containsProjectionReceiver(); } const char* getName() const { return mName.string(); } @@ -169,12 +169,14 @@ public: bool nothingToDraw() const { const Outline& outline = properties().getOutline(); - return mDisplayList == nullptr || properties().getAlpha() <= 0 || + return !mDisplayList.isValid() || properties().getAlpha() <= 0 || (outline.getShouldClip() && outline.isEmpty()) || properties().getScaleX() == 0 || properties().getScaleY() == 0; } - const DisplayList* getDisplayList() const { return mDisplayList; } + const DisplayList& getDisplayList() const { return mDisplayList; } + // TODO: can this be cleaned up? + DisplayList& getDisplayList() { return mDisplayList; } // Note: The position callbacks are relying on the listener using // the frameNumber to appropriately batch/synchronize these transactions. @@ -253,8 +255,8 @@ private: bool mNeedsDisplayListSync; // WARNING: Do not delete this directly, you must go through deleteDisplayList()! - DisplayList* mDisplayList; - DisplayList* mStagingDisplayList; + DisplayList mDisplayList; + DisplayList mStagingDisplayList; int64_t mDamageGenerationId; diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index 584321ec9094..6161ddf4efa5 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -53,9 +53,9 @@ public: LOG_ALWAYS_FATAL("SkiaCanvas cannot be reset as a recording canvas"); } - virtual uirenderer::DisplayList* finishRecording() override { + virtual uirenderer::DisplayList finishRecording() override { LOG_ALWAYS_FATAL("SkiaCanvas does not produce a DisplayList"); - return nullptr; + return uirenderer::DisplayList(); } virtual void enableZ(bool enableZ) override { LOG_ALWAYS_FATAL("SkiaCanvas does not support enableZ"); diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h index 11fa3223a9c8..b4bfd269007e 100644 --- a/libs/hwui/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -117,7 +117,7 @@ public: virtual void resetRecording(int width, int height, uirenderer::RenderNode* renderNode = nullptr) = 0; - virtual uirenderer::DisplayList* finishRecording() = 0; + [[nodiscard]] virtual uirenderer::DisplayList finishRecording() = 0; virtual void enableZ(bool enableZ) = 0; bool isHighContrastText() const { return uirenderer::Properties::enableHighContrastText; } diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index eb9885a4436a..05278f24ebbd 100755 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -3,11 +3,12 @@ #include "Bitmap.h" #include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkColor.h" +#include "SkColorSpace.h" #include "SkPixelRef.h" #include "SkImageEncoder.h" #include "SkImageInfo.h" -#include "SkColor.h" -#include "SkColorSpace.h" #include "GraphicsJNI.h" #include "SkStream.h" #include "SkWebpEncoder.h" diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp index 52522a320821..cf02051831c6 100644 --- a/libs/hwui/jni/BitmapFactory.cpp +++ b/libs/hwui/jni/BitmapFactory.cpp @@ -8,9 +8,11 @@ #include "MimeType.h" #include "NinePatchPeeker.h" #include "SkAndroidCodec.h" +#include "SkCanvas.h" #include "SkMath.h" #include "SkPixelRef.h" #include "SkStream.h" +#include "SkString.h" #include "SkUtils.h" #include "Utils.h" diff --git a/libs/hwui/jni/GraphicsJNI.h b/libs/hwui/jni/GraphicsJNI.h index 541d5a53de07..ba407f2164de 100644 --- a/libs/hwui/jni/GraphicsJNI.h +++ b/libs/hwui/jni/GraphicsJNI.h @@ -24,6 +24,7 @@ namespace android { namespace skia { class BitmapRegionDecoder; } +class Canvas; class Paint; struct Typeface; } diff --git a/libs/hwui/pipeline/skia/DumpOpsCanvas.h b/libs/hwui/pipeline/skia/DumpOpsCanvas.h index 26ff8bf53f90..3580bed45a1f 100644 --- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h +++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h @@ -29,7 +29,7 @@ namespace skiapipeline { */ class DumpOpsCanvas : public SkCanvas { public: - DumpOpsCanvas(std::ostream& output, int level, SkiaDisplayList& displayList) + DumpOpsCanvas(std::ostream& output, int level, const SkiaDisplayList& displayList) : mOutput(output) , mLevel(level) , mDisplayList(displayList) @@ -127,7 +127,7 @@ protected: } private: - RenderNodeDrawable* getRenderNodeDrawable(SkDrawable* drawable) { + const RenderNodeDrawable* getRenderNodeDrawable(SkDrawable* drawable) { for (auto& child : mDisplayList.mChildNodes) { if (drawable == &child) { return &child; @@ -147,7 +147,7 @@ private: std::ostream& mOutput; int mLevel; - SkiaDisplayList& mDisplayList; + const SkiaDisplayList& mDisplayList; std::string mIdent; }; diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp index 1473b3e5abb7..070a765cf7ca 100644 --- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp +++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp @@ -61,12 +61,11 @@ void RenderNodeDrawable::drawBackwardsProjectedNodes(SkCanvas* canvas, SkAutoCanvasRestore acr(canvas, true); SkMatrix nodeMatrix; mat4 hwuiMatrix(child.getRecordedMatrix()); - auto childNode = child.getRenderNode(); + const RenderNode* childNode = child.getRenderNode(); childNode->applyViewPropertyTransforms(hwuiMatrix); hwuiMatrix.copyTo(nodeMatrix); canvas->concat(nodeMatrix); - SkiaDisplayList* childDisplayList = static_cast<SkiaDisplayList*>( - (const_cast<DisplayList*>(childNode->getDisplayList()))); + const SkiaDisplayList* childDisplayList = childNode->getDisplayList().asSkiaDl(); if (childDisplayList) { drawBackwardsProjectedNodes(canvas, *childDisplayList, nestLevel + 1); } @@ -144,7 +143,7 @@ void RenderNodeDrawable::forceDraw(SkCanvas* canvas) const { return; } - SkiaDisplayList* displayList = (SkiaDisplayList*)renderNode->getDisplayList(); + SkiaDisplayList* displayList = renderNode->getDisplayList().asSkiaDl(); SkAutoCanvasRestore acr(canvas, true); const RenderProperties& properties = this->getNodeProperties(); @@ -213,14 +212,14 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const { if (mComposeLayer) { setViewProperties(properties, canvas, &alphaMultiplier); } - SkiaDisplayList* displayList = (SkiaDisplayList*)mRenderNode->getDisplayList(); + SkiaDisplayList* displayList = mRenderNode->getDisplayList().asSkiaDl(); displayList->mParentMatrix = canvas->getTotalMatrix(); // TODO should we let the bound of the drawable do this for us? const SkRect bounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight()); bool quickRejected = properties.getClipToBounds() && canvas->quickReject(bounds); if (!quickRejected) { - SkiaDisplayList* displayList = (SkiaDisplayList*)renderNode->getDisplayList(); + SkiaDisplayList* displayList = renderNode->getDisplayList().asSkiaDl(); const LayerProperties& layerProperties = properties.layerProperties(); // composing a hardware layer if (renderNode->getLayerSurface() && mComposeLayer) { diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp index c63f5d349311..e6c6e1094c40 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp @@ -172,7 +172,7 @@ void SkiaDisplayList::reset() { new (&allocator) LinearAllocator(); } -void SkiaDisplayList::output(std::ostream& output, uint32_t level) { +void SkiaDisplayList::output(std::ostream& output, uint32_t level) const { DumpOpsCanvas canvas(output, level, *this); mDisplayList.draw(&canvas); } diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h index f2f19ba2975e..483264f95e60 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.h +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h @@ -142,7 +142,7 @@ public: void draw(SkCanvas* canvas) { mDisplayList.draw(canvas); } - void output(std::ostream& output, uint32_t level); + void output(std::ostream& output, uint32_t level) const; LinearAllocator allocator; diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index 6e7493cb443d..d14dc3672b99 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -98,7 +98,7 @@ void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) continue; } SkASSERT(layerNode->getLayerSurface()); - SkiaDisplayList* displayList = (SkiaDisplayList*)layerNode->getDisplayList(); + SkiaDisplayList* displayList = layerNode->getDisplayList().asSkiaDl(); if (!displayList || displayList->isEmpty()) { ALOGE("%p drawLayers(%s) : missing drawable", layerNode, layerNode->getName()); return; @@ -288,7 +288,7 @@ bool SkiaPipeline::setupMultiFrameCapture() { // recurse through the rendernode's children, add any nodes which are layers to the queue. static void collectLayers(RenderNode* node, LayerUpdateQueue* layers) { - SkiaDisplayList* dl = (SkiaDisplayList*)node->getDisplayList(); + SkiaDisplayList* dl = node->getDisplayList().asSkiaDl(); if (dl) { const auto& prop = node->properties(); if (node->hasLayer()) { diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index a43627803e71..f460783d3b97 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -55,11 +55,11 @@ void SkiaRecordingCanvas::initDisplayList(uirenderer::RenderNode* renderNode, in SkiaCanvas::reset(&mRecorder); } -uirenderer::DisplayList* SkiaRecordingCanvas::finishRecording() { +uirenderer::DisplayList SkiaRecordingCanvas::finishRecording() { // close any existing chunks if necessary enableZ(false); mRecorder.restoreToCount(1); - return mDisplayList.release(); + return uirenderer::DisplayList(std::move(mDisplayList)); } // ---------------------------------------------------------------------------- diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h index 83e934974afd..cbad4671eee5 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h @@ -43,7 +43,7 @@ public: initDisplayList(renderNode, width, height); } - virtual uirenderer::DisplayList* finishRecording() override; + virtual uirenderer::DisplayList finishRecording() override; virtual void drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) override; virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const Paint* paint) override; diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h index c1d8b761514b..81cc6a941968 100644 --- a/libs/hwui/tests/common/TestUtils.h +++ b/libs/hwui/tests/common/TestUtils.h @@ -212,7 +212,8 @@ public: int left, int top, int right, int bottom, std::function<void(RenderProperties& props, skiapipeline::SkiaRecordingCanvas& canvas)> setup, - const char* name = nullptr, skiapipeline::SkiaDisplayList* displayList = nullptr) { + const char* name = nullptr, + std::unique_ptr<skiapipeline::SkiaDisplayList> displayList = nullptr) { sp<RenderNode> node = new RenderNode(); if (name) { node->setName(name); @@ -220,7 +221,7 @@ public: RenderProperties& props = node->mutateStagingProperties(); props.setLeftTopRightBottom(left, top, right, bottom); if (displayList) { - node->setStagingDisplayList(displayList); + node->setStagingDisplayList(DisplayList(std::move(displayList))); } if (setup) { std::unique_ptr<skiapipeline::SkiaRecordingCanvas> canvas( @@ -348,13 +349,11 @@ private: node->mNeedsDisplayListSync = false; node->syncDisplayList(observer, nullptr); } - auto displayList = node->getDisplayList(); + auto& displayList = node->getDisplayList(); if (displayList) { - for (auto&& childDr : - static_cast<skiapipeline::SkiaDisplayList*>(const_cast<DisplayList*>(displayList)) - ->mChildNodes) { - syncHierarchyPropertiesAndDisplayListImpl(childDr.getRenderNode()); - } + displayList.updateChildren([](RenderNode* child) { + syncHierarchyPropertiesAndDisplayListImpl(child); + }); } } diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp index d393c693c774..ade1ddd3f703 100644 --- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp +++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp @@ -45,19 +45,19 @@ BENCHMARK(BM_DisplayList_alloc_theoretical); void BM_DisplayListCanvas_record_empty(benchmark::State& benchState) { std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100)); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); while (benchState.KeepRunning()) { canvas->resetRecording(100, 100); benchmark::DoNotOptimize(canvas.get()); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); } } BENCHMARK(BM_DisplayListCanvas_record_empty); void BM_DisplayListCanvas_record_saverestore(benchmark::State& benchState) { std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100)); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); while (benchState.KeepRunning()) { canvas->resetRecording(100, 100); @@ -66,20 +66,20 @@ void BM_DisplayListCanvas_record_saverestore(benchmark::State& benchState) { benchmark::DoNotOptimize(canvas.get()); canvas->restore(); canvas->restore(); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); } } BENCHMARK(BM_DisplayListCanvas_record_saverestore); void BM_DisplayListCanvas_record_translate(benchmark::State& benchState) { std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100)); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); while (benchState.KeepRunning()) { canvas->resetRecording(100, 100); canvas->scale(10, 10); benchmark::DoNotOptimize(canvas.get()); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); } } BENCHMARK(BM_DisplayListCanvas_record_translate); @@ -92,7 +92,7 @@ BENCHMARK(BM_DisplayListCanvas_record_translate); */ void BM_DisplayListCanvas_record_simpleBitmapView(benchmark::State& benchState) { std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100)); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); Paint rectPaint; sk_sp<Bitmap> iconBitmap(TestUtils::createBitmap(80, 80)); @@ -111,7 +111,7 @@ void BM_DisplayListCanvas_record_simpleBitmapView(benchmark::State& benchState) canvas->restore(); } benchmark::DoNotOptimize(canvas.get()); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); } } BENCHMARK(BM_DisplayListCanvas_record_simpleBitmapView); @@ -122,7 +122,7 @@ void BM_DisplayListCanvas_basicViewGroupDraw(benchmark::State& benchState) { }); std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100)); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); while (benchState.KeepRunning()) { canvas->resetRecording(200, 200); @@ -143,7 +143,7 @@ void BM_DisplayListCanvas_basicViewGroupDraw(benchmark::State& benchState) { canvas->enableZ(false); canvas->restoreToCount(clipRestoreCount); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); } } BENCHMARK(BM_DisplayListCanvas_basicViewGroupDraw)->Arg(1)->Arg(5)->Arg(10); diff --git a/libs/hwui/tests/microbench/RenderNodeBench.cpp b/libs/hwui/tests/microbench/RenderNodeBench.cpp index 618988fd04d4..dd3f737abfa9 100644 --- a/libs/hwui/tests/microbench/RenderNodeBench.cpp +++ b/libs/hwui/tests/microbench/RenderNodeBench.cpp @@ -35,7 +35,7 @@ BENCHMARK(BM_RenderNode_create); void BM_RenderNode_recordSimple(benchmark::State& state) { sp<RenderNode> node = new RenderNode(); std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100)); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); while (state.KeepRunning()) { canvas->resetRecording(100, 100, node.get()); @@ -48,12 +48,12 @@ BENCHMARK(BM_RenderNode_recordSimple); void BM_RenderNode_recordSimpleWithReuse(benchmark::State& state) { sp<RenderNode> node = new RenderNode(); std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100)); - delete canvas->finishRecording(); + static_cast<void>(canvas->finishRecording()); while (state.KeepRunning()) { canvas->resetRecording(100, 100, node.get()); canvas->drawColor(0x00000000, SkBlendMode::kSrcOver); - canvas->finishRecording()->reuseDisplayList(node.get()); + canvas->finishRecording().clear(node.get()); } } BENCHMARK(BM_RenderNode_recordSimpleWithReuse);
\ No newline at end of file diff --git a/libs/hwui/tests/unit/RenderNodeTests.cpp b/libs/hwui/tests/unit/RenderNodeTests.cpp index 4659a929a9eb..61bd646b0a76 100644 --- a/libs/hwui/tests/unit/RenderNodeTests.cpp +++ b/libs/hwui/tests/unit/RenderNodeTests.cpp @@ -326,7 +326,7 @@ RENDERTHREAD_TEST(DISABLED_RenderNode, prepareTree_HwLayer_AVD_enqueueDamage) { // Check that the VD is in the dislay list, and the layer update queue contains the correct // damage rect. - EXPECT_TRUE(rootNode->getDisplayList()->hasVectorDrawables()); + EXPECT_TRUE(rootNode->getDisplayList().hasVectorDrawables()); ASSERT_FALSE(info.layerUpdateQueue->entries().empty()); EXPECT_EQ(rootNode.get(), info.layerUpdateQueue->entries().at(0).renderNode.get()); EXPECT_EQ(uirenderer::Rect(0, 0, 200, 400), info.layerUpdateQueue->entries().at(0).damage); diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp index c63f008c4aed..801a294b5648 100644 --- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp +++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp @@ -38,12 +38,13 @@ TEST(SkiaDisplayList, create) { } TEST(SkiaDisplayList, reset) { - std::unique_ptr<SkiaDisplayList> skiaDL; + DisplayList displayList; { SkiaRecordingCanvas canvas{nullptr, 1, 1}; canvas.drawColor(0, SkBlendMode::kSrc); - skiaDL.reset(canvas.finishRecording()); + displayList = canvas.finishRecording(); } + SkiaDisplayList* skiaDL = displayList.asSkiaDl(); SkCanvas dummyCanvas; RenderNodeDrawable drawable(nullptr, &dummyCanvas); |