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#if HWUI_NEW_OPS
21#include "RecordingCanvas.h"
22#else
23#include "DisplayListCanvas.h"
24#endif
25#include "tests/common/TestUtils.h"
26
27using namespace android;
28using namespace android::uirenderer;
29
30#if HWUI_NEW_OPS
31typedef RecordingCanvas TestCanvas;
32#else
33typedef DisplayListCanvas TestCanvas;
34#endif
35
36void BM_DisplayList_alloc(benchmark::State& benchState) {
37    while (benchState.KeepRunning()) {
38        auto displayList = new DisplayList();
39        benchmark::DoNotOptimize(displayList);
40        delete displayList;
41    }
42}
43BENCHMARK(BM_DisplayList_alloc);
44
45void BM_DisplayList_alloc_theoretical(benchmark::State& benchState) {
46    while (benchState.KeepRunning()) {
47        auto displayList = new char[sizeof(DisplayList)];
48        benchmark::DoNotOptimize(displayList);
49        delete[] displayList;
50    }
51}
52BENCHMARK(BM_DisplayList_alloc_theoretical);
53
54void BM_DisplayListCanvas_record_empty(benchmark::State& benchState) {
55    TestCanvas canvas(100, 100);
56    delete canvas.finishRecording();
57
58    while (benchState.KeepRunning()) {
59        canvas.resetRecording(100, 100);
60        benchmark::DoNotOptimize(&canvas);
61        delete canvas.finishRecording();
62    }
63}
64BENCHMARK(BM_DisplayListCanvas_record_empty);
65
66void BM_DisplayListCanvas_record_saverestore(benchmark::State& benchState) {
67    TestCanvas canvas(100, 100);
68    delete canvas.finishRecording();
69
70    while (benchState.KeepRunning()) {
71        canvas.resetRecording(100, 100);
72        canvas.save(SaveFlags::MatrixClip);
73        canvas.save(SaveFlags::MatrixClip);
74        benchmark::DoNotOptimize(&canvas);
75        canvas.restore();
76        canvas.restore();
77        delete canvas.finishRecording();
78    }
79}
80BENCHMARK(BM_DisplayListCanvas_record_saverestore);
81
82void BM_DisplayListCanvas_record_translate(benchmark::State& benchState) {
83    TestCanvas canvas(100, 100);
84    delete canvas.finishRecording();
85
86    while (benchState.KeepRunning()) {
87        canvas.resetRecording(100, 100);
88        canvas.scale(10, 10);
89        benchmark::DoNotOptimize(&canvas);
90        delete canvas.finishRecording();
91    }
92}
93BENCHMARK(BM_DisplayListCanvas_record_translate);
94
95/**
96 * Simulate a simple view drawing a background, overlapped by an image.
97 *
98 * Note that the recording commands are intentionally not perfectly efficient, as the
99 * View system frequently produces unneeded save/restores.
100 */
101void BM_DisplayListCanvas_record_simpleBitmapView(benchmark::State& benchState) {
102    TestCanvas canvas(100, 100);
103    delete canvas.finishRecording();
104
105    SkPaint rectPaint;
106    SkBitmap iconBitmap = TestUtils::createSkBitmap(80, 80);
107
108    while (benchState.KeepRunning()) {
109        canvas.resetRecording(100, 100);
110        {
111            canvas.save(SaveFlags::MatrixClip);
112            canvas.drawRect(0, 0, 100, 100, rectPaint);
113            canvas.restore();
114        }
115        {
116            canvas.save(SaveFlags::MatrixClip);
117            canvas.translate(10, 10);
118            canvas.drawBitmap(iconBitmap, 0, 0, nullptr);
119            canvas.restore();
120        }
121        benchmark::DoNotOptimize(&canvas);
122        delete canvas.finishRecording();
123    }
124}
125BENCHMARK(BM_DisplayListCanvas_record_simpleBitmapView);
126
127class NullClient: public CanvasStateClient {
128    void onViewportInitialized() override {}
129    void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
130    GLuint getTargetFbo() const override { return 0; }
131};
132
133void BM_CanvasState_saverestore(benchmark::State& benchState) {
134    NullClient client;
135    CanvasState state(client);
136    state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
137
138    while (benchState.KeepRunning()) {
139        state.save(SaveFlags::MatrixClip);
140        state.save(SaveFlags::MatrixClip);
141        benchmark::DoNotOptimize(&state);
142        state.restore();
143        state.restore();
144    }
145}
146BENCHMARK(BM_CanvasState_saverestore);
147
148void BM_CanvasState_init(benchmark::State& benchState) {
149    NullClient client;
150    CanvasState state(client);
151    state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
152
153    while (benchState.KeepRunning()) {
154        state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
155        benchmark::DoNotOptimize(&state);
156    }
157}
158BENCHMARK(BM_CanvasState_init);
159
160void BM_CanvasState_translate(benchmark::State& benchState) {
161    NullClient client;
162    CanvasState state(client);
163    state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
164
165    while (benchState.KeepRunning()) {
166        state.translate(5, 5, 0);
167        benchmark::DoNotOptimize(&state);
168        state.translate(-5, -5, 0);
169    }
170}
171BENCHMARK(BM_CanvasState_translate);
172