Home | History | Annotate | Download | only in unit
      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 
     28 using namespace android;
     29 using namespace android::uirenderer;
     30 using namespace android::uirenderer::renderthread;
     31 
     32 class ContextFactory : public android::uirenderer::IContextFactory {
     33 public:
     34     android::uirenderer::AnimationContext* createAnimationContext
     35         (android::uirenderer::renderthread::TimeLord& clock) override {
     36         return new android::uirenderer::AnimationContext(clock);
     37     }
     38 };
     39 
     40 TEST(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 
     68 TEST(RenderNode, releasedCallback) {
     69     class DecRefOnReleased : public GlFunctorLifecycleListener {
     70     public:
     71         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 
    106 RENDERTHREAD_TEST(RenderNode, prepareTree_nullableDisplayList) {
    107     ContextFactory contextFactory;
    108     CanvasContext canvasContext(renderThread, false, nullptr, &contextFactory);
    109     TreeInfo info(TreeInfo::MODE_RT_ONLY, canvasContext);
    110     DamageAccumulator damageAccumulator;
    111     info.damageAccumulator = &damageAccumulator;
    112     info.observer = nullptr;
    113 
    114     {
    115         auto nonNullDLNode = TestUtils::createNode(0, 0, 200, 400,
    116                 [](RenderProperties& props, TestCanvas& canvas) {
    117             canvas.drawColor(Color::Red_500, SkXfermode::kSrcOver_Mode);
    118         });
    119         TestUtils::syncHierarchyPropertiesAndDisplayList(nonNullDLNode);
    120         EXPECT_TRUE(nonNullDLNode->getDisplayList());
    121         nonNullDLNode->prepareTree(info);
    122     }
    123 
    124     {
    125         auto nullDLNode = TestUtils::createNode(0, 0, 200, 400, nullptr);
    126         TestUtils::syncHierarchyPropertiesAndDisplayList(nullDLNode);
    127         EXPECT_FALSE(nullDLNode->getDisplayList());
    128         nullDLNode->prepareTree(info);
    129     }
    130 
    131     canvasContext.destroy(nullptr);
    132 }
    133