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
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index dc63e5d..3aa5b4b 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 @@
/**
* 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 c4189da..a6a7b12 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 1c78eed..44f54ee 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -70,19 +70,17 @@
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 @@
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 @@
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 @@
}
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 @@
// 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 @@
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 @@
// 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 @@
drawn.join(bounds);
}
}
- mDisplayList->mDisplayList.applyColorTransform(
+ mDisplayList.applyColorTransform(
usage == UsageHint::Background ? ColorTransform::Dark : ColorTransform::Light);
}
@@ -382,20 +372,17 @@
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 @@
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 1eaf0d4..39ea53b 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -100,17 +100,17 @@
// 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 @@
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 @@
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 584321e..6161ddf 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -53,9 +53,9 @@
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 11fa322..b4bfd26 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -117,7 +117,7 @@
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 eb9885a..05278f2 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 52522a3..cf02051 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 541d5a5..ba407f2 100644
--- a/libs/hwui/jni/GraphicsJNI.h
+++ b/libs/hwui/jni/GraphicsJNI.h
@@ -24,6 +24,7 @@
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 26ff8bf..3580bed 100644
--- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h
+++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
@@ -29,7 +29,7 @@
*/
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 @@
}
private:
- RenderNodeDrawable* getRenderNodeDrawable(SkDrawable* drawable) {
+ const RenderNodeDrawable* getRenderNodeDrawable(SkDrawable* drawable) {
for (auto& child : mDisplayList.mChildNodes) {
if (drawable == &child) {
return &child;
@@ -147,7 +147,7 @@
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 1473b3e..070a765 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -61,12 +61,11 @@
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 @@
return;
}
- SkiaDisplayList* displayList = (SkiaDisplayList*)renderNode->getDisplayList();
+ SkiaDisplayList* displayList = renderNode->getDisplayList().asSkiaDl();
SkAutoCanvasRestore acr(canvas, true);
const RenderProperties& properties = this->getNodeProperties();
@@ -213,14 +212,14 @@
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 c63f5d3..e6c6e10 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -172,7 +172,7 @@
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 f2f19ba..483264f 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -142,7 +142,7 @@
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 6e7493c..d14dc36 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -98,7 +98,7 @@
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 @@
// 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 a436278..f460783 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -55,11 +55,11 @@
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 83e9349..cbad467 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -43,7 +43,7 @@
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 c1d8b76..81cc6a9 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -212,7 +212,8 @@
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 @@
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 @@
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 d393c69..ade1ddd 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -45,19 +45,19 @@
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 @@
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 @@
*/
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 @@
canvas->restore();
}
benchmark::DoNotOptimize(canvas.get());
- delete canvas->finishRecording();
+ static_cast<void>(canvas->finishRecording());
}
}
BENCHMARK(BM_DisplayListCanvas_record_simpleBitmapView);
@@ -122,7 +122,7 @@
});
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 @@
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 618988f..dd3f737 100644
--- a/libs/hwui/tests/microbench/RenderNodeBench.cpp
+++ b/libs/hwui/tests/microbench/RenderNodeBench.cpp
@@ -35,7 +35,7 @@
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 @@
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 4659a92..61bd646 100644
--- a/libs/hwui/tests/unit/RenderNodeTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeTests.cpp
@@ -326,7 +326,7 @@
// 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 c63f008..801a294 100644
--- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
+++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
@@ -38,12 +38,13 @@
}
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);