1 /* 2 * Copyright (C) 2018 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 package android.gameperformance; 17 18 import java.io.File; 19 import java.io.IOException; 20 import java.util.ArrayList; 21 import java.util.List; 22 import java.util.Map; 23 import java.util.concurrent.CountDownLatch; 24 25 import android.annotation.NonNull; 26 import android.app.Activity; 27 import android.content.Context; 28 import android.graphics.PixelFormat; 29 import android.os.Build; 30 import android.os.Bundle; 31 import android.os.Debug; 32 import android.os.Trace; 33 import android.test.ActivityInstrumentationTestCase2; 34 import android.test.suitebuilder.annotation.SmallTest; 35 import android.util.Log; 36 37 public class GamePerformanceTest extends 38 ActivityInstrumentationTestCase2<GamePerformanceActivity> { 39 private final static String TAG = "GamePerformanceTest"; 40 41 private final static int GRAPHIC_BUFFER_WARMUP_LOOP_CNT = 60; 42 GamePerformanceTest()43 public GamePerformanceTest() { 44 super(GamePerformanceActivity.class); 45 } 46 47 @SmallTest testGraphicBufferMetrics()48 public void testGraphicBufferMetrics() throws IOException, InterruptedException { 49 Bundle status = new Bundle(); 50 51 for (int i = 0; i < 2; ++i) { 52 if (i == 0) { 53 getActivity().attachSurfaceView(); 54 } else { 55 getActivity().attachOpenGLView(); 56 } 57 58 // Perform warm-up. 59 Thread.sleep(2000); 60 61 // Once atrace is done, this one is triggered. 62 CountDownLatch latch = new CountDownLatch(1); 63 64 final String passTag = i == 0 ? "surface" : "opengl"; 65 final String output = (new File(getInstrumentation().getContext().getFilesDir(), 66 "atrace_" + passTag + ".log")).getAbsolutePath(); 67 Log.i(TAG, "Collecting traces to " + output); 68 new ATraceRunner(getInstrumentation(), output, 5, "gfx", new ATraceRunner.Delegate() { 69 @Override 70 public void onProcessed(boolean success) { 71 latch.countDown(); 72 } 73 }).execute(); 74 75 // Reset frame times and perform invalidation loop while atrace is running. 76 getActivity().resetFrameTimes(); 77 latch.await(); 78 79 // Copy results. 80 final Map<String, Double> metrics = 81 GraphicBufferMetrics.processGraphicBufferResult(output, passTag); 82 for (Map.Entry<String, Double> metric : metrics.entrySet()) { 83 status.putDouble(metric.getKey(), metric.getValue()); 84 } 85 // Also record FPS. 86 status.putDouble(passTag + "_fps", getActivity().getFps()); 87 } 88 89 getInstrumentation().sendStatus(Activity.RESULT_OK, status); 90 } 91 92 @SmallTest testPerformanceMetricsWithoutExtraLoad()93 public void testPerformanceMetricsWithoutExtraLoad() throws IOException, InterruptedException { 94 final Bundle status = runPerformanceTests("no_extra_load_"); 95 getInstrumentation().sendStatus(Activity.RESULT_OK, status); 96 } 97 98 @SmallTest testPerformanceMetricsWithExtraLoad()99 public void testPerformanceMetricsWithExtraLoad() throws IOException, InterruptedException { 100 // Start CPU ballast threads first. 101 CPULoadThread[] cpuLoadThreads = new CPULoadThread[2]; 102 for (int i = 0; i < cpuLoadThreads.length; ++i) { 103 cpuLoadThreads[i] = new CPULoadThread(); 104 cpuLoadThreads[i].start(); 105 } 106 107 final Bundle status = runPerformanceTests("extra_load_"); 108 109 for (int i = 0; i < cpuLoadThreads.length; ++i) { 110 cpuLoadThreads[i].issueStopRequest(); 111 cpuLoadThreads[i].join(); 112 } 113 114 getInstrumentation().sendStatus(Activity.RESULT_OK, status); 115 } 116 117 @NonNull runPerformanceTests(@onNull String prefix)118 private Bundle runPerformanceTests(@NonNull String prefix) { 119 final Bundle status = new Bundle(); 120 121 final GamePerformanceActivity activity = getActivity(); 122 123 final List<BaseTest> tests = new ArrayList<>(); 124 tests.add(new TriangleCountOpenGLTest(activity)); 125 tests.add(new FillRateOpenGLTest(activity, false /* testBlend */)); 126 tests.add(new FillRateOpenGLTest(activity, true /* testBlend */)); 127 tests.add(new DeviceCallsOpenGLTest(activity)); 128 tests.add(new ControlsTest(activity)); 129 130 for (BaseTest test : tests) { 131 final double result = test.run(); 132 status.putDouble(prefix + test.getName(), result); 133 } 134 135 return status; 136 } 137 } 138