FrameBuilderBench.cpp revision eecff56fed5dd5206acfbc5007b4912081b36d3b
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#include "tests/microbench/MicroBench.h" 31 32#include <vector> 33 34using namespace android; 35using namespace android::uirenderer; 36using namespace android::uirenderer::renderthread; 37using namespace android::uirenderer::test; 38 39const LayerUpdateQueue sEmptyLayerUpdateQueue; 40const Vector3 sLightCenter = {100, 100, 100}; 41 42static std::vector<sp<RenderNode>> createTestNodeList() { 43 auto node = TestUtils::createNode(0, 0, 200, 200, 44 [](RenderProperties& props, RecordingCanvas& canvas) { 45 SkBitmap bitmap = TestUtils::createSkBitmap(10, 10); 46 SkPaint paint; 47 48 // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects. 49 // Rects don't overlap bitmaps, so bitmaps should be brought to front as a group. 50 canvas.save(SaveFlags::MatrixClip); 51 for (int i = 0; i < 30; i++) { 52 canvas.translate(0, 10); 53 canvas.drawRect(0, 0, 10, 10, paint); 54 canvas.drawBitmap(bitmap, 5, 0, nullptr); 55 } 56 canvas.restore(); 57 }); 58 TestUtils::syncHierarchyPropertiesAndDisplayList(node); 59 std::vector<sp<RenderNode>> vec; 60 vec.emplace_back(node); 61 return vec; 62} 63 64BENCHMARK_NO_ARG(BM_FrameBuilder_defer); 65void BM_FrameBuilder_defer::Run(int iters) { 66 auto nodes = createTestNodeList(); 67 StartBenchmarkTiming(); 68 for (int i = 0; i < iters; i++) { 69 FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, 70 nodes, sLightCenter); 71 MicroBench::DoNotOptimize(&frameBuilder); 72 } 73 StopBenchmarkTiming(); 74} 75 76BENCHMARK_NO_ARG(BM_FrameBuilder_deferAndRender); 77void BM_FrameBuilder_deferAndRender::Run(int iters) { 78 TestUtils::runOnRenderThread([this, iters](RenderThread& thread) { 79 auto nodes = createTestNodeList(); 80 BakedOpRenderer::LightInfo lightInfo = {50.0f, 128, 128 }; 81 82 RenderState& renderState = thread.renderState(); 83 Caches& caches = Caches::getInstance(); 84 85 StartBenchmarkTiming(); 86 for (int i = 0; i < iters; i++) { 87 FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, 88 nodes, sLightCenter); 89 90 BakedOpRenderer renderer(caches, renderState, true, lightInfo); 91 frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); 92 MicroBench::DoNotOptimize(&renderer); 93 } 94 StopBenchmarkTiming(); 95 }); 96} 97 98static std::vector<sp<RenderNode>> getSyncedSceneNodes(const char* sceneName) { 99 gDisplay = getBuiltInDisplay(); // switch to real display if present 100 101 TestContext testContext; 102 TestScene::Options opts; 103 std::unique_ptr<TestScene> scene(TestScene::testMap()[sceneName].createScene(opts)); 104 105 sp<RenderNode> rootNode = TestUtils::createNode(0, 0, gDisplay.w, gDisplay.h, 106 [&scene](RenderProperties& props, TestCanvas& canvas) { 107 scene->createContent(gDisplay.w, gDisplay.h, canvas); 108 }); 109 110 TestUtils::syncHierarchyPropertiesAndDisplayList(rootNode); 111 std::vector<sp<RenderNode>> nodes; 112 nodes.emplace_back(rootNode); 113 return nodes; 114} 115 116static void benchDeferScene(testing::Benchmark& benchmark, int iters, const char* sceneName) { 117 auto nodes = getSyncedSceneNodes(sceneName); 118 benchmark.StartBenchmarkTiming(); 119 for (int i = 0; i < iters; i++) { 120 FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, 121 SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, 122 nodes, sLightCenter); 123 MicroBench::DoNotOptimize(&frameBuilder); 124 } 125 benchmark.StopBenchmarkTiming(); 126} 127 128static void benchDeferAndRenderScene(testing::Benchmark& benchmark, 129 int iters, const char* sceneName) { 130 TestUtils::runOnRenderThread([&benchmark, iters, sceneName](RenderThread& thread) { 131 auto nodes = getSyncedSceneNodes(sceneName); 132 BakedOpRenderer::LightInfo lightInfo = {50.0f, 128, 128 }; // TODO! 133 134 RenderState& renderState = thread.renderState(); 135 Caches& caches = Caches::getInstance(); 136 137 benchmark.StartBenchmarkTiming(); 138 for (int i = 0; i < iters; i++) { 139 FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, 140 SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, 141 nodes, sLightCenter); 142 143 BakedOpRenderer renderer(caches, renderState, true, lightInfo); 144 frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); 145 MicroBench::DoNotOptimize(&renderer); 146 } 147 benchmark.StopBenchmarkTiming(); 148 }); 149} 150 151BENCHMARK_NO_ARG(BM_FrameBuilder_listview_defer); 152void BM_FrameBuilder_listview_defer::Run(int iters) { 153 benchDeferScene(*this, iters, "listview"); 154} 155 156BENCHMARK_NO_ARG(BM_FrameBuilder_listview_deferAndRender); 157void BM_FrameBuilder_listview_deferAndRender::Run(int iters) { 158 benchDeferAndRenderScene(*this, iters, "listview"); 159} 160 161