blob: 8af4bbe286731675d341250685d2761be0f7b899 [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>
Doris Liu5876e7d2016-08-02 17:28:30 -070018#include <VectorDrawable.h>
John Reck44b49f02016-03-25 14:29:48 -070019
Doris Liua7952b32016-06-13 14:49:26 -070020#include "AnimationContext.h"
21#include "DamageAccumulator.h"
22#include "IContextFactory.h"
John Reck44b49f02016-03-25 14:29:48 -070023#include "RenderNode.h"
24#include "TreeInfo.h"
Doris Liua7952b32016-06-13 14:49:26 -070025#include "renderthread/CanvasContext.h"
John Reck44b49f02016-03-25 14:29:48 -070026#include "tests/common/TestUtils.h"
27#include "utils/Color.h"
28
29using namespace android;
30using namespace android::uirenderer;
Doris Liua7952b32016-06-13 14:49:26 -070031using namespace android::uirenderer::renderthread;
32
33class ContextFactory : public android::uirenderer::IContextFactory {
34public:
35 android::uirenderer::AnimationContext* createAnimationContext
36 (android::uirenderer::renderthread::TimeLord& clock) override {
37 return new android::uirenderer::AnimationContext(clock);
38 }
39};
John Reck44b49f02016-03-25 14:29:48 -070040
41TEST(RenderNode, hasParents) {
42 auto child = TestUtils::createNode(0, 0, 200, 400,
Stan Iliev06152cd2016-07-27 17:55:43 -040043 [](RenderProperties& props, Canvas& canvas) {
Mike Reed260ab722016-10-07 15:59:20 -040044 canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver);
John Reck44b49f02016-03-25 14:29:48 -070045 });
46 auto parent = TestUtils::createNode(0, 0, 200, 400,
Stan Iliev06152cd2016-07-27 17:55:43 -040047 [&child](RenderProperties& props, Canvas& canvas) {
John Reck44b49f02016-03-25 14:29:48 -070048 canvas.drawRenderNode(child.get());
49 });
50
51 TestUtils::syncHierarchyPropertiesAndDisplayList(parent);
52
53 EXPECT_TRUE(child->hasParents()) << "Child node has no parent";
54 EXPECT_FALSE(parent->hasParents()) << "Root node shouldn't have any parents";
55
Stan Iliev06152cd2016-07-27 17:55:43 -040056 TestUtils::recordNode(*parent, [](Canvas& canvas) {
Mike Reed260ab722016-10-07 15:59:20 -040057 canvas.drawColor(Color::Amber_500, SkBlendMode::kSrcOver);
John Reck44b49f02016-03-25 14:29:48 -070058 });
59
60 EXPECT_TRUE(child->hasParents()) << "Child should still have a parent";
61 EXPECT_FALSE(parent->hasParents()) << "Root node shouldn't have any parents";
62
63 TestUtils::syncHierarchyPropertiesAndDisplayList(parent);
64
65 EXPECT_FALSE(child->hasParents()) << "Child should be removed";
66 EXPECT_FALSE(parent->hasParents()) << "Root node shouldn't have any parents";
67}
John Reckcd1c3eb2016-04-14 10:38:54 -070068
John Reck2de950d2017-01-25 10:58:30 -080069TEST(RenderNode, validity) {
70 auto child = TestUtils::createNode(0, 0, 200, 400,
71 [](RenderProperties& props, Canvas& canvas) {
72 canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver);
73 });
74 auto parent = TestUtils::createNode(0, 0, 200, 400,
75 [&child](RenderProperties& props, Canvas& canvas) {
76 canvas.drawRenderNode(child.get());
77 });
78
79 EXPECT_TRUE(child->isValid());
80 EXPECT_TRUE(parent->isValid());
81 EXPECT_TRUE(child->nothingToDraw());
82 EXPECT_TRUE(parent->nothingToDraw());
83
84 TestUtils::syncHierarchyPropertiesAndDisplayList(parent);
85
86 EXPECT_TRUE(child->isValid());
87 EXPECT_TRUE(parent->isValid());
88 EXPECT_FALSE(child->nothingToDraw());
89 EXPECT_FALSE(parent->nothingToDraw());
90
91 TestUtils::recordNode(*parent, [](Canvas& canvas) {
92 canvas.drawColor(Color::Amber_500, SkBlendMode::kSrcOver);
93 });
94
95 EXPECT_TRUE(child->isValid());
96 EXPECT_TRUE(parent->isValid());
97 EXPECT_FALSE(child->nothingToDraw());
98 EXPECT_FALSE(parent->nothingToDraw());
99
100 TestUtils::syncHierarchyPropertiesAndDisplayList(parent);
101
102 EXPECT_FALSE(child->isValid());
103 EXPECT_TRUE(parent->isValid());
104 EXPECT_TRUE(child->nothingToDraw());
105 EXPECT_FALSE(parent->nothingToDraw());
106
107 TestUtils::recordNode(*child, [](Canvas& canvas) {
108 canvas.drawColor(Color::Amber_500, SkBlendMode::kSrcOver);
109 });
110
111 EXPECT_TRUE(child->isValid());
112 EXPECT_TRUE(child->nothingToDraw());
113
114 TestUtils::recordNode(*parent, [&child](Canvas& canvas) {
115 canvas.drawRenderNode(child.get());
116 });
117
118 TestUtils::syncHierarchyPropertiesAndDisplayList(parent);
119
120 EXPECT_TRUE(child->isValid());
121 EXPECT_TRUE(parent->isValid());
122 EXPECT_FALSE(child->nothingToDraw());
123 EXPECT_FALSE(parent->nothingToDraw());
124
125 parent->destroyHardwareResources();
126
127 EXPECT_FALSE(child->isValid());
128 EXPECT_FALSE(parent->isValid());
129 EXPECT_TRUE(child->nothingToDraw());
130 EXPECT_TRUE(parent->nothingToDraw());
131}
132
John Reckcd1c3eb2016-04-14 10:38:54 -0700133TEST(RenderNode, releasedCallback) {
134 class DecRefOnReleased : public GlFunctorLifecycleListener {
135 public:
Chih-Hung Hsiehd53e3be2016-05-03 10:02:51 -0700136 explicit DecRefOnReleased(int* refcnt) : mRefCnt(refcnt) {}
John Reckcd1c3eb2016-04-14 10:38:54 -0700137 void onGlFunctorReleased(Functor* functor) override {
138 *mRefCnt -= 1;
139 }
140 private:
141 int* mRefCnt;
142 };
143
144 int refcnt = 0;
145 sp<DecRefOnReleased> listener(new DecRefOnReleased(&refcnt));
146 Functor noopFunctor;
147
148 auto node = TestUtils::createNode(0, 0, 200, 400,
Stan Iliev06152cd2016-07-27 17:55:43 -0400149 [&](RenderProperties& props, Canvas& canvas) {
John Reckcd1c3eb2016-04-14 10:38:54 -0700150 refcnt++;
151 canvas.callDrawGLFunction(&noopFunctor, listener.get());
152 });
153 TestUtils::syncHierarchyPropertiesAndDisplayList(node);
154 EXPECT_EQ(1, refcnt);
155
Stan Iliev06152cd2016-07-27 17:55:43 -0400156 TestUtils::recordNode(*node, [&](Canvas& canvas) {
John Reckcd1c3eb2016-04-14 10:38:54 -0700157 refcnt++;
158 canvas.callDrawGLFunction(&noopFunctor, listener.get());
159 });
160 EXPECT_EQ(2, refcnt);
161
162 TestUtils::syncHierarchyPropertiesAndDisplayList(node);
163 EXPECT_EQ(1, refcnt);
164
Stan Iliev06152cd2016-07-27 17:55:43 -0400165 TestUtils::recordNode(*node, [](Canvas& canvas) {});
John Reckcd1c3eb2016-04-14 10:38:54 -0700166 EXPECT_EQ(1, refcnt);
167 TestUtils::syncHierarchyPropertiesAndDisplayList(node);
168 EXPECT_EQ(0, refcnt);
169}
Doris Liua7952b32016-06-13 14:49:26 -0700170
171RENDERTHREAD_TEST(RenderNode, prepareTree_nullableDisplayList) {
Derek Sollenberger56ad6ec2016-07-22 12:13:32 -0400172 auto rootNode = TestUtils::createNode(0, 0, 200, 400, nullptr);
Doris Liua7952b32016-06-13 14:49:26 -0700173 ContextFactory contextFactory;
Stan Iliev03de0742016-07-07 12:35:54 -0400174 std::unique_ptr<CanvasContext> canvasContext(CanvasContext::create(
Derek Sollenberger56ad6ec2016-07-22 12:13:32 -0400175 renderThread, false, rootNode.get(), &contextFactory));
Stan Iliev03de0742016-07-07 12:35:54 -0400176 TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
Doris Liua7952b32016-06-13 14:49:26 -0700177 DamageAccumulator damageAccumulator;
178 info.damageAccumulator = &damageAccumulator;
Doris Liua7952b32016-06-13 14:49:26 -0700179
180 {
181 auto nonNullDLNode = TestUtils::createNode(0, 0, 200, 400,
Stan Iliev06152cd2016-07-27 17:55:43 -0400182 [](RenderProperties& props, Canvas& canvas) {
Mike Reed260ab722016-10-07 15:59:20 -0400183 canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver);
Doris Liua7952b32016-06-13 14:49:26 -0700184 });
185 TestUtils::syncHierarchyPropertiesAndDisplayList(nonNullDLNode);
186 EXPECT_TRUE(nonNullDLNode->getDisplayList());
187 nonNullDLNode->prepareTree(info);
188 }
189
190 {
191 auto nullDLNode = TestUtils::createNode(0, 0, 200, 400, nullptr);
192 TestUtils::syncHierarchyPropertiesAndDisplayList(nullDLNode);
193 EXPECT_FALSE(nullDLNode->getDisplayList());
194 nullDLNode->prepareTree(info);
195 }
196
John Reck2de950d2017-01-25 10:58:30 -0800197 canvasContext->destroy();
Doris Liua7952b32016-06-13 14:49:26 -0700198}
Doris Liu5876e7d2016-08-02 17:28:30 -0700199
200RENDERTHREAD_TEST(RenderNode, prepareTree_HwLayer_AVD_enqueueDamage) {
201
202 VectorDrawable::Group* group = new VectorDrawable::Group();
Greg Daniel98c78dad2017-01-04 14:45:56 -0500203 sp<VectorDrawableRoot> vectorDrawable(new VectorDrawableRoot(group));
204
Doris Liu5876e7d2016-08-02 17:28:30 -0700205 auto rootNode = TestUtils::createNode(0, 0, 200, 400,
206 [&](RenderProperties& props, Canvas& canvas) {
Greg Daniel98c78dad2017-01-04 14:45:56 -0500207 canvas.drawVectorDrawable(vectorDrawable.get());
Doris Liu5876e7d2016-08-02 17:28:30 -0700208 });
209 ContextFactory contextFactory;
210 std::unique_ptr<CanvasContext> canvasContext(CanvasContext::create(
211 renderThread, false, rootNode.get(), &contextFactory));
212 TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
213 DamageAccumulator damageAccumulator;
214 LayerUpdateQueue layerUpdateQueue;
215 info.damageAccumulator = &damageAccumulator;
216 info.layerUpdateQueue = &layerUpdateQueue;
Doris Liu5876e7d2016-08-02 17:28:30 -0700217
218 // Put node on HW layer
219 rootNode->mutateStagingProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
220
221 TestUtils::syncHierarchyPropertiesAndDisplayList(rootNode);
222 rootNode->prepareTree(info);
223
224 // Check that the VD is in the dislay list, and the layer update queue contains the correct
225 // damage rect.
Derek Sollenberger0df62092016-09-27 16:04:42 -0400226 EXPECT_TRUE(rootNode->getDisplayList()->hasVectorDrawables());
Doris Liu5876e7d2016-08-02 17:28:30 -0700227 EXPECT_FALSE(info.layerUpdateQueue->entries().empty());
228 EXPECT_EQ(rootNode.get(), info.layerUpdateQueue->entries().at(0).renderNode);
229 EXPECT_EQ(uirenderer::Rect(0, 0, 200, 400), info.layerUpdateQueue->entries().at(0).damage);
John Reck2de950d2017-01-25 10:58:30 -0800230 canvasContext->destroy();
Doris Liu5876e7d2016-08-02 17:28:30 -0700231}