aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/unix/gl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libui_sdl/libui/unix/gl.c')
-rw-r--r--src/libui_sdl/libui/unix/gl.c201
1 files changed, 176 insertions, 25 deletions
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 <GL/glx.h>
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);