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 29namespace 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 56static 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 71static 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 87static 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 103static 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 131static 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 143const char* const kClassPathName = "android/view/HardwareRenderer"; 144 145static 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 158int register_android_view_HardwareRenderer(JNIEnv* env) { 159 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 160} 161 162}; 163