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 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} 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, [](auto& props, auto& canvas) { 165 canvas.drawColor(0xFFFFFFFF, SkBlendMode::kSrcOver); 166 }); 167 168 std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(100, 100)); 169 delete canvas->finishRecording(); 170 171 while (benchState.KeepRunning()) { 172 canvas->resetRecording(200, 200); 173 canvas->translate(0, 0); // mScrollX, mScrollY 174 175 // Clip to padding 176 // Can expect ~25% of views to have clip to padding with a non-null padding 177 int clipRestoreCount = canvas->save(SaveFlags::MatrixClip); 178 canvas->clipRect(1, 1, 199, 199, SkClipOp::kIntersect); 179 180 canvas->insertReorderBarrier(true); 181 182 // Draw child loop 183 for (int i = 0; i < benchState.range(0); i++) { 184 canvas->drawRenderNode(child.get()); 185 } 186 187 canvas->insertReorderBarrier(false); 188 canvas->restoreToCount(clipRestoreCount); 189 190 delete canvas->finishRecording(); 191 } 192} 193BENCHMARK(BM_DisplayListCanvas_basicViewGroupDraw)->Arg(1)->Arg(5)->Arg(10); 194