TestSceneRunner.cpp revision 2705c983f5e3299e1481fd98a80fc78bce927527
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 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(); 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(); 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, 0); 126} 127