TestSceneRunner.cpp revision 96bf5985d5a360568832fd26b6d5b44236c9343e
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 "AnimationContext.h"
18#include "RenderNode.h"
19#include "tests/common/TestContext.h"
20#include "tests/common/TestScene.h"
21#include "tests/common/scenes/TestSceneBase.h"
22#include "renderthread/RenderProxy.h"
23#include "renderthread/RenderTask.h"
24
25#include <gui/Surface.h>
26#include <log/log.h>
27#include <ui/PixelFormat.h>
28
29using namespace android;
30using namespace android::uirenderer;
31using namespace android::uirenderer::renderthread;
32using namespace android::uirenderer::test;
33
34class ContextFactory : public IContextFactory {
35public:
36    virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {
37        return new AnimationContext(clock);
38    }
39};
40
41template<class T>
42class ModifiedMovingAverage {
43public:
44    ModifiedMovingAverage(int weight) : mWeight(weight) {}
45
46    T add(T today) {
47        if (!mHasValue) {
48            mAverage = today;
49        } else {
50            mAverage = (((mWeight - 1) * mAverage) + today) / mWeight;
51        }
52        return mAverage;
53    }
54
55    T average() {
56        return mAverage;
57    }
58
59private:
60    bool mHasValue = false;
61    int mWeight;
62    T mAverage;
63};
64
65void run(const TestScene::Info& info, const TestScene::Options& opts) {
66    // Switch to the real display
67    gDisplay = getBuiltInDisplay();
68
69    std::unique_ptr<TestScene> scene(info.createScene(opts));
70
71    TestContext testContext;
72
73    // create the native surface
74    const int width = gDisplay.w;
75    const int height = gDisplay.h;
76    sp<Surface> surface = testContext.surface();
77
78    sp<RenderNode> rootNode = TestUtils::createNode(0, 0, width, height,
79            [&scene, width, height](RenderProperties& props, TestCanvas& canvas) {
80        props.setClipToBounds(false);
81        scene->createContent(width, height, canvas);
82    });
83
84    ContextFactory factory;
85    std::unique_ptr<RenderProxy> proxy(new RenderProxy(false,
86            rootNode.get(), &factory));
87    proxy->loadSystemProperties();
88    proxy->initialize(surface);
89    float lightX = width / 2.0;
90    proxy->setup(width, height, dp(800.0f), 255 * 0.075, 255 * 0.15);
91    proxy->setLightCenter((Vector3){lightX, dp(-200.0f), dp(800.0f)});
92
93    // Do a few cold runs then reset the stats so that the caches are all hot
94    for (int i = 0; i < 5; i++) {
95        testContext.waitForVsync();
96        nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
97        UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
98        proxy->syncAndDrawFrame(nullptr);
99    }
100
101    proxy->resetProfileInfo();
102    proxy->fence();
103
104    ModifiedMovingAverage<double> avgMs(opts.reportFrametimeWeight);
105
106    for (int i = 0; i < opts.count; i++) {
107        testContext.waitForVsync();
108        nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
109        {
110            ATRACE_NAME("UI-Draw Frame");
111            UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
112            scene->doFrame(i);
113            proxy->syncAndDrawFrame(nullptr);
114        }
115        if (opts.reportFrametimeWeight) {
116            proxy->fence();
117            nsecs_t done = systemTime(CLOCK_MONOTONIC);
118            avgMs.add((done - vsync) / 1000000.0);
119            if (i % 10 == 9) {
120                printf("Average frametime %.3fms\n", avgMs.average());
121            }
122        }
123    }
124
125    proxy->dumpProfileInfo(STDOUT_FILENO, DumpFlags::JankStats);
126}
127