1a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy/* 2a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * Copyright (C) 2010 The Android Open Source Project 3a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * 4a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * you may not use this file except in compliance with the License. 6a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * You may obtain a copy of the License at 7a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * 8a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 9a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * 10a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * Unless required by applicable law or agreed to in writing, software 11a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * See the License for the specific language governing permissions and 14a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * limitations under the License. 15a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy */ 16a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 17a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy#define LOG_TAG "HardwareRenderer" 18a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 19a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy#include "jni.h" 20a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy#include <nativehelper/JNIHelp.h> 21a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy#include <android_runtime/AndroidRuntime.h> 22a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 236db53c34a7fe8fdc2a8775dc5a400776e2716d38Romain Guy#include <EGL/egl_cache.h> 246db53c34a7fe8fdc2a8775dc5a400776e2716d38Romain Guy 25244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#ifdef USE_OPENGL_RENDERER 26244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface); 27244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#endif 28b335fad4705348ff78d764fb4be53dcbe6b67abeJamie Gennis 29a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guynamespace android { 30a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 31244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy/** 32244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * Note: OpenGLRenderer JNI layer is generated and compiled only on supported 33244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * devices. This means all the logic must be compiled only when the 34244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * preprocessor variable USE_OPENGL_RENDERER is defined. 35244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy */ 36244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#ifdef USE_OPENGL_RENDERER 37244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 38a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy// ---------------------------------------------------------------------------- 39244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// Defines 40a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy// ---------------------------------------------------------------------------- 41a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 42244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// Debug 43244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#define DEBUG_RENDERER 0 44a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 45244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// Debug 46244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#if DEBUG_RENDERER 47244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__) 48244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#else 49244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy #define RENDERER_LOGD(...) 50244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#endif 51244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 52244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ---------------------------------------------------------------------------- 53244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// Surface and display management 54244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ---------------------------------------------------------------------------- 55244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 56244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guystatic jboolean android_view_HardwareRenderer_preserveBackBuffer(JNIEnv* env, jobject clazz) { 57244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLDisplay display = eglGetCurrentDisplay(); 58244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLSurface surface = eglGetCurrentSurface(EGL_DRAW); 59244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 60244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy eglGetError(); 61244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); 62244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 63244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLint error = eglGetError(); 64244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy if (error != EGL_SUCCESS) { 65244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error); 66244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy } 67244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 68244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy return error == EGL_SUCCESS; 69a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy} 70a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 71244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guystatic jboolean android_view_HardwareRenderer_isBackBufferPreserved(JNIEnv* env, jobject clazz) { 72244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLDisplay display = eglGetCurrentDisplay(); 73244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLSurface surface = eglGetCurrentSurface(EGL_DRAW); 74244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLint value; 75244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 76244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy eglGetError(); 77244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &value); 78244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 79244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLint error = eglGetError(); 80244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy if (error != EGL_SUCCESS) { 81244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy RENDERER_LOGD("Could not query buffer preserved swap behavior (%x)", error); 82244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy } 83244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 84244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy return error == EGL_SUCCESS && value == EGL_BUFFER_PRESERVED; 85244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy} 86244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 87244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guystatic void android_view_HardwareRenderer_disableVsync(JNIEnv* env, jobject clazz) { 88244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLDisplay display = eglGetCurrentDisplay(); 89244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 90244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy eglGetError(); 91244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy eglSwapInterval(display, 0); 92244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 93244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy EGLint error = eglGetError(); 94244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy if (error != EGL_SUCCESS) { 95244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy RENDERER_LOGD("Could not disable v-sync (%x)", error); 96244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy } 97244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy} 98244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 99244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ---------------------------------------------------------------------------- 100244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// Tracing and debugging 101244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ---------------------------------------------------------------------------- 102244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 1037687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guystatic void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz, 1047687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy jintArray size) { 1057687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 1067687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy EGLDisplay display = eglGetCurrentDisplay(); 1077687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy EGLSurface surface = eglGetCurrentSurface(EGL_DRAW); 1087687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 1097687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy if (size) { 1107687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy EGLint value; 1117687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy jint* storage = env->GetIntArrayElements(size, NULL); 1127687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 1137687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy eglQuerySurface(display, surface, EGL_WIDTH, &value); 1147687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy storage[0] = value; 1157687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 1167687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy eglQuerySurface(display, surface, EGL_HEIGHT, &value); 1177687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy storage[1] = value; 1187687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 1197687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy env->ReleaseIntArrayElements(size, storage, 0); 1207687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy } 1217687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 1227687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy eglBeginFrame(display, surface); 123b335fad4705348ff78d764fb4be53dcbe6b67abeJamie Gennis} 124b335fad4705348ff78d764fb4be53dcbe6b67abeJamie Gennis 125244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#endif // USE_OPENGL_RENDERER 126244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 127244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ---------------------------------------------------------------------------- 128244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// Shaders 129244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ---------------------------------------------------------------------------- 130244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 131244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guystatic void android_view_HardwareRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz, 132244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy jstring diskCachePath) { 133244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 134244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL); 135244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy egl_cache_t::get()->setCacheFilename(cacheArray); 136244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy env->ReleaseStringUTFChars(diskCachePath, cacheArray); 137244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy} 138244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 139a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy// ---------------------------------------------------------------------------- 140a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy// JNI Glue 141a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy// ---------------------------------------------------------------------------- 142a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 143a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guyconst char* const kClassPathName = "android/view/HardwareRenderer"; 144a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 145a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guystatic JNINativeMethod gMethods[] = { 146244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#ifdef USE_OPENGL_RENDERER 1477687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy { "nIsBackBufferPreserved", "()Z", (void*) android_view_HardwareRenderer_isBackBufferPreserved }, 1487687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy { "nPreserveBackBuffer", "()Z", (void*) android_view_HardwareRenderer_preserveBackBuffer }, 1497687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy { "nDisableVsync", "()V", (void*) android_view_HardwareRenderer_disableVsync }, 1507687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 1517687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy { "nBeginFrame", "([I)V", (void*) android_view_HardwareRenderer_beginFrame }, 152244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy#endif 153244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 154244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy { "nSetupShadersDiskCache", "(Ljava/lang/String;)V", 155244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy (void*) android_view_HardwareRenderer_setupShadersDiskCache }, 156a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy}; 157a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 158a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guyint register_android_view_HardwareRenderer(JNIEnv* env) { 159a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 160a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy} 161a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 162a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy}; 163