blob: 132601efb543e274a8ab5e9ae9999c124491b0ce [file] [log] [blame]
John Reck44b49f02016-03-25 14:29:48 -07001/*
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
Doris Liua7952b32016-06-13 14:49:26 -070019#include "AnimationContext.h"
20#include "DamageAccumulator.h"
21#include "IContextFactory.h"
John Reck44b49f02016-03-25 14:29:48 -070022#include "RenderNode.h"
23#include "TreeInfo.h"
Doris Liua7952b32016-06-13 14:49:26 -070024#include "renderthread/CanvasContext.h"
John Reck44b49f02016-03-25 14:29:48 -070025#include "tests/common/TestUtils.h"
26#include "utils/Color.h"
27
28using namespace android;
29using namespace android::uirenderer;
Doris Liua7952b32016-06-13 14:49:26 -070030using 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};
John Reck44b49f02016-03-25 14:29:48 -070039
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}
John Reckcd1c3eb2016-04-14 10:38:54 -070067
68TEST(RenderNode, releasedCallback) {
69 class DecRefOnReleased : public GlFunctorLifecycleListener {
70 public:
Chih-Hung Hsiehd53e3be2016-05-03 10:02:51 -070071 explicit DecRefOnReleased(int* refcnt) : mRefCnt(refcnt) {}
John Reckcd1c3eb2016-04-14 10:38:54 -070072 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}
Doris Liua7952b32016-06-13 14:49:26 -0700105
106RENDERTHREAD_TEST(RenderNode, prepareTree_nullableDisplayList) {
107 ContextFactory contextFactory;
Stan Iliev03de0742016-07-07 12:35:54 -0400108 std::unique_ptr<CanvasContext> canvasContext(CanvasContext::create(
109 renderThread, false, nullptr, &contextFactory));
110 TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
Doris Liua7952b32016-06-13 14:49:26 -0700111 DamageAccumulator damageAccumulator;
112 info.damageAccumulator = &damageAccumulator;
113 info.observer = nullptr;
114
115 {
116 auto nonNullDLNode = TestUtils::createNode(0, 0, 200, 400,
117 [](RenderProperties& props, TestCanvas& canvas) {
118 canvas.drawColor(Color::Red_500, SkXfermode::kSrcOver_Mode);
119 });
120 TestUtils::syncHierarchyPropertiesAndDisplayList(nonNullDLNode);
121 EXPECT_TRUE(nonNullDLNode->getDisplayList());
122 nonNullDLNode->prepareTree(info);
123 }
124
125 {
126 auto nullDLNode = TestUtils::createNode(0, 0, 200, 400, nullptr);
127 TestUtils::syncHierarchyPropertiesAndDisplayList(nullDLNode);
128 EXPECT_FALSE(nullDLNode->getDisplayList());
129 nullDLNode->prepareTree(info);
130 }
131
Stan Iliev03de0742016-07-07 12:35:54 -0400132 canvasContext->destroy(nullptr);
Doris Liua7952b32016-06-13 14:49:26 -0700133}