GLSurfaceView: remove old implementation, import the one from AOSP

Now that we have a reasonably well working SurfaceView implementation,
it is actually cleaner to just implement GLSurfaceView the way AOSP
does. In fact, their code doesn't have any weird dependencies, and
can mostly be used as-is.

The AOSP code is pure Java, which means we had to implement some
EGL wrappers.

This change fixes issues with Wayland (it only ever worked because
the pbuffers were allocated using an XWayland EGLDisplay), and
with resizing (which we simply didn't support), all while getting
rid of quite some (arguably not very readable) LoC.
This commit is contained in:
Mis012
2023-10-20 20:54:37 +02:00
parent 621cb866c1
commit 9ef2151c5e
19 changed files with 2140 additions and 879 deletions

View File

@@ -3,6 +3,8 @@
#include "../defines.h"
#include "../util.h"
#include "../../libandroid/native_window.h"
#include "../generated_headers/com_google_android_gles_jni_EGLImpl.h"
// helpers from android source (TODO: either use GetIntArrayElements, or figure out if GetPrimitiveArrayCritical is superior and use it everywhere if so)
@@ -67,3 +69,59 @@ JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1egl
return ret;
}
JNIEXPORT jlong JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglCreateWindowSurface(JNIEnv *env, jobject this, jlong display, jlong config, jobject surface, jintArray _attrib_list)
{
struct ANativeWindow *native_window = ANativeWindow_fromSurface(env, surface);
EGLint *attrib_list = get_int_array_crit(env, _attrib_list);
EGLSurface ret = bionic_eglCreateWindowSurface(_PTR(display), _PTR(config), native_window, attrib_list);
release_int_array_crit(env, _attrib_list, attrib_list);
return _INTPTR(ret);
}
JNIEXPORT jlong JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglGetDisplay(JNIEnv *env, jobject this, jobject display)
{
return _INTPTR(bionic_eglGetDisplay(0)); // FIXME: why is display passed as an Object??? how do we get an integer from that
}
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglInitialize(JNIEnv *env, jobject this, jlong display, jintArray _major_minor)
{
EGLint *major_minor = get_int_array_crit(env, _major_minor);
bool ret = eglInitialize(_PTR(display), &major_minor[0], &major_minor[1]);
release_int_array_crit(env, _major_minor, major_minor);
return ret;
}
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglGetConfigAttrib(JNIEnv *env, jobject this, jlong display, jlong config, jint attribute, jintArray _value)
{
EGLint *value = get_int_array_crit(env, _value);
bool ret = eglGetConfigAttrib(_PTR(display), _PTR(config), attribute, &value[0]);
release_int_array_crit(env, _value, value);
return ret;
}
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglMakeCurrent(JNIEnv *env, jobject this, jlong display, jlong draw_surface, jlong read_surface, jlong context)
{
return eglMakeCurrent(_PTR(display), _PTR(draw_surface), _PTR(read_surface), _PTR(context));
}
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglSwapBuffers(JNIEnv *env, jobject this, jlong display, jlong surface)
{
return eglSwapBuffers(_PTR(display), _PTR(surface));
}
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglDestroySurface(JNIEnv *env, jobject this, jlong display, jlong surface)
{
struct ANativeWindow *native_window = g_hash_table_lookup(egl_surface_hashtable, _PTR(surface));
bool ret = eglDestroySurface(_PTR(display), _PTR(surface));
/* ANativeWindow_fromSurface starts the refcounter at 1, so this will destroy the native window */
ANativeWindow_release(native_window);
return ret;
}
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglDestroyContext(JNIEnv *env, jobject this, jlong display, jlong context)
{
return eglDestroyContext(_PTR(display), _PTR(context));
}

View File

@@ -1,221 +0,0 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class android_opengl_GLSurfaceView */
#ifndef _Included_android_opengl_GLSurfaceView
#define _Included_android_opengl_GLSurfaceView
#ifdef __cplusplus
extern "C" {
#endif
#undef android_opengl_GLSurfaceView_NO_ID
#define android_opengl_GLSurfaceView_NO_ID -1L
#undef android_opengl_GLSurfaceView_NOT_FOCUSABLE
#define android_opengl_GLSurfaceView_NOT_FOCUSABLE 0L
#undef android_opengl_GLSurfaceView_FOCUSABLE
#define android_opengl_GLSurfaceView_FOCUSABLE 1L
#undef android_opengl_GLSurfaceView_FOCUSABLE_MASK
#define android_opengl_GLSurfaceView_FOCUSABLE_MASK 1L
#undef android_opengl_GLSurfaceView_FITS_SYSTEM_WINDOWS
#define android_opengl_GLSurfaceView_FITS_SYSTEM_WINDOWS 2L
#undef android_opengl_GLSurfaceView_VISIBLE
#define android_opengl_GLSurfaceView_VISIBLE 0L
#undef android_opengl_GLSurfaceView_INVISIBLE
#define android_opengl_GLSurfaceView_INVISIBLE 4L
#undef android_opengl_GLSurfaceView_GONE
#define android_opengl_GLSurfaceView_GONE 8L
#undef android_opengl_GLSurfaceView_VISIBILITY_MASK
#define android_opengl_GLSurfaceView_VISIBILITY_MASK 12L
#undef android_opengl_GLSurfaceView_ENABLED
#define android_opengl_GLSurfaceView_ENABLED 0L
#undef android_opengl_GLSurfaceView_DISABLED
#define android_opengl_GLSurfaceView_DISABLED 32L
#undef android_opengl_GLSurfaceView_ENABLED_MASK
#define android_opengl_GLSurfaceView_ENABLED_MASK 32L
#undef android_opengl_GLSurfaceView_WILL_NOT_DRAW
#define android_opengl_GLSurfaceView_WILL_NOT_DRAW 128L
#undef android_opengl_GLSurfaceView_DRAW_MASK
#define android_opengl_GLSurfaceView_DRAW_MASK 128L
#undef android_opengl_GLSurfaceView_SCROLLBARS_NONE
#define android_opengl_GLSurfaceView_SCROLLBARS_NONE 0L
#undef android_opengl_GLSurfaceView_SCROLLBARS_HORIZONTAL
#define android_opengl_GLSurfaceView_SCROLLBARS_HORIZONTAL 256L
#undef android_opengl_GLSurfaceView_SCROLLBARS_VERTICAL
#define android_opengl_GLSurfaceView_SCROLLBARS_VERTICAL 512L
#undef android_opengl_GLSurfaceView_SCROLLBARS_MASK
#define android_opengl_GLSurfaceView_SCROLLBARS_MASK 768L
#undef android_opengl_GLSurfaceView_FILTER_TOUCHES_WHEN_OBSCURED
#define android_opengl_GLSurfaceView_FILTER_TOUCHES_WHEN_OBSCURED 1024L
#undef android_opengl_GLSurfaceView_OPTIONAL_FITS_SYSTEM_WINDOWS
#define android_opengl_GLSurfaceView_OPTIONAL_FITS_SYSTEM_WINDOWS 2048L
#undef android_opengl_GLSurfaceView_FADING_EDGE_NONE
#define android_opengl_GLSurfaceView_FADING_EDGE_NONE 0L
#undef android_opengl_GLSurfaceView_FADING_EDGE_HORIZONTAL
#define android_opengl_GLSurfaceView_FADING_EDGE_HORIZONTAL 4096L
#undef android_opengl_GLSurfaceView_FADING_EDGE_VERTICAL
#define android_opengl_GLSurfaceView_FADING_EDGE_VERTICAL 8192L
#undef android_opengl_GLSurfaceView_FADING_EDGE_MASK
#define android_opengl_GLSurfaceView_FADING_EDGE_MASK 12288L
#undef android_opengl_GLSurfaceView_CLICKABLE
#define android_opengl_GLSurfaceView_CLICKABLE 16384L
#undef android_opengl_GLSurfaceView_DRAWING_CACHE_ENABLED
#define android_opengl_GLSurfaceView_DRAWING_CACHE_ENABLED 32768L
#undef android_opengl_GLSurfaceView_SAVE_DISABLED
#define android_opengl_GLSurfaceView_SAVE_DISABLED 65536L
#undef android_opengl_GLSurfaceView_SAVE_DISABLED_MASK
#define android_opengl_GLSurfaceView_SAVE_DISABLED_MASK 65536L
#undef android_opengl_GLSurfaceView_WILL_NOT_CACHE_DRAWING
#define android_opengl_GLSurfaceView_WILL_NOT_CACHE_DRAWING 131072L
#undef android_opengl_GLSurfaceView_FOCUSABLE_IN_TOUCH_MODE
#define android_opengl_GLSurfaceView_FOCUSABLE_IN_TOUCH_MODE 262144L
#undef android_opengl_GLSurfaceView_DRAWING_CACHE_QUALITY_LOW
#define android_opengl_GLSurfaceView_DRAWING_CACHE_QUALITY_LOW 524288L
#undef android_opengl_GLSurfaceView_DRAWING_CACHE_QUALITY_HIGH
#define android_opengl_GLSurfaceView_DRAWING_CACHE_QUALITY_HIGH 1048576L
#undef android_opengl_GLSurfaceView_DRAWING_CACHE_QUALITY_AUTO
#define android_opengl_GLSurfaceView_DRAWING_CACHE_QUALITY_AUTO 0L
#undef android_opengl_GLSurfaceView_DRAWING_CACHE_QUALITY_MASK
#define android_opengl_GLSurfaceView_DRAWING_CACHE_QUALITY_MASK 1572864L
#undef android_opengl_GLSurfaceView_LONG_CLICKABLE
#define android_opengl_GLSurfaceView_LONG_CLICKABLE 2097152L
#undef android_opengl_GLSurfaceView_DUPLICATE_PARENT_STATE
#define android_opengl_GLSurfaceView_DUPLICATE_PARENT_STATE 4194304L
#undef android_opengl_GLSurfaceView_SCROLLBARS_INSIDE_OVERLAY
#define android_opengl_GLSurfaceView_SCROLLBARS_INSIDE_OVERLAY 0L
#undef android_opengl_GLSurfaceView_SCROLLBARS_INSIDE_INSET
#define android_opengl_GLSurfaceView_SCROLLBARS_INSIDE_INSET 16777216L
#undef android_opengl_GLSurfaceView_SCROLLBARS_OUTSIDE_OVERLAY
#define android_opengl_GLSurfaceView_SCROLLBARS_OUTSIDE_OVERLAY 33554432L
#undef android_opengl_GLSurfaceView_SCROLLBARS_OUTSIDE_INSET
#define android_opengl_GLSurfaceView_SCROLLBARS_OUTSIDE_INSET 50331648L
#undef android_opengl_GLSurfaceView_SCROLLBARS_INSET_MASK
#define android_opengl_GLSurfaceView_SCROLLBARS_INSET_MASK 16777216L
#undef android_opengl_GLSurfaceView_SCROLLBARS_OUTSIDE_MASK
#define android_opengl_GLSurfaceView_SCROLLBARS_OUTSIDE_MASK 33554432L
#undef android_opengl_GLSurfaceView_SCROLLBARS_STYLE_MASK
#define android_opengl_GLSurfaceView_SCROLLBARS_STYLE_MASK 50331648L
#undef android_opengl_GLSurfaceView_KEEP_SCREEN_ON
#define android_opengl_GLSurfaceView_KEEP_SCREEN_ON 67108864L
#undef android_opengl_GLSurfaceView_SOUND_EFFECTS_ENABLED
#define android_opengl_GLSurfaceView_SOUND_EFFECTS_ENABLED 134217728L
#undef android_opengl_GLSurfaceView_HAPTIC_FEEDBACK_ENABLED
#define android_opengl_GLSurfaceView_HAPTIC_FEEDBACK_ENABLED 268435456L
#undef android_opengl_GLSurfaceView_PARENT_SAVE_DISABLED
#define android_opengl_GLSurfaceView_PARENT_SAVE_DISABLED 536870912L
#undef android_opengl_GLSurfaceView_PARENT_SAVE_DISABLED_MASK
#define android_opengl_GLSurfaceView_PARENT_SAVE_DISABLED_MASK 536870912L
#undef android_opengl_GLSurfaceView_FOCUSABLES_ALL
#define android_opengl_GLSurfaceView_FOCUSABLES_ALL 0L
#undef android_opengl_GLSurfaceView_FOCUSABLES_TOUCH_MODE
#define android_opengl_GLSurfaceView_FOCUSABLES_TOUCH_MODE 1L
#undef android_opengl_GLSurfaceView_FOCUS_BACKWARD
#define android_opengl_GLSurfaceView_FOCUS_BACKWARD 1L
#undef android_opengl_GLSurfaceView_FOCUS_FORWARD
#define android_opengl_GLSurfaceView_FOCUS_FORWARD 2L
#undef android_opengl_GLSurfaceView_FOCUS_LEFT
#define android_opengl_GLSurfaceView_FOCUS_LEFT 17L
#undef android_opengl_GLSurfaceView_FOCUS_UP
#define android_opengl_GLSurfaceView_FOCUS_UP 33L
#undef android_opengl_GLSurfaceView_FOCUS_RIGHT
#define android_opengl_GLSurfaceView_FOCUS_RIGHT 66L
#undef android_opengl_GLSurfaceView_FOCUS_DOWN
#define android_opengl_GLSurfaceView_FOCUS_DOWN 130L
#undef android_opengl_GLSurfaceView_MEASURED_SIZE_MASK
#define android_opengl_GLSurfaceView_MEASURED_SIZE_MASK 16777215L
#undef android_opengl_GLSurfaceView_MEASURED_STATE_MASK
#define android_opengl_GLSurfaceView_MEASURED_STATE_MASK -16777216L
#undef android_opengl_GLSurfaceView_MEASURED_HEIGHT_STATE_SHIFT
#define android_opengl_GLSurfaceView_MEASURED_HEIGHT_STATE_SHIFT 16L
#undef android_opengl_GLSurfaceView_MEASURED_STATE_TOO_SMALL
#define android_opengl_GLSurfaceView_MEASURED_STATE_TOO_SMALL 16777216L
#undef android_opengl_GLSurfaceView_PFLAG2_DRAG_CAN_ACCEPT
#define android_opengl_GLSurfaceView_PFLAG2_DRAG_CAN_ACCEPT 1L
#undef android_opengl_GLSurfaceView_PFLAG2_DRAG_HOVERED
#define android_opengl_GLSurfaceView_PFLAG2_DRAG_HOVERED 2L
#undef android_opengl_GLSurfaceView_LAYOUT_DIRECTION_LTR
#define android_opengl_GLSurfaceView_LAYOUT_DIRECTION_LTR 0L
#undef android_opengl_GLSurfaceView_LAYOUT_DIRECTION_RTL
#define android_opengl_GLSurfaceView_LAYOUT_DIRECTION_RTL 1L
#undef android_opengl_GLSurfaceView_LAYOUT_DIRECTION_INHERIT
#define android_opengl_GLSurfaceView_LAYOUT_DIRECTION_INHERIT 2L
#undef android_opengl_GLSurfaceView_LAYOUT_DIRECTION_LOCALE
#define android_opengl_GLSurfaceView_LAYOUT_DIRECTION_LOCALE 3L
#undef android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT
#define android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT 2L
#undef android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_MASK
#define android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_MASK 12L
#undef android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL
#define android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL 16L
#undef android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_RESOLVED
#define android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_RESOLVED 32L
#undef android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK
#define android_opengl_GLSurfaceView_PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK 48L
#undef android_opengl_GLSurfaceView_STATUS_BAR_HIDDEN
#define android_opengl_GLSurfaceView_STATUS_BAR_HIDDEN 1L
#undef android_opengl_GLSurfaceView_STATUS_BAR_VISIBLE
#define android_opengl_GLSurfaceView_STATUS_BAR_VISIBLE 0L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_FULLSCREEN
#define android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_FULLSCREEN 4L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_HIDE_NAVIGATION
#define android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_HIDE_NAVIGATION 2L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_IMMERSIVE
#define android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_IMMERSIVE 2048L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_IMMERSIVE_STICKY
#define android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_IMMERSIVE_STICKY 4096L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
#define android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 1024L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
#define android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 512L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_LAYOUT_STABLE
#define android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_LAYOUT_STABLE 256L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_LOW_PROFILE
#define android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_LOW_PROFILE 1L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_VISIBLE
#define android_opengl_GLSurfaceView_SYSTEM_UI_FLAG_VISIBLE 0L
#undef android_opengl_GLSurfaceView_SYSTEM_UI_LAYOUT_FLAGS
#define android_opengl_GLSurfaceView_SYSTEM_UI_LAYOUT_FLAGS 1536L
#undef android_opengl_GLSurfaceView_TEXT_ALIGNMENT_CENTER
#define android_opengl_GLSurfaceView_TEXT_ALIGNMENT_CENTER 4L
#undef android_opengl_GLSurfaceView_TEXT_ALIGNMENT_GRAVITY
#define android_opengl_GLSurfaceView_TEXT_ALIGNMENT_GRAVITY 1L
#undef android_opengl_GLSurfaceView_TEXT_ALIGNMENT_INHERIT
#define android_opengl_GLSurfaceView_TEXT_ALIGNMENT_INHERIT 0L
#undef android_opengl_GLSurfaceView_TEXT_ALIGNMENT_TEXT_END
#define android_opengl_GLSurfaceView_TEXT_ALIGNMENT_TEXT_END 3L
#undef android_opengl_GLSurfaceView_TEXT_ALIGNMENT_TEXT_START
#define android_opengl_GLSurfaceView_TEXT_ALIGNMENT_TEXT_START 2L
#undef android_opengl_GLSurfaceView_TEXT_ALIGNMENT_VIEW_END
#define android_opengl_GLSurfaceView_TEXT_ALIGNMENT_VIEW_END 6L
#undef android_opengl_GLSurfaceView_TEXT_ALIGNMENT_VIEW_START
#define android_opengl_GLSurfaceView_TEXT_ALIGNMENT_VIEW_START 5L
#undef android_opengl_GLSurfaceView_TEXT_DIRECTION_ANY_RTL
#define android_opengl_GLSurfaceView_TEXT_DIRECTION_ANY_RTL 2L
#undef android_opengl_GLSurfaceView_TEXT_DIRECTION_FIRST_STRONG
#define android_opengl_GLSurfaceView_TEXT_DIRECTION_FIRST_STRONG 1L
#undef android_opengl_GLSurfaceView_TEXT_DIRECTION_INHERIT
#define android_opengl_GLSurfaceView_TEXT_DIRECTION_INHERIT 0L
#undef android_opengl_GLSurfaceView_TEXT_DIRECTION_LOCALE
#define android_opengl_GLSurfaceView_TEXT_DIRECTION_LOCALE 5L
#undef android_opengl_GLSurfaceView_TEXT_DIRECTION_LTR
#define android_opengl_GLSurfaceView_TEXT_DIRECTION_LTR 3L
#undef android_opengl_GLSurfaceView_TEXT_DIRECTION_RTL
#define android_opengl_GLSurfaceView_TEXT_DIRECTION_RTL 4L
/*
* Class: android_opengl_GLSurfaceView
* Method: native_constructor
* Signature: (Landroid/content/Context;Landroid/util/AttributeSet;)J
*/
JNIEXPORT jlong JNICALL Java_android_opengl_GLSurfaceView_native_1constructor
(JNIEnv *, jobject, jobject, jobject);
/*
* Class: android_opengl_GLSurfaceView
* Method: native_set_renderer
* Signature: (Landroid/opengl/GLSurfaceView/Renderer;)V
*/
JNIEXPORT void JNICALL Java_android_opengl_GLSurfaceView_native_1set_1renderer
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -23,6 +23,70 @@ JNIEXPORT jlong JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglCre
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglChooseConfig
(JNIEnv *, jobject, jlong, jintArray, jlongArray, jint, jintArray);
/*
* Class: com_google_android_gles_jni_EGLImpl
* Method: native_eglCreateWindowSurface
* Signature: (JJLandroid/view/Surface;[I)J
*/
JNIEXPORT jlong JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglCreateWindowSurface
(JNIEnv *, jobject, jlong, jlong, jobject, jintArray);
/*
* Class: com_google_android_gles_jni_EGLImpl
* Method: native_eglGetDisplay
* Signature: (Ljava/lang/Object;)J
*/
JNIEXPORT jlong JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglGetDisplay
(JNIEnv *, jobject, jobject);
/*
* Class: com_google_android_gles_jni_EGLImpl
* Method: native_eglInitialize
* Signature: (J[I)Z
*/
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglInitialize
(JNIEnv *, jobject, jlong, jintArray);
/*
* Class: com_google_android_gles_jni_EGLImpl
* Method: native_eglGetConfigAttrib
* Signature: (JJI[I)Z
*/
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglGetConfigAttrib
(JNIEnv *, jobject, jlong, jlong, jint, jintArray);
/*
* Class: com_google_android_gles_jni_EGLImpl
* Method: native_eglMakeCurrent
* Signature: (JJJJ)Z
*/
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglMakeCurrent
(JNIEnv *, jobject, jlong, jlong, jlong, jlong);
/*
* Class: com_google_android_gles_jni_EGLImpl
* Method: native_eglSwapBuffers
* Signature: (JJ)Z
*/
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglSwapBuffers
(JNIEnv *, jobject, jlong, jlong);
/*
* Class: com_google_android_gles_jni_EGLImpl
* Method: native_eglDestroySurface
* Signature: (JJ)Z
*/
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglDestroySurface
(JNIEnv *, jobject, jlong, jlong);
/*
* Class: com_google_android_gles_jni_EGLImpl
* Method: native_eglDestroyContext
* Signature: (JJ)Z
*/
JNIEXPORT jboolean JNICALL Java_com_google_android_gles_1jni_EGLImpl_native_1eglDestroyContext
(JNIEnv *, jobject, jlong, jlong);
#ifdef __cplusplus
}
#endif

View File

@@ -87,24 +87,15 @@ void set_up_handle_cache(JNIEnv *env)
handle_cache.canvas.class = _REF((*env)->FindClass(env, "android/graphics/Canvas"));
handle_cache.canvas.constructor = _METHOD(handle_cache.canvas.class, "<init>", "(JJ)V");
handle_cache.renderer.class = _REF((*env)->FindClass(env, "android/opengl/GLSurfaceView$Renderer"));
handle_cache.renderer.onSurfaceCreated = _METHOD(handle_cache.renderer.class, "onSurfaceCreated", "(Ljavax/microedition/khronos/opengles/GL10;Ljavax/microedition/khronos/egl/EGLConfig;)V");
handle_cache.renderer.onSurfaceChanged = _METHOD(handle_cache.renderer.class, "onSurfaceChanged", "(Ljavax/microedition/khronos/opengles/GL10;II)V");
handle_cache.renderer.onDrawFrame = _METHOD(handle_cache.renderer.class, "onDrawFrame", "(Ljavax/microedition/khronos/opengles/GL10;)V");
handle_cache.gl_surface_view.class = _REF((*env)->FindClass(env, "android/opengl/GLSurfaceView"));
handle_cache.gl_surface_view.onTouchEvent = _METHOD(handle_cache.gl_surface_view.class, "onTouchEvent", "(Landroid/view/MotionEvent;)Z");
handle_cache.gl_surface_view.wrap_EGLContextFactory_createContext = _METHOD(handle_cache.gl_surface_view.class, "wrap_EGLContextFactory_createContext", "(JJ)J");
handle_cache.gl_surface_view.wrap_EGLConfigChooser_chooseConfig = _METHOD(handle_cache.gl_surface_view.class, "wrap_EGLConfigChooser_chooseConfig", "(J)J");
handle_cache.audio_track_periodic_listener.class = _REF((*env)->FindClass(env, "android/media/AudioTrack$OnPlaybackPositionUpdateListener"));
handle_cache.audio_track_periodic_listener.onPeriodicNotification = _METHOD(handle_cache.audio_track_periodic_listener.class, "onPeriodicNotification", "(Landroid/media/AudioTrack;)V");
handle_cache.input_queue_callback.class = _REF((*env)->FindClass(env, "android/view/InputQueue$Callback"));
handle_cache.input_queue_callback.onInputQueueCreated = _METHOD(handle_cache.input_queue_callback.class, "onInputQueueCreated", "(Landroid/view/InputQueue;)V");
handle_cache.surface_holder_callback.class = _REF((*env)->FindClass(env, "android/view/SurfaceHolder$Callback"));
handle_cache.surface_holder_callback.surfaceCreated = _METHOD(handle_cache.surface_holder_callback.class, "surfaceCreated", "(Landroid/view/SurfaceHolder;)V");
handle_cache.surface_view.class = _REF((*env)->FindClass(env, "android/view/SurfaceView"));
handle_cache.surface_view.surfaceCreated = _METHOD(handle_cache.surface_view.class, "surfaceCreated", "()V");
handle_cache.surface_view.surfaceChanged = _METHOD(handle_cache.surface_view.class, "surfaceChanged", "(III)V");
handle_cache.view.class = _REF((*env)->FindClass(env, "android/view/View"));
if((*env)->ExceptionCheck(env))

View File

@@ -41,18 +41,6 @@ struct handle_cache {
jclass class;
jmethodID constructor;
} canvas;
struct {
jclass class;
jmethodID onSurfaceCreated;
jmethodID onSurfaceChanged;
jmethodID onDrawFrame;
} renderer;
struct {
jclass class;
jmethodID onTouchEvent;
jmethodID wrap_EGLContextFactory_createContext;
jmethodID wrap_EGLConfigChooser_chooseConfig;
} gl_surface_view;
struct {
jclass class;
jmethodID onPeriodicNotification;
@@ -64,7 +52,8 @@ struct handle_cache {
struct {
jclass class;
jmethodID surfaceCreated;
} surface_holder_callback;
jmethodID surfaceChanged;
} surface_view;
struct {
jclass class;
jmethodID setLayoutParams;

View File

@@ -65,7 +65,6 @@ static gboolean on_event(GtkEventControllerLegacy *event_controller, GdkEvent *e
if(d->num_clicks == 0)
break;
case GDK_TOUCH_UPDATE:
printf("d->num_clicks: %u\n", d->num_clicks);
gdk_event_get_widget_relative_position(event, widget, &x, &y);
call_ontouch_callback(MOTION_EVENT_ACTION_MOVE, x, y, d);
break;

View File

@@ -1,498 +0,0 @@
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glcorearb.h>
#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#include <gtk/gtk.h>
#ifdef GDK_WINDOWING_WAYLAND
#include <gdk/wayland/gdkwayland.h>
#endif
#include "../defines.h"
#include "../util.h"
#include "WrapperWidget.h"
#include "../generated_headers/android_opengl_GLSurfaceView.h"
#define SOURCE_TOUCHSCREEN 4098
// for whatever reason, some Mesa builds don't export the OES function (which we use in order to have GLESv1 support)
GL_APICALL void GL_APIENTRY _glEGLImageTargetTexture2DOES_load(GLenum target, GLeglImageOES image);
static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC _glEGLImageTargetTexture2DOES = &_glEGLImageTargetTexture2DOES_load;
GL_APICALL void GL_APIENTRY _glEGLImageTargetTexture2DOES_load(GLenum target, GLeglImageOES image)
{
_glEGLImageTargetTexture2DOES =
(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
_glEGLImageTargetTexture2DOES(target, image);
}
GL_APICALL void GL_APIENTRY __attribute__((weak)) glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
{
_glEGLImageTargetTexture2DOES(target, image);
}
// end of OES workaround
//#define FIXME__WIDTH 540
//#define FIXME__HEIGHT 960
// FIXME: what do we do here? we should probably take these from the size of the GLArea, but how do we change the sizes of all the textures and buffers etc when the GLArea changes size?
// for now, borrow the initial app window width/height
extern int FIXME__WIDTH;
extern int FIXME__HEIGHT;
// mainly frame markers (very obtrusive, not recommended for most builds)
#ifdef DEBUG_GLAREA
#define d_printf(...) printf(__VA_ARGS__)
#else
#define d_printf(...)
#endif
#define ___GL_TRACE___(message) glDebugMessageInsert(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_MARKER, 0xdeadbeef, GL_DEBUG_SEVERITY_NOTIFICATION, strlen(message), message)
JNIEXPORT jlong JNICALL Java_android_opengl_GLSurfaceView_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
{
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
gtk_widget_set_vexpand(wrapper, TRUE);
GtkWidget *gl_area = gtk_gl_area_new();
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), gl_area);
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);
return _INTPTR(gl_area);
}
//two triangles put together to make a square
const float positions[] = {
-1, -1, 0,
-1, 1, 0,
1, -1, 0,
1, -1, 0,
-1, 1, 0,
1, 1, 0
};
const char *vertexStr = "#version 320 es\n"
"in vec3 pos;\n"
"out vec2 texCoords;\n"
"void main(){\n"
" texCoords = vec2(pos.x, pos.y);\n"
" gl_Position = vec4((pos.x * 2.0) - 1.0, (pos.y * 2.0) - 1.0, pos.z, 1.0);\n"
"}\n";
const char *fragmentStr = "#version 320 es\n"
"out highp vec4 outputColor;\n"
"in highp vec2 texCoords;\n"
"uniform sampler2D texSampler;\n"
"void main(){\n"
" outputColor = texture(texSampler, texCoords);\n"
"}\n";
struct render_priv {
GLuint program;
GLuint vao;
int texUnit;
GLuint texBufferdObject;
GLuint sampler;
/* --- */
EGLSurface eglSurface;
EGLContext eglContext;
GLuint FramebufferName;
GLuint renderedTexture;
GLuint texture_id;
EGLImage egl_image;
};
static void check_shader_compile_error(GLuint shader)
{
GLint compileResult;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
if(compileResult != GL_TRUE) {
GLint log_size = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_size);
GLchar *info_log = malloc(log_size);
glGetShaderInfoLog(shader, log_size, &log_size, info_log);
fprintf(stderr, "\nError compiling one of the shaders used by GLSurfaceView:\n%s\n---\nsince this error shouldn't ever happen, we fail hard\n", info_log);
free(info_log);
exit(1);
}
}
static void check_program_link_error(GLuint program)
{
GLint link_status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &link_status);
if(link_status != GL_TRUE) {
GLint log_size = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_size);
GLchar *info_log = malloc(log_size);
glGetProgramInfoLog(program, log_size, &log_size, info_log);
fprintf(stderr, "\nError linking the program used by GLSurfaceView:\n%s\n---\nsince this error shouldn't ever happen, we fail hard\n", info_log);
free(info_log);
exit(1);
}
}
#define check_egl_error() \
do { \
EGLint error_ = eglGetError(); \
if(error_ != EGL_SUCCESS) \
fprintf(stderr, "\nError in %s (%s:%d): \n" \
"eglGetError reported 0x%x\n" \
"this might be because we need to implement more stuff, so we will continue from here\n", \
__func__, __FILE__, __LINE__, error_); \
} while(0)
// TODO: use this where appropriate
#define check_gl_error() \
do { \
GLenum error_ = glGetError(); \
if(error_ != GL_NO_ERROR) \
fprintf(stderr, "\nError in %s (%s:%d): \n" \
"glGetError reported 0x%x\n" \
"this might be because we need to implement more stuff, so we will continue from here\n", \
__func__, __FILE__, __LINE__, error_); \
} while(0)
struct jni_gl_callback_data { JavaVM *jvm; jobject this; jobject renderer; bool first_time;};
static void on_realize(GtkGLArea *gl_area, struct jni_gl_callback_data *d)
{
// ---
// compensate for offset between the widget coordinates and the surface coordinates
double off_x;
double off_y;
GtkWidget *window = GTK_WIDGET(gtk_widget_get_native(gl_area));
gtk_native_get_surface_transform(GTK_NATIVE(window), &off_x, &off_y);
FIXME__WIDTH -= off_x;
FIXME__HEIGHT -= off_y;
// ---
gtk_gl_area_make_current(gl_area);
struct render_priv *render_priv = g_object_get_data(G_OBJECT(gl_area), "render_priv");
JNIEnv *env;
(*d->jvm)->GetEnv(d->jvm, (void**)&env, JNI_VERSION_1_6);
EGLNativeDisplayType display_id = EGL_DEFAULT_DISPLAY;
#ifdef GDK_WINDOWING_WAYLAND
GdkDisplay *gdk_dpy = gdk_display_get_default();
if (GDK_IS_WAYLAND_DISPLAY(gdk_dpy)) {
display_id = (EGLNativeDisplayType)gdk_wayland_display_get_wl_display(gdk_dpy);
}
#endif
EGLDisplay eglDisplay = eglGetDisplay(display_id);
EGLDisplay old_eglDisplay = eglGetCurrentDisplay();
d_printf("GTK version: >%d__%d__%d<\n", gtk_get_major_version(), gtk_get_minor_version(), gtk_get_micro_version());
d_printf("OpenGL version: >%s<\n", glGetString(GL_VERSION));
glGenTextures(1, &render_priv->texture_id);
// vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexStr, NULL);
glCompileShader(vertexShader);
check_shader_compile_error(vertexShader);
// fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentStr, NULL);
glCompileShader(fragmentShader);
check_shader_compile_error(fragmentShader);
// program
render_priv->program = glCreateProgram();
glAttachShader(render_priv->program, vertexShader);
glAttachShader(render_priv->program, fragmentShader);
glLinkProgram(render_priv->program);
check_program_link_error(render_priv->program);
glUseProgram(render_priv->program);
// the triangles
glGenVertexArrays(1, &render_priv->vao);
glBindVertexArray(render_priv->vao);
GLuint positionBufferObject;
glGenBuffers(1, &positionBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*6*3,positions, GL_STREAM_DRAW);
GLuint posIndex = glGetAttribLocation(render_priv->program, "pos");
glEnableVertexAttribArray(posIndex);
glVertexAttribPointer(posIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glUseProgram(0);
glUseProgram(render_priv->program);
// the texture we will be rendering to
glGenTextures(1, &render_priv->texBufferdObject);
glBindTexture(GL_TEXTURE_2D, render_priv->texBufferdObject);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// texture sampler for our triangles
glGenSamplers(1, &render_priv->sampler);
glSamplerParameteri(render_priv->sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameteri(render_priv->sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(render_priv->sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GLuint samplerUniform = glGetUniformLocation(render_priv->program, "texSampler");
glUniform1i(samplerUniform, render_priv->texUnit);
glUseProgram(0);
// EGL setup
eglInitialize(eglDisplay, 0, 0);
eglBindAPI(EGL_OPENGL_ES_API);
EGLConfig eglConfig;
// a roundabout way to let the app define the parameter list, and then choose the best fit out of all the returned configs
eglConfig = (EGLConfig)_PTR((*env)->CallLongMethod(env, d->this, handle_cache.gl_surface_view.wrap_EGLConfigChooser_chooseConfig, _INTPTR(eglDisplay)));
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
check_egl_error();
// set up the pbuffer (TODO: is there any way to dynamically change the width/height?)
EGLint pbufferAttribs[5];
pbufferAttribs[0] = EGL_WIDTH;
pbufferAttribs[1] = FIXME__WIDTH;
pbufferAttribs[2] = EGL_HEIGHT;
pbufferAttribs[3] = FIXME__HEIGHT;
pbufferAttribs[4] = EGL_NONE;
render_priv->eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs);
check_egl_error();
// a roundabout way to run eglCreateContext with the atrribute list that the app chose
render_priv->eglContext = (EGLContext)_PTR((*env)->CallLongMethod(env, d->this, handle_cache.gl_surface_view.wrap_EGLContextFactory_createContext, _INTPTR(eglDisplay), _INTPTR(eglConfig)));
check_egl_error();
// save the EGL state before we change it, so we can switch back later
EGLContext old_eglContext = eglGetCurrentContext();
EGLSurface old_read_surface = eglGetCurrentSurface(EGL_READ);
EGLSurface old_draw_surface = eglGetCurrentSurface(EGL_DRAW);
bool result = eglMakeCurrent(eglDisplay, render_priv->eglSurface, render_priv->eglSurface, render_priv->eglContext);
check_egl_error();
// set up the framebuffer
glGenFramebuffers(1, &render_priv->FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, render_priv->FramebufferName);
check_gl_error();
glGenTextures(1, &render_priv->renderedTexture);
glBindTexture(GL_TEXTURE_2D, render_priv->renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, FIXME__WIDTH, FIXME__HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
check_gl_error();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
check_gl_error();
GLuint depthrenderbuffer;
glGenRenderbuffers(1, &depthrenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, FIXME__WIDTH, FIXME__HEIGHT);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer);
check_gl_error();
// Set "renderedTexture" as our colour attachement #0
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_priv->renderedTexture, 0);
check_gl_error();
// Set the list of draw buffers.
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
check_gl_error();
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
fprintf(stderr, "Error: glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE\n");
// create the EGL Image which we will use to access the rendered-to texture from Gtk's EGL context
render_priv->egl_image = eglCreateImage(eglDisplay, render_priv->eglContext, EGL_GL_TEXTURE_2D, (EGLClientBuffer)(intptr_t)render_priv->renderedTexture, NULL);
check_egl_error();
// the GLSurfaceView implements SurfaceHolder.Callback, and the app may expect that we call the `surfaceCreated` method
(*env)->CallVoidMethod(env, d->this, handle_cache.surface_holder_callback.surfaceCreated, NULL);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
// Here we call the app's onSurfaceCreated callback. This is the android API's equivalent of the `realize` callback that we are currently in.
___GL_TRACE___("---- calling onSurfaceCreated");
(*env)->CallVoidMethod(env, d->renderer, handle_cache.renderer.onSurfaceCreated, _GET_OBJ_FIELD(d->this, "java_gl_wrapper", "Ljavax/microedition/khronos/opengles/GL10;"), NULL); // FIXME passing NULL only works if the app doesn't use these parameters
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
___GL_TRACE___("---- returned from calling onSurfaceCreated");
// This should be called from Gtk's `resize` callback. However, until we figure out how to resize the pbuffer, the framebuffer, and the texture, we can't afford to pass the actual widget's dimensions here
___GL_TRACE___("---- calling onSurfaceChanged");
(*env)->CallVoidMethod(env, d->renderer, handle_cache.renderer.onSurfaceChanged, NULL, FIXME__WIDTH, FIXME__HEIGHT); // FIXME put this in the right callback (and pass the actual dimensions)
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
___GL_TRACE___("---- returned from calling onSurfaceChanged");
// restore the EGL context so that Gtk doesn't get confused
result = eglMakeCurrent(old_eglDisplay, old_read_surface, old_draw_surface, old_eglContext);
check_egl_error();
}
static gboolean render(GtkGLArea *gl_area, GdkGLContext *context, struct jni_gl_callback_data *d)
{
struct render_priv *render_priv = g_object_get_data(G_OBJECT(gl_area), "render_priv");
JNIEnv *env;
(*d->jvm)->GetEnv(d->jvm, (void**)&env, JNI_VERSION_1_6);
EGLNativeDisplayType display_id = EGL_DEFAULT_DISPLAY;
#ifdef GDK_WINDOWING_WAYLAND
GdkDisplay *gdk_dpy = gdk_display_get_default();
if (GDK_IS_WAYLAND_DISPLAY(gdk_dpy)) {
display_id = (EGLNativeDisplayType)gdk_wayland_display_get_wl_display(gdk_dpy);
}
#endif
EGLDisplay eglDisplay = eglGetDisplay(display_id);
EGLDisplay old_eglDisplay = eglGetCurrentDisplay();
// save the EGL state before we change it, so we can switch back later
EGLContext old_eglContext = eglGetCurrentContext();
EGLSurface old_read_surface = eglGetCurrentSurface(EGL_READ);
EGLSurface old_draw_surface = eglGetCurrentSurface(EGL_DRAW);
bool result = eglMakeCurrent(eglDisplay, render_priv->eglSurface, render_priv->eglSurface, render_priv->eglContext);
check_egl_error();
// bind the framebuffer that we are rendering into
check_gl_error();
glBindFramebuffer(GL_FRAMEBUFFER, render_priv->FramebufferName);
check_gl_error();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_priv->renderedTexture, 0);
check_gl_error();
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
fprintf(stderr, "Error: glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE\n");
d_printf("OpenGL version before calling onDrawFrame: >%s<\n", glGetString(GL_VERSION));
d_printf("\n\n\n---- calling onDrawFrame\n\n");
// this marks the part where the app is doing the rendering (as opposed to Gtk) for easier orientation in a trace (e.g apitrace)
// TODO: make a program that extracts just these fragments from a trace
// TODO: add a unique identifier of this GLArea (worst case the pointer to this widget)
check_gl_error();
___GL_TRACE___("---- calling onDrawFrame");
// Here we call the app's onDrawFrame callback. This is the android API's equivalent of the `render` callback that we are currently in.
(*env)->CallVoidMethod(env, d->renderer, handle_cache.renderer.onDrawFrame, NULL); // FIXME passing NULL only works if the app doesn't use this parameter
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
___GL_TRACE___("---- returned from calling onDrawFrame");
check_gl_error();
d_printf("\n---- returned from calling onDrawFrame\n\n\n\n");
eglSwapBuffers(eglDisplay, render_priv->eglSurface);
// switch the EGL context back to Gtk's one
result = eglMakeCurrent(old_eglDisplay, old_read_surface, old_draw_surface, old_eglContext);
check_egl_error();
gtk_gl_area_make_current(gl_area);
d_printf("OpenGL version after restore: >%s<\n", glGetString(GL_VERSION));
d_printf("\n\n\n---- drawing the texture containing our frame\n\n");
___GL_TRACE___("---- drawing the texture containing our frame");
// draw on a black background (TODO: isn't this pointless?)
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw two triangles (a rectangle) painted with the texture that we were rendering into
glUseProgram(render_priv->program);
glBindVertexArray(render_priv->vao);
glActiveTexture(GL_TEXTURE0 + render_priv->texUnit);
glBindTexture(GL_TEXTURE_2D, render_priv->texBufferdObject);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, render_priv->egl_image);
glBindSampler(render_priv->texUnit, render_priv->sampler);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);
___GL_TRACE___("---- end of drawing the texture containing our frame");
d_printf("\n---- end of drawing the texture containing our frame\n\n\n\n");
return TRUE;
}
extern gboolean tick_callback(GtkWidget* widget, GdkFrameClock* frame_clock, gpointer user_data);
JNIEXPORT void JNICALL Java_android_opengl_GLSurfaceView_native_1set_1renderer(JNIEnv *env, jobject this, jobject renderer)
{
GtkWidget *gl_area = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")));
gtk_gl_area_set_has_stencil_buffer(GTK_GL_AREA(gl_area), true); // FIXME don't assume what the app wants
gtk_gl_area_set_has_depth_buffer(GTK_GL_AREA(gl_area), true);
gtk_gl_area_set_use_es(GTK_GL_AREA(gl_area), true); // FIXME
struct render_priv *render_priv = malloc(sizeof(struct render_priv));
render_priv->texUnit = 0;
render_priv->sampler = 0;
render_priv->FramebufferName = 0;
g_object_set_data(G_OBJECT(gl_area), "render_priv", render_priv);
JavaVM *jvm;
(*env)->GetJavaVM(env, &jvm);
struct jni_gl_callback_data *gl_callback_data = malloc(sizeof(struct jni_gl_callback_data));
gl_callback_data->jvm = jvm;
gl_callback_data->this = _REF(this);
gl_callback_data->renderer = _REF(renderer);
gl_callback_data->first_time = 1;
g_signal_connect(gl_area, "render", G_CALLBACK(render), gl_callback_data);
g_signal_connect(gl_area, "realize", G_CALLBACK(on_realize), gl_callback_data);
gtk_widget_add_tick_callback(gl_area, tick_callback, NULL, NULL);
//FIXME
gtk_widget_set_hexpand(gtk_widget_get_parent(GTK_WIDGET(gl_area)), true);
}

View File

@@ -78,9 +78,16 @@ static void on_resize(GtkWidget* self, gint width, gint height, struct jni_callb
// TODO: are there cases where returning RGBA_8888 is a bad idea?
// NOTE: we want to call the private method of android.view.SurfaceView, not the related method with this name in the API
(*env)->CallVoidMethod(env, d->this, _METHOD(d->this_class, "surfaceChanged", "(Landroid/view/SurfaceHolder;III)V"),
_GET_OBJ_FIELD(d->this, "mSurfaceHolder", "Landroid/view/SurfaceHolder;"), 1 /*RGBA_8888*/,
width, height);
(*env)->CallVoidMethod(env, d->this, handle_cache.surface_view.surfaceChanged, 1 /*RGBA_8888*/, width, height);
}
static void on_realize(GtkWidget* self, struct jni_callback_data *d)
{
JNIEnv *env;
(*d->jvm)->GetEnv(d->jvm, (void**)&env, JNI_VERSION_1_6);
// NOTE: we want to call the private method of android.view.SurfaceView, not the related method with this name in the API
(*env)->CallVoidMethod(env, d->this, handle_cache.surface_view.surfaceCreated);
}
JNIEXPORT jlong JNICALL Java_android_view_SurfaceView_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs)
@@ -89,6 +96,7 @@ JNIEXPORT jlong JNICALL Java_android_view_SurfaceView_native_1constructor(JNIEnv
GtkWidget *dummy = surface_view_widget_new();
gtk_widget_set_name(dummy, "dummy widget for SurfaceView");
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), dummy);
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);
// TODO: is this correct for all usecases? how do we know when it's not?
gtk_widget_set_hexpand(wrapper, true);
gtk_widget_set_vexpand(wrapper, true);
@@ -102,6 +110,7 @@ JNIEXPORT jlong JNICALL Java_android_view_SurfaceView_native_1constructor(JNIEnv
callback_data->this_class = _REF((*env)->FindClass(env, "android/view/SurfaceView"));
g_signal_connect(dummy, "resize", G_CALLBACK(on_resize), callback_data);
g_signal_connect(dummy, "realize", G_CALLBACK(on_realize), callback_data);
return _INTPTR(dummy);
}