RenderNodeDrawableTests.cpp revision 500a0c30d4dcd012218c3e44a62926a1c34a259f
1021693b967a2c5556dddd183eb0247df4079e1adStan Iliev/* 2021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * Copyright (C) 2016 The Android Open Source Project 3021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * 4021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * Licensed under the Apache License, Version 2.0 (the "License"); 5021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * you may not use this file except in compliance with the License. 6021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * You may obtain a copy of the License at 7021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * 8021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * http://www.apache.org/licenses/LICENSE-2.0 9021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * 10021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * Unless required by applicable law or agreed to in writing, software 11021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * distributed under the License is distributed on an "AS IS" BASIS, 12021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * See the License for the specific language governing permissions and 14021693b967a2c5556dddd183eb0247df4079e1adStan Iliev * limitations under the License. 15021693b967a2c5556dddd183eb0247df4079e1adStan Iliev */ 16021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 17021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include <gtest/gtest.h> 18021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include <VectorDrawable.h> 19021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 20021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "AnimationContext.h" 21021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "DamageAccumulator.h" 22021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "IContextFactory.h" 23021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "pipeline/skia/SkiaDisplayList.h" 24021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "pipeline/skia/SkiaRecordingCanvas.h" 25021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "renderthread/CanvasContext.h" 26021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "tests/common/TestUtils.h" 27021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "SkiaCanvas.h" 28021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include <SkLiteRecorder.h> 29021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include <string.h> 30021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 31021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 32021693b967a2c5556dddd183eb0247df4079e1adStan Ilievusing namespace android; 33021693b967a2c5556dddd183eb0247df4079e1adStan Ilievusing namespace android::uirenderer; 34021693b967a2c5556dddd183eb0247df4079e1adStan Ilievusing namespace android::uirenderer::renderthread; 35021693b967a2c5556dddd183eb0247df4079e1adStan Ilievusing namespace android::uirenderer::skiapipeline; 36021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 37021693b967a2c5556dddd183eb0247df4079e1adStan IlievTEST(RenderNodeDrawable, create) { 38021693b967a2c5556dddd183eb0247df4079e1adStan Iliev auto rootNode = TestUtils::createNode(0, 0, 200, 400, 39021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [](RenderProperties& props, Canvas& canvas) { 40021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver); 41021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }); 42021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 43021693b967a2c5556dddd183eb0247df4079e1adStan Iliev auto skLiteDL = SkLiteDL::New(SkRect::MakeWH(1, 1)); 44021693b967a2c5556dddd183eb0247df4079e1adStan Iliev SkLiteRecorder canvas; 45021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.reset(skLiteDL.get()); 46021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.translate(100, 100); 47021693b967a2c5556dddd183eb0247df4079e1adStan Iliev RenderNodeDrawable drawable(rootNode.get(), &canvas); 48021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 49021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(drawable.getRenderNode(), rootNode.get()); 50021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(&drawable.getNodeProperties(), &rootNode->properties()); 51021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(drawable.getRecordedMatrix(), canvas.getTotalMatrix()); 52021693b967a2c5556dddd183eb0247df4079e1adStan Iliev} 53021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 54021693b967a2c5556dddd183eb0247df4079e1adStan IlievTEST(RenderNodeDrawable, drawContent) { 55021693b967a2c5556dddd183eb0247df4079e1adStan Iliev auto surface = SkSurface::MakeRasterN32Premul(1, 1); 56021693b967a2c5556dddd183eb0247df4079e1adStan Iliev SkCanvas& canvas = *surface->getCanvas(); 57021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); 58021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); 59021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 60021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //create a RenderNodeDrawable backed by a RenderNode backed by a SkLiteRecorder 61500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev auto rootNode = TestUtils::createSkiaNode(0, 0, 1, 1, 62021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [](RenderProperties& props, SkiaRecordingCanvas& recorder) { 63021693b967a2c5556dddd183eb0247df4079e1adStan Iliev recorder.drawColor(SK_ColorRED, SkBlendMode::kSrcOver); 64021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }); 65021693b967a2c5556dddd183eb0247df4079e1adStan Iliev RenderNodeDrawable drawable(rootNode.get(), &canvas, false); 66021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 67021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //negative and positive Z order are drawn out of order 68021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rootNode->animatorProperties().setElevation(10.0f); 69021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawDrawable(&drawable); 70021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); 71021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rootNode->animatorProperties().setElevation(-10.0f); 72021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawDrawable(&drawable); 73021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); 74021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 75021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //zero Z are drawn immediately 76021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rootNode->animatorProperties().setElevation(0.0f); 77021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawDrawable(&drawable); 78021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED); 79021693b967a2c5556dddd183eb0247df4079e1adStan Iliev} 80021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 81021693b967a2c5556dddd183eb0247df4079e1adStan Iliev//TODO: another test that verifies equal z values are drawn in order, and barriers prevent Z 82021693b967a2c5556dddd183eb0247df4079e1adStan Iliev//intermixing (model after FrameBuilder zReorder) 83021693b967a2c5556dddd183eb0247df4079e1adStan IlievTEST(RenderNodeDrawable, drawAndReorder) { 84021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //this test exercises StartReorderBarrierDrawable, EndReorderBarrierDrawable and 85021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //SkiaRecordingCanvas 86021693b967a2c5556dddd183eb0247df4079e1adStan Iliev auto surface = SkSurface::MakeRasterN32Premul(4, 4); 87021693b967a2c5556dddd183eb0247df4079e1adStan Iliev SkCanvas& canvas = *surface->getCanvas(); 88021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 89021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver); 90021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE); 91021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 92021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //-z draws to all 4 pixels (RED) 93500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev auto redNode = TestUtils::createSkiaNode(0, 0, 4, 4, 94021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) { 95021693b967a2c5556dddd183eb0247df4079e1adStan Iliev redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver); 96021693b967a2c5556dddd183eb0247df4079e1adStan Iliev props.setElevation(-10.0f); 97021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }, "redNode"); 98021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 99021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //0z draws to bottom 2 pixels (GREEN) 100500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev auto bottomHalfGreenNode = TestUtils::createSkiaNode(0, 0, 4, 4, 101021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) { 102021693b967a2c5556dddd183eb0247df4079e1adStan Iliev SkPaint greenPaint; 103021693b967a2c5556dddd183eb0247df4079e1adStan Iliev greenPaint.setColor(SK_ColorGREEN); 104021693b967a2c5556dddd183eb0247df4079e1adStan Iliev greenPaint.setStyle(SkPaint::kFill_Style); 105021693b967a2c5556dddd183eb0247df4079e1adStan Iliev bottomHalfGreenCanvas.drawRect(0, 2, 4, 4, greenPaint); 106021693b967a2c5556dddd183eb0247df4079e1adStan Iliev props.setElevation(0.0f); 107021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }, "bottomHalfGreenNode"); 108021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 109021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //+z draws to right 2 pixels (BLUE) 110500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev auto rightHalfBlueNode = TestUtils::createSkiaNode(0, 0, 4, 4, 111021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [](RenderProperties& props, SkiaRecordingCanvas& rightHalfBlueCanvas) { 112021693b967a2c5556dddd183eb0247df4079e1adStan Iliev SkPaint bluePaint; 113021693b967a2c5556dddd183eb0247df4079e1adStan Iliev bluePaint.setColor(SK_ColorBLUE); 114021693b967a2c5556dddd183eb0247df4079e1adStan Iliev bluePaint.setStyle(SkPaint::kFill_Style); 115021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rightHalfBlueCanvas.drawRect(2, 0, 4, 4, bluePaint); 116021693b967a2c5556dddd183eb0247df4079e1adStan Iliev props.setElevation(10.0f); 117021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }, "rightHalfBlueNode"); 118021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 119500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev auto rootNode = TestUtils::createSkiaNode(0, 0, 4, 4, 120021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [&](RenderProperties& props, SkiaRecordingCanvas& rootRecorder) { 121021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rootRecorder.insertReorderBarrier(true); 122021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //draw in reverse Z order, so Z alters draw order 123021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rootRecorder.drawRenderNode(rightHalfBlueNode.get()); 124021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rootRecorder.drawRenderNode(bottomHalfGreenNode.get()); 125021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rootRecorder.drawRenderNode(redNode.get()); 126021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }, "rootNode"); 127021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 128021693b967a2c5556dddd183eb0247df4079e1adStan Iliev RenderNodeDrawable drawable3(rootNode.get(), &canvas, false); 129021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawDrawable(&drawable3); 130021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED); 131021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 3), SK_ColorGREEN); 132021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 3, 3), SK_ColorBLUE); 133021693b967a2c5556dddd183eb0247df4079e1adStan Iliev} 134021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 135021693b967a2c5556dddd183eb0247df4079e1adStan IlievTEST(RenderNodeDrawable, composeOnLayer) 136021693b967a2c5556dddd183eb0247df4079e1adStan Iliev{ 137021693b967a2c5556dddd183eb0247df4079e1adStan Iliev auto surface = SkSurface::MakeRasterN32Premul(1, 1); 138021693b967a2c5556dddd183eb0247df4079e1adStan Iliev SkCanvas& canvas = *surface->getCanvas(); 139021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); 140021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); 141021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 142500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev auto rootNode = TestUtils::createSkiaNode(0, 0, 1, 1, 143021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [](RenderProperties& props, SkiaRecordingCanvas& recorder) { 144021693b967a2c5556dddd183eb0247df4079e1adStan Iliev recorder.drawColor(SK_ColorRED, SkBlendMode::kSrcOver); 145021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }); 146021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 147021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //attach a layer to the render node 148021693b967a2c5556dddd183eb0247df4079e1adStan Iliev auto surfaceLayer = SkSurface::MakeRasterN32Premul(1, 1); 149021693b967a2c5556dddd183eb0247df4079e1adStan Iliev auto canvas2 = surfaceLayer->getCanvas(); 150021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas2->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver); 151500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev rootNode->setLayerSurface(surfaceLayer); 152021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 153021693b967a2c5556dddd183eb0247df4079e1adStan Iliev RenderNodeDrawable drawable1(rootNode.get(), &canvas, false); 154021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawDrawable(&drawable1); 155021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(SK_ColorRED, TestUtils::getColor(surface, 0, 0)); 156021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 157021693b967a2c5556dddd183eb0247df4079e1adStan Iliev RenderNodeDrawable drawable2(rootNode.get(), &canvas, true); 158021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawDrawable(&drawable2); 159021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(SK_ColorWHITE, TestUtils::getColor(surface, 0, 0)); 160021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 161021693b967a2c5556dddd183eb0247df4079e1adStan Iliev RenderNodeDrawable drawable3(rootNode.get(), &canvas, false); 162021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawDrawable(&drawable3); 163021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(SK_ColorRED, TestUtils::getColor(surface, 0, 0)); 164021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 165500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev rootNode->setLayerSurface(sk_sp<SkSurface>()); 166021693b967a2c5556dddd183eb0247df4079e1adStan Iliev} 167021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 168021693b967a2c5556dddd183eb0247df4079e1adStan Iliev//TODO: refactor to cover test cases from FrameBuilderTests_projectionReorder 169021693b967a2c5556dddd183eb0247df4079e1adStan Iliev//validate with bounds and projection path mask. 170021693b967a2c5556dddd183eb0247df4079e1adStan Iliev//TODO: research if we could hook in and mock/validate different aspects of the drawing, 171021693b967a2c5556dddd183eb0247df4079e1adStan Iliev//instead of validating pixels 172021693b967a2c5556dddd183eb0247df4079e1adStan IlievTEST(RenderNodeDrawable, projectDraw) { 173021693b967a2c5556dddd183eb0247df4079e1adStan Iliev auto surface = SkSurface::MakeRasterN32Premul(1, 1); 174021693b967a2c5556dddd183eb0247df4079e1adStan Iliev SkCanvas& canvas = *surface->getCanvas(); 175021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); 176021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); 177021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 178500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev auto redNode = TestUtils::createSkiaNode(0, 0, 1, 1, 179021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) { 180021693b967a2c5556dddd183eb0247df4079e1adStan Iliev redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver); 181021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }, "redNode"); 182021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 183500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev auto greenNodeWithRedChild = TestUtils::createSkiaNode(0, 0, 1, 1, 184021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [&](RenderProperties& props, SkiaRecordingCanvas& greenCanvasWithRedChild) { 185021693b967a2c5556dddd183eb0247df4079e1adStan Iliev greenCanvasWithRedChild.drawRenderNode(redNode.get()); 186021693b967a2c5556dddd183eb0247df4079e1adStan Iliev greenCanvasWithRedChild.drawColor(SK_ColorGREEN, SkBlendMode::kSrcOver); 187021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }, "greenNodeWithRedChild"); 188021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 189500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev auto rootNode = TestUtils::createSkiaNode(0, 0, 1, 1, 190021693b967a2c5556dddd183eb0247df4079e1adStan Iliev [&](RenderProperties& props, SkiaRecordingCanvas& rootCanvas) { 191021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rootCanvas.drawRenderNode(greenNodeWithRedChild.get()); 192021693b967a2c5556dddd183eb0247df4079e1adStan Iliev }, "rootNode"); 193021693b967a2c5556dddd183eb0247df4079e1adStan Iliev SkiaDisplayList* rootDisplayList = static_cast<SkiaDisplayList*>( 194021693b967a2c5556dddd183eb0247df4079e1adStan Iliev (const_cast<DisplayList*>(rootNode->getDisplayList()))); 195021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 196021693b967a2c5556dddd183eb0247df4079e1adStan Iliev RenderNodeDrawable rootDrawable(rootNode.get(), &canvas, false); 197021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawDrawable(&rootDrawable); 198021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorGREEN); 199021693b967a2c5556dddd183eb0247df4079e1adStan Iliev 200021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //project redNode on rootNode, which will change the test outcome, 201021693b967a2c5556dddd183eb0247df4079e1adStan Iliev //because redNode will draw after greenNodeWithRedChild 202021693b967a2c5556dddd183eb0247df4079e1adStan Iliev rootDisplayList->mIsProjectionReceiver = true; 203021693b967a2c5556dddd183eb0247df4079e1adStan Iliev redNode->animatorProperties().setProjectBackwards(true); 204021693b967a2c5556dddd183eb0247df4079e1adStan Iliev canvas.drawDrawable(&rootDrawable); 205021693b967a2c5556dddd183eb0247df4079e1adStan Iliev ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED); 206021693b967a2c5556dddd183eb0247df4079e1adStan Iliev} 207