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