summaryrefslogtreecommitdiff
path: root/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java
blob: d6e2861c03a71cbd2ebf84d147df2f09def5f1fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.gameperformance;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import android.annotation.NonNull;
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Trace;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;

public class GamePerformanceTest extends
        ActivityInstrumentationTestCase2<GamePerformanceActivity> {
    private final static String TAG = "GamePerformanceTest";

    private final static int GRAPHIC_BUFFER_WARMUP_LOOP_CNT = 60;

    public GamePerformanceTest() {
        super(GamePerformanceActivity.class);
    }

    @SmallTest
    public void testGraphicBufferMetrics() throws IOException, InterruptedException {
        Bundle status = new Bundle();

        for (int i = 0; i < 2; ++i) {
            if (i == 0) {
                getActivity().attachSurfaceView();
            } else {
                getActivity().attachOpenGLView();
            }

            // Perform warm-up.
            Thread.sleep(2000);

            // Once atrace is done, this one is triggered.
            CountDownLatch latch = new CountDownLatch(1);

            final String passTag = i == 0 ? "surface" : "opengl";
            final String output = (new File(getInstrumentation().getContext().getFilesDir(),
                    "atrace_" + passTag + ".log")).getAbsolutePath();
            Log.i(TAG, "Collecting traces to " + output);
            new ATraceRunner(getInstrumentation(), output, 5, "gfx", new ATraceRunner.Delegate() {
                @Override
                public void onProcessed(boolean success) {
                    latch.countDown();
                }
            }).execute();

            // Reset frame times and perform invalidation loop while atrace is running.
            getActivity().resetFrameTimes();
            latch.await();

            // Copy results.
            final Map<String, Double> metrics =
                    GraphicBufferMetrics.processGraphicBufferResult(output, passTag);
            for (Map.Entry<String, Double> metric : metrics.entrySet()) {
                status.putDouble(metric.getKey(), metric.getValue());
            }
            // Also record FPS.
            status.putDouble(passTag + "_fps", getActivity().getFps());
        }

        getInstrumentation().sendStatus(Activity.RESULT_OK, status);
    }

    @SmallTest
    public void testPerformanceMetricsWithoutExtraLoad() throws IOException, InterruptedException {
        final Bundle status = runPerformanceTests("no_extra_load_");
        getInstrumentation().sendStatus(Activity.RESULT_OK, status);
    }

    @SmallTest
    public void testPerformanceMetricsWithExtraLoad() throws IOException, InterruptedException {
        // Start CPU ballast threads first.
        CPULoadThread[] cpuLoadThreads = new CPULoadThread[2];
        for (int i = 0; i < cpuLoadThreads.length; ++i) {
            cpuLoadThreads[i] = new CPULoadThread();
            cpuLoadThreads[i].start();
        }

        final Bundle status = runPerformanceTests("extra_load_");

        for (int i = 0; i < cpuLoadThreads.length; ++i) {
            cpuLoadThreads[i].issueStopRequest();
            cpuLoadThreads[i].join();
        }

        getInstrumentation().sendStatus(Activity.RESULT_OK, status);
    }

    @NonNull
    private Bundle runPerformanceTests(@NonNull String prefix) {
        final Bundle status = new Bundle();

        final GamePerformanceActivity activity = getActivity();

        final List<BaseTest> tests = new ArrayList<>();
        tests.add(new TriangleCountOpenGLTest(activity));
        tests.add(new FillRateOpenGLTest(activity, false /* testBlend */));
        tests.add(new FillRateOpenGLTest(activity, true /* testBlend */));
        tests.add(new DeviceCallsOpenGLTest(activity));
        tests.add(new ControlsTest(activity));

        for (BaseTest test : tests) {
            final double result = test.run();
            status.putDouble(prefix + test.getName(), result);
        }

        return status;
    }
}