• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 "DisplayList.h"
20 #include "RecordingCanvas.h"
21 #include "tests/common/TestUtils.h"
22 
23 using namespace android;
24 using namespace android::uirenderer;
25 
BM_DisplayList_alloc(benchmark::State & benchState)26 void BM_DisplayList_alloc(benchmark::State& benchState) {
27     while (benchState.KeepRunning()) {
28         auto displayList = new DisplayList();
29         benchmark::DoNotOptimize(displayList);
30         delete displayList;
31     }
32 }
33 BENCHMARK(BM_DisplayList_alloc);
34 
BM_DisplayList_alloc_theoretical(benchmark::State & benchState)35 void BM_DisplayList_alloc_theoretical(benchmark::State& benchState) {
36     while (benchState.KeepRunning()) {
37         auto displayList = new char[sizeof(DisplayList)];
38         benchmark::DoNotOptimize(displayList);
39         delete[] displayList;
40     }
41 }
42 BENCHMARK(BM_DisplayList_alloc_theoretical);
43 
BM_DisplayListCanvas_record_empty(benchmark::State & benchState)44 void BM_DisplayListCanvas_record_empty(benchmark::State& benchState) {
45     std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100));
46     delete canvas->finishRecording();
47 
48     while (benchState.KeepRunning()) {
49         canvas->resetRecording(100, 100);
50         benchmark::DoNotOptimize(canvas.get());
51         delete canvas->finishRecording();
52     }
53 }
54 BENCHMARK(BM_DisplayListCanvas_record_empty);
55 
BM_DisplayListCanvas_record_saverestore(benchmark::State & benchState)56 void BM_DisplayListCanvas_record_saverestore(benchmark::State& benchState) {
57     std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100));
58     delete canvas->finishRecording();
59 
60     while (benchState.KeepRunning()) {
61         canvas->resetRecording(100, 100);
62         canvas->save(SaveFlags::MatrixClip);
63         canvas->save(SaveFlags::MatrixClip);
64         benchmark::DoNotOptimize(canvas.get());
65         canvas->restore();
66         canvas->restore();
67         delete canvas->finishRecording();
68     }
69 }
70 BENCHMARK(BM_DisplayListCanvas_record_saverestore);
71 
BM_DisplayListCanvas_record_translate(benchmark::State & benchState)72 void BM_DisplayListCanvas_record_translate(benchmark::State& benchState) {
73     std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100));
74     delete canvas->finishRecording();
75 
76     while (benchState.KeepRunning()) {
77         canvas->resetRecording(100, 100);
78         canvas->scale(10, 10);
79         benchmark::DoNotOptimize(canvas.get());
80         delete canvas->finishRecording();
81     }
82 }
83 BENCHMARK(BM_DisplayListCanvas_record_translate);
84 
85 /**
86  * Simulate a simple view drawing a background, overlapped by an image.
87  *
88  * Note that the recording commands are intentionally not perfectly efficient, as the
89  * View system frequently produces unneeded save/restores.
90  */
BM_DisplayListCanvas_record_simpleBitmapView(benchmark::State & benchState)91 void BM_DisplayListCanvas_record_simpleBitmapView(benchmark::State& benchState) {
92     std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100));
93     delete canvas->finishRecording();
94 
95     SkPaint rectPaint;
96     sk_sp<Bitmap> iconBitmap(TestUtils::createBitmap(80, 80));
97 
98     while (benchState.KeepRunning()) {
99         canvas->resetRecording(100, 100);
100         {
101             canvas->save(SaveFlags::MatrixClip);
102             canvas->drawRect(0, 0, 100, 100, rectPaint);
103             canvas->restore();
104         }
105         {
106             canvas->save(SaveFlags::MatrixClip);
107             canvas->translate(10, 10);
108             canvas->drawBitmap(*iconBitmap, 0, 0, nullptr);
109             canvas->restore();
110         }
111         benchmark::DoNotOptimize(canvas.get());
112         delete canvas->finishRecording();
113     }
114 }
115 BENCHMARK(BM_DisplayListCanvas_record_simpleBitmapView);
116 
117 class NullClient: public CanvasStateClient {
onViewportInitialized()118     void onViewportInitialized() override {}
onSnapshotRestored(const Snapshot & removed,const Snapshot & restored)119     void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
getTargetFbo() const120     GLuint getTargetFbo() const override { return 0; }
121 };
122 
BM_CanvasState_saverestore(benchmark::State & benchState)123 void BM_CanvasState_saverestore(benchmark::State& benchState) {
124     NullClient client;
125     CanvasState state(client);
126     state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
127 
128     while (benchState.KeepRunning()) {
129         state.save(SaveFlags::MatrixClip);
130         state.save(SaveFlags::MatrixClip);
131         benchmark::DoNotOptimize(&state);
132         state.restore();
133         state.restore();
134     }
135 }
136 BENCHMARK(BM_CanvasState_saverestore);
137 
BM_CanvasState_init(benchmark::State & benchState)138 void BM_CanvasState_init(benchmark::State& benchState) {
139     NullClient client;
140     CanvasState state(client);
141     state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
142 
143     while (benchState.KeepRunning()) {
144         state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
145         benchmark::DoNotOptimize(&state);
146     }
147 }
148 BENCHMARK(BM_CanvasState_init);
149 
BM_CanvasState_translate(benchmark::State & benchState)150 void BM_CanvasState_translate(benchmark::State& benchState) {
151     NullClient client;
152     CanvasState state(client);
153     state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
154 
155     while (benchState.KeepRunning()) {
156         state.translate(5, 5, 0);
157         benchmark::DoNotOptimize(&state);
158         state.translate(-5, -5, 0);
159     }
160 }
161 BENCHMARK(BM_CanvasState_translate);
162 
BM_DisplayListCanvas_basicViewGroupDraw(benchmark::State & benchState)163 void BM_DisplayListCanvas_basicViewGroupDraw(benchmark::State& benchState) {
164     sp<RenderNode> child = TestUtils::createNode(50, 50, 100, 100,
165             [](auto& props, auto& canvas) {
166         canvas.drawColor(0xFFFFFFFF, SkBlendMode::kSrcOver);
167     });
168 
169     std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100));
170     delete canvas->finishRecording();
171 
172     while (benchState.KeepRunning()) {
173         canvas->resetRecording(200, 200);
174         canvas->setHighContrastText(false);
175         canvas->translate(0, 0); // mScrollX, mScrollY
176 
177         // Clip to padding
178         // Can expect ~25% of views to have clip to padding with a non-null padding
179         int clipRestoreCount = canvas->save(SaveFlags::MatrixClip);
180         canvas->clipRect(1, 1, 199, 199, SkClipOp::kIntersect);
181 
182         canvas->insertReorderBarrier(true);
183 
184         // Draw child loop
185         for (int i = 0; i < benchState.range(0); i++) {
186             canvas->drawRenderNode(child.get());
187         }
188 
189         canvas->insertReorderBarrier(false);
190         canvas->restoreToCount(clipRestoreCount);
191 
192         delete canvas->finishRecording();
193     }
194 }
195 BENCHMARK(BM_DisplayListCanvas_basicViewGroupDraw)->Arg(1)->Arg(5)->Arg(10);
196