RenderNodeTests.cpp revision 56ad6ec42f814e9e61030ff819cac4e5d31def8b
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <gtest/gtest.h> 18 19#include "AnimationContext.h" 20#include "DamageAccumulator.h" 21#include "IContextFactory.h" 22#include "RenderNode.h" 23#include "TreeInfo.h" 24#include "renderthread/CanvasContext.h" 25#include "tests/common/TestUtils.h" 26#include "utils/Color.h" 27 28using namespace android; 29using namespace android::uirenderer; 30using namespace android::uirenderer::renderthread; 31 32class ContextFactory : public android::uirenderer::IContextFactory { 33public: 34 android::uirenderer::AnimationContext* createAnimationContext 35 (android::uirenderer::renderthread::TimeLord& clock) override { 36 return new android::uirenderer::AnimationContext(clock); 37 } 38}; 39 40TEST(RenderNode, hasParents) { 41 auto child = TestUtils::createNode(0, 0, 200, 400, 42 [](RenderProperties& props, TestCanvas& canvas) { 43 canvas.drawColor(Color::Red_500, SkXfermode::kSrcOver_Mode); 44 }); 45 auto parent = TestUtils::createNode(0, 0, 200, 400, 46 [&child](RenderProperties& props, TestCanvas& canvas) { 47 canvas.drawRenderNode(child.get()); 48 }); 49 50 TestUtils::syncHierarchyPropertiesAndDisplayList(parent); 51 52 EXPECT_TRUE(child->hasParents()) << "Child node has no parent"; 53 EXPECT_FALSE(parent->hasParents()) << "Root node shouldn't have any parents"; 54 55 TestUtils::recordNode(*parent, [](TestCanvas& canvas) { 56 canvas.drawColor(Color::Amber_500, SkXfermode::kSrcOver_Mode); 57 }); 58 59 EXPECT_TRUE(child->hasParents()) << "Child should still have a parent"; 60 EXPECT_FALSE(parent->hasParents()) << "Root node shouldn't have any parents"; 61 62 TestUtils::syncHierarchyPropertiesAndDisplayList(parent); 63 64 EXPECT_FALSE(child->hasParents()) << "Child should be removed"; 65 EXPECT_FALSE(parent->hasParents()) << "Root node shouldn't have any parents"; 66} 67 68TEST(RenderNode, releasedCallback) { 69 class DecRefOnReleased : public GlFunctorLifecycleListener { 70 public: 71 explicit DecRefOnReleased(int* refcnt) : mRefCnt(refcnt) {} 72 void onGlFunctorReleased(Functor* functor) override { 73 *mRefCnt -= 1; 74 } 75 private: 76 int* mRefCnt; 77 }; 78 79 int refcnt = 0; 80 sp<DecRefOnReleased> listener(new DecRefOnReleased(&refcnt)); 81 Functor noopFunctor; 82 83 auto node = TestUtils::createNode(0, 0, 200, 400, 84 [&](RenderProperties& props, TestCanvas& canvas) { 85 refcnt++; 86 canvas.callDrawGLFunction(&noopFunctor, listener.get()); 87 }); 88 TestUtils::syncHierarchyPropertiesAndDisplayList(node); 89 EXPECT_EQ(1, refcnt); 90 91 TestUtils::recordNode(*node, [&](TestCanvas& canvas) { 92 refcnt++; 93 canvas.callDrawGLFunction(&noopFunctor, listener.get()); 94 }); 95 EXPECT_EQ(2, refcnt); 96 97 TestUtils::syncHierarchyPropertiesAndDisplayList(node); 98 EXPECT_EQ(1, refcnt); 99 100 TestUtils::recordNode(*node, [](TestCanvas& canvas) {}); 101 EXPECT_EQ(1, refcnt); 102 TestUtils::syncHierarchyPropertiesAndDisplayList(node); 103 EXPECT_EQ(0, refcnt); 104} 105 106RENDERTHREAD_TEST(RenderNode, prepareTree_nullableDisplayList) { 107 auto rootNode = TestUtils::createNode(0, 0, 200, 400, nullptr); 108 ContextFactory contextFactory; 109 std::unique_ptr<CanvasContext> canvasContext(CanvasContext::create( 110 renderThread, false, rootNode.get(), &contextFactory)); 111 TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get()); 112 DamageAccumulator damageAccumulator; 113 info.damageAccumulator = &damageAccumulator; 114 info.observer = nullptr; 115 116 { 117 auto nonNullDLNode = TestUtils::createNode(0, 0, 200, 400, 118 [](RenderProperties& props, TestCanvas& canvas) { 119 canvas.drawColor(Color::Red_500, SkXfermode::kSrcOver_Mode); 120 }); 121 TestUtils::syncHierarchyPropertiesAndDisplayList(nonNullDLNode); 122 EXPECT_TRUE(nonNullDLNode->getDisplayList()); 123 nonNullDLNode->prepareTree(info); 124 } 125 126 { 127 auto nullDLNode = TestUtils::createNode(0, 0, 200, 400, nullptr); 128 TestUtils::syncHierarchyPropertiesAndDisplayList(nullDLNode); 129 EXPECT_FALSE(nullDLNode->getDisplayList()); 130 nullDLNode->prepareTree(info); 131 } 132 133 canvasContext->destroy(nullptr); 134} 135