116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck/*
216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Copyright (C) 2015 The Android Open Source Project
316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *
416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Licensed under the Apache License, Version 2.0 (the "License");
516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * you may not use this file except in compliance with the License.
616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * You may obtain a copy of the License at
716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *
816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *      http://www.apache.org/licenses/LICENSE-2.0
916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *
1016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Unless required by applicable law or agreed to in writing, software
1116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * distributed under the License is distributed on an "AS IS" BASIS,
1216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * See the License for the specific language governing permissions and
1416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * limitations under the License.
1516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck */
1616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
1716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include "AnimationContext.h"
1816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include "RenderNode.h"
1927e58b4f54d693ff1db7ab2edb5d47ca296c1278Chris Craik#include "tests/common/TestContext.h"
2027e58b4f54d693ff1db7ab2edb5d47ca296c1278Chris Craik#include "tests/common/TestScene.h"
218160f20b0aca8c6595d4b385d673f59b6bcd16a4Chris Craik#include "tests/common/scenes/TestSceneBase.h"
2216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include "renderthread/RenderProxy.h"
2316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include "renderthread/RenderTask.h"
2416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
2516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include <cutils/log.h>
2616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include <gui/Surface.h>
2716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include <ui/PixelFormat.h>
2816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
2916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckusing namespace android;
3016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckusing namespace android::uirenderer;
3116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckusing namespace android::uirenderer::renderthread;
3216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckusing namespace android::uirenderer::test;
3316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
3416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckclass ContextFactory : public IContextFactory {
3516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reckpublic:
3616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {
3716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        return new AnimationContext(clock);
3816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    }
3916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck};
4016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
41682573c84b7c21dc8ce4a2375da3961147442c4aJohn Recktemplate<class T>
42682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reckclass ModifiedMovingAverage {
43682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reckpublic:
44682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    ModifiedMovingAverage(int weight) : mWeight(weight) {}
45682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck
46682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    T add(T today) {
47682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck        if (!mHasValue) {
48682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck            mAverage = today;
49682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck        } else {
50682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck            mAverage = (((mWeight - 1) * mAverage) + today) / mWeight;
51682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck        }
52682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck        return mAverage;
53682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    }
54682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck
55682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    T average() {
56682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck        return mAverage;
57682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    }
58682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck
59682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reckprivate:
60682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    bool mHasValue = false;
61682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    int mWeight;
62682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    T mAverage;
63682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck};
64682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck
6527e58b4f54d693ff1db7ab2edb5d47ca296c1278Chris Craikvoid run(const TestScene::Info& info, const TestScene::Options& opts) {
6616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    // Switch to the real display
6716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    gDisplay = getBuiltInDisplay();
6816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
6916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    std::unique_ptr<TestScene> scene(info.createScene(opts));
7016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
7116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    TestContext testContext;
7216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
7316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    // create the native surface
7416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    const int width = gDisplay.w;
7516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    const int height = gDisplay.h;
7616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    sp<Surface> surface = testContext.surface();
7716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
7816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    sp<RenderNode> rootNode = TestUtils::createNode(0, 0, width, height,
7916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck            [&scene, width, height](RenderProperties& props, TestCanvas& canvas) {
8016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        props.setClipToBounds(false);
8116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        scene->createContent(width, height, canvas);
8216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    });
8316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
8416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    ContextFactory factory;
8516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    std::unique_ptr<RenderProxy> proxy(new RenderProxy(false,
8616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck            rootNode.get(), &factory));
8716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    proxy->loadSystemProperties();
8816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    proxy->initialize(surface);
8916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    float lightX = width / 2.0;
9016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    proxy->setup(width, height, dp(800.0f), 255 * 0.075, 255 * 0.15);
9116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    proxy->setLightCenter((Vector3){lightX, dp(-200.0f), dp(800.0f)});
9216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
9316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    // Do a few cold runs then reset the stats so that the caches are all hot
94682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    for (int i = 0; i < 5; i++) {
9516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        testContext.waitForVsync();
9616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
9716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
9851f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reck        proxy->syncAndDrawFrame(nullptr);
9916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    }
100682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck
10116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    proxy->resetProfileInfo();
102682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    proxy->fence();
103682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck
104682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck    ModifiedMovingAverage<double> avgMs(opts.reportFrametimeWeight);
10516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
10616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    for (int i = 0; i < opts.count; i++) {
10716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        testContext.waitForVsync();
10816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck        nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
109682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck        {
110682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck            ATRACE_NAME("UI-Draw Frame");
111682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck            UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
112682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck            scene->doFrame(i);
11351f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reck            proxy->syncAndDrawFrame(nullptr);
114682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck        }
115682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck        if (opts.reportFrametimeWeight) {
1162705c983f5e3299e1481fd98a80fc78bce927527Chris Craik            proxy->fence();
1172705c983f5e3299e1481fd98a80fc78bce927527Chris Craik            nsecs_t done = systemTime(CLOCK_MONOTONIC);
118682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck            avgMs.add((done - vsync) / 1000000.0);
119682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck            if (i % 10 == 9) {
120682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck                printf("Average frametime %.3fms\n", avgMs.average());
121682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck            }
122682573c84b7c21dc8ce4a2375da3961147442c4aJohn Reck        }
12316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    }
12416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
125a41f2445156fe0bcfde6bd4d813dfc43796a526dJohn Reck    proxy->dumpProfileInfo(STDOUT_FILENO, DumpFlags::JankStats);
12616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck}
127