From 14e3617736c63bd22b0785ad418acef825db221f Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 28 Oct 2021 17:10:41 +0200 Subject: Use a separate glx context for every window Fix vertex buffer causing crash on render if update is called with an empty list. --- src/graphics/vertex_buffer.c | 15 ++++++++++++++- src/mgl.c | 11 ----------- src/window/window.c | 16 ++++++++++++++-- 3 files changed, 28 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/graphics/vertex_buffer.c b/src/graphics/vertex_buffer.c index 1f122c3..aa4fdbb 100644 --- a/src/graphics/vertex_buffer.c +++ b/src/graphics/vertex_buffer.c @@ -56,6 +56,7 @@ static int mgl_vertex_buffer_resize(mgl_vertex_buffer *self, const mgl_vertex *v self->usage = usage; context->gl.glBindBuffer(GL_ARRAY_BUFFER, self->id); + /* TODO: Optimize by calling with NULL data first? or do that in |mgl_vertex_buffer_update| */ context->gl.glBufferData(GL_ARRAY_BUFFER, sizeof(mgl_vertex) * vertex_count, vertices, mgl_vertex_buffer_usage_to_gl_usage(self->usage)); mgl_vertex_buffer_set_gl_buffer_pointers(context); context->gl.glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -69,10 +70,22 @@ void mgl_vertex_buffer_set_position(mgl_vertex_buffer *self, mgl_vec2f position) /* TODO: Check for glBufferSubData error */ int mgl_vertex_buffer_update(mgl_vertex_buffer *self, const mgl_vertex *vertices, size_t vertex_count, mgl_primitive_type primitive_type, mgl_vertex_buffer_usage usage) { + mgl_context *context = mgl_get_context(); + + if(vertex_count == 0) { + if(self->id) { + context->gl.glDeleteBuffers(1, &self->id); + self->id = 0; + } + self->vertex_count = vertex_count; + self->primitive_type = primitive_type; + self->usage = usage; + return 0; + } + if(vertex_count != self->vertex_count || primitive_type != self->primitive_type || usage != self->usage) return mgl_vertex_buffer_resize(self, vertices, vertex_count, primitive_type, usage); - mgl_context *context = mgl_get_context(); context->gl.glBindBuffer(GL_ARRAY_BUFFER, self->id); context->gl.glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(mgl_vertex) * vertex_count, vertices); mgl_vertex_buffer_set_gl_buffer_pointers(context); diff --git a/src/mgl.c b/src/mgl.c index 549121f..6407d9e 100644 --- a/src/mgl.c +++ b/src/mgl.c @@ -39,21 +39,10 @@ static int glx_context_init() { return -1; } - context.glx_context = context.gl.glXCreateContext(context.connection, context.visual_info, NULL, 1); - if(!context.glx_context) { - fprintf(stderr, "glXCreateContext failed\n"); - return -1; - } - return 0; } static void glx_context_deinit() { - if(context.glx_context) { - context.gl.glXDestroyContext(context.connection, context.glx_context); - context.glx_context = NULL; - } - if(context.visual_info) { XFree(context.visual_info); context.visual_info = NULL; diff --git a/src/window/window.c b/src/window/window.c index 2e9a1ba..f29b920 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -49,6 +49,12 @@ static int mgl_window_init(mgl_window *self, const char *title, int width, int h if(parent_window == 0) parent_window = DefaultRootWindow(context->connection); + self->glx_context = context->gl.glXCreateContext(context->connection, context->visual_info, NULL, 1); + if(!self->glx_context) { + fprintf(stderr, "glXCreateContext failed\n"); + return -1; + } + Colormap color_map = XCreateColormap(context->connection, DefaultRootWindow(context->connection), ((XVisualInfo*)context->visual_info)->visual, AllocNone); if(!color_map) { fprintf(stderr, "XCreateColormap failed\n"); @@ -68,6 +74,7 @@ static int mgl_window_init(mgl_window *self, const char *title, int width, int h if(!XChangeWindowAttributes(context->connection, existing_window, CWColormap | CWEventMask | CWBitGravity, &window_attr)) { fprintf(stderr, "XChangeWindowAttributes failed\n"); XFreeColormap(context->connection, color_map); + mgl_window_deinit(self); return -1; } XFreeColormap(context->connection, color_map); @@ -89,8 +96,8 @@ static int mgl_window_init(mgl_window *self, const char *title, int width, int h XFlush(context->connection); - /* TODO: Switch current when rendering to another window, and set current to NULL when destroying the currently selected context */ - context->gl.glXMakeCurrent(context->connection, self->window, context->glx_context); + /* TODO: Check for failure? */ + context->gl.glXMakeCurrent(context->connection, self->window, self->glx_context); set_vertical_sync_enabled(self->window, 1); context->gl.glEnable(GL_TEXTURE_2D); context->gl.glEnable(GL_BLEND); @@ -123,6 +130,10 @@ int mgl_window_init_from_existing_window(mgl_window *self, mgl_window_handle exi void mgl_window_deinit(mgl_window *self) { mgl_context *context = mgl_get_context(); + if(self->glx_context) { + context->gl.glXDestroyContext(context->connection, self->glx_context); + self->glx_context = NULL; + } if(self->window) { XDestroyWindow(context->connection, self->window); self->window = 0; @@ -172,3 +183,4 @@ void mgl_window_display(mgl_window *self) { mgl_context *context = mgl_get_context(); context->gl.glXSwapBuffers(context->connection, self->window); } + -- cgit v1.2.3