From 38f61a24fcdf5a78cbabc9184f55ded3b496f1d4 Mon Sep 17 00:00:00 2001 From: PoroCYon Date: Sun, 26 May 2019 00:38:24 +0200 Subject: 'port' libui GL stuff to Linux Only implemented the functions needed by melonDS, and only tested using a very recent mesa+libglvnd+nouveau. Will most likely bork using proprietary nvidia or old(er) drivers (see gl.c) --- src/libui_sdl/libui/unix/uipriv_unix.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/libui_sdl/libui/unix/uipriv_unix.h') diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h index 33ff1e3..42d5d76 100644 --- a/src/libui_sdl/libui/unix/uipriv_unix.h +++ b/src/libui_sdl/libui/unix/uipriv_unix.h @@ -5,7 +5,7 @@ #define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_10 #include #include -#include // see drawtext.c +#include // see drawtext.c, gl.c #include #include #include @@ -63,3 +63,7 @@ extern GtkCellRenderer *newCellRendererButton(void); extern void loadFutures(void); 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); + -- cgit v1.2.3 From ce9d728fb6fe97a36eba5294a793f0d451c8fd6d Mon Sep 17 00:00:00 2001 From: StapleButter Date: Thu, 30 May 2019 17:29:41 +0200 Subject: 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(-) (limited to 'src/libui_sdl/libui/unix/uipriv_unix.h') diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt index 61e0981..e9a54e2 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 0c89d90..47da54b 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 ec9ab75..c69081e 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 bf92ddf..62a4cb0 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 3504d3a..3861cda 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[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[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][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]);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);printf("ylarg2 %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[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[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 409b659..66bd335 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 42d5d76..7a7b208 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 e2686f9..fa6a2b5 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; -- cgit v1.2.3 From 27d451d07a398a79cedef8040dfb6a612672b06c Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 31 May 2019 01:46:47 +0200 Subject: clean up code, attempt at shit --- src/libui_sdl/libui/unix/area.c | 61 ++--- src/libui_sdl/libui/unix/gl.c | 399 ++++----------------------------- src/libui_sdl/libui/unix/uipriv_unix.h | 1 + src/libui_sdl/main.cpp | 2 +- 4 files changed, 67 insertions(+), 396 deletions(-) (limited to 'src/libui_sdl/libui/unix/uipriv_unix.h') diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c index 62a4cb0..62fe512 100644 --- a/src/libui_sdl/libui/unix/area.c +++ b/src/libui_sdl/libui/unix/area.c @@ -28,12 +28,11 @@ struct uiArea { GtkWidget *areaWidget; GtkDrawingArea *drawingArea; - GtkGLArea *glArea; areaWidget *area; gboolean opengl; uiGLContext *glContext; - gboolean drawreq; + unsigned int* req_versions; int bgR, bgG, bgB; @@ -132,8 +131,6 @@ 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; @@ -181,8 +178,6 @@ 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); @@ -664,8 +659,6 @@ 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; } @@ -676,11 +669,7 @@ 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) @@ -762,7 +751,7 @@ void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge) uiArea *uiNewArea(uiAreaHandler *ah) { uiArea *a; -printf("create regular area\n"); + uiUnixNewControl(uiArea, a); a->ah = ah; @@ -782,44 +771,38 @@ printf("create regular area\n"); return a; } -uiGLContext* FARTOMATIC(int major, int minor); -void databotte(GtkWidget* gla, uiGLContext* ctx); -void majoricc(GtkWidget* widget, gpointer data) +void _areaCreateGLContext(GtkWidget* widget, gpointer data) { - printf("ACTUALLY CREATE CONTEXT\n"); - uiArea* a = (uiArea*)data; - uiGLContext* ctx = a->glContext; - databotte(a->widget, ctx); + uiGLContext* ctx = NULL; + for (int i = 0; a->req_versions[i] && !ctx; i++) + { + int major = uiGLVerMajor(a->req_versions[i]); + int minor = uiGLVerMinor(a->req_versions[i]); + + // we cannot support any version older than 3.2 via GDK + if ((major < 3) || (major == 3 && minor < 2)) + break; + + ctx = createGLContext(widget, major, minor); + } + + a->glContext = ctx; } uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions) { uiArea *a; -printf("create glarea\n"); + uiUnixNewControl(uiArea, a); 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]); - //gtk_gl_area_set_required_version(gla, major, minor); - //ctx = createGLContext(gla, major, minor); - ctx = FARTOMATIC(major, minor); - } -printf("create jfghjjgh: %p\n", ctx); - a->glContext = ctx; - //a->areaWidget = GTK_WIDGET(gla); - //a->glArea = gla; + + a->glContext = NULL; + a->req_versions = req_versions; a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, "libui-area", a, NULL)); @@ -827,7 +810,7 @@ printf("create jfghjjgh: %p\n", ctx); a->widget = a->areaWidget; - g_signal_connect(a->widget, "realize", G_CALLBACK(majoricc), a); + g_signal_connect(a->widget, "realize", G_CALLBACK(_areaCreateGLContext), a); uiAreaSetBackgroundColor(a, -1, -1, -1); diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index 3861cda..ab29abb 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -1,63 +1,29 @@ // 26 may 2019 #include "uipriv_unix.h" -#include #include -#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 +struct uiGLContext { - 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; GtkWidget* widget; GdkWindow* window; + GdkGLContext *gctx; + int vermaj, vermin; GMutex mutex; - GLsync sync; - GLsync sync2; - int zog; - - Display* xdisp; - GLXPixmap glxpm; - GLXContext glxctx; - int vermaj, vermin; int width, height; int scale; GLuint renderbuffer[2][2]; GLuint framebuffer[2]; + int backbuffer; }; +static void areaAllocRenderbuffer(uiGLContext* glctx); + static PFNGLGENRENDERBUFFERSPROC _glGenRenderbuffers; static PFNGLDELETERENDERBUFFERSPROC _glDeleteRenderbuffers; static PFNGLBINDRENDERBUFFERPROC _glBindRenderbuffer; @@ -73,15 +39,6 @@ static PFNGLCHECKFRAMEBUFFERSTATUSPROC _glCheckFramebufferStatus; static int _procsLoaded = 0; -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; @@ -100,101 +57,31 @@ static void _loadGLProcs(GdkGLContext* glctx) _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; - -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 = widget; - ret->gctx = NULL; - //while (!ret->gctx) - /*{ - gtk_widget_realize(GTK_WIDGET(gla)); - printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla))); - ret->gla = gla; - ret->gctx = gtk_gl_area_get_context(gla); - printf("context: %p\n", ret->gctx); - }*/ - - - - /* - GtkAllocation allocation; - GdkWindow *window; - Display *display; - int id; - - window = gtk_widget_get_window(widget); - display = gdk_x11_display_get_xdisplay(gdk_window_get_display(window)); - id = gdk_x11_window_get_xid(window); + GdkWindow* gdkwin = gtk_widget_get_window(widget); - if (glXMakeCurrent(display, id, context) == TRUE) {*/ - - - /*GdkWindow* window; - Display* disp; - - window = gtk_widget_get_window(GTK_WIDGET(gla)); - display = */ - - - - ret->vermaj = maj; ret->vermin = 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) -{ - /*printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla))); - ctx->gctx = gtk_gl_area_get_context(gla); - printf("context: %p\n", ctx->gctx);*/ - - printf("DATABOTTE\n"); - - GdkWindow* gdkwin = gtk_widget_get_window(widget); - printf("window=%p\n", gdkwin); - GError* err = NULL; - GdkGLContext* glctx = gdk_window_create_gl_context(gdkwin, &err); - if (err != NULL) + GdkGLContext* gctx = gdk_window_create_gl_context(gdkwin, &err); + if (err != NULL || gctx == NULL) { - printf("CONTEXT SHAT ITSELF\n"); - return; + return NULL; } - gdk_gl_context_set_use_es(glctx, FALSE); - gdk_gl_context_set_required_version(glctx, 3, 2); + // TODO: make the set_use_es call conditional (#ifdef or smth) for older versions of gdk? + gdk_gl_context_set_use_es(gctx, FALSE); + gdk_gl_context_set_required_version(gctx, maj, min); - gdk_gl_context_realize(glctx, &err); - if (err != NULL) + gboolean res = gdk_gl_context_realize(gctx, &err); + if (err != NULL || res == FALSE) { - printf("CONTEXT REALIZE SHAT ITSELF\n"); - return; + return NULL; } + uiGLContext* ctx = uiNew(uiGLContext); + GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int window_scale = gdk_window_get_scale_factor(gdkwin); @@ -202,13 +89,26 @@ void databotte(GtkWidget* widget, uiGLContext* ctx) ctx->height = allocation.height; ctx->scale = window_scale; - gdk_gl_context_make_current(glctx); - _loadGLProcs(glctx); + gdk_gl_context_make_current(gctx); + _loadGLProcs(gctx); areaAllocRenderbuffer(ctx); + ctx->backbuffer = 0; + + g_mutex_init(&ctx->mutex); ctx->widget = widget; ctx->window = gdkwin; - ctx->gctx = glctx; + ctx->gctx = gctx; + + return ctx; +} + +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) @@ -279,41 +179,16 @@ static void areaRellocRenderbuffer(uiGLContext* glctx) 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; + glctx->backbuffer = glctx->backbuffer ? 0 : 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) @@ -325,145 +200,13 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex } gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), - glctx->renderbuffer[glctx->zog][0], GL_RENDERBUFFER, + glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER, 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale); - - //uiGLEnd(glctx); -} - -uiGLContext* FARTOMATIC(int major, int minor) -{ - uiGLContext *_ret = uiNew(uiGLContext); - _ret->vermaj = major; - _ret->vermin = minor; - _ret->width = -1; - _ret->height = -1; - _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; - - Display* disp; - XVisualInfo* vizir; - GLXFBConfig *cfg; - Pixmap pm; - GLXPixmap glxpm; - GLXContext ctx; - - disp = XOpenDisplay(NULL); - derp = disp; - - int kaa, baa; - glXQueryVersion(disp, &kaa, &baa); - printf("GL VERSION: %d.%d\n", kaa, baa); - - const int sbAttrib[] = { GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - None }; - const int dbAttrib[] = { GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_DOUBLEBUFFER, - None }; - - int scrnum = DefaultScreen( disp ); - Window root = RootWindow( disp, scrnum ); - - vizir = glXChooseVisual( disp, scrnum, (int *) sbAttrib ); - if (!vizir) { - vizir = glXChooseVisual( disp, scrnum, (int *) dbAttrib ); - if (!vizir) { - printf("Error: couldn't get an RGB visual\n"); - return NULL; - } - } - - const int fb_attr[] = { - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_DOUBLEBUFFER, True, - GLX_X_RENDERABLE, True, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_ALPHA_SIZE, 8, - GLX_DEPTH_SIZE, 24, - GLX_STENCIL_SIZE, 8, - None - }; - int configs; - cfg = glXChooseFBConfig(disp, scrnum, (int *)&fb_attr, &configs); - - if (!cfg) - { - printf("NO GOOD FBCONFIG\n"); - return NULL; - } - - /*ctx = glXCreateContext( disp, vizir, NULL, True ); - if (!ctx) - { - printf("Error: glXCreateContext failed\n"); - return NULL; - }*/ - - PFNGLXCREATECONTEXTATTRIBSARBPROC createctx; - createctx = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB("glXCreateContextAttribsARB"); - if (!createctx) - { - printf("bad shito\n"); - return NULL; - } - - const int ctx_attr[] = - { - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_MAJOR_VERSION_ARB, 3,//major, - GLX_CONTEXT_MINOR_VERSION_ARB, 2,//minor, - None - }; - - ctx = glXCreateContextAttribsARB(disp, cfg[0], 0, True, ctx_attr); - if (!ctx) - { - printf("FAILED TO CREATE FANCYPANTS GL CONTEXT\n"); - return NULL; - } - - //printf("CONTEXT GOOD. Direct rendering: %s\n", glXIsDirect(disp, ctx) ? "Yes" : "No"); - - printf("blorp: %d\n", vizir->depth); - pm = XCreatePixmap(disp, root, 256, 384, vizir->depth); - if (!pm) printf("PIXMAP SHAT ITSELF\n"); - else printf("PIXMAP GOOD\n"); - - glxpm = glXCreateGLXPixmap(disp, vizir, pm); - if (!glxpm) printf("GLXPIXMAP SHAT ITSELF\n"); - else printf("GLXPIXMAP GOOD\n"); - - uiGLContext *ret = uiNew(uiGLContext); - printf("CREATE CTX: %p, %p\n", ret, g_thread_self()); - ret->xdisp = disp; - ret->glxpm = glxpm; - ret->glxctx = ctx; - - return ret; } int uiGLGetFramebuffer(uiGLContext* ctx) { - return ctx->framebuffer[ctx->zog];// ? 0:1]; + return ctx->framebuffer[ctx->backbuffer];// ? 0 : 1]; } float uiGLGetFramebufferScale(uiGLContext* ctx) @@ -473,91 +216,35 @@ float uiGLGetFramebufferScale(uiGLContext* ctx) void uiGLSwapBuffers(uiGLContext* ctx) { - /*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); + // nothing to do here, GTK will take care of this //glFinish(); - nswaps++; -} - -static volatile int _ctxset_done; - -gboolean _threadsafe_ctxset(gpointer data) -{ - uiGLContext* ctx = (uiGLContext*)data; - gtk_gl_area_make_current(ctx->gla); - _ctxset_done = 1; - return FALSE; } void uiGLMakeContextCurrent(uiGLContext* ctx) { - //if (!ctx) return; - /*if (g_thread_self() != gtkthread) - { - _ctxset_done = 0; - g_idle_add(_threadsafe_ctxset, ctx); - while (!_ctxset_done); - } - else*/ - //gtk_gl_area_make_current(ctx->gla); - /*printf("MAKE CONTEXT CURRENT %p, %p\n", ctx, g_thread_self()); - if (!ctx) - { - // BLERUGEHZFZF - glXMakeCurrent(derp, None, NULL); - return; - } - Bool ret = True; - if (glXGetCurrentContext() != ctx->glxctx) - {printf("DZJSKFLD\n"); - ret = glXMakeCurrent(ctx->xdisp, ctx->glxpm, ctx->glxctx); - //glXMakeContextCurrent(ctx->xdisp, ctx->glxpm, ctx->glxpm, ctx->glxctx); - } - printf("WE MAED IT CURRENT: %d\n", ret);*/ - - //printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL); if (!ctx) { gdk_gl_context_clear_current(); return; } - //gtk_gl_area_make_current(ctx->gla); + + if (ctx->gctx == gdk_gl_context_get_current()) return; gdk_gl_context_make_current(ctx->gctx); - GdkGLContext* burp = gdk_gl_context_get_current(); - //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); + g_mutex_lock(&ctx->mutex); } } 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(); + g_mutex_unlock(&ctx->mutex); } } @@ -568,7 +255,7 @@ void* a = dlsym(NULL, proc); void* b = glXGetProcAddress(proc); void* c = glXGetProcAddressARB(proc); printf("%p / %p / %p\n", a, b, c); -return c; +return a; // this *will* break for older systems that don't have libglvnd! // TODO: use a real solution return dlsym(NULL /* RTLD_DEFAULT */, proc); diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h index 7a7b208..6f14091 100644 --- a/src/libui_sdl/libui/unix/uipriv_unix.h +++ b/src/libui_sdl/libui/unix/uipriv_unix.h @@ -68,6 +68,7 @@ extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min); extern void freeGLContext(uiGLContext* glctx); extern void areaPreRedrawGL(uiGLContext* glctx); +extern void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx); extern void areaPostRedrawGL(uiGLContext* glctx); // notes: diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index fa6a2b5..a686cb4 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -66,7 +66,7 @@ uiWindow* MainWindow; uiArea* MainDrawArea; uiAreaHandler MainDrawAreaHandler; -const u32 kGLVersions[] = {uiGLVersion(3,1), 0}; +const u32 kGLVersions[] = {uiGLVersion(3,2), uiGLVersion(3,1), 0}; uiGLContext* GLContext; int WindowWidth, WindowHeight; -- cgit v1.2.3 From 464b1169165b2e4d866c033e4c3288c9742539a8 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 31 May 2019 04:15:37 +0200 Subject: fix the whole mutex shito fixes potential crash when resizing window --- src/libui_sdl/libui/unix/area.c | 28 ++++++++++++---------------- src/libui_sdl/libui/unix/gl.c | 33 +++++++++++---------------------- src/libui_sdl/libui/unix/main.c | 17 +++++------------ src/libui_sdl/libui/unix/uipriv_unix.h | 17 ----------------- src/libui_sdl/main.cpp | 6 ------ 5 files changed, 28 insertions(+), 73 deletions(-) (limited to 'src/libui_sdl/libui/unix/uipriv_unix.h') diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c index 62fe512..5734b4b 100644 --- a/src/libui_sdl/libui/unix/area.c +++ b/src/libui_sdl/libui/unix/area.c @@ -3,6 +3,18 @@ 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; @@ -131,22 +143,6 @@ static void loadAreaSize(uiArea *a, double *width, double *height) } } -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); diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index 0511639..6965969 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -6,6 +6,7 @@ void* glXGetProcAddressARB(const GLubyte* name); extern GThread* gtkthread; +extern GMutex glmutex; struct uiGLContext { @@ -15,8 +16,6 @@ struct uiGLContext GdkGLContext *gctx; int vermaj, vermin; - GMutex mutex; - int width, height; int scale; GLuint renderbuffer[2][2]; @@ -96,8 +95,6 @@ uiGLContext *createGLContext(GtkWidget* widget, int maj, int min) areaAllocRenderbuffer(ctx); ctx->backbuffer = 0; - g_mutex_init(&ctx->mutex); - ctx->widget = widget; ctx->window = gdkwin; ctx->gctx = gctx; @@ -144,7 +141,7 @@ static void areaAllocRenderbuffer(uiGLContext* glctx) // printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER)); } -static void areaRellocRenderbuffer(uiGLContext* glctx) +static void areaReallocRenderbuffer(uiGLContext* glctx) { _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]); _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale); @@ -157,16 +154,6 @@ static void areaRellocRenderbuffer(uiGLContext* glctx) //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); } -void areaPreRedrawGL(uiGLContext* glctx) -{ - g_mutex_lock(&glctx->mutex); -} - -void areaPostRedrawGL(uiGLContext* glctx) -{ - g_mutex_unlock(&glctx->mutex); -} - void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx) { int window_scale = gdk_window_get_scale_factor(glctx->window); @@ -176,12 +163,14 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex glctx->width = dp->AreaWidth; glctx->height = dp->AreaHeight; glctx->scale = window_scale; - areaRellocRenderbuffer(glctx); + areaReallocRenderbuffer(glctx); + } + else + { + gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), + glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER, + 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale); } - - gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), - glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER, - 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale); } int uiGLGetFramebuffer(uiGLContext* ctx) @@ -215,7 +204,7 @@ void uiGLBegin(uiGLContext* ctx) { if (g_thread_self() != gtkthread) { - g_mutex_lock(&ctx->mutex); + g_mutex_lock(&glmutex); } } @@ -223,7 +212,7 @@ void uiGLEnd(uiGLContext* ctx) { if (g_thread_self() != gtkthread) { - g_mutex_unlock(&ctx->mutex); + g_mutex_unlock(&glmutex); } } diff --git a/src/libui_sdl/libui/unix/main.c b/src/libui_sdl/libui/unix/main.c index 66bd335..516bd76 100644 --- a/src/libui_sdl/libui/unix/main.c +++ b/src/libui_sdl/libui/unix/main.c @@ -5,24 +5,16 @@ 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; - } + g_mutex_lock(&glmutex); + gtk_main_do_event(evt); + g_mutex_unlock(&glmutex); + return; } gtk_main_do_event(evt); @@ -48,6 +40,7 @@ const char *uiInit(uiInitOptions *o) loadFutures(); gtkthread = g_thread_self(); + g_mutex_init(&glmutex); GList* iconlist = NULL; iconlist = g_list_append(iconlist, gdk_pixbuf_new_from_resource("/org/kuriboland/melonDS/icon/melon_16x16.png", NULL)); diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h index 6f14091..9b77188 100644 --- a/src/libui_sdl/libui/unix/uipriv_unix.h +++ b/src/libui_sdl/libui/unix/uipriv_unix.h @@ -67,22 +67,5 @@ extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, // gl.c extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min); extern void freeGLContext(uiGLContext* glctx); -extern void areaPreRedrawGL(uiGLContext* glctx); extern void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, 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 74d3fc9..6cc6c50 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -430,12 +430,6 @@ void GLScreen_DrawScreen() uiGLSwapBuffers(GLContext); } -void norp(void* data) -{ - uiGLMakeContextCurrent(GLContext); - GLScreen_DrawScreen(); -} - void MicLoadWav(char* name) { SDL_AudioSpec format; -- cgit v1.2.3