From 43ef0c3d9b8fc909d45479fa92f2f91240309a81 Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Wed, 3 Apr 2019 17:30:40 -0600 Subject: [PATCH] EGLAttrib requires special handling in JNI EGLAttrib is defined for a C / C++ interface and is intended to be the size of a pointer. That can change depending on which abi the code is built for but Java doesn't have a way of dealing with such types. Java defines EGLAttrib as a jlong, so need to convert jlong to 32bit when running on a 32bit device. Bug: 124382141 Test: atest --all-abi CtsGraphicsTestCases:EGL15Test Change-Id: I966f6a3716b2710e17d10e0d0cb58314853675e0 --- core/jni/android_opengl_EGL15.cpp | 165 +++++++++++++++----------- opengl/java/android/opengl/EGL15.java | 23 ++-- 2 files changed, 106 insertions(+), 82 deletions(-) diff --git a/core/jni/android_opengl_EGL15.cpp b/core/jni/android_opengl_EGL15.cpp index 99bdce274f3e9..717b50579325a 100644 --- a/core/jni/android_opengl_EGL15.cpp +++ b/core/jni/android_opengl_EGL15.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -206,6 +207,24 @@ toEGLHandle(JNIEnv *_env, jclass cls, jmethodID con, void *handle) { return _env->NewObject(cls, con, reinterpret_cast(handle)); } +struct WrappedEGLAttribs { +private: + std::vector backing; // only for 32-bit +public: + EGLAttrib *attribs; + WrappedEGLAttribs(): attribs(nullptr) { }; + void init(jlong *array, jint size) { + if (sizeof(EGLAttrib) != sizeof(jlong)) { + for (jint i = 0; i < size; ++i) { + backing.push_back(array[i]); + } + attribs = backing.data(); + } else { + attribs = (EGLAttrib*)array; + } + } +}; + // -------------------------------------------------------------------------- /* EGLSync eglCreateSync ( EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list ) */ static jobject @@ -216,9 +235,9 @@ android_eglCreateSync const char * _exceptionMessage = NULL; EGLSync _returnValue = (EGLSync) 0; EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy); - EGLAttrib *attrib_list_base = (EGLAttrib *) 0; + jlong *attrib_list_base = (jlong *) 0; jint _remaining; - EGLAttrib *attrib_list = (EGLAttrib *) 0; + WrappedEGLAttribs attrib_list; if (!attrib_list_ref) { _exception = 1; @@ -233,14 +252,14 @@ android_eglCreateSync goto exit; } _remaining = _env->GetArrayLength(attrib_list_ref) - offset; - attrib_list_base = (EGLAttrib *) + attrib_list_base = (jlong *) _env->GetLongArrayElements(attrib_list_ref, (jboolean *)0); - attrib_list = attrib_list_base + offset; + attrib_list.init(attrib_list_base + offset, _remaining); _returnValue = eglCreateSync( (EGLDisplay)dpy_native, (EGLenum)type, - (EGLAttrib *)attrib_list + attrib_list.attribs ); exit: @@ -255,6 +274,59 @@ exit: return toEGLHandle(_env, eglsyncClass, eglsyncConstructor, _returnValue); } +/* EGLBoolean eglGetSyncAttrib ( EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value ) */ +static jboolean +android_eglGetSyncAttrib + (JNIEnv *_env, jobject _this, jobject dpy, jobject sync, jint attribute, jlongArray value_ref, jint offset) { + jint _exception = 0; + const char * _exceptionType = NULL; + const char * _exceptionMessage = NULL; + EGLBoolean _returnValue = (EGLBoolean) 0; + EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy); + EGLSync sync_native = (EGLSync) fromEGLHandle(_env, eglsyncGetHandleID, sync); + jlong *value_base = (jlong *) 0; + jint _remaining; + EGLAttrib value; + + if (!value_ref) { + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "value == null"; + goto exit; + } + if (offset < 0) { + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "offset < 0"; + goto exit; + } + _remaining = _env->GetArrayLength(value_ref) - offset; + value_base = (jlong *) + _env->GetLongArrayElements(value_ref, (jboolean *)0); + + _returnValue = eglGetSyncAttrib( + (EGLDisplay)dpy_native, + (EGLSync)sync_native, + (EGLint)attribute, + &value + ); + + if (value_base && _returnValue == EGL_TRUE) { + *(value_base + offset) = (jlong) value; + } + +exit: + if (value_base) { + _env->ReleaseLongArrayElements(value_ref, (jlong*)value_base, + _exception ? JNI_ABORT: 0); + } + if (_exception) { + jniThrowException(_env, _exceptionType, _exceptionMessage); + return JNI_FALSE; + } + return (jboolean)_returnValue; +} + /* EGLBoolean eglDestroySync ( EGLDisplay dpy, EGLSync sync ) */ static jboolean android_eglDestroySync @@ -287,56 +359,6 @@ android_eglClientWaitSync return (jint)_returnValue; } -/* EGLBoolean eglGetSyncAttrib ( EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value ) */ -static jboolean -android_eglGetSyncAttrib - (JNIEnv *_env, jobject _this, jobject dpy, jobject sync, jint attribute, jlongArray value_ref, jint offset) { - jint _exception = 0; - const char * _exceptionType = NULL; - const char * _exceptionMessage = NULL; - EGLBoolean _returnValue = (EGLBoolean) 0; - EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy); - EGLSync sync_native = (EGLSync) fromEGLHandle(_env, eglsyncGetHandleID, sync); - EGLAttrib *value_base = (EGLAttrib *) 0; - jint _remaining; - EGLAttrib *value = (EGLAttrib *) 0; - - if (!value_ref) { - _exception = 1; - _exceptionType = "java/lang/IllegalArgumentException"; - _exceptionMessage = "value == null"; - goto exit; - } - if (offset < 0) { - _exception = 1; - _exceptionType = "java/lang/IllegalArgumentException"; - _exceptionMessage = "offset < 0"; - goto exit; - } - _remaining = _env->GetArrayLength(value_ref) - offset; - value_base = (EGLAttrib *) - _env->GetLongArrayElements(value_ref, (jboolean *)0); - value = value_base + offset; - - _returnValue = eglGetSyncAttrib( - (EGLDisplay)dpy_native, - (EGLSync)sync_native, - (EGLint)attribute, - (EGLAttrib *)value - ); - -exit: - if (value_base) { - _env->ReleaseLongArrayElements(value_ref, (jlong*)value_base, - _exception ? JNI_ABORT: 0); - } - if (_exception) { - jniThrowException(_env, _exceptionType, _exceptionMessage); - return JNI_FALSE; - } - return (jboolean)_returnValue; -} - /* EGLDisplay eglGetPlatformDisplay ( EGLenum platform, EGLAttrib native_display, const EGLAttrib *attrib_list ) */ static jobject android_eglGetPlatformDisplay @@ -345,9 +367,9 @@ android_eglGetPlatformDisplay const char * _exceptionType = NULL; const char * _exceptionMessage = NULL; EGLDisplay _returnValue = (EGLDisplay) 0; - EGLAttrib *attrib_list_base = (EGLAttrib *) 0; + jlong *attrib_list_base = (jlong *) 0; jint _remaining; - EGLAttrib *attrib_list = (EGLAttrib *) 0; + WrappedEGLAttribs attrib_list; if (!attrib_list_ref) { _exception = 1; @@ -362,14 +384,14 @@ android_eglGetPlatformDisplay goto exit; } _remaining = _env->GetArrayLength(attrib_list_ref) - offset; - attrib_list_base = (EGLAttrib *) + attrib_list_base = (jlong *) _env->GetLongArrayElements(attrib_list_ref, (jboolean *)0); - attrib_list = attrib_list_base + offset; + attrib_list.init(attrib_list_base + offset, _remaining); _returnValue = eglGetPlatformDisplay( (EGLenum)platform, (void *)native_display, - (EGLAttrib *)attrib_list + attrib_list.attribs ); exit: @@ -398,9 +420,9 @@ android_eglCreatePlatformWindowSurface EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config); jint _native_windowRemaining; void *native_window = (void *) 0; - EGLAttrib *attrib_list_base = (EGLAttrib *) 0; + jlong *attrib_list_base = (jlong *) 0; jint _attrib_listRemaining; - EGLAttrib *attrib_list = (EGLAttrib *) 0; + WrappedEGLAttribs attrib_list; if (!native_window_buf) { _exception = 1; @@ -422,9 +444,9 @@ android_eglCreatePlatformWindowSurface goto exit; } _attrib_listRemaining = _env->GetArrayLength(attrib_list_ref) - offset; - attrib_list_base = (EGLAttrib *) + attrib_list_base = (jlong *) _env->GetLongArrayElements(attrib_list_ref, (jboolean *)0); - attrib_list = attrib_list_base + offset; + attrib_list.init(attrib_list_base + offset, _attrib_listRemaining); if (native_window == NULL) { char * _native_windowBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0); @@ -434,7 +456,7 @@ android_eglCreatePlatformWindowSurface (EGLDisplay)dpy_native, (EGLConfig)config_native, (void *)native_window, - (EGLAttrib *)attrib_list + attrib_list.attribs ); exit: @@ -487,9 +509,9 @@ android_eglCreateImage EGLImage _returnValue = (EGLImage) 0; EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy); EGLContext context_native = (EGLContext) fromEGLHandle(_env, eglcontextGetHandleID, context); - EGLAttrib *attrib_list_base = (EGLAttrib *) 0; + jlong *attrib_list_base = (jlong *) 0; jint _remaining; - EGLAttrib *attrib_list = (EGLAttrib *) 0; + WrappedEGLAttribs attrib_list; if (!attrib_list_ref) { _exception = 1; @@ -504,16 +526,16 @@ android_eglCreateImage goto exit; } _remaining = _env->GetArrayLength(attrib_list_ref) - offset; - attrib_list_base = (EGLAttrib *) + attrib_list_base = (jlong *) _env->GetLongArrayElements(attrib_list_ref, (jboolean *)0); - attrib_list = attrib_list_base + offset; + attrib_list.init(attrib_list_base + offset, _remaining); _returnValue = eglCreateImage( (EGLDisplay)dpy_native, (EGLContext)context_native, (EGLenum)target, (EGLClientBuffer)buffer, - (EGLAttrib *)attrib_list + attrib_list.attribs ); exit: @@ -527,7 +549,6 @@ exit: } return toEGLHandle(_env, eglimageClass, eglimageConstructor, _returnValue); } - /* EGLBoolean eglDestroyImage ( EGLDisplay dpy, EGLImage image ) */ static jboolean android_eglDestroyImage @@ -548,9 +569,9 @@ static const char *classPathName = "android/opengl/EGL15"; static const JNINativeMethod methods[] = { {"_nativeClassInit", "()V", (void*)nativeClassInit }, {"eglCreateSync", "(Landroid/opengl/EGLDisplay;I[JI)Landroid/opengl/EGLSync;", (void *) android_eglCreateSync }, +{"eglGetSyncAttrib", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;I[JI)Z", (void *) android_eglGetSyncAttrib }, {"eglDestroySync", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;)Z", (void *) android_eglDestroySync }, {"eglClientWaitSync", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;IJ)I", (void *) android_eglClientWaitSync }, -{"eglGetSyncAttrib", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;I[JI)Z", (void *) android_eglGetSyncAttrib }, {"eglGetPlatformDisplay", "(IJ[JI)Landroid/opengl/EGLDisplay;", (void *) android_eglGetPlatformDisplay }, {"eglCreatePlatformWindowSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/nio/Buffer;[JI)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePlatformWindowSurface }, {"eglCreatePlatformPixmapSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/nio/Buffer;[JI)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePlatformPixmapSurface }, diff --git a/opengl/java/android/opengl/EGL15.java b/opengl/java/android/opengl/EGL15.java index bd845e7ec1a0b..93acc674a4b72 100644 --- a/opengl/java/android/opengl/EGL15.java +++ b/opengl/java/android/opengl/EGL15.java @@ -85,6 +85,19 @@ public final class EGL15 { int offset ); + /** + * C function EGLBoolean eglGetSyncAttrib ( EGLDisplay dpy, EGLSync sync, EGLint attribute, + * EGLAttrib *value ) + */ + + public static native boolean eglGetSyncAttrib( + EGLDisplay dpy, + EGLSync sync, + int attribute, + long[] value, + int offset + ); + // C function EGLBoolean eglDestroySync ( EGLDisplay dpy, EGLSync sync ) public static native boolean eglDestroySync( @@ -101,16 +114,6 @@ public final class EGL15 { long timeout ); - // C function EGLBoolean eglGetSyncAttrib ( EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value ) - - public static native boolean eglGetSyncAttrib( - EGLDisplay dpy, - EGLSync sync, - int attribute, - long[] value, - int offset - ); - // C function EGLDisplay eglGetPlatformDisplay ( EGLenum platform, EGLAttrib native_display, const EGLAttrib *attrib_list ) public static native EGLDisplay eglGetPlatformDisplay(