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