1 /* 2 * Copyright (C) 2010 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 17 #define LOG_TAG "HardwareRenderer" 18 19 #include "jni.h" 20 #include <nativehelper/JNIHelp.h> 21 #include <android_runtime/AndroidRuntime.h> 22 23 #include <EGL/egl_cache.h> 24 25 #ifdef USE_OPENGL_RENDERER 26 EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface); 27 #endif 28 29 namespace android { 30 31 /** 32 * Note: OpenGLRenderer JNI layer is generated and compiled only on supported 33 * devices. This means all the logic must be compiled only when the 34 * preprocessor variable USE_OPENGL_RENDERER is defined. 35 */ 36 #ifdef USE_OPENGL_RENDERER 37 38 // ---------------------------------------------------------------------------- 39 // Defines 40 // ---------------------------------------------------------------------------- 41 42 // Debug 43 #define DEBUG_RENDERER 0 44 45 // Debug 46 #if DEBUG_RENDERER 47 #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__) 48 #else 49 #define RENDERER_LOGD(...) 50 #endif 51 52 // ---------------------------------------------------------------------------- 53 // Surface and display management 54 // ---------------------------------------------------------------------------- 55 56 static jboolean android_view_HardwareRenderer_preserveBackBuffer(JNIEnv* env, jobject clazz) { 57 EGLDisplay display = eglGetCurrentDisplay(); 58 EGLSurface surface = eglGetCurrentSurface(EGL_DRAW); 59 60 eglGetError(); 61 eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); 62 63 EGLint error = eglGetError(); 64 if (error != EGL_SUCCESS) { 65 RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error); 66 } 67 68 return error == EGL_SUCCESS; 69 } 70 71 static jboolean android_view_HardwareRenderer_isBackBufferPreserved(JNIEnv* env, jobject clazz) { 72 EGLDisplay display = eglGetCurrentDisplay(); 73 EGLSurface surface = eglGetCurrentSurface(EGL_DRAW); 74 EGLint value; 75 76 eglGetError(); 77 eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &value); 78 79 EGLint error = eglGetError(); 80 if (error != EGL_SUCCESS) { 81 RENDERER_LOGD("Could not query buffer preserved swap behavior (%x)", error); 82 } 83 84 return error == EGL_SUCCESS && value == EGL_BUFFER_PRESERVED; 85 } 86 87 static void android_view_HardwareRenderer_disableVsync(JNIEnv* env, jobject clazz) { 88 EGLDisplay display = eglGetCurrentDisplay(); 89 90 eglGetError(); 91 eglSwapInterval(display, 0); 92 93 EGLint error = eglGetError(); 94 if (error != EGL_SUCCESS) { 95 RENDERER_LOGD("Could not disable v-sync (%x)", error); 96 } 97 } 98 99 // ---------------------------------------------------------------------------- 100 // Tracing and debugging 101 // ---------------------------------------------------------------------------- 102 103 static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz, 104 jintArray size) { 105 106 EGLDisplay display = eglGetCurrentDisplay(); 107 EGLSurface surface = eglGetCurrentSurface(EGL_DRAW); 108 109 if (size) { 110 EGLint value; 111 jint* storage = env->GetIntArrayElements(size, NULL); 112 113 eglQuerySurface(display, surface, EGL_WIDTH, &value); 114 storage[0] = value; 115 116 eglQuerySurface(display, surface, EGL_HEIGHT, &value); 117 storage[1] = value; 118 119 env->ReleaseIntArrayElements(size, storage, 0); 120 } 121 122 eglBeginFrame(display, surface); 123 } 124 125 #endif // USE_OPENGL_RENDERER 126 127 // ---------------------------------------------------------------------------- 128 // Shaders 129 // ---------------------------------------------------------------------------- 130 131 static void android_view_HardwareRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz, 132 jstring diskCachePath) { 133 134 const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL); 135 egl_cache_t::get()->setCacheFilename(cacheArray); 136 env->ReleaseStringUTFChars(diskCachePath, cacheArray); 137 } 138 139 // ---------------------------------------------------------------------------- 140 // JNI Glue 141 // ---------------------------------------------------------------------------- 142 143 const char* const kClassPathName = "android/view/HardwareRenderer"; 144 145 static JNINativeMethod gMethods[] = { 146 #ifdef USE_OPENGL_RENDERER 147 { "nIsBackBufferPreserved", "()Z", (void*) android_view_HardwareRenderer_isBackBufferPreserved }, 148 { "nPreserveBackBuffer", "()Z", (void*) android_view_HardwareRenderer_preserveBackBuffer }, 149 { "nDisableVsync", "()V", (void*) android_view_HardwareRenderer_disableVsync }, 150 151 { "nBeginFrame", "([I)V", (void*) android_view_HardwareRenderer_beginFrame }, 152 #endif 153 154 { "nSetupShadersDiskCache", "(Ljava/lang/String;)V", 155 (void*) android_view_HardwareRenderer_setupShadersDiskCache }, 156 }; 157 158 int register_android_view_HardwareRenderer(JNIEnv* env) { 159 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 160 } 161 162 }; 163