Home | History | Annotate | Download | only in microbench
      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 
     33 using namespace android;
     34 using namespace android::uirenderer;
     35 using namespace android::uirenderer::renderthread;
     36 using namespace android::uirenderer::test;
     37 
     38 const FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50};
     39 const BakedOpRenderer::LightInfo sLightInfo = { 128, 128 };
     40 
     41 static sp<RenderNode> createTestNode() {
     42     auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
     43             [](RenderProperties& props, RecordingCanvas& canvas) {
     44         sk_sp<Bitmap> bitmap(TestUtils::createBitmap(10, 10));
     45         SkPaint paint;
     46 
     47         // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
     48         // Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
     49         canvas.save(SaveFlags::MatrixClip);
     50         for (int i = 0; i < 30; i++) {
     51             canvas.translate(0, 10);
     52             canvas.drawRect(0, 0, 10, 10, paint);
     53             canvas.drawBitmap(*bitmap, 5, 0, nullptr);
     54         }
     55         canvas.restore();
     56     });
     57     TestUtils::syncHierarchyPropertiesAndDisplayList(node);
     58     return node;
     59 }
     60 
     61 void BM_FrameBuilder_defer(benchmark::State& state) {
     62     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
     63         auto node = createTestNode();
     64         while (state.KeepRunning()) {
     65             FrameBuilder frameBuilder(SkRect::MakeWH(100, 200), 100, 200,
     66                     sLightGeometry, Caches::getInstance());
     67             frameBuilder.deferRenderNode(*node);
     68             benchmark::DoNotOptimize(&frameBuilder);
     69         }
     70     });
     71 }
     72 BENCHMARK(BM_FrameBuilder_defer);
     73 
     74 void BM_FrameBuilder_deferAndRender(benchmark::State& state) {
     75     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
     76         auto node = createTestNode();
     77 
     78         RenderState& renderState = thread.renderState();
     79         Caches& caches = Caches::getInstance();
     80 
     81         while (state.KeepRunning()) {
     82             FrameBuilder frameBuilder(SkRect::MakeWH(100, 200), 100, 200,
     83                     sLightGeometry, caches);
     84             frameBuilder.deferRenderNode(*node);
     85 
     86             BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
     87             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
     88             benchmark::DoNotOptimize(&renderer);
     89         }
     90     });
     91 }
     92 BENCHMARK(BM_FrameBuilder_deferAndRender);
     93 
     94 static sp<RenderNode> getSyncedSceneNode(const char* sceneName) {
     95     gDisplay = getBuiltInDisplay(); // switch to real display if present
     96 
     97     TestContext testContext;
     98     TestScene::Options opts;
     99     std::unique_ptr<TestScene> scene(TestScene::testMap()[sceneName].createScene(opts));
    100 
    101     sp<RenderNode> rootNode = TestUtils::createNode<RecordingCanvas>(0, 0, gDisplay.w, gDisplay.h,
    102                 [&scene](RenderProperties& props, RecordingCanvas& canvas) {
    103             scene->createContent(gDisplay.w, gDisplay.h, canvas);
    104     });
    105 
    106     TestUtils::syncHierarchyPropertiesAndDisplayList(rootNode);
    107     return rootNode;
    108 }
    109 
    110 static auto SCENES = {
    111         "listview",
    112 };
    113 
    114 void BM_FrameBuilder_defer_scene(benchmark::State& state) {
    115     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
    116         const char* sceneName = *(SCENES.begin() + state.range(0));
    117         state.SetLabel(sceneName);
    118         auto node = getSyncedSceneNode(sceneName);
    119         while (state.KeepRunning()) {
    120             FrameBuilder frameBuilder(SkRect::MakeWH(gDisplay.w, gDisplay.h),
    121                     gDisplay.w, gDisplay.h,
    122                     sLightGeometry, Caches::getInstance());
    123             frameBuilder.deferRenderNode(*node);
    124             benchmark::DoNotOptimize(&frameBuilder);
    125         }
    126     });
    127 }
    128 BENCHMARK(BM_FrameBuilder_defer_scene)->DenseRange(0, SCENES.size() - 1);
    129 
    130 void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) {
    131     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
    132         const char* sceneName = *(SCENES.begin() + state.range(0));
    133         state.SetLabel(sceneName);
    134         auto node = getSyncedSceneNode(sceneName);
    135 
    136         RenderState& renderState = thread.renderState();
    137         Caches& caches = Caches::getInstance();
    138 
    139         while (state.KeepRunning()) {
    140             FrameBuilder frameBuilder(SkRect::MakeWH(gDisplay.w, gDisplay.h),
    141                     gDisplay.w, gDisplay.h,
    142                     sLightGeometry, Caches::getInstance());
    143             frameBuilder.deferRenderNode(*node);
    144 
    145             BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
    146             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
    147             benchmark::DoNotOptimize(&renderer);
    148         }
    149     });
    150 }
    151 BENCHMARK(BM_FrameBuilder_deferAndRender_scene)->DenseRange(0, SCENES.size() - 1);
    152