• 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 "BakedOpState.h"
20 #include "BakedOpDispatcher.h"
21 #include "BakedOpRenderer.h"
22 #include "FrameBuilder.h"
23 #include "LayerUpdateQueue.h"
24 #include "RecordedOp.h"
25 #include "RecordingCanvas.h"
26 #include "tests/common/TestContext.h"
27 #include "tests/common/TestScene.h"
28 #include "tests/common/TestUtils.h"
29 #include "Vector.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>(0, 0, 200, 200,
43             [](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,
66                     sLightGeometry, 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,
83                     sLightGeometry, caches);
84             frameBuilder.deferRenderNode(*node);
85 
86             BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
87             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
88             benchmark::DoNotOptimize(&renderer);
89         }
90     });
91 }
92 BENCHMARK(BM_FrameBuilder_deferAndRender);
93 
getSyncedSceneNode(const char * sceneName)94 static sp<RenderNode> getSyncedSceneNode(const char* sceneName) {
95     gDisplay = getBuiltInDisplay(); // switch to real display if present
96 
97     TestContext testContext;
98     TestScene::Options opts;
99     std::unique_ptr<TestScene> scene(TestScene::testMap()[sceneName].createScene(opts));
100 
101     sp<RenderNode> rootNode = TestUtils::createNode<RecordingCanvas>(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),
121                     gDisplay.w, gDisplay.h,
122                     sLightGeometry, Caches::getInstance());
123             frameBuilder.deferRenderNode(*node);
124             benchmark::DoNotOptimize(&frameBuilder);
125         }
126     });
127 }
128 BENCHMARK(BM_FrameBuilder_defer_scene)->DenseRange(0, SCENES.size() - 1);
129 
BM_FrameBuilder_deferAndRender_scene(benchmark::State & state)130 void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) {
131     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
132         const char* sceneName = *(SCENES.begin() + state.range(0));
133         state.SetLabel(sceneName);
134         auto node = getSyncedSceneNode(sceneName);
135 
136         RenderState& renderState = thread.renderState();
137         Caches& caches = Caches::getInstance();
138 
139         while (state.KeepRunning()) {
140             FrameBuilder frameBuilder(SkRect::MakeWH(gDisplay.w, gDisplay.h),
141                     gDisplay.w, gDisplay.h,
142                     sLightGeometry, Caches::getInstance());
143             frameBuilder.deferRenderNode(*node);
144 
145             BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
146             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
147             benchmark::DoNotOptimize(&renderer);
148         }
149     });
150 }
151 BENCHMARK(BM_FrameBuilder_deferAndRender_scene)->DenseRange(0, SCENES.size() - 1);
152