• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <benchmark/benchmark.h>
18 
19 #include "BakedOpDispatcher.h"
20 #include "BakedOpRenderer.h"
21 #include "BakedOpState.h"
22 #include "FrameBuilder.h"
23 #include "LayerUpdateQueue.h"
24 #include "RecordedOp.h"
25 #include "RecordingCanvas.h"
26 #include "Vector.h"
27 #include "tests/common/TestContext.h"
28 #include "tests/common/TestScene.h"
29 #include "tests/common/TestUtils.h"
30 
31 #include <vector>
32 
33 using namespace android;
34 using namespace android::uirenderer;
35 using namespace android::uirenderer::renderthread;
36 using namespace android::uirenderer::test;
37 
38 const FrameBuilder::LightGeometry sLightGeometry = {{100, 100, 100}, 50};
39 const BakedOpRenderer::LightInfo sLightInfo = {128, 128};
40 
createTestNode()41 static sp<RenderNode> createTestNode() {
42     auto node = TestUtils::createNode<RecordingCanvas>(
43             0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
44                 sk_sp<Bitmap> bitmap(TestUtils::createBitmap(10, 10));
45                 SkPaint paint;
46 
47                 // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
48                 // Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
49                 canvas.save(SaveFlags::MatrixClip);
50                 for (int i = 0; i < 30; i++) {
51                     canvas.translate(0, 10);
52                     canvas.drawRect(0, 0, 10, 10, paint);
53                     canvas.drawBitmap(*bitmap, 5, 0, nullptr);
54                 }
55                 canvas.restore();
56             });
57     TestUtils::syncHierarchyPropertiesAndDisplayList(node);
58     return node;
59 }
60 
BM_FrameBuilder_defer(benchmark::State & state)61 void BM_FrameBuilder_defer(benchmark::State& state) {
62     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
63         auto node = createTestNode();
64         while (state.KeepRunning()) {
65             FrameBuilder frameBuilder(SkRect::MakeWH(100, 200), 100, 200, sLightGeometry,
66                                       Caches::getInstance());
67             frameBuilder.deferRenderNode(*node);
68             benchmark::DoNotOptimize(&frameBuilder);
69         }
70     });
71 }
72 BENCHMARK(BM_FrameBuilder_defer);
73 
BM_FrameBuilder_deferAndRender(benchmark::State & state)74 void BM_FrameBuilder_deferAndRender(benchmark::State& state) {
75     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
76         auto node = createTestNode();
77 
78         RenderState& renderState = thread.renderState();
79         Caches& caches = Caches::getInstance();
80 
81         while (state.KeepRunning()) {
82             FrameBuilder frameBuilder(SkRect::MakeWH(100, 200), 100, 200, sLightGeometry, caches);
83             frameBuilder.deferRenderNode(*node);
84 
85             BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
86             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
87             benchmark::DoNotOptimize(&renderer);
88         }
89     });
90 }
91 BENCHMARK(BM_FrameBuilder_deferAndRender);
92 
getSyncedSceneNode(const char * sceneName)93 static sp<RenderNode> getSyncedSceneNode(const char* sceneName) {
94     gDisplay = getBuiltInDisplay();  // switch to real display if present
95 
96     TestContext testContext;
97     TestScene::Options opts;
98     std::unique_ptr<TestScene> scene(TestScene::testMap()[sceneName].createScene(opts));
99 
100     sp<RenderNode> rootNode = TestUtils::createNode<RecordingCanvas>(
101             0, 0, gDisplay.w, gDisplay.h,
102             [&scene](RenderProperties& props, RecordingCanvas& canvas) {
103                 scene->createContent(gDisplay.w, gDisplay.h, canvas);
104             });
105 
106     TestUtils::syncHierarchyPropertiesAndDisplayList(rootNode);
107     return rootNode;
108 }
109 
110 static auto SCENES = {
111         "listview",
112 };
113 
BM_FrameBuilder_defer_scene(benchmark::State & state)114 void BM_FrameBuilder_defer_scene(benchmark::State& state) {
115     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
116         const char* sceneName = *(SCENES.begin() + state.range(0));
117         state.SetLabel(sceneName);
118         auto node = getSyncedSceneNode(sceneName);
119         while (state.KeepRunning()) {
120             FrameBuilder frameBuilder(SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w,
121                                       gDisplay.h, sLightGeometry, Caches::getInstance());
122             frameBuilder.deferRenderNode(*node);
123             benchmark::DoNotOptimize(&frameBuilder);
124         }
125     });
126 }
127 BENCHMARK(BM_FrameBuilder_defer_scene)->DenseRange(0, SCENES.size() - 1);
128 
BM_FrameBuilder_deferAndRender_scene(benchmark::State & state)129 void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) {
130     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
131         const char* sceneName = *(SCENES.begin() + state.range(0));
132         state.SetLabel(sceneName);
133         auto node = getSyncedSceneNode(sceneName);
134 
135         RenderState& renderState = thread.renderState();
136         Caches& caches = Caches::getInstance();
137 
138         while (state.KeepRunning()) {
139             FrameBuilder frameBuilder(SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w,
140                                       gDisplay.h, sLightGeometry, Caches::getInstance());
141             frameBuilder.deferRenderNode(*node);
142 
143             BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
144             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
145             benchmark::DoNotOptimize(&renderer);
146         }
147     });
148 }
149 BENCHMARK(BM_FrameBuilder_deferAndRender_scene)->DenseRange(0, SCENES.size() - 1);
150