aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-10-28 17:10:41 +0200
committerdec05eba <dec05eba@protonmail.com>2021-10-28 17:32:34 +0200
commit14e3617736c63bd22b0785ad418acef825db221f (patch)
treedc18c593a1e74c4218657136772e4409094414af
parent1e3df56a5c91bce2ef7b03e31156721e2f76a063 (diff)
Use a separate glx context for every window
Fix vertex buffer causing crash on render if update is called with an empty list.
-rw-r--r--README.md9
-rw-r--r--TODO7
-rw-r--r--include/mgl/mgl.h1
-rw-r--r--include/mgl/window/window.h2
-rw-r--r--src/graphics/vertex_buffer.c15
-rw-r--r--src/mgl.c11
-rw-r--r--src/window/window.c16
7 files changed, 38 insertions, 23 deletions
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 <stdbool.h>
+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);
}
+