Home | History | Annotate | Download | only in macrobench
      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 <cutils/log.h>
     26 #include <gui/Surface.h>
     27 #include <ui/PixelFormat.h>
     28 
     29 using namespace android;
     30 using namespace android::uirenderer;
     31 using namespace android::uirenderer::renderthread;
     32 using namespace android::uirenderer::test;
     33 
     34 class ContextFactory : public IContextFactory {
     35 public:
     36     virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {
     37         return new AnimationContext(clock);
     38     }
     39 };
     40 
     41 template<class T>
     42 class ModifiedMovingAverage {
     43 public:
     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 
     59 private:
     60     bool mHasValue = false;
     61     int mWeight;
     62     T mAverage;
     63 };
     64 
     65 void 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