blob: fd3cf3731f04b027022333df02eedc80275546d4 [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,
Stan Iliev06152cd2016-07-27 17:55:43 -040042 [](RenderProperties& props, Canvas& canvas) {
John Reck44b49f02016-03-25 14:29:48 -070043 canvas.drawColor(Color::Red_500, SkXfermode::kSrcOver_Mode);
44 });
45 auto parent = TestUtils::createNode(0, 0, 200, 400,
Stan Iliev06152cd2016-07-27 17:55:43 -040046 [&child](RenderProperties& props, Canvas& canvas) {
John Reck44b49f02016-03-25 14:29:48 -070047 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
Stan Iliev06152cd2016-07-27 17:55:43 -040055 TestUtils::recordNode(*parent, [](Canvas& canvas) {
John Reck44b49f02016-03-25 14:29:48 -070056 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,
Stan Iliev06152cd2016-07-27 17:55:43 -040084 [&](RenderProperties& props, Canvas& canvas) {
John Reckcd1c3eb2016-04-14 10:38:54 -070085 refcnt++;
86 canvas.callDrawGLFunction(&noopFunctor, listener.get());
87 });
88 TestUtils::syncHierarchyPropertiesAndDisplayList(node);
89 EXPECT_EQ(1, refcnt);
90
Stan Iliev06152cd2016-07-27 17:55:43 -040091 TestUtils::recordNode(*node, [&](Canvas& canvas) {
John Reckcd1c3eb2016-04-14 10:38:54 -070092 refcnt++;
93 canvas.callDrawGLFunction(&noopFunctor, listener.get());
94 });
95 EXPECT_EQ(2, refcnt);
96
97 TestUtils::syncHierarchyPropertiesAndDisplayList(node);
98 EXPECT_EQ(1, refcnt);
99
Stan Iliev06152cd2016-07-27 17:55:43 -0400100 TestUtils::recordNode(*node, [](Canvas& canvas) {});
John Reckcd1c3eb2016-04-14 10:38:54 -0700101 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) {
Derek Sollenberger56ad6ec2016-07-22 12:13:32 -0400107 auto rootNode = TestUtils::createNode(0, 0, 200, 400, nullptr);
Doris Liua7952b32016-06-13 14:49:26 -0700108 ContextFactory contextFactory;
Stan Iliev03de0742016-07-07 12:35:54 -0400109 std::unique_ptr<CanvasContext> canvasContext(CanvasContext::create(
Derek Sollenberger56ad6ec2016-07-22 12:13:32 -0400110 renderThread, false, rootNode.get(), &contextFactory));
Stan Iliev03de0742016-07-07 12:35:54 -0400111 TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
Doris Liua7952b32016-06-13 14:49:26 -0700112 DamageAccumulator damageAccumulator;
113 info.damageAccumulator = &damageAccumulator;
114 info.observer = nullptr;
115
116 {
117 auto nonNullDLNode = TestUtils::createNode(0, 0, 200, 400,
Stan Iliev06152cd2016-07-27 17:55:43 -0400118 [](RenderProperties& props, Canvas& canvas) {
Doris Liua7952b32016-06-13 14:49:26 -0700119 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
Stan Iliev03de0742016-07-07 12:35:54 -0400133 canvasContext->destroy(nullptr);
Doris Liua7952b32016-06-13 14:49:26 -0700134}