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. --- README.md | 9 +-------- TODO | 7 +++++++ include/mgl/mgl.h | 1 - include/mgl/window/window.h | 2 ++ src/graphics/vertex_buffer.c | 15 ++++++++++++++- src/mgl.c | 11 ----------- src/window/window.c | 16 ++++++++++++++-- 7 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 TODO diff --git a/README.md b/README.md index ac7c82d..620699a 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,4 @@ Right now mgl only supports x11. ## Build `xlib` ## Runtime -`libglvnd (libGL.so)` -## TODO -Handle window close (window destroyed event, disconnected from server and socket becomes invalid (check select return?)).\ -Bind texture and cache the bound texture to reduce calls to opengl. -Use gl triangle instead of quad. -Fix crash on exit. -Support using multiple textures in shaders by using glActiveTexture for each one and set the uniform sampler2D value for each as as the index. -Make sure clock is monotonic (there has been some issues with CLOCK\_MONOTONIC not being monotonic on linux). +`libglvnd (libGL.so)` \ No newline at end of file diff --git a/TODO b/TODO new file mode 100644 index 0000000..611b9c1 --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ +Handle window close (window destroyed event, disconnected from server and socket becomes invalid (check select return?)).\ +Bind texture and cache the bound texture to reduce calls to opengl. +Use gl triangle instead of quad. +Fix crash on exit. +Support using multiple textures in shaders by using glActiveTexture for each one and set the uniform sampler2D value for each as as the index. +Make sure clock is monotonic (there has been some issues with CLOCK\_MONOTONIC not being monotonic on linux). +Verify if using a separate glx context for every window is the correct approach. \ No newline at end of file diff --git a/include/mgl/mgl.h b/include/mgl/mgl.h index 15020e9..8e5e2a4 100644 --- a/include/mgl/mgl.h +++ b/include/mgl/mgl.h @@ -9,7 +9,6 @@ typedef struct mgl_context mgl_context; struct mgl_context { mgl_connection connection; - GLXContext glx_context; _XVisualInfo *visual_info; mgl_gl gl; }; diff --git a/include/mgl/window/window.h b/include/mgl/window/window.h index c1542b4..b30583b 100644 --- a/include/mgl/window/window.h +++ b/include/mgl/window/window.h @@ -5,6 +5,7 @@ #include "../system/vec.h" #include +typedef struct __GLXcontextRec *GLXContext; typedef struct mgl_event mgl_event; /* x11 window handle. TODO: Add others when wayland, etc is added */ typedef unsigned long mgl_window_handle; @@ -13,6 +14,7 @@ typedef struct mgl_window mgl_window; struct mgl_window { mgl_window_handle window; + GLXContext glx_context; mgl_vec2i size; mgl_vec2i cursor_position; }; 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