diff options
author | 2016-11-02 15:29:03 -0400 | |
---|---|---|
committer | 2016-11-03 13:44:41 -0400 | |
commit | 2f06e8ad1a1c4d0866bb66854d2759e275898635 (patch) | |
tree | 56c502dddffbc950880729226b8d894807bae97c | |
parent | 500a0c30d4dcd012218c3e44a62926a1c34a259f (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.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/RenderNodeDrawable.h | 11 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/tests/unit/RenderNodeDrawableTests.cpp | 123 |
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) |