FrameBuilderBench.cpp revision 0418afa362630e69bd853121770b115750ee46a4
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 31#include <vector> 32 33using namespace android; 34using namespace android::uirenderer; 35using namespace android::uirenderer::renderthread; 36using namespace android::uirenderer::test; 37 38const LayerUpdateQueue sEmptyLayerUpdateQueue; 39const FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50}; 40const BakedOpRenderer::LightInfo sLightInfo = { 128, 128 }; 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 64void BM_FrameBuilder_defer(benchmark::State& state) { 65 auto nodes = createTestNodeList(); 66 while (state.KeepRunning()) { 67 FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, 68 nodes, sLightGeometry, nullptr); 69 benchmark::DoNotOptimize(&frameBuilder); 70 } 71} 72BENCHMARK(BM_FrameBuilder_defer); 73 74void BM_FrameBuilder_deferAndRender(benchmark::State& state) { 75 TestUtils::runOnRenderThread([&state](RenderThread& thread) { 76 auto nodes = createTestNodeList(); 77 78 RenderState& renderState = thread.renderState(); 79 Caches& caches = Caches::getInstance(); 80 81 while (state.KeepRunning()) { 82 FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, 83 nodes, sLightGeometry, nullptr); 84 85 BakedOpRenderer renderer(caches, renderState, true, sLightInfo); 86 frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); 87 benchmark::DoNotOptimize(&renderer); 88 } 89 }); 90} 91BENCHMARK(BM_FrameBuilder_deferAndRender); 92 93static std::vector<sp<RenderNode>> getSyncedSceneNodes(const char* sceneName) { 94 gDisplay = getBuiltInDisplay(); // switch to real display if present 95 96 TestContext testContext; 97 TestScene::Options opts; 98 std::unique_ptr<TestScene> scene(TestScene::testMap()[sceneName].createScene(opts)); 99 100 sp<RenderNode> rootNode = TestUtils::createNode(0, 0, gDisplay.w, gDisplay.h, 101 [&scene](RenderProperties& props, TestCanvas& canvas) { 102 scene->createContent(gDisplay.w, gDisplay.h, canvas); 103 }); 104 105 TestUtils::syncHierarchyPropertiesAndDisplayList(rootNode); 106 std::vector<sp<RenderNode>> nodes; 107 nodes.emplace_back(rootNode); 108 return nodes; 109} 110 111static auto SCENES = { 112 "listview", 113}; 114 115void BM_FrameBuilder_defer_scene(benchmark::State& state) { 116 const char* sceneName = *(SCENES.begin() + state.range_x()); 117 state.SetLabel(sceneName); 118 auto nodes = getSyncedSceneNodes(sceneName); 119 while (state.KeepRunning()) { 120 FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, 121 SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, 122 nodes, sLightGeometry, nullptr); 123 benchmark::DoNotOptimize(&frameBuilder); 124 } 125} 126BENCHMARK(BM_FrameBuilder_defer_scene)->DenseRange(0, SCENES.size() - 1); 127 128void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) { 129 TestUtils::runOnRenderThread([&state](RenderThread& thread) { 130 const char* sceneName = *(SCENES.begin() + state.range_x()); 131 state.SetLabel(sceneName); 132 auto nodes = getSyncedSceneNodes(sceneName); 133 134 RenderState& renderState = thread.renderState(); 135 Caches& caches = Caches::getInstance(); 136 137 while (state.KeepRunning()) { 138 FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, 139 SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, 140 nodes, sLightGeometry, nullptr); 141 142 BakedOpRenderer renderer(caches, renderState, true, sLightInfo); 143 frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); 144 benchmark::DoNotOptimize(&renderer); 145 } 146 }); 147} 148BENCHMARK(BM_FrameBuilder_deferAndRender_scene)->DenseRange(0, SCENES.size() - 1); 149