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 Talvala#define LOG_TAG "Camera2-Legacy-PerfMeasurement-JNI" 18e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include <utils/Log.h> 19e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include <utils/Errors.h> 20e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include <utils/Trace.h> 21e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include <utils/Vector.h> 22e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 23e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include "jni.h" 24e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include "JNIHelp.h" 25e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include "android_runtime/AndroidRuntime.h" 26e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 27e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include <ui/GraphicBuffer.h> 28e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include <system/window.h> 29e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include <GLES2/gl2.h> 30e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#include <GLES2/gl2ext.h> 31e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 32e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalausing namespace android; 33e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 34e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala// fully-qualified class name 35e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala#define PERF_MEASUREMENT_CLASS_NAME "android/hardware/camera2/legacy/PerfMeasurement" 36e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 37e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala/** GL utility methods copied from com_google_android_gles_jni_GLImpl.cpp */ 38e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 39e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala// Check if the extension at the head of pExtensions is pExtension. Note that pExtensions is 40e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala// terminated by either 0 or space, while pExtension is terminated by 0. 41e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 42e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic bool 43e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville TalvalaextensionEqual(const GLubyte* pExtensions, const GLubyte* pExtension) { 44e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala while (true) { 45e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala char a = *pExtensions++; 46e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala char b = *pExtension++; 47e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala bool aEnd = a == '\0' || a == ' '; 48e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala bool bEnd = b == '\0'; 49e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (aEnd || bEnd) { 50e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return aEnd == bEnd; 51e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 52e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (a != b) { 53e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return false; 54e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 55e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 56e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 57e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 58e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic const GLubyte* 59e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville TalvalanextExtension(const GLubyte* pExtensions) { 60e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala while (true) { 61e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala char a = *pExtensions++; 62e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (a == '\0') { 63e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return pExtensions-1; 64e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } else if ( a == ' ') { 65e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return pExtensions; 66e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 67e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 68e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 69e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 70e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic bool 71e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville TalvalacheckForExtension(const GLubyte* pExtensions, const GLubyte* pExtension) { 72e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala for (; *pExtensions != '\0'; pExtensions = nextExtension(pExtensions)) { 73e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (extensionEqual(pExtensions, pExtension)) { 74e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return true; 75e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 76e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 77e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return false; 78e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 79e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 80e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala/** End copied GL utility methods */ 81e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 82e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalabool checkGlError(JNIEnv* env) { 83e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala int error; 84e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if ((error = glGetError()) != GL_NO_ERROR) { 85e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 86e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "GLES20 error: 0x%d", error); 87e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return true; 88e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 89e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return false; 90e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 91e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 92e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala/** 93e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Asynchronous low-overhead GL performance measurement using 94e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * http://www.khronos.org/registry/gles/extensions/EXT/EXT_disjoint_timer_query.txt 95e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 96e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Measures the duration of GPU processing for a set of GL commands, delivering 97e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * the measurement asynchronously once processing completes. 98e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 99e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * All calls must come from a single thread with a valid GL context active. 100e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala **/ 101e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaclass PerfMeasurementContext { 102e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala private: 103e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala Vector<GLuint> mTimingQueries; 104e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala size_t mTimingStartIndex; 105e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala size_t mTimingEndIndex; 106e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala size_t mTimingQueryIndex; 107e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala size_t mFreeQueries; 108e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 109e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala bool mInitDone; 110e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala public: 111e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 112e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 113e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * maxQueryCount should be a conservative estimate of how many query objects 114e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * will be active at once, which is a function of the GPU's level of 115e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * pipelining and the frequency of queries. 116e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 117e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala PerfMeasurementContext(size_t maxQueryCount): 118e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mTimingStartIndex(0), 119e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mTimingEndIndex(0), 120e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mTimingQueryIndex(0) { 121e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mTimingQueries.resize(maxQueryCount); 122e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mFreeQueries = maxQueryCount; 123e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mInitDone = false; 124e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 125e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 126e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala int getMaxQueryCount() { 127e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return mTimingQueries.size(); 128e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 129e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 130e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 131e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Start a measurement period using the next available query object. 132e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Returns INVALID_OPERATION if called multiple times in a row, 133e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * and BAD_VALUE if no more query objects are available. 134e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 135e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala int startGlTimer() { 136e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala // Lazy init of queries to avoid needing GL context during construction 137e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (!mInitDone) { 138e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala glGenQueriesEXT(mTimingQueries.size(), mTimingQueries.editArray()); 139e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mInitDone = true; 140e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 141e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 142e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (mTimingEndIndex != mTimingStartIndex) { 143e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return INVALID_OPERATION; 144e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 145e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 146e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (mFreeQueries == 0) { 147e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return BAD_VALUE; 148e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 149e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 150e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala glBeginQueryEXT(GL_TIME_ELAPSED_EXT, mTimingQueries[mTimingStartIndex]); 151e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 152e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mTimingStartIndex = (mTimingStartIndex + 1) % mTimingQueries.size(); 153e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mFreeQueries--; 154e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 155e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return OK; 156e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 157e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 158e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 159e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Finish the current measurement period 160e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Returns INVALID_OPERATION if called before any startGLTimer calls 161e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * or if called multiple times in a row. 162e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 163e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala int stopGlTimer() { 164e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala size_t nextEndIndex = (mTimingEndIndex + 1) % mTimingQueries.size(); 165e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (nextEndIndex != mTimingStartIndex) { 166e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return INVALID_OPERATION; 167e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 168e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala glEndQueryEXT(GL_TIME_ELAPSED_EXT); 169e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 170e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mTimingEndIndex = nextEndIndex; 171e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 172e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return OK; 173e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 174e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 175e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala static const nsecs_t NO_DURATION_YET = -1L; 176e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala static const nsecs_t FAILED_MEASUREMENT = -2L; 177e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 178e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala /** 179e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Get the next available duration measurement. 180e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 181e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Returns NO_DURATION_YET if no new measurement is available, 182e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * and FAILED_MEASUREMENT if an error occurred during the next 183e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * measurement period. 184e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * 185e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * Otherwise returns a positive number of nanoseconds measuring the 186e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala * duration of the oldest completed query. 187e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala */ 188e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala nsecs_t getNextGlDuration() { 189e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (!mInitDone) { 190e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala // No start/stop called yet 191e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return NO_DURATION_YET; 192e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 193e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 194e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala GLint available; 195e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala glGetQueryObjectivEXT(mTimingQueries[mTimingQueryIndex], 196e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala GL_QUERY_RESULT_AVAILABLE_EXT, &available); 197e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (!available) { 198e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return NO_DURATION_YET; 199e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 200e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 201e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala GLint64 duration = FAILED_MEASUREMENT; 202e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala GLint disjointOccurred; 203e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjointOccurred); 204e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 205e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (!disjointOccurred) { 206e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala glGetQueryObjecti64vEXT(mTimingQueries[mTimingQueryIndex], 207e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala GL_QUERY_RESULT_EXT, 208e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala &duration); 209e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 210e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 211e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mTimingQueryIndex = (mTimingQueryIndex + 1) % mTimingQueries.size(); 212e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala mFreeQueries++; 213e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 214e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return static_cast<nsecs_t>(duration); 215e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 216e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 217e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala static bool isMeasurementSupported() { 218e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala const GLubyte* extensions = glGetString(GL_EXTENSIONS); 219e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return checkForExtension(extensions, 220e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala reinterpret_cast<const GLubyte*>("GL_EXT_disjoint_timer_query")); 221e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 222e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 223e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala}; 224e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 225e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville TalvalaPerfMeasurementContext* getContext(jlong context) { 226e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return reinterpret_cast<PerfMeasurementContext*>(context); 227e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 228e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 229e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaextern "C" { 230e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 231e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic jlong PerfMeasurement_nativeCreateContext(JNIEnv* env, jobject thiz, 232e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jint maxQueryCount) { 233e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala PerfMeasurementContext *context = new PerfMeasurementContext(maxQueryCount); 234e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return reinterpret_cast<jlong>(context); 235e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 236e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 237e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic void PerfMeasurement_nativeDeleteContext(JNIEnv* env, jobject thiz, 238e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jlong contextHandle) { 239e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala PerfMeasurementContext *context = getContext(contextHandle); 240e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala delete(context); 241e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 242e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 243e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic jboolean PerfMeasurement_nativeQuerySupport(JNIEnv* env, jobject thiz) { 244e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala bool supported = PerfMeasurementContext::isMeasurementSupported(); 245e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala checkGlError(env); 246e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return static_cast<jboolean>(supported); 247e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 248e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 249e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic void PerfMeasurement_nativeStartGlTimer(JNIEnv* env, jobject thiz, 250e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jlong contextHandle) { 251e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 252e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala PerfMeasurementContext *context = getContext(contextHandle); 253e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala status_t err = context->startGlTimer(); 254e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (err != OK) { 255e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala switch (err) { 256e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala case INVALID_OPERATION: 257e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 258e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "Mismatched start/end GL timing calls"); 259e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return; 260e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala case BAD_VALUE: 261e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 262e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "Too many timing queries in progress, max %d", 263e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala context->getMaxQueryCount()); 264e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return; 265e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala default: 266e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 267e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "Unknown error starting GL timing"); 268e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return; 269e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 270e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 271e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala checkGlError(env); 272e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 273e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 274e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic void PerfMeasurement_nativeStopGlTimer(JNIEnv* env, jobject thiz, 275e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jlong contextHandle) { 276e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 277e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala PerfMeasurementContext *context = getContext(contextHandle); 278e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala status_t err = context->stopGlTimer(); 279e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala if (err != OK) { 280e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala switch (err) { 281e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala case INVALID_OPERATION: 282e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 283e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "Mismatched start/end GL timing calls"); 284e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return; 285e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala default: 286e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jniThrowExceptionFmt(env, "java/lang/IllegalStateException", 287e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "Unknown error ending GL timing"); 288e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return; 289e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 290e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala } 291e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala checkGlError(env); 292e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 293e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 294e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic jlong PerfMeasurement_nativeGetNextGlDuration(JNIEnv* env, 295e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala jobject thiz, jlong contextHandle) { 296e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala PerfMeasurementContext *context = getContext(contextHandle); 297e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala nsecs_t duration = context->getNextGlDuration(); 298e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 299e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala checkGlError(env); 300e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return static_cast<jlong>(duration); 301e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 302e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 303e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} // extern "C" 304e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 305e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalastatic JNINativeMethod gPerfMeasurementMethods[] = { 306e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala { "nativeCreateContext", 307e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "(I)J", 308e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala (jlong *)PerfMeasurement_nativeCreateContext }, 309e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala { "nativeDeleteContext", 310e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "(J)V", 311e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala (void *)PerfMeasurement_nativeDeleteContext }, 312e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala { "nativeQuerySupport", 313e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "()Z", 314e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala (jboolean *)PerfMeasurement_nativeQuerySupport }, 315e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala { "nativeStartGlTimer", 316e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "(J)V", 317e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala (void *)PerfMeasurement_nativeStartGlTimer }, 318e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala { "nativeStopGlTimer", 319e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "(J)V", 320e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala (void *)PerfMeasurement_nativeStopGlTimer }, 321e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala { "nativeGetNextGlDuration", 322e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala "(J)J", 323e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala (jlong *)PerfMeasurement_nativeGetNextGlDuration } 324e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala}; 325e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 326e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala 327e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala// Get all the required offsets in java class and register native functions 328e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvalaint register_android_hardware_camera2_legacy_PerfMeasurement(JNIEnv* env) 329e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala{ 330e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala // Register native functions 331e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala return AndroidRuntime::registerNativeMethods(env, 332e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala PERF_MEASUREMENT_CLASS_NAME, 333e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala gPerfMeasurementMethods, 334e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala NELEM(gPerfMeasurementMethods)); 335e1f57d6f44909a66c7ab0af33dbc5289287e823aEino-Ville Talvala} 336