summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Stan Iliev <stani@google.com> 2016-11-02 15:29:03 -0400
committer Stan Iliev <stani@google.com> 2016-11-03 13:44:41 -0400
commit2f06e8ad1a1c4d0866bb66854d2759e275898635 (patch)
tree56c502dddffbc950880729226b8d894807bae97c
parent500a0c30d4dcd012218c3e44a62926a1c34a259f (diff)
Fix RenderNodeDrawable to draw nonzero Z nodes when needed
Fix RenderNodeDrawable to draw nonzero Z nodes if not in a reordering section. Write an unit test modeled after FrameBuilder zReorder, which verifies the bug fix. Test: built and run unit tests on angler-eng. bug: 32541103 Change-Id: Ifbf2d51f4432f5de3af4abe5987c2a72fed14185
-rw-r--r--libs/hwui/pipeline/skia/RenderNodeDrawable.cpp5
-rw-r--r--libs/hwui/pipeline/skia/RenderNodeDrawable.h11
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp2
-rw-r--r--libs/hwui/tests/unit/RenderNodeDrawableTests.cpp123
4 files changed, 60 insertions, 81 deletions
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index f263c490668a..a7fab7e35eae 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -49,8 +49,9 @@ const RenderProperties& RenderNodeDrawable::getNodeProperties() const {
}
void RenderNodeDrawable::onDraw(SkCanvas* canvas) {
- //negative and positive Z order are drawn out of order
- if (MathUtils::isZero(mRenderNode->properties().getZ())) {
+ //negative and positive Z order are drawn out of order, if this render node drawable is in
+ //a reordering section
+ if ((!mInReorderingSection) || MathUtils::isZero(mRenderNode->properties().getZ())) {
this->forceDraw(canvas);
}
}
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
index 0762f37ff591..a2ffc6c3647b 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.h
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -56,10 +56,12 @@ public:
* we should draw into the contents of the layer or compose the existing contents of the
* layer into the canvas.
*/
- explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas, bool composeLayer = true)
+ explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas, bool composeLayer = true,
+ bool inReorderingSection = false)
: mRenderNode(node)
, mRecordedTransform(canvas->getTotalMatrix())
- , mComposeLayer(composeLayer) {}
+ , mComposeLayer(composeLayer)
+ , mInReorderingSection(inReorderingSection) {}
/**
* Draws into the canvas this render node and its children. If the node is marked as a
@@ -138,6 +140,11 @@ private:
std::vector<ProjectedChild>* mNextProjectedChildrenTarget = nullptr;
/*
+ * True if the render node is in a reordering section
+ */
+ bool mInReorderingSection;
+
+ /*
* Draw the content into a canvas, depending on the render node layer type and mComposeLayer.
*/
void drawContent(SkCanvas* canvas) const;
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 8a429839377c..ecc6d5115eda 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -107,7 +107,7 @@ void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
}
// record the child node
- mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas());
+ mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier);
drawDrawable(&mDisplayList->mChildNodes.back());
// use staging property, since recording on UI thread
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index c68ca4e74368..623d9712fd56 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -51,85 +51,56 @@ TEST(RenderNodeDrawable, create) {
ASSERT_EQ(drawable.getRecordedMatrix(), canvas.getTotalMatrix());
}
-TEST(RenderNodeDrawable, drawContent) {
- auto surface = SkSurface::MakeRasterN32Premul(1, 1);
- SkCanvas& canvas = *surface->getCanvas();
- canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
- ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
-
- //create a RenderNodeDrawable backed by a RenderNode backed by a SkLiteRecorder
- auto rootNode = TestUtils::createSkiaNode(0, 0, 1, 1,
- [](RenderProperties& props, SkiaRecordingCanvas& recorder) {
- recorder.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
- });
- RenderNodeDrawable drawable(rootNode.get(), &canvas, false);
-
- //negative and positive Z order are drawn out of order
- rootNode->animatorProperties().setElevation(10.0f);
- canvas.drawDrawable(&drawable);
- ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
- rootNode->animatorProperties().setElevation(-10.0f);
- canvas.drawDrawable(&drawable);
- ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
-
- //zero Z are drawn immediately
- rootNode->animatorProperties().setElevation(0.0f);
- canvas.drawDrawable(&drawable);
- ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
+static void drawOrderedRect(Canvas* canvas, uint8_t expectedDrawOrder) {
+ SkPaint paint;
+ // order put in blue channel, transparent so overlapped content doesn't get rejected
+ paint.setColor(SkColorSetARGB(1, 0, 0, expectedDrawOrder));
+ canvas->drawRect(0, 0, 100, 100, paint);
}
-//TODO: another test that verifies equal z values are drawn in order, and barriers prevent Z
-//intermixing (model after FrameBuilder zReorder)
-TEST(RenderNodeDrawable, drawAndReorder) {
- //this test exercises StartReorderBarrierDrawable, EndReorderBarrierDrawable and
- //SkiaRecordingCanvas
- auto surface = SkSurface::MakeRasterN32Premul(4, 4);
- SkCanvas& canvas = *surface->getCanvas();
-
- canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
- ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
-
- //-z draws to all 4 pixels (RED)
- auto redNode = TestUtils::createSkiaNode(0, 0, 4, 4,
- [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
- redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
- props.setElevation(-10.0f);
- }, "redNode");
-
- //0z draws to bottom 2 pixels (GREEN)
- auto bottomHalfGreenNode = TestUtils::createSkiaNode(0, 0, 4, 4,
- [](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) {
- SkPaint greenPaint;
- greenPaint.setColor(SK_ColorGREEN);
- greenPaint.setStyle(SkPaint::kFill_Style);
- bottomHalfGreenCanvas.drawRect(0, 2, 4, 4, greenPaint);
- props.setElevation(0.0f);
- }, "bottomHalfGreenNode");
-
- //+z draws to right 2 pixels (BLUE)
- auto rightHalfBlueNode = TestUtils::createSkiaNode(0, 0, 4, 4,
- [](RenderProperties& props, SkiaRecordingCanvas& rightHalfBlueCanvas) {
- SkPaint bluePaint;
- bluePaint.setColor(SK_ColorBLUE);
- bluePaint.setStyle(SkPaint::kFill_Style);
- rightHalfBlueCanvas.drawRect(2, 0, 4, 4, bluePaint);
- props.setElevation(10.0f);
- }, "rightHalfBlueNode");
-
- auto rootNode = TestUtils::createSkiaNode(0, 0, 4, 4,
- [&](RenderProperties& props, SkiaRecordingCanvas& rootRecorder) {
- rootRecorder.insertReorderBarrier(true);
- //draw in reverse Z order, so Z alters draw order
- rootRecorder.drawRenderNode(rightHalfBlueNode.get());
- rootRecorder.drawRenderNode(bottomHalfGreenNode.get());
- rootRecorder.drawRenderNode(redNode.get());
- }, "rootNode");
+static void drawOrderedNode(Canvas* canvas, uint8_t expectedDrawOrder, float z) {
+ auto node = TestUtils::createSkiaNode(0, 0, 100, 100,
+ [expectedDrawOrder, z](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+ drawOrderedRect(&canvas, expectedDrawOrder);
+ props.setTranslationZ(z);
+ });
+ canvas->drawRenderNode(node.get()); // canvas takes reference/sole ownership
+}
- RenderNodeDrawable drawable3(rootNode.get(), &canvas, false);
- canvas.drawDrawable(&drawable3);
- ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
- ASSERT_EQ(TestUtils::getColor(surface, 0, 3), SK_ColorGREEN);
- ASSERT_EQ(TestUtils::getColor(surface, 3, 3), SK_ColorBLUE);
+TEST(RenderNodeDrawable, zReorder) {
+ class ZReorderCanvas : public SkCanvas {
+ public:
+ ZReorderCanvas(int width, int height) : SkCanvas(width, height) {}
+ void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
+ int expectedOrder = SkColorGetB(paint.getColor()); // extract order from blue channel
+ EXPECT_EQ(expectedOrder, mIndex++) << "An op was drawn out of order";
+ }
+ int getIndex() { return mIndex; }
+ protected:
+ int mIndex = 0;
+ };
+
+ auto parent = TestUtils::createSkiaNode(0, 0, 100, 100,
+ [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+ drawOrderedNode(&canvas, 0, 10.0f); // in reorder=false at this point, so played inorder
+ drawOrderedRect(&canvas, 1);
+ canvas.insertReorderBarrier(true);
+ drawOrderedNode(&canvas, 6, 2.0f);
+ drawOrderedRect(&canvas, 3);
+ drawOrderedNode(&canvas, 4, 0.0f);
+ drawOrderedRect(&canvas, 5);
+ drawOrderedNode(&canvas, 2, -2.0f);
+ drawOrderedNode(&canvas, 7, 2.0f);
+ canvas.insertReorderBarrier(false);
+ drawOrderedRect(&canvas, 8);
+ drawOrderedNode(&canvas, 9, -10.0f); // in reorder=false at this point, so played inorder
+ });
+
+ //create a canvas not backed by any device/pixels, but with dimensions to avoid quick rejection
+ ZReorderCanvas canvas(100, 100);
+ RenderNodeDrawable drawable(parent.get(), &canvas, false);
+ canvas.drawDrawable(&drawable);
+ EXPECT_EQ(10, canvas.getIndex());
}
TEST(RenderNodeDrawable, composeOnLayer)