1 /*
2  * Copyright (C) 2014 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 <stdio.h>
18 
19 #include <cutils/log.h>
20 #include <gui/Surface.h>
21 #include <ui/PixelFormat.h>
22 
23 #include <AnimationContext.h>
24 #include <DisplayListRenderer.h>
25 #include <RenderNode.h>
26 #include <renderthread/RenderProxy.h>
27 
28 #include "TestContext.h"
29 
30 using namespace android;
31 using namespace android::uirenderer;
32 using namespace android::uirenderer::renderthread;
33 
34 class ContextFactory : public IContextFactory {
35 public:
createAnimationContext(renderthread::TimeLord & clock)36     virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) {
37         return new AnimationContext(clock);
38     }
39 };
40 
startRecording(RenderNode * node)41 static DisplayListRenderer* startRecording(RenderNode* node) {
42     DisplayListRenderer* renderer = new DisplayListRenderer();
43     renderer->setViewport(node->getWidth(), node->getHeight());
44     renderer->prepare(false);
45     return renderer;
46 }
47 
endRecording(DisplayListRenderer * renderer,RenderNode * node)48 static void endRecording(DisplayListRenderer* renderer, RenderNode* node) {
49     renderer->finish();
50     node->setStagingDisplayList(renderer->finishRecording());
51     delete renderer;
52 }
53 
createCard(int x,int y,int width,int height)54 sp<RenderNode> createCard(int x, int y, int width, int height) {
55     sp<RenderNode> node = new RenderNode();
56     node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
57     node->mutateStagingProperties().setElevation(dp(16));
58     node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1);
59     node->mutateStagingProperties().mutableOutline().setShouldClip(true);
60     node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z);
61 
62     DisplayListRenderer* renderer = startRecording(node.get());
63     renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode);
64     endRecording(renderer, node.get());
65 
66     return node;
67 }
68 
main(int argc,char * argv[])69 int main(int argc, char* argv[]) {
70     createTestEnvironment();
71 
72     // create the native surface
73     const int width = gDisplay.w;
74     const int height = gDisplay.h;
75     sp<SurfaceControl> control = createWindow(width, height);
76     sp<Surface> surface = control->getSurface();
77 
78     RenderNode* rootNode = new RenderNode();
79     rootNode->incStrong(0);
80     rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height);
81     rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
82     rootNode->mutateStagingProperties().setClipToBounds(false);
83     rootNode->setPropertyFieldsDirty(RenderNode::GENERIC);
84 
85     ContextFactory factory;
86     RenderProxy* proxy = new RenderProxy(false, rootNode, &factory);
87     proxy->loadSystemProperties();
88     proxy->initialize(surface);
89     float lightX = width / 2.0;
90     proxy->setup(width, height, (Vector3){lightX, dp(-200.0f), dp(800.0f)},
91             dp(800.0f), 255 * 0.075, 255 * 0.15);
92 
93     android::uirenderer::Rect DUMMY;
94 
95     std::vector< sp<RenderNode> > cards;
96 
97     DisplayListRenderer* renderer = startRecording(rootNode);
98     renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
99     renderer->insertReorderBarrier(true);
100 
101     for (int x = dp(16); x < (width - dp(116)); x += dp(116)) {
102         for (int y = dp(16); y < (height - dp(116)); y += dp(116)) {
103             sp<RenderNode> card = createCard(x, y, dp(100), dp(100));
104             renderer->drawRenderNode(card.get(), DUMMY, 0);
105             cards.push_back(card);
106         }
107     }
108 
109     renderer->insertReorderBarrier(false);
110     endRecording(renderer, rootNode);
111 
112     for (int i = 0; i < 150; i++) {
113         ATRACE_NAME("UI-Draw Frame");
114         for (int ci = 0; ci < cards.size(); ci++) {
115             cards[ci]->mutateStagingProperties().setTranslationX(i);
116             cards[ci]->mutateStagingProperties().setTranslationY(i);
117             cards[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
118         }
119         nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC);
120         proxy->syncAndDrawFrame(frameTimeNs, 0, gDisplay.density);
121         usleep(12000);
122     }
123 
124     sleep(5);
125 
126     delete proxy;
127     rootNode->decStrong(0);
128 
129     printf("Success!\n");
130     return 0;
131 }
132