diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-03-19 01:19:54 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-03-19 01:21:12 -0400 |
commit | ffb277ee58613ef6ab04d1e64eaf3cd54c110b40 (patch) | |
tree | 88c44e2af8e9281d29296d0226519370a32117ee | |
parent | 8fdedbd73b71608f970d3a8f99557122726f4729 (diff) | |
download | gtk+-ngl-setup-once.tar.gz |
ngl: Set up buffers and arrays oncengl-setup-once
Keep the array buffer around, and use glBufferSubData
to update it when possible, and only set up the vertex
array once, too.
-rw-r--r-- | gsk/ngl/gsknglbuffer.c | 21 | ||||
-rw-r--r-- | gsk/ngl/gsknglbufferprivate.h | 2 | ||||
-rw-r--r-- | gsk/ngl/gsknglcommandqueue.c | 71 | ||||
-rw-r--r-- | gsk/ngl/gsknglcommandqueueprivate.h | 3 |
4 files changed, 60 insertions, 37 deletions
diff --git a/gsk/ngl/gsknglbuffer.c b/gsk/ngl/gsknglbuffer.c index f65923d003..3a8a340898 100644 --- a/gsk/ngl/gsknglbuffer.c +++ b/gsk/ngl/gsknglbuffer.c @@ -45,25 +45,36 @@ gsk_ngl_buffer_init (GskNglBuffer *self, self->buffer = g_malloc (self->buffer_len); self->target = target; self->element_size = element_size; + self->vbo_size = 0; + self->vbo_id = 0; } GLuint gsk_ngl_buffer_submit (GskNglBuffer *buffer) { - GLuint id; + if (buffer->vbo_id == 0) + glGenBuffers (1, &buffer->vbo_id); - glGenBuffers (1, &id); - glBindBuffer (buffer->target, id); - glBufferData (buffer->target, buffer->buffer_pos, buffer->buffer, GL_STATIC_DRAW); + if (buffer->vbo_size < buffer->buffer_pos) + { + glBindBuffer (buffer->target, buffer->vbo_id); + glBufferData (buffer->target, buffer->buffer_pos, buffer->buffer, GL_DYNAMIC_DRAW); + buffer->vbo_size = buffer->buffer_pos; + } + else + { + glBufferSubData (buffer->target, 0, buffer->buffer_pos, buffer->buffer); + } buffer->buffer_pos = 0; buffer->count = 0; - return id; + return buffer->vbo_id; } void gsk_ngl_buffer_destroy (GskNglBuffer *buffer) { + glDeleteBuffers (1, &buffer->vbo_id); g_clear_pointer (&buffer->buffer, g_free); } diff --git a/gsk/ngl/gsknglbufferprivate.h b/gsk/ngl/gsknglbufferprivate.h index cbd21c83da..2b76b8cd8e 100644 --- a/gsk/ngl/gsknglbufferprivate.h +++ b/gsk/ngl/gsknglbufferprivate.h @@ -33,6 +33,8 @@ typedef struct _GskNglBuffer guint count; GLenum target; gsize element_size; + GLuint vbo_id; + gsize vbo_size; } GskNglBuffer; void gsk_ngl_buffer_init (GskNglBuffer *self, diff --git a/gsk/ngl/gsknglcommandqueue.c b/gsk/ngl/gsknglcommandqueue.c index bebd315823..da1ede281f 100644 --- a/gsk/ngl/gsknglcommandqueue.c +++ b/gsk/ngl/gsknglcommandqueue.c @@ -402,6 +402,9 @@ gsk_ngl_command_queue_dispose (GObject *object) gsk_ngl_command_binds_clear (&self->batch_binds); gsk_ngl_command_uniforms_clear (&self->batch_uniforms); + glDeleteVertexArrays (1, &self->vao_id); + self->vao_id = 0; + gsk_ngl_buffer_destroy (&self->vertices); G_OBJECT_CLASS (gsk_ngl_command_queue_parent_class)->dispose (object); @@ -929,6 +932,40 @@ gsk_ngl_command_queue_sort_batches (GskNglCommandQueue *self) g_free (seen_free); } +static void +init_vertex_array (GskNglCommandQueue *self) +{ + if (self->vao_id == 0) + { + glGenVertexArrays (1, &self->vao_id); + glBindVertexArray (self->vao_id); + + /* 0 = position location */ + glEnableVertexAttribArray (0); + glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, + sizeof (GskNglDrawVertex), + (void *) G_STRUCT_OFFSET (GskNglDrawVertex, position)); + + /* 1 = texture coord location */ + glEnableVertexAttribArray (1); + glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, + sizeof (GskNglDrawVertex), + (void *) G_STRUCT_OFFSET (GskNglDrawVertex, uv)); + + /* 2 = color location */ + glEnableVertexAttribArray (2); + glVertexAttribPointer (2, 4, GL_FLOAT, GL_FALSE, + sizeof (GskNglDrawVertex), + (void *) G_STRUCT_OFFSET (GskNglDrawVertex, color)); + + /* 3 = color2 location */ + glEnableVertexAttribArray (3); + glVertexAttribPointer (3, 4, GL_FLOAT, GL_FALSE, + sizeof (GskNglDrawVertex), + (void *) G_STRUCT_OFFSET (GskNglDrawVertex, color2)); + } +} + /** * gsk_ngl_command_queue_execute: * @self: a #GskNglCommandQueue @@ -954,8 +991,6 @@ gsk_ngl_command_queue_execute (GskNglCommandQueue *self, guint n_binds = 0; guint n_fbos = 0; guint n_uniforms = 0; - guint vao_id; - guint vbo_id; int textures[4]; int framebuffer = -1; int next_batch_index; @@ -987,34 +1022,9 @@ gsk_ngl_command_queue_execute (GskNglCommandQueue *self, glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation (GL_FUNC_ADD); - glGenVertexArrays (1, &vao_id); - glBindVertexArray (vao_id); - - vbo_id = gsk_ngl_buffer_submit (&self->vertices); - - /* 0 = position location */ - glEnableVertexAttribArray (0); - glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, - sizeof (GskNglDrawVertex), - (void *) G_STRUCT_OFFSET (GskNglDrawVertex, position)); + gsk_ngl_buffer_submit (&self->vertices); - /* 1 = texture coord location */ - glEnableVertexAttribArray (1); - glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, - sizeof (GskNglDrawVertex), - (void *) G_STRUCT_OFFSET (GskNglDrawVertex, uv)); - - /* 2 = color location */ - glEnableVertexAttribArray (2); - glVertexAttribPointer (2, 4, GL_FLOAT, GL_FALSE, - sizeof (GskNglDrawVertex), - (void *) G_STRUCT_OFFSET (GskNglDrawVertex, color)); - - /* 3 = color2 location */ - glEnableVertexAttribArray (3); - glVertexAttribPointer (3, 4, GL_FLOAT, GL_FALSE, - sizeof (GskNglDrawVertex), - (void *) G_STRUCT_OFFSET (GskNglDrawVertex, color2)); + init_vertex_array (self); /* Setup initial scissor clip */ if (scissor != NULL) @@ -1141,9 +1151,6 @@ gsk_ngl_command_queue_execute (GskNglCommandQueue *self, next_batch_index = batch->any.next_batch_index; } - glDeleteBuffers (1, &vbo_id); - glDeleteVertexArrays (1, &vao_id); - gdk_profiler_set_int_counter (self->metrics.n_binds, n_binds); gdk_profiler_set_int_counter (self->metrics.n_uniforms, n_uniforms); gdk_profiler_set_int_counter (self->metrics.n_fbos, n_fbos); diff --git a/gsk/ngl/gsknglcommandqueueprivate.h b/gsk/ngl/gsknglcommandqueueprivate.h index 9a35326cee..abf43ba0a5 100644 --- a/gsk/ngl/gsknglcommandqueueprivate.h +++ b/gsk/ngl/gsknglcommandqueueprivate.h @@ -228,6 +228,9 @@ struct _GskNglCommandQueue /* String storage for debug groups */ GStringChunk *debug_groups; + /* The vertex array */ + GLuint vao_id; + /* Discovered max texture size when loading the command queue so that we * can either scale down or slice textures to fit within this size. Assumed * to be both height and width. |