blob: 479fbe2d4e9906358104a4912424140cc260c4dc [file] [log] [blame]
Romain Guya9582652011-11-10 14:20:10 -08001/*
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
Romain Guye9bc11f2013-05-23 12:47:26 -070023#include <EGL/egl.h>
24#include <EGL/eglext.h>
Romain Guy6db53c32012-04-02 10:52:52 -070025#include <EGL/egl_cache.h>
26
Romain Guye9bc11f2013-05-23 12:47:26 -070027#include <utils/Timers.h>
28
Romain Guy5bb3c732012-11-29 17:52:58 -080029#include <Caches.h>
Romain Guye9bc11f2013-05-23 12:47:26 -070030#include <Extensions.h>
Romain Guy5bb3c732012-11-29 17:52:58 -080031
Romain Guy244ada12012-03-28 16:41:26 -070032#ifdef USE_OPENGL_RENDERER
Romain Guy244ada12012-03-28 16:41:26 -070033 EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface);
34#endif
Jamie Gennisb335fad2012-01-15 18:54:57 -080035
Romain Guya9582652011-11-10 14:20:10 -080036namespace android {
37
Romain Guy244ada12012-03-28 16:41:26 -070038/**
39 * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
40 * devices. This means all the logic must be compiled only when the
41 * preprocessor variable USE_OPENGL_RENDERER is defined.
42 */
43#ifdef USE_OPENGL_RENDERER
44
Romain Guya9582652011-11-10 14:20:10 -080045// ----------------------------------------------------------------------------
Romain Guy244ada12012-03-28 16:41:26 -070046// Defines
47// ----------------------------------------------------------------------------
48
49// Debug
50#define DEBUG_RENDERER 0
51
52// Debug
53#if DEBUG_RENDERER
54 #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__)
55#else
56 #define RENDERER_LOGD(...)
57#endif
58
59// ----------------------------------------------------------------------------
60// Surface and display management
61// ----------------------------------------------------------------------------
62
63static jboolean android_view_HardwareRenderer_preserveBackBuffer(JNIEnv* env, jobject clazz) {
64 EGLDisplay display = eglGetCurrentDisplay();
65 EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
66
67 eglGetError();
68 eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
69
70 EGLint error = eglGetError();
71 if (error != EGL_SUCCESS) {
72 RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error);
73 }
74
75 return error == EGL_SUCCESS;
76}
77
78static jboolean android_view_HardwareRenderer_isBackBufferPreserved(JNIEnv* env, jobject clazz) {
79 EGLDisplay display = eglGetCurrentDisplay();
80 EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
81 EGLint value;
82
83 eglGetError();
84 eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &value);
85
86 EGLint error = eglGetError();
87 if (error != EGL_SUCCESS) {
88 RENDERER_LOGD("Could not query buffer preserved swap behavior (%x)", error);
89 }
90
91 return error == EGL_SUCCESS && value == EGL_BUFFER_PRESERVED;
92}
93
Romain Guy244ada12012-03-28 16:41:26 -070094// ----------------------------------------------------------------------------
95// Tracing and debugging
96// ----------------------------------------------------------------------------
97
Romain Guy5bb3c732012-11-29 17:52:58 -080098static bool android_view_HardwareRenderer_loadProperties(JNIEnv* env, jobject clazz) {
99 if (uirenderer::Caches::hasInstance()) {
100 return uirenderer::Caches::getInstance().initProperties();
101 }
102 return false;
103}
104
Romain Guy76878822012-03-30 14:54:22 -0700105static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz,
106 jintArray size) {
107
108 EGLDisplay display = eglGetCurrentDisplay();
109 EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
110
111 if (size) {
112 EGLint value;
113 jint* storage = env->GetIntArrayElements(size, NULL);
114
115 eglQuerySurface(display, surface, EGL_WIDTH, &value);
116 storage[0] = value;
117
118 eglQuerySurface(display, surface, EGL_HEIGHT, &value);
119 storage[1] = value;
120
121 env->ReleaseIntArrayElements(size, storage, 0);
122 }
123
124 eglBeginFrame(display, surface);
Romain Guy244ada12012-03-28 16:41:26 -0700125}
126
Romain Guye9bc11f2013-05-23 12:47:26 -0700127static jlong android_view_HardwareRenderer_getSystemTime(JNIEnv* env, jobject clazz) {
128 if (uirenderer::Extensions::getInstance().hasNvSystemTime()) {
129 return eglGetSystemTimeNV();
130 }
131 return systemTime(SYSTEM_TIME_MONOTONIC);
132}
133
Romain Guy244ada12012-03-28 16:41:26 -0700134#endif // USE_OPENGL_RENDERER
135
136// ----------------------------------------------------------------------------
137// Shaders
Romain Guya9582652011-11-10 14:20:10 -0800138// ----------------------------------------------------------------------------
139
140static void android_view_HardwareRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
141 jstring diskCachePath) {
142
143 const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
144 egl_cache_t::get()->setCacheFilename(cacheArray);
145 env->ReleaseStringUTFChars(diskCachePath, cacheArray);
146}
147
148// ----------------------------------------------------------------------------
149// JNI Glue
150// ----------------------------------------------------------------------------
151
152const char* const kClassPathName = "android/view/HardwareRenderer";
153
154static JNINativeMethod gMethods[] = {
Romain Guy244ada12012-03-28 16:41:26 -0700155#ifdef USE_OPENGL_RENDERER
Romain Guy76878822012-03-30 14:54:22 -0700156 { "nIsBackBufferPreserved", "()Z", (void*) android_view_HardwareRenderer_isBackBufferPreserved },
157 { "nPreserveBackBuffer", "()Z", (void*) android_view_HardwareRenderer_preserveBackBuffer },
Romain Guy5bb3c732012-11-29 17:52:58 -0800158 { "nLoadProperties", "()Z", (void*) android_view_HardwareRenderer_loadProperties },
Romain Guy244ada12012-03-28 16:41:26 -0700159
Romain Guy76878822012-03-30 14:54:22 -0700160 { "nBeginFrame", "([I)V", (void*) android_view_HardwareRenderer_beginFrame },
Romain Guye9bc11f2013-05-23 12:47:26 -0700161
162 { "nGetSystemTime", "()J", (void*) android_view_HardwareRenderer_getSystemTime },
Romain Guy244ada12012-03-28 16:41:26 -0700163#endif
164
165 { "nSetupShadersDiskCache", "(Ljava/lang/String;)V",
166 (void*) android_view_HardwareRenderer_setupShadersDiskCache },
Romain Guya9582652011-11-10 14:20:10 -0800167};
168
169int register_android_view_HardwareRenderer(JNIEnv* env) {
170 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
171}
172
173};