1e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala/* 2e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Copyright (C) 2014 The Android Open Source Project 3e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 4e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); 5e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * you may not use this file except in compliance with the License. 6e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * You may obtain a copy of the License at 7e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 8e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 9e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 10e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 11e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, 12e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * See the License for the specific language governing permissions and 14e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * limitations under the License. 15e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 16e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 17e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalapackage android.hardware.camera2.legacy; 18e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 19e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaimport android.os.SystemClock; 20e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaimport android.util.Log; 21e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 22e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaimport java.io.BufferedWriter; 23e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaimport java.io.FileWriter; 24e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaimport java.io.IOException; 25e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaimport java.util.ArrayList; 26e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaimport java.util.LinkedList; 27e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaimport java.util.Queue; 28e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 29e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala/** 30e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * GPU and CPU performance measurement for the legacy implementation. 31e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 32e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Measures CPU and GPU processing duration for a set of operations, and dumps 33e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * the results into a file.</p> 34e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 35e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Rough usage: 36e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <pre> 37e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * {@code 38e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <set up workload> 39e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <start long-running workload> 40e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * mPerfMeasurement.startTimer(); 41e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * ...render a frame... 42e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * mPerfMeasurement.stopTimer(); 43e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <end workload> 44e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * mPerfMeasurement.dumpPerformanceData("/sdcard/my_data.txt"); 45e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * } 46e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * </pre> 47e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * </p> 48e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 49e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>All calls to this object must be made within the same thread, and the same GL context. 50e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * PerfMeasurement cannot be used outside of a GL context. The only exception is 51e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * dumpPerformanceData, which can be called outside of a valid GL context.</p> 52e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 53e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaclass PerfMeasurement { 54e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private static final String TAG = "PerfMeasurement"; 55e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 56e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public static final int DEFAULT_MAX_QUERIES = 3; 57e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 58e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private final long mNativeContext; 59e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 60e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private int mCompletedQueryCount = 0; 61e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 62e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 63e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Values for completed measurements 64e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 65e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private ArrayList<Long> mCollectedGpuDurations = new ArrayList<>(); 66e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private ArrayList<Long> mCollectedCpuDurations = new ArrayList<>(); 67e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private ArrayList<Long> mCollectedTimestamps = new ArrayList<>(); 68e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 69e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 70e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Values for in-progress measurements (waiting for async GPU results) 71e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 72e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private Queue<Long> mTimestampQueue = new LinkedList<>(); 73e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private Queue<Long> mCpuDurationsQueue = new LinkedList<>(); 74e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 75e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private long mStartTimeNs; 76e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 77e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 78e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * The value returned by {@link #nativeGetNextGlDuration} if no new timing 79e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * measurement is available since the last call. 80e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 81e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private static final long NO_DURATION_YET = -1l; 82e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 83e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 84e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * The value returned by {@link #nativeGetNextGlDuration} if timing failed for 85e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * the next timing interval 86e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 87e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private static final long FAILED_TIMING = -2l; 88e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 89e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 90e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Create a performance measurement object with a maximum of {@value #DEFAULT_MAX_QUERIES} 91e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * in-progess queries. 92e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 93e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public PerfMeasurement() { 94e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mNativeContext = nativeCreateContext(DEFAULT_MAX_QUERIES); 95e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 96e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 97e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 98e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Create a performance measurement object with maxQueries as the maximum number of 99e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * in-progress queries. 100e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 101e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @param maxQueries maximum in-progress queries, must be larger than 0. 102e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @throws IllegalArgumentException if maxQueries is less than 1. 103e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 104e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public PerfMeasurement(int maxQueries) { 105e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (maxQueries < 1) throw new IllegalArgumentException("maxQueries is less than 1"); 106e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mNativeContext = nativeCreateContext(maxQueries); 107e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 108e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 109e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 110e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Returns true if the Gl timing methods will work, false otherwise. 111e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 112e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Must be called within a valid GL context.</p> 113e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 114e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public static boolean isGlTimingSupported() { 115e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return nativeQuerySupport(); 116e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 117e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 118e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 119e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Dump collected data to file, and clear the stored data. 120e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 121e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p> 122e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Format is a simple csv-like text file with a header, 123e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * followed by a 3-column list of values in nanoseconds: 124e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <pre> 125e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * timestamp gpu_duration cpu_duration 126e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <long> <long> <long> 127e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <long> <long> <long> 128e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <long> <long> <long> 129e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * .... 130e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * </pre> 131e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * </p> 132e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 133e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public void dumpPerformanceData(String path) { 134e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala try (BufferedWriter dump = new BufferedWriter(new FileWriter(path))) { 135e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala dump.write("timestamp gpu_duration cpu_duration\n"); 136e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala for (int i = 0; i < mCollectedGpuDurations.size(); i++) { 137e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala dump.write(String.format("%d %d %d\n", 138e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCollectedTimestamps.get(i), 139e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCollectedGpuDurations.get(i), 140e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCollectedCpuDurations.get(i))); 141e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 142e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCollectedTimestamps.clear(); 143e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCollectedGpuDurations.clear(); 144e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCollectedCpuDurations.clear(); 145e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } catch (IOException e) { 146e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala Log.e(TAG, "Error writing data dump to " + path + ":" + e); 147e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 148e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 149e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 150e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 151e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Start a GPU/CPU timing measurement. 152e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 153e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Call before starting a rendering pass. Only one timing measurement can be active at once, 154e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * so {@link #stopTimer} must be called before the next call to this method.</p> 155e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 156e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @throws IllegalStateException if the maximum number of queries are in progress already, 157e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * or the method is called multiple times in a row, or there is 158e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * a GPU error. 159e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 160e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public void startTimer() { 161e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala nativeStartGlTimer(mNativeContext); 162e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mStartTimeNs = SystemClock.elapsedRealtimeNanos(); 163e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 164e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 165e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 166e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Finish a GPU/CPU timing measurement. 167e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 168e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Call after finishing all the drawing for a rendering pass. Only one timing measurement can 169e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * be active at once, so {@link #startTimer} must be called before the next call to this 170e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * method.</p> 171e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 172e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @throws IllegalStateException if no GL timer is currently started, or there is a GPU 173e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * error. 174e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 175e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public void stopTimer() { 176e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala // Complete CPU timing 177e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala long endTimeNs = SystemClock.elapsedRealtimeNanos(); 178e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCpuDurationsQueue.add(endTimeNs - mStartTimeNs); 179e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala // Complete GL timing 180e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala nativeStopGlTimer(mNativeContext); 181e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 182e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala // Poll to see if GL timing results have arrived; if so 183e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala // store the results for a frame 184e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala long duration = getNextGlDuration(); 185e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (duration > 0) { 186e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCollectedGpuDurations.add(duration); 187e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCollectedTimestamps.add(mTimestampQueue.isEmpty() ? 188e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala NO_DURATION_YET : mTimestampQueue.poll()); 189e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCollectedCpuDurations.add(mCpuDurationsQueue.isEmpty() ? 190e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala NO_DURATION_YET : mCpuDurationsQueue.poll()); 191e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 192e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (duration == FAILED_TIMING) { 193e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala // Discard timestamp and CPU measurement since GPU measurement failed 194e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (!mTimestampQueue.isEmpty()) { 195e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mTimestampQueue.poll(); 196e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 197e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (!mCpuDurationsQueue.isEmpty()) { 198e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCpuDurationsQueue.poll(); 199e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 200e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 201e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 202e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 203e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 204e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Add a timestamp to a timing measurement. These are queued up and matched to completed 205e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * workload measurements as they become available. 206e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 207e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public void addTimestamp(long timestamp) { 208e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mTimestampQueue.add(timestamp); 209e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 210e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 211e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 212e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Get the next available GPU timing measurement. 213e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 214e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Since the GPU works asynchronously, the results of a single start/stopGlTimer measurement 215e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * will only be available some time after the {@link #stopTimer} call is made. Poll this method 216e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * until the result becomes available. If multiple start/endTimer measurements are made in a 217e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * row, the results will be available in FIFO order.</p> 218e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 219e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @return The measured duration of the GPU workload for the next pending query, or 220e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * {@link #NO_DURATION_YET} if no queries are pending or the next pending query has not 221e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * yet finished, or {@link #FAILED_TIMING} if the GPU was unable to complete the 222e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * measurement. 223e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 224e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @throws IllegalStateException If there is a GPU error. 225e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 226e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 227e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private long getNextGlDuration() { 228e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala long duration = nativeGetNextGlDuration(mNativeContext); 229e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (duration > 0) { 230e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mCompletedQueryCount++; 231e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 232e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return duration; 233e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 234e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 235e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 236e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Returns the number of measurements so far that returned a valid duration 237e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * measurement. 238e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 239e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public int getCompletedQueryCount() { 240e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return mCompletedQueryCount; 241e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 242e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 243e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala @Override 244e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala protected void finalize() { 245e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala nativeDeleteContext(mNativeContext); 246e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 247e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 248e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 249e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Create a native performance measurement context. 250e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 251e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @param maxQueryCount maximum in-progress queries; must be >= 1. 252e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 253e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private static native long nativeCreateContext(int maxQueryCount); 254e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 255e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 256e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Delete the native context. 257e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 258e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Not safe to call more than once.</p> 259e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 260e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private static native void nativeDeleteContext(long contextHandle); 261e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 262e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 263e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Query whether the relevant Gl extensions are available for Gl timing 264e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 265e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private static native boolean nativeQuerySupport(); 266e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 267e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 268e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Start a GL timing section. 269e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 270e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>All GL commands between this method and the next {@link #nativeEndGlTimer} will be 271e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * included in the timing.</p> 272e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 273e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Must be called from the same thread as calls to {@link #nativeEndGlTimer} and 274e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * {@link #nativeGetNextGlDuration}.</p> 275e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 276e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @throws IllegalStateException if a GL error occurs or start is called repeatedly. 277e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 278e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala protected static native void nativeStartGlTimer(long contextHandle); 279e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 280e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 281e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Finish a GL timing section. 282e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 283e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Some time after this call returns, the time the GPU took to 284e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * execute all work submitted between the latest {@link #nativeStartGlTimer} and 285e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * this call, will become available from calling {@link #nativeGetNextGlDuration}.</p> 286e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 287e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Must be called from the same thread as calls to {@link #nativeStartGlTimer} and 288e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * {@link #nativeGetNextGlDuration}.</p> 289e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 290e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @throws IllegalStateException if a GL error occurs or stop is called before start 291e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 292e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala protected static native void nativeStopGlTimer(long contextHandle); 293e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 294e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 295e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Get the next available GL duration measurement, in nanoseconds. 296e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 297e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * <p>Must be called from the same thread as calls to {@link #nativeStartGlTimer} and 298e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * {@link #nativeEndGlTimer}.</p> 299e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 300e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @return the next GL duration measurement, or {@link #NO_DURATION_YET} if 301e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * no new measurement is available, or {@link #FAILED_TIMING} if timing 302e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * failed for the next duration measurement. 303e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * @throws IllegalStateException if a GL error occurs 304e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 305e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala protected static native long nativeGetNextGlDuration(long contextHandle); 306e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 307e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 308e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 309