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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user