ngl: Set up buffers and arrays once

Keep the array buffer around, and use glBufferSubData
to update it when possible, and only set up the vertex
array once, too.
This commit is contained in:
Matthias Clasen
2021-03-19 01:19:54 -04:00
parent 8fdedbd73b
commit ffb277ee58
4 changed files with 60 additions and 37 deletions

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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);
gsk_ngl_buffer_submit (&self->vertices);
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));
/* 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);

View File

@@ -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.