DisplayListCanvasBench.cpp revision 260ab726486317496bc12a57d599ea96dcde3284
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
23using namespace android;
24using namespace android::uirenderer;
25
26void BM_DisplayList_alloc(benchmark::State& benchState) {
27    while (benchState.KeepRunning()) {
28        auto displayList = new DisplayList();
29        benchmark::DoNotOptimize(displayList);
30        delete displayList;
31    }
32}
33BENCHMARK(BM_DisplayList_alloc);
34
35void 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}
42BENCHMARK(BM_DisplayList_alloc_theoretical);
43
44void 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}
54BENCHMARK(BM_DisplayListCanvas_record_empty);
55
56void 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}
70BENCHMARK(BM_DisplayListCanvas_record_saverestore);
71
72void 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}
83BENCHMARK(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 */
91void 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    SkBitmap iconBitmap = TestUtils::createSkBitmap(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}
115BENCHMARK(BM_DisplayListCanvas_record_simpleBitmapView);
116
117class NullClient: public CanvasStateClient {
118    void onViewportInitialized() override {}
119    void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
120    GLuint getTargetFbo() const override { return 0; }
121};
122
123void 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}
136BENCHMARK(BM_CanvasState_saverestore);
137
138void 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}
148BENCHMARK(BM_CanvasState_init);
149
150void 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}
161BENCHMARK(BM_CanvasState_translate);
162
163void 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, SkRegion::kIntersect_Op);
181
182        canvas->insertReorderBarrier(true);
183
184        // Draw child loop
185        for (int i = 0; i < benchState.range_x(); i++) {
186            canvas->drawRenderNode(child.get());
187        }
188
189        canvas->insertReorderBarrier(false);
190        canvas->restoreToCount(clipRestoreCount);
191
192        delete canvas->finishRecording();
193    }
194}
195BENCHMARK(BM_DisplayListCanvas_basicViewGroupDraw)->Arg(1)->Arg(5)->Arg(10);
196