From ce9d728fb6fe97a36eba5294a793f0d451c8fd6d Mon Sep 17 00:00:00 2001 From: StapleButter Date: Thu, 30 May 2019 17:29:41 +0200 Subject: [PATCH] fix cleanup of libui objects when closing melonDS fixes to Cmake shito attempt shit --- src/libui_sdl/CMakeLists.txt | 5 +- src/libui_sdl/libui/ui.h | 2 + src/libui_sdl/libui/unix/CMakeLists.txt | 1 + src/libui_sdl/libui/unix/area.c | 67 ++++++-- src/libui_sdl/libui/unix/gl.c | 201 +++++++++++++++++++++--- src/libui_sdl/libui/unix/main.c | 31 ++++ src/libui_sdl/libui/unix/uipriv_unix.h | 20 ++- src/libui_sdl/main.cpp | 31 ++-- 8 files changed, 304 insertions(+), 54 deletions(-) diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt index 61e09812..e9a54e2f 100644 --- a/src/libui_sdl/CMakeLists.txt +++ b/src/libui_sdl/CMakeLists.txt @@ -9,9 +9,8 @@ SET(SOURCES_LIBUI DlgAudioSettings.cpp DlgEmuSettings.cpp DlgInputConfig.cpp - DlgWifiSettings.cpp - # opengl backend stuff DlgVideoSettings.cpp + DlgWifiSettings.cpp ) option(BUILD_SHARED_LIBS "Whether to build libui as a shared library or a static library" ON) @@ -47,7 +46,7 @@ if (UNIX) --generate-header "${CMAKE_SOURCE_DIR}/melon_grc.xml") if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_link_libraries(melonDS dl X11) + target_link_libraries(melonDS dl) endif () target_sources(melonDS PUBLIC melon_grc.c) diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index 0c89d906..47da54be 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -613,6 +613,8 @@ typedef struct uiGLContext uiGLContext; _UI_EXTERN uiGLContext *uiAreaGetGLContext(uiArea* a); _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx); +_UI_EXTERN void uiGLBegin(uiGLContext* ctx); +_UI_EXTERN void uiGLEnd(uiGLContext* ctx); _UI_EXTERN unsigned int uiGLGetVersion(uiGLContext* ctx); _UI_EXTERN void *uiGLGetProcAddress(const char* proc); _UI_EXTERN int uiGLGetFramebuffer(uiGLContext* ctx); diff --git a/src/libui_sdl/libui/unix/CMakeLists.txt b/src/libui_sdl/libui/unix/CMakeLists.txt index ec9ab758..c69081ee 100644 --- a/src/libui_sdl/libui/unix/CMakeLists.txt +++ b/src/libui_sdl/libui/unix/CMakeLists.txt @@ -63,6 +63,7 @@ macro(_handle_static) set(_oname libui-combined.o) add_custom_command( OUTPUT ${_oname} + DEPENDS ${_LIBUINAME} COMMAND ld -r --whole-archive ${_aname} -o ${_oname} COMMAND diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c index bf92ddf4..62a4cb0e 100644 --- a/src/libui_sdl/libui/unix/area.c +++ b/src/libui_sdl/libui/unix/area.c @@ -3,18 +3,6 @@ extern GThread* gtkthread; -// notes: -// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14) -#define areaWidgetType (areaWidget_get_type()) -#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget)) -#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType)) -#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass)) -#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget)) -#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass)) - -typedef struct areaWidget areaWidget; -typedef struct areaWidgetClass areaWidgetClass; - struct areaWidget { GtkDrawingArea parent_instance; uiArea *a; @@ -45,6 +33,7 @@ struct uiArea { gboolean opengl; uiGLContext *glContext; + gboolean drawreq; int bgR, bgG, bgB; @@ -63,6 +52,21 @@ struct uiArea { G_DEFINE_TYPE(areaWidget, areaWidget, GTK_TYPE_DRAWING_AREA) +int boub(GtkWidget* w) { return isAreaWidget(w); } +void baba(GtkWidget* w) +{ + if (!isAreaWidget(w)) return; + + areaWidget *aw = areaWidget(w); + uiArea *a = aw->a; + if (!a->opengl) return; + + GdkGLContext* oldctx = gdk_gl_context_get_current(); + uiGLMakeContextCurrent(a->glContext); + glFinish(); + gdk_gl_context_make_current(oldctx); +} + static void areaWidget_init(areaWidget *aw) { // for events @@ -130,6 +134,22 @@ static void loadAreaSize(uiArea *a, double *width, double *height) void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx); +void areaPreRedraw(areaWidget* widget) +{ + uiArea* a = widget->a; + if (!a->opengl) return; + + areaPreRedrawGL(a->glContext); +} + +void areaPostRedraw(areaWidget* widget) +{ + uiArea* a = widget->a; + if (!a->opengl) return; + + areaPostRedrawGL(a->glContext); +} + static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) { areaWidget *aw = areaWidget(w); @@ -161,6 +181,8 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) else { areaDrawGL(w, &dp, cr, a->glContext); + //if (a->drawreq) uiGLEnd(a->glContext); + a->drawreq = FALSE; } freeContext(dp.Context); @@ -613,7 +635,15 @@ static void areaWidget_class_init(areaWidgetClass *class) // control implementation -uiUnixControlAllDefaults(uiArea) +uiUnixControlAllDefaultsExceptDestroy(uiArea) + +static void uiAreaDestroy(uiControl *c) +{ + uiArea* a = uiArea(c); + if (a->opengl && a->glContext) freeGLContext(a->glContext); + g_object_unref(uiArea(c)->widget); + uiFreeControl(c); +} void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b) { @@ -634,6 +664,8 @@ void uiAreaSetSize(uiArea *a, int width, int height) gboolean _threadsaferefresh(gpointer data) { uiArea* a = (uiArea*)data; + a->drawreq = TRUE; + //if (a->opengl) uiGLBegin(a->glContext); gtk_widget_queue_draw(a->areaWidget); return FALSE; } @@ -644,7 +676,11 @@ void uiAreaQueueRedrawAll(uiArea *a) if (g_thread_self() != gtkthread) g_idle_add(_threadsaferefresh, a); else + { + a->drawreq = TRUE; + //if (a->opengl) uiGLBegin(a->glContext); gtk_widget_queue_draw(a->areaWidget); + } } void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height) @@ -767,10 +803,12 @@ printf("create glarea\n"); a->ah = ah; a->scrolling = FALSE; a->opengl = TRUE; + a->drawreq = FALSE; //GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new(); uiGLContext* ctx = NULL; printf("create sdfsf\n"); + // TODO: move this elsewhere!! so we can actually try all possible versions for (int i = 0; req_versions[i] && !ctx; i++) { int major = uiGLVerMajor(req_versions[i]); int minor = uiGLVerMinor(req_versions[i]); @@ -792,8 +830,7 @@ printf("create jfghjjgh: %p\n", ctx); g_signal_connect(a->widget, "realize", G_CALLBACK(majoricc), a); uiAreaSetBackgroundColor(a, -1, -1, -1); - //printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla))); -printf("create qssssq\n"); + return a; } diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index 3504d3a6..3861cdad 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -6,12 +6,35 @@ #include extern GThread* gtkthread; +extern GMutex glmutex; /* *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed (melonDS:17013): GLib-GObject-WARNING **: 00:28:09.096: invalid cast from 'GtkGLArea' to 'areaWidget' */ + +// MISERABLE LITTLE PILE OF HACKS +#define HAX_GDK_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass)) +#define HAX_GDK_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT)) +#define HAX_GDK_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass)) + +typedef struct _HAX_GdkGLContextClass HAX_GdkGLContextClass; + +struct _HAX_GdkGLContextClass +{ + GObjectClass parent_class; + + gboolean (* realize) (GdkGLContext *context, + GError **error); + + void (* end_frame) (GdkGLContext *context, + cairo_region_t *painted, + cairo_region_t *damage); + gboolean (* texture_from_surface) (GdkGLContext *context, + cairo_surface_t *surface, + cairo_region_t *region); +}; struct uiGLContext { GtkGLArea *gla; @@ -19,6 +42,11 @@ struct uiGLContext { GdkWindow* window; GdkGLContext *gctx; + GMutex mutex; + GLsync sync; + GLsync sync2; + int zog; + Display* xdisp; GLXPixmap glxpm; GLXContext glxctx; @@ -26,8 +54,8 @@ struct uiGLContext { int width, height; int scale; - GLuint renderbuffer[2]; - GLuint framebuffer; + GLuint renderbuffer[2][2]; + GLuint framebuffer[2]; }; static PFNGLGENRENDERBUFFERSPROC _glGenRenderbuffers; @@ -45,7 +73,16 @@ static PFNGLCHECKFRAMEBUFFERSTATUSPROC _glCheckFramebufferStatus; static int _procsLoaded = 0; -static void _loadGLProcs() +static void (*vniorp)(GdkGLContext*, cairo_region_t*, cairo_region_t*); + +static void class_hax(GdkGLContext* glctx, cairo_region_t* painted, cairo_region_t* damage) +{ + //printf("END FRAME HIJACK\n"); + //glClearColor(0, 1, 0, 1); + vniorp(glctx, painted, damage); +} + +static void _loadGLProcs(GdkGLContext* glctx) { if (_procsLoaded) return; @@ -63,17 +100,25 @@ static void _loadGLProcs() _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)uiGLGetProcAddress("glCheckFramebufferStatus"); _procsLoaded = 1; + + HAX_GdkGLContextClass* class = HAX_GDK_GL_CONTEXT_GET_CLASS(glctx); + printf("HAX class = %p\n", class); + printf("class end_frame = %p\n", class->end_frame); + vniorp = class->end_frame; + class->end_frame = class_hax; } Display* derp; -uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min) +int nswaps = 0; + +uiGLContext *createGLContext(GtkWidget* widget, int maj, int min) { printf("barp\n"); uiGLContext *ret = uiNew(uiGLContext);//uiAlloc(sizeof(uiGLContext), "uiGLContext"); // herp - ret->gla = gla; + ret->gla = widget; ret->gctx = NULL; //while (!ret->gctx) /*{ @@ -111,6 +156,14 @@ uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min) return ret; } +void freeGLContext(uiGLContext* glctx) +{ + if (glctx == NULL) return; + gdk_gl_context_clear_current(); + g_object_unref(glctx->gctx); + uiFree(glctx); +} + static void areaAllocRenderbuffer(uiGLContext* glctx); void databotte(GtkWidget* widget, uiGLContext* ctx) @@ -150,7 +203,7 @@ void databotte(GtkWidget* widget, uiGLContext* ctx) ctx->scale = window_scale; gdk_gl_context_make_current(glctx); - _loadGLProcs(); + _loadGLProcs(glctx); areaAllocRenderbuffer(ctx); ctx->widget = widget; @@ -160,10 +213,10 @@ void databotte(GtkWidget* widget, uiGLContext* ctx) static void areaAllocRenderbuffer(uiGLContext* glctx) { - _glGenRenderbuffers(2, &glctx->renderbuffer[0]);printf("ylarg0 %04X, %d %d\n", glGetError(), glctx->width, glctx->height); + _glGenRenderbuffers(4, &glctx->renderbuffer[0][0]);printf("ylarg0 %04X, %d %d\n", glGetError(), glctx->width, glctx->height); //glGenTextures(2, &glctx->renderbuffer[0]); - _glGenFramebuffers(1, &glctx->framebuffer);printf("ylarg1 %04X\n", glGetError()); - printf("FB %08X created under ctx %p (%p %p)\n", glctx?glctx->framebuffer:0, gdk_gl_context_get_current(), glctx?glctx->gctx:NULL, glctx); + _glGenFramebuffers(2, &glctx->framebuffer[0]);printf("ylarg1 %04X\n", glGetError()); + printf("FB %08X created under ctx %p (%p %p)\n", glctx?glctx->framebuffer[0]:0, gdk_gl_context_get_current(), glctx?glctx->gctx:NULL, glctx); /*glBindTexture(GL_TEXTURE_2D, glctx->renderbuffer[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -176,37 +229,91 @@ static void areaAllocRenderbuffer(uiGLContext* glctx) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);*/ - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]);printf("ylarg1 %04X\n", glGetError()); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);printf("ylarg1 %04X\n", glGetError()); _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError()); - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1]);printf("ylarg1 %04X\n", glGetError()); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);printf("ylarg1 %04X\n", glGetError()); _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError()); - _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer);printf("ylarg2 %04X\n", glGetError()); + _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[0]);printf("ylarg2 %04X\n", glGetError()); /*_glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glctx->renderbuffer[0], 0); _glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, glctx->renderbuffer[1], 0);*/ - _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0]);printf("ylarg3 %04X\n", glGetError()); - _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1]);printf("ylarg4 %04X\n", glGetError()); + _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0][0]);printf("ylarg3 %04X\n", glGetError()); + _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[0][1]);printf("ylarg4 %04X\n", glGetError()); + //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]); + + + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]);printf("ylarg1 %04X\n", glGetError()); + _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError()); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);printf("ylarg1 %04X\n", glGetError()); + _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError()); + + _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[1]);printf("ylarg2 %04X\n", glGetError()); + /*_glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glctx->renderbuffer[0], 0); + _glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, glctx->renderbuffer[1], 0);*/ + _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[1][0]);printf("ylarg3 %04X\n", glGetError()); + _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1][1]);printf("ylarg4 %04X\n", glGetError()); //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]); if(_glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER)); int alpha_size; - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]); _glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_ALPHA_SIZE, &alpha_size); printf("FRAMEBUFFER GOOD. ALPHA SIZE IS %d\n", alpha_size); } static void areaRellocRenderbuffer(uiGLContext* glctx) { - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]); _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale); - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1]); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]); _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); + + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]); + _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]); + _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); +} + +void areaPreRedrawGL(uiGLContext* glctx) +{ + g_mutex_lock(&glctx->mutex); + + /*gdk_gl_context_make_current(glctx->gctx); + //glClientWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED); + glDeleteSync(glctx->sync); + glFinish(); + gdk_gl_context_clear_current();*/ + /*GdkGLContext* oldctx = gdk_gl_context_get_current(); + gdk_gl_context_make_current(glctx->gctx); + printf("[%p] PRE DRAW\n", gdk_gl_context_get_current()); + + gdk_gl_context_make_current(oldctx);*/ + //glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT); + //glWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED); + /*int ret = glClientWaitSync(glctx->sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50); + printf("PRE-DRAW: SYNC %p, %04X, %04X\n", glctx->sync, ret, glGetError()); + glDeleteSync(glctx->sync); + glctx->sync = NULL;*/ + //glFlush(); + if (nswaps > 1) printf("MISSED %d FRAMES\n", nswaps-1); + nswaps = 0; + //glctx->zog ^= 1; +} + +void areaPostRedrawGL(uiGLContext* glctx) +{ + //glctx->sync2 = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + //glFlush(); + //printf("[%p] POST DRAW\n", gdk_gl_context_get_current()); + g_mutex_unlock(&glctx->mutex); } void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx) { + //uiGLBegin(glctx); + int window_scale = gdk_window_get_scale_factor(glctx->window); if (glctx->width != dp->AreaWidth || glctx->height != dp->AreaHeight || glctx->scale != window_scale) @@ -218,8 +325,10 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex } gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), - glctx->renderbuffer[0], GL_RENDERBUFFER, + glctx->renderbuffer[glctx->zog][0], GL_RENDERBUFFER, 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale); + + //uiGLEnd(glctx); } uiGLContext* FARTOMATIC(int major, int minor) @@ -229,9 +338,15 @@ uiGLContext* FARTOMATIC(int major, int minor) _ret->vermin = minor; _ret->width = -1; _ret->height = -1; - _ret->renderbuffer[0] = 0; - _ret->renderbuffer[1] = 0; - _ret->framebuffer = 0; + _ret->renderbuffer[0][0] = 0; + _ret->renderbuffer[0][1] = 0; + _ret->framebuffer[0] = 0; + _ret->renderbuffer[1][0] = 0; + _ret->renderbuffer[1][1] = 0; + _ret->framebuffer[1] = 0; + _ret->zog = 0; + + g_mutex_init(&_ret->mutex); return _ret; @@ -348,7 +463,7 @@ uiGLContext* FARTOMATIC(int major, int minor) int uiGLGetFramebuffer(uiGLContext* ctx) { - return ctx->framebuffer; + return ctx->framebuffer[ctx->zog];// ? 0:1]; } float uiGLGetFramebufferScale(uiGLContext* ctx) @@ -358,8 +473,18 @@ float uiGLGetFramebufferScale(uiGLContext* ctx) void uiGLSwapBuffers(uiGLContext* ctx) { - if (!ctx) return; - //gtk_gl_area_attach_buffers(ctx->gla); + /*ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + //gdk_gl_context_clear_current(); + glWaitSync(ctx->sync, 0, GL_TIMEOUT_IGNORED); + glDeleteSync(ctx->sync);*/ + /*printf("[%p] SWAPBUFFERS\n", gdk_gl_context_get_current()); + glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT); + glFinish();*/ + //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + //glFlush(); + //printf("SWAP: SYNC=%p\n", ctx->sync); + //glFinish(); + nswaps++; } static volatile int _ctxset_done; @@ -398,7 +523,7 @@ void uiGLMakeContextCurrent(uiGLContext* ctx) } printf("WE MAED IT CURRENT: %d\n", ret);*/ - printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL); + //printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL); if (!ctx) { gdk_gl_context_clear_current(); @@ -410,6 +535,32 @@ void uiGLMakeContextCurrent(uiGLContext* ctx) //gtk_gl_area_attach_buffers(ctx->gla); //printf("burp = %p / %p\n", burp, ctx->gctx); } + +void uiGLBegin(uiGLContext* ctx) +{ + //g_mutex_lock(&ctx->mutex); + if (g_thread_self() != gtkthread) + { + g_mutex_lock(&glmutex); + + //int ret = glClientWaitSync(ctx->sync2, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50); + //printf("GLBEGIN: SYNC %p, %04X, %04X\n", ctx->sync2, ret, glGetError()); + //glDeleteSync(ctx->sync2); + } +} + +void uiGLEnd(uiGLContext* ctx) +{ + //g_mutex_unlock(&ctx->mutex); + if (g_thread_self() != gtkthread) + { + g_mutex_unlock(&glmutex); + + //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + //glFlush(); + } +} + void *uiGLGetProcAddress(const char* proc) { printf("get: %s - ", proc); diff --git a/src/libui_sdl/libui/unix/main.c b/src/libui_sdl/libui/unix/main.c index 409b659f..66bd335f 100644 --- a/src/libui_sdl/libui/unix/main.c +++ b/src/libui_sdl/libui/unix/main.c @@ -6,6 +6,33 @@ uiInitOptions options; // kind of a hack GThread* gtkthread; +GMutex glmutex; +int boub(GtkWidget* w); +void baba(GtkWidget* w); + +static void _eventfilter(GdkEvent* evt, gpointer data) +{ + if (evt->type == GDK_EXPOSE) + { + GtkWidget* widget = gtk_get_event_widget(evt); + if (isAreaWidget(widget)) + { + areaWidget* area = areaWidget(widget); + areaPreRedraw(area); + gtk_main_do_event(evt); + areaPostRedraw(area); + return; + } + } + + gtk_main_do_event(evt); +} + +static void _eventfilterdestroy(gpointer data) +{ + printf("DELET\n"); +} + const char *uiInit(uiInitOptions *o) { GError *err = NULL; @@ -31,6 +58,10 @@ const char *uiInit(uiInitOptions *o) gtk_window_set_default_icon_list(iconlist); + g_mutex_init(&glmutex); + + gdk_event_handler_set(_eventfilter, NULL, _eventfilterdestroy); + return NULL; } diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h index 42d5d764..7a7b208a 100644 --- a/src/libui_sdl/libui/unix/uipriv_unix.h +++ b/src/libui_sdl/libui/unix/uipriv_unix.h @@ -65,5 +65,23 @@ extern PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha); extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name); // gl.c -extern uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min); +extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min); +extern void freeGLContext(uiGLContext* glctx); +extern void areaPreRedrawGL(uiGLContext* glctx); +extern void areaPostRedrawGL(uiGLContext* glctx); + +// notes: +// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14) +#define areaWidgetType (areaWidget_get_type()) +#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget)) +#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType)) +#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass)) +#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget)) +#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass)) + +typedef struct areaWidget areaWidget; +typedef struct areaWidgetClass areaWidgetClass; + +extern void areaPreRedraw(areaWidget* widget); +extern void areaPostRedraw(areaWidget* widget); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index e2686f99..fa6a2b54 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -379,26 +379,24 @@ void GLScreen_DrawScreen() glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GL_ScreenVertices), GL_ScreenVertices); } - printf("rarp4 %04X\n", glGetError()); + glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); -printf("rarp2 %04X\n", glGetError()); glViewport(0, 0, WindowWidth*scale, WindowHeight*scale); - printf("draw screen: viewport=%d/%d\n", WindowWidth, WindowHeight); if (GPU3D::Renderer == 0) OpenGL_UseShaderProgram(GL_ScreenShader); else OpenGL_UseShaderProgram(GL_ScreenShaderAccel); -printf("rarp3 %04X\n", glGetError()); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext)); - printf("rarp8 %04X\n", glGetError()); + glClearColor(0, 0, 1, 1); glClear(GL_COLOR_BUFFER_BIT); -printf("rarp5 %04X\n", glGetError()); + int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); @@ -424,11 +422,11 @@ printf("rarp5 %04X\n", glGetError()); glActiveTexture(GL_TEXTURE1); if (GPU3D::Renderer != 0) GPU3D::GLRenderer::SetupAccelFrame(); -printf("rarp6 %04X\n", glGetError()); + glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); glBindVertexArray(GL_ScreenVertexArrayID); glDrawArrays(GL_TRIANGLES, 0, 4*3); -printf("rarp7 %04X\n", glGetError()); + glFlush(); uiGLSwapBuffers(GLContext); } @@ -826,7 +824,11 @@ int EmuThreadFunc(void* burp) // microphone input FeedMicInput(); - if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); + if (Screen_UseGL) + { + uiGLBegin(GLContext); + uiGLMakeContextCurrent(GLContext); + } // auto screen layout { @@ -862,7 +864,11 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 0) break; - if (Screen_UseGL) GLScreen_DrawScreen(); + if (Screen_UseGL) + { + GLScreen_DrawScreen(); + uiGLEnd(GLContext); + } uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx @@ -917,8 +923,10 @@ int EmuThreadFunc(void* burp) { if (Screen_UseGL) { + uiGLBegin(GLContext); uiGLMakeContextCurrent(GLContext); GLScreen_DrawScreen(); + uiGLEnd(GLContext); //uiGLMakeContextCurrent(NULL); //uiQueueMain(norp, NULL); } @@ -2537,6 +2545,9 @@ int main(int argc, char** argv) if (MicDevice) SDL_CloseAudioDevice(MicDevice); if (MicWavBuffer) delete[] MicWavBuffer; + + if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); + if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); Config::ScreenRotation = ScreenRotation; Config::ScreenGap = ScreenGap;