blob: 4452065956bfcb0670fbbbc8a1ee6b999e66fe25 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2**
3** Copyright 2006, The Android Open Source Project
4**
Jack Palevich4c7533c2009-03-24 22:48:26 -07005** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008**
Jack Palevich4c7533c2009-03-24 22:48:26 -07009** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010**
Jack Palevich4c7533c2009-03-24 22:48:26 -070011** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015** limitations under the License.
16*/
17
18#include <android_runtime/AndroidRuntime.h>
19#include <utils/misc.h>
20
21#include <EGL/egl.h>
22#include <GLES/gl.h>
23
24#include <ui/EGLNativeWindowSurface.h>
25#include <ui/Surface.h>
26#include <SkBitmap.h>
27#include <SkPixelRef.h>
28
29namespace android {
30
31static jclass gDisplay_class;
32static jclass gContext_class;
33static jclass gSurface_class;
34static jclass gConfig_class;
35
36static jmethodID gConfig_ctorID;
37
38static jfieldID gDisplay_EGLDisplayFieldID;
39static jfieldID gContext_EGLContextFieldID;
40static jfieldID gSurface_EGLSurfaceFieldID;
41static jfieldID gSurface_NativePixelRefFieldID;
42static jfieldID gConfig_EGLConfigFieldID;
43static jfieldID gSurface_SurfaceFieldID;
44static jfieldID gBitmap_NativeBitmapFieldID;
45
46static __attribute__((noinline))
47void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
48{
49 jclass npeClazz = env->FindClass(exc);
50 env->ThrowNew(npeClazz, msg);
51}
52
53static __attribute__((noinline))
54bool hasException(JNIEnv *env) {
55 if (env->ExceptionCheck() != 0) {
56 env->ExceptionDescribe();
57 return true;
58 }
59 return false;
60}
61
62static __attribute__((noinline))
63jclass make_globalref(JNIEnv* env, const char classname[]) {
64 jclass c = env->FindClass(classname);
65 return (jclass)env->NewGlobalRef(c);
66}
67
68static inline EGLDisplay getDisplay(JNIEnv* env, jobject o) {
69 if (!o) return EGL_NO_DISPLAY;
70 return (EGLDisplay)env->GetIntField(o, gDisplay_EGLDisplayFieldID);
71}
72static inline EGLSurface getSurface(JNIEnv* env, jobject o) {
73 if (!o) return EGL_NO_SURFACE;
74 return (EGLSurface)env->GetIntField(o, gSurface_EGLSurfaceFieldID);
75}
76static inline EGLContext getContext(JNIEnv* env, jobject o) {
77 if (!o) return EGL_NO_CONTEXT;
78 return (EGLContext)env->GetIntField(o, gContext_EGLContextFieldID);
79}
80static inline EGLConfig getConfig(JNIEnv* env, jobject o) {
81 if (!o) return 0;
82 return (EGLConfig)env->GetIntField(o, gConfig_EGLConfigFieldID);
83}
84static void nativeClassInit(JNIEnv *_env, jclass eglImplClass)
85{
86 gDisplay_class = make_globalref(_env, "com/google/android/gles_jni/EGLDisplayImpl");
87 gContext_class = make_globalref(_env, "com/google/android/gles_jni/EGLContextImpl");
88 gSurface_class = make_globalref(_env, "com/google/android/gles_jni/EGLSurfaceImpl");
89 gConfig_class = make_globalref(_env, "com/google/android/gles_jni/EGLConfigImpl");
90
91 gConfig_ctorID = _env->GetMethodID(gConfig_class, "<init>", "(I)V");
Jack Palevich4c7533c2009-03-24 22:48:26 -070092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 gDisplay_EGLDisplayFieldID = _env->GetFieldID(gDisplay_class, "mEGLDisplay", "I");
94 gContext_EGLContextFieldID = _env->GetFieldID(gContext_class, "mEGLContext", "I");
95 gSurface_EGLSurfaceFieldID = _env->GetFieldID(gSurface_class, "mEGLSurface", "I");
96 gSurface_NativePixelRefFieldID = _env->GetFieldID(gSurface_class, "mNativePixelRef", "I");
97 gConfig_EGLConfigFieldID = _env->GetFieldID(gConfig_class, "mEGLConfig", "I");
98
99 jclass surface_class = _env->FindClass("android/view/Surface");
100 gSurface_SurfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I");
101
102 jclass bitmap_class = _env->FindClass("android/graphics/Bitmap");
Jack Palevich4c7533c2009-03-24 22:48:26 -0700103 gBitmap_NativeBitmapFieldID = _env->GetFieldID(bitmap_class, "mNativeBitmap", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104}
105
Jack Palevich4c7533c2009-03-24 22:48:26 -0700106static const jint gNull_attrib_base[] = {EGL_NONE};
107
108static bool validAttribList(JNIEnv *_env, jintArray attrib_list) {
109 if (attrib_list == NULL) {
110 return true;
111 }
112 jsize len = _env->GetArrayLength(attrib_list);
113 if (len < 1) {
114 return false;
115 }
116 jint item = 0;
117 _env->GetIntArrayRegion(attrib_list, len-1, 1, &item);
118 return item == EGL_NONE;
119}
120
121static jint* beginNativeAttribList(JNIEnv *_env, jintArray attrib_list) {
122 if (attrib_list != NULL) {
123 return (jint *)_env->GetPrimitiveArrayCritical(attrib_list, (jboolean *)0);
124 } else {
125 return(jint*) gNull_attrib_base;
126 }
127}
128
129static void endNativeAttributeList(JNIEnv *_env, jintArray attrib_list, jint* attrib_base) {
130 if (attrib_list != NULL) {
131 _env->ReleasePrimitiveArrayCritical(attrib_list, attrib_base, JNI_ABORT);
132 }
133}
134
135static jboolean jni_eglInitialize(JNIEnv *_env, jobject _this, jobject display,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 jintArray major_minor) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700137 if (display == NULL || (major_minor != NULL &&
138 _env->GetArrayLength(major_minor) < 2)) {
139 doThrow(_env, "java/lang/IllegalArgumentException");
140 return JNI_FALSE;
141 }
142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 EGLDisplay dpy = getDisplay(_env, display);
144 jboolean success = eglInitialize(dpy, NULL, NULL);
145 if (success && major_minor) {
146 int len = _env->GetArrayLength(major_minor);
147 if (len) {
148 // we're exposing only EGL 1.0
149 jint* base = (jint *)_env->GetPrimitiveArrayCritical(major_minor, (jboolean *)0);
150 if (len >= 1) base[0] = 1;
151 if (len >= 2) base[1] = 0;
152 _env->ReleasePrimitiveArrayCritical(major_minor, base, JNI_ABORT);
153 }
154 }
155 return success;
156}
157
Jack Palevich4c7533c2009-03-24 22:48:26 -0700158static jboolean jni_eglQueryContext(JNIEnv *_env, jobject _this, jobject display,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 jobject context, jint attribute, jintArray value) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700160 if (display == NULL || context == NULL || value == NULL
161 || _env->GetArrayLength(value) < 1) {
162 doThrow(_env, "java/lang/IllegalArgumentException");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 return JNI_FALSE;
164 }
Jack Palevich4c7533c2009-03-24 22:48:26 -0700165 EGLDisplay dpy = getDisplay(_env, display);
166 EGLContext ctx = getContext(_env, context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 jboolean success = JNI_FALSE;
168 int len = _env->GetArrayLength(value);
169 if (len) {
170 jint* base = (jint *)_env->GetPrimitiveArrayCritical(value, (jboolean *)0);
171 success = eglQueryContext(dpy, ctx, attribute, base);
172 _env->ReleasePrimitiveArrayCritical(value, base, JNI_ABORT);
173 }
174 return success;
175}
Jack Palevich4c7533c2009-03-24 22:48:26 -0700176
177static jboolean jni_eglQuerySurface(JNIEnv *_env, jobject _this, jobject display,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 jobject surface, jint attribute, jintArray value) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700179 if (display == NULL || surface == NULL || value == NULL
180 || _env->GetArrayLength(value) < 1) {
181 doThrow(_env, "java/lang/IllegalArgumentException");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 return JNI_FALSE;
183 }
Jack Palevich4c7533c2009-03-24 22:48:26 -0700184 EGLDisplay dpy = getDisplay(_env, display);
185 EGLContext sur = getSurface(_env, surface);
186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 jboolean success = JNI_FALSE;
188 int len = _env->GetArrayLength(value);
189 if (len) {
190 jint* base = (jint *)_env->GetPrimitiveArrayCritical(value, (jboolean *)0);
191 success = eglQuerySurface(dpy, sur, attribute, base);
192 _env->ReleasePrimitiveArrayCritical(value, base, JNI_ABORT);
193 }
194 return success;
195}
196
Jack Palevich4c7533c2009-03-24 22:48:26 -0700197static jboolean jni_eglChooseConfig(JNIEnv *_env, jobject _this, jobject display,
198 jintArray attrib_list, jobjectArray configs, jint config_size, jintArray num_config) {
199 if (display == NULL
200 || !validAttribList(_env, attrib_list)
201 || (configs != NULL && _env->GetArrayLength(configs) < config_size)
202 || (num_config != NULL && _env->GetArrayLength(num_config) < 1)) {
203 doThrow(_env, "java/lang/IllegalArgumentException");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 return JNI_FALSE;
205 }
Jack Palevich4c7533c2009-03-24 22:48:26 -0700206 EGLDisplay dpy = getDisplay(_env, display);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 jboolean success = JNI_FALSE;
Jack Palevich4c7533c2009-03-24 22:48:26 -0700208
209 if (configs == NULL) {
210 config_size = 0;
211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 EGLConfig nativeConfigs[config_size];
Jack Palevich4c7533c2009-03-24 22:48:26 -0700213
214 int num = 0;
215 jint* attrib_base = beginNativeAttribList(_env, attrib_list);
216 success = eglChooseConfig(dpy, attrib_base, configs ? nativeConfigs : 0, config_size, &num);
217 endNativeAttributeList(_env, attrib_list, attrib_base);
218
219 if (num_config != NULL) {
220 _env->SetIntArrayRegion(num_config, 0, 1, (jint*) &num);
221 }
222
223 if (success && configs!=NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 for (int i=0 ; i<num ; i++) {
225 jobject obj = _env->NewObject(gConfig_class, gConfig_ctorID, (jint)nativeConfigs[i]);
226 _env->SetObjectArrayElement(configs, i, obj);
227 }
228 }
229 return success;
Jack Palevich4c7533c2009-03-24 22:48:26 -0700230}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231
Jack Palevich4c7533c2009-03-24 22:48:26 -0700232static jint jni_eglCreateContext(JNIEnv *_env, jobject _this, jobject display,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 jobject config, jobject share_context, jintArray attrib_list) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700234 if (display == NULL || config == NULL || share_context == NULL
235 || !validAttribList(_env, attrib_list)) {
236 doThrow(_env, "java/lang/IllegalArgumentException");
237 return JNI_FALSE;
238 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 EGLDisplay dpy = getDisplay(_env, display);
240 EGLConfig cnf = getConfig(_env, config);
241 EGLContext shr = getContext(_env, share_context);
Jack Palevich4c7533c2009-03-24 22:48:26 -0700242 jint* base = beginNativeAttribList(_env, attrib_list);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 EGLContext ctx = eglCreateContext(dpy, cnf, shr, base);
Jack Palevich4c7533c2009-03-24 22:48:26 -0700244 endNativeAttributeList(_env, attrib_list, base);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 return (jint)ctx;
246}
247
Jack Palevich4c7533c2009-03-24 22:48:26 -0700248static jint jni_eglCreatePbufferSurface(JNIEnv *_env, jobject _this, jobject display,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 jobject config, jintArray attrib_list) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700250 if (display == NULL || config == NULL
251 || !validAttribList(_env, attrib_list)) {
252 doThrow(_env, "java/lang/IllegalArgumentException");
253 return JNI_FALSE;
254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 EGLDisplay dpy = getDisplay(_env, display);
256 EGLConfig cnf = getConfig(_env, config);
Jack Palevich4c7533c2009-03-24 22:48:26 -0700257 jint* base = beginNativeAttribList(_env, attrib_list);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 EGLSurface sur = eglCreatePbufferSurface(dpy, cnf, base);
Jack Palevich4c7533c2009-03-24 22:48:26 -0700259 endNativeAttributeList(_env, attrib_list, base);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 return (jint)sur;
261}
262
263static PixelFormat convertPixelFormat(SkBitmap::Config format)
264{
265 switch (format) {
266 case SkBitmap::kARGB_8888_Config: return PIXEL_FORMAT_RGBA_8888;
267 case SkBitmap::kARGB_4444_Config: return PIXEL_FORMAT_RGBA_4444;
268 case SkBitmap::kRGB_565_Config: return PIXEL_FORMAT_RGB_565;
269 case SkBitmap::kA8_Config: return PIXEL_FORMAT_A_8;
270 default: return PIXEL_FORMAT_NONE;
271 }
272}
273
Jack Palevich4c7533c2009-03-24 22:48:26 -0700274static void jni_eglCreatePixmapSurface(JNIEnv *_env, jobject _this, jobject out_sur,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 jobject display, jobject config, jobject native_pixmap,
Jack Palevich4c7533c2009-03-24 22:48:26 -0700276 jintArray attrib_list)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277{
Jack Palevich4c7533c2009-03-24 22:48:26 -0700278 if (display == NULL || config == NULL || native_pixmap == NULL
279 || !validAttribList(_env, attrib_list)) {
280 doThrow(_env, "java/lang/IllegalArgumentException");
281 return;
282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 EGLDisplay dpy = getDisplay(_env, display);
284 EGLConfig cnf = getConfig(_env, config);
285 jint* base = 0;
286
287 SkBitmap const * nativeBitmap =
288 (SkBitmap const *)_env->GetIntField(native_pixmap,
289 gBitmap_NativeBitmapFieldID);
290 SkPixelRef* ref = nativeBitmap ? nativeBitmap->pixelRef() : 0;
291 if (ref == NULL) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700292 doThrow(_env, "java/lang/IllegalArgumentException", "Bitmap has no PixelRef");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 return;
294 }
Jack Palevich4c7533c2009-03-24 22:48:26 -0700295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 ref->safeRef();
297 ref->lockPixels();
Jack Palevich4c7533c2009-03-24 22:48:26 -0700298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 egl_native_pixmap_t pixmap;
300 pixmap.version = sizeof(pixmap);
301 pixmap.width = nativeBitmap->width();
302 pixmap.height = nativeBitmap->height();
303 pixmap.stride = nativeBitmap->rowBytes() / nativeBitmap->bytesPerPixel();
304 pixmap.format = convertPixelFormat(nativeBitmap->config());
305 pixmap.data = (uint8_t*)ref->pixels();
Jack Palevich4c7533c2009-03-24 22:48:26 -0700306
307 base = beginNativeAttribList(_env, attrib_list);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 EGLSurface sur = eglCreatePixmapSurface(dpy, cnf, &pixmap, base);
Jack Palevich4c7533c2009-03-24 22:48:26 -0700309 endNativeAttributeList(_env, attrib_list, base);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310
311 if (sur != EGL_NO_SURFACE) {
312 _env->SetIntField(out_sur, gSurface_EGLSurfaceFieldID, (int)sur);
313 _env->SetIntField(out_sur, gSurface_NativePixelRefFieldID, (int)ref);
314 } else {
315 ref->unlockPixels();
316 ref->safeUnref();
317 }
318}
319
Jack Palevich4c7533c2009-03-24 22:48:26 -0700320static jint jni_eglCreateWindowSurface(JNIEnv *_env, jobject _this, jobject display,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 jobject config, jobject native_window, jintArray attrib_list) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700322 if (display == NULL || config == NULL
323 || !validAttribList(_env, attrib_list)) {
324 doThrow(_env, "java/lang/IllegalArgumentException");
325 return JNI_FALSE;
326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 EGLDisplay dpy = getDisplay(_env, display);
328 EGLContext cnf = getConfig(_env, config);
329 Surface* window = 0;
330 if (native_window == NULL) {
331not_valid_surface:
Jack Palevich4c7533c2009-03-24 22:48:26 -0700332 doThrow(_env, "java/lang/IllegalArgumentException",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface");
334 return 0;
335 }
336 window = (Surface*)_env->GetIntField(native_window, gSurface_SurfaceFieldID);
337 if (window == NULL)
338 goto not_valid_surface;
339
Jack Palevich4c7533c2009-03-24 22:48:26 -0700340 jint* base = beginNativeAttribList(_env, attrib_list);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 EGLSurface sur = eglCreateWindowSurface(dpy, cnf, new EGLNativeWindowSurface(window), base);
Jack Palevich4c7533c2009-03-24 22:48:26 -0700342 endNativeAttributeList(_env, attrib_list, base);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 return (jint)sur;
344}
345
Jack Palevich4c7533c2009-03-24 22:48:26 -0700346static jboolean jni_eglGetConfigAttrib(JNIEnv *_env, jobject _this, jobject display,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 jobject config, jint attribute, jintArray value) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700348 if (display == NULL || config == NULL
349 || (value == NULL || _env->GetArrayLength(value) < 1)) {
350 doThrow(_env, "java/lang/IllegalArgumentException");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 return JNI_FALSE;
352 }
Jack Palevich4c7533c2009-03-24 22:48:26 -0700353 EGLDisplay dpy = getDisplay(_env, display);
354 EGLContext cnf = getConfig(_env, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 jboolean success = JNI_FALSE;
Jack Palevich4c7533c2009-03-24 22:48:26 -0700356 jint localValue;
357 success = eglGetConfigAttrib(dpy, cnf, attribute, &localValue);
358 if (success) {
359 _env->SetIntArrayRegion(value, 0, 1, &localValue);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 }
361 return success;
362}
363
Jack Palevich4c7533c2009-03-24 22:48:26 -0700364static jboolean jni_eglGetConfigs(JNIEnv *_env, jobject _this, jobject display,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 jobjectArray configs, jint config_size, jintArray num_config) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700366 if (display == NULL || (configs != NULL && _env->GetArrayLength(configs) < config_size)
367 || (num_config != NULL && _env->GetArrayLength(num_config) < 1)) {
368 doThrow(_env, "java/lang/IllegalArgumentException");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 return JNI_FALSE;
370 }
Jack Palevich4c7533c2009-03-24 22:48:26 -0700371 EGLDisplay dpy = getDisplay(_env, display);
372 jboolean success = JNI_FALSE;
373 if (configs == NULL) {
374 config_size = 0;
375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 EGLConfig nativeConfigs[config_size];
Jack Palevich4c7533c2009-03-24 22:48:26 -0700377 int num;
378 success = eglGetConfigs(dpy, configs ? nativeConfigs : 0, config_size, &num);
379 if (num_config != NULL) {
380 _env->SetIntArrayRegion(num_config, 0, 1, (jint*) &num);
381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 if (success && configs) {
383 for (int i=0 ; i<num ; i++) {
384 jobject obj = _env->NewObject(gConfig_class, gConfig_ctorID, (jint)nativeConfigs[i]);
385 _env->SetObjectArrayElement(configs, i, obj);
386 }
387 }
388 return success;
389}
Jack Palevich4c7533c2009-03-24 22:48:26 -0700390
391static jint jni_eglGetError(JNIEnv *_env, jobject _this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 EGLint error = eglGetError();
393 return error;
394}
395
Jack Palevich4c7533c2009-03-24 22:48:26 -0700396static jint jni_eglGetCurrentContext(JNIEnv *_env, jobject _this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 return (jint)eglGetCurrentContext();
398}
399
Jack Palevich4c7533c2009-03-24 22:48:26 -0700400static jint jni_eglGetCurrentDisplay(JNIEnv *_env, jobject _this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 return (jint)eglGetCurrentDisplay();
402}
403
Jack Palevich4c7533c2009-03-24 22:48:26 -0700404static jint jni_eglGetCurrentSurface(JNIEnv *_env, jobject _this, jint readdraw) {
405 if (!(readdraw == EGL_READ) || (readdraw == EGL_DRAW)) {
406 doThrow(_env, "java/lang/IllegalArgumentException");
407 return 0;
408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 return (jint)eglGetCurrentSurface(readdraw);
410}
411
Jack Palevich4c7533c2009-03-24 22:48:26 -0700412static jboolean jni_eglDestroyContext(JNIEnv *_env, jobject _this, jobject display, jobject context) {
413 if (display == NULL || context == NULL) {
414 doThrow(_env, "java/lang/IllegalArgumentException");
415 return JNI_FALSE;
416 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 EGLDisplay dpy = getDisplay(_env, display);
418 EGLContext ctx = getContext(_env, context);
419 return eglDestroyContext(dpy, ctx);
420}
421
Jack Palevich4c7533c2009-03-24 22:48:26 -0700422static jboolean jni_eglDestroySurface(JNIEnv *_env, jobject _this, jobject display, jobject surface) {
423 if (display == NULL || surface == NULL) {
424 doThrow(_env, "java/lang/IllegalArgumentException");
425 return JNI_FALSE;
426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 EGLDisplay dpy = getDisplay(_env, display);
428 EGLSurface sur = getSurface(_env, surface);
429
430 if (sur) {
431 SkPixelRef* ref = (SkPixelRef*)(_env->GetIntField(surface,
432 gSurface_NativePixelRefFieldID));
433 if (ref) {
434 ref->unlockPixels();
435 ref->safeUnref();
436 }
437 }
438 return eglDestroySurface(dpy, sur);
439}
440
Jack Palevich4c7533c2009-03-24 22:48:26 -0700441static jint jni_eglGetDisplay(JNIEnv *_env, jobject _this, jobject native_display) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 return (jint)eglGetDisplay(EGL_DEFAULT_DISPLAY);
443}
444
Jack Palevich4c7533c2009-03-24 22:48:26 -0700445static jboolean jni_eglMakeCurrent(JNIEnv *_env, jobject _this, jobject display, jobject draw, jobject read, jobject context) {
446 if (display == NULL || draw == NULL || read == NULL || context == NULL) {
447 doThrow(_env, "java/lang/IllegalArgumentException");
448 return JNI_FALSE;
449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 EGLDisplay dpy = getDisplay(_env, display);
451 EGLSurface sdr = getSurface(_env, draw);
452 EGLSurface srd = getSurface(_env, read);
453 EGLContext ctx = getContext(_env, context);
454 return eglMakeCurrent(dpy, sdr, srd, ctx);
455}
456
Jack Palevich4c7533c2009-03-24 22:48:26 -0700457static jstring jni_eglQueryString(JNIEnv *_env, jobject _this, jobject display, jint name) {
458 if (display == NULL) {
459 doThrow(_env, "java/lang/IllegalArgumentException");
460 return NULL;
461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 EGLDisplay dpy = getDisplay(_env, display);
463 const char* chars = eglQueryString(dpy, name);
464 return _env->NewStringUTF(chars);
465}
466
Jack Palevich4c7533c2009-03-24 22:48:26 -0700467static jboolean jni_eglSwapBuffers(JNIEnv *_env, jobject _this, jobject display, jobject surface) {
468 if (display == NULL || surface == NULL) {
469 doThrow(_env, "java/lang/IllegalArgumentException");
470 return JNI_FALSE;
471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 EGLDisplay dpy = getDisplay(_env, display);
473 EGLSurface sur = getSurface(_env, surface);
474 return eglSwapBuffers(dpy, sur);
475}
476
Jack Palevich4c7533c2009-03-24 22:48:26 -0700477static jboolean jni_eglTerminate(JNIEnv *_env, jobject _this, jobject display) {
478 if (display == NULL) {
479 doThrow(_env, "java/lang/IllegalArgumentException");
480 return JNI_FALSE;
481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 EGLDisplay dpy = getDisplay(_env, display);
483 return eglTerminate(dpy);
484}
485
Jack Palevich4c7533c2009-03-24 22:48:26 -0700486static jboolean jni_eglCopyBuffers(JNIEnv *_env, jobject _this, jobject display,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 jobject surface, jobject native_pixmap) {
Jack Palevich4c7533c2009-03-24 22:48:26 -0700488 if (display == NULL || surface == NULL || native_pixmap == NULL) {
489 doThrow(_env, "java/lang/IllegalArgumentException");
490 return JNI_FALSE;
491 }
492 // TODO: Implement this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 return JNI_FALSE;
494}
495
Jack Palevich4c7533c2009-03-24 22:48:26 -0700496static jboolean jni_eglWaitGL(JNIEnv *_env, jobject _this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 return eglWaitGL();
498}
499
Jack Palevich4c7533c2009-03-24 22:48:26 -0700500static jboolean jni_eglWaitNative(JNIEnv *_env, jobject _this, jint engine, jobject bindTarget) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 return eglWaitNative(engine);
502}
503
504
505static const char *classPathName = "com/google/android/gles_jni/EGLImpl";
506
507#define DISPLAY "Ljavax/microedition/khronos/egl/EGLDisplay;"
508#define CONTEXT "Ljavax/microedition/khronos/egl/EGLContext;"
509#define CONFIG "Ljavax/microedition/khronos/egl/EGLConfig;"
510#define SURFACE "Ljavax/microedition/khronos/egl/EGLSurface;"
511#define OBJECT "Ljava/lang/Object;"
512#define STRING "Ljava/lang/String;"
513
514static JNINativeMethod methods[] = {
515{"_nativeClassInit","()V", (void*)nativeClassInit },
516{"eglWaitGL", "()Z", (void*)jni_eglWaitGL },
517{"eglInitialize", "(" DISPLAY "[I)Z", (void*)jni_eglInitialize },
518{"eglQueryContext", "(" DISPLAY CONTEXT "I[I)Z", (void*)jni_eglQueryContext },
519{"eglQuerySurface", "(" DISPLAY SURFACE "I[I)Z", (void*)jni_eglQuerySurface },
520{"eglChooseConfig", "(" DISPLAY "[I[" CONFIG "I[I)Z", (void*)jni_eglChooseConfig },
521{"_eglCreateContext","(" DISPLAY CONFIG CONTEXT "[I)I", (void*)jni_eglCreateContext },
522{"eglGetConfigs", "(" DISPLAY "[" CONFIG "I[I)Z", (void*)jni_eglGetConfigs },
523{"eglTerminate", "(" DISPLAY ")Z", (void*)jni_eglTerminate },
524{"eglCopyBuffers", "(" DISPLAY SURFACE OBJECT ")Z", (void*)jni_eglCopyBuffers },
525{"eglWaitNative", "(I" OBJECT ")Z", (void*)jni_eglWaitNative },
526{"eglGetError", "()I", (void*)jni_eglGetError },
527{"eglGetConfigAttrib", "(" DISPLAY CONFIG "I[I)Z", (void*)jni_eglGetConfigAttrib },
528{"_eglGetDisplay", "(" OBJECT ")I", (void*)jni_eglGetDisplay },
529{"_eglGetCurrentContext", "()I", (void*)jni_eglGetCurrentContext },
530{"_eglGetCurrentDisplay", "()I", (void*)jni_eglGetCurrentDisplay },
531{"_eglGetCurrentSurface", "(I)I", (void*)jni_eglGetCurrentSurface },
532{"_eglCreatePbufferSurface","(" DISPLAY CONFIG "[I)I", (void*)jni_eglCreatePbufferSurface },
533{"_eglCreatePixmapSurface", "(" SURFACE DISPLAY CONFIG OBJECT "[I)V", (void*)jni_eglCreatePixmapSurface },
534{"_eglCreateWindowSurface", "(" DISPLAY CONFIG OBJECT "[I)I", (void*)jni_eglCreateWindowSurface },
535{"eglDestroyContext", "(" DISPLAY CONTEXT ")Z", (void*)jni_eglDestroyContext },
536{"eglDestroySurface", "(" DISPLAY SURFACE ")Z", (void*)jni_eglDestroySurface },
537{"eglMakeCurrent", "(" DISPLAY SURFACE SURFACE CONTEXT")Z", (void*)jni_eglMakeCurrent },
538{"eglQueryString", "(" DISPLAY "I)" STRING, (void*)jni_eglQueryString },
539{"eglSwapBuffers", "(" DISPLAY SURFACE ")Z", (void*)jni_eglSwapBuffers },
540};
541
542} // namespace android
543
544int register_com_google_android_gles_jni_EGLImpl(JNIEnv *_env)
545{
546 int err;
547 err = android::AndroidRuntime::registerNativeMethods(_env,
548 android::classPathName, android::methods, NELEM(android::methods));
549 return err;
550}
551