[gtk/wip/chergert/glproto: 462/493] implement basic batch reordering by framebuffer
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glproto: 462/493] implement basic batch reordering by framebuffer
- Date: Fri, 19 Feb 2021 02:25:24 +0000 (UTC)
commit 3840fb88d8d7125a5d25fd9839b97b39d278ffdf
Author: Christian Hergert <chergert redhat com>
Date: Mon Feb 15 17:19:25 2021 -0800
implement basic batch reordering by framebuffer
Still a lot we can do here, just some basics.
gsk/next/gskglcommandqueue.c | 285 ++++++++++++++++++------------------
gsk/next/gskglcommandqueueprivate.h | 25 ++--
gsk/next/gskgldriver.c | 7 +-
gsk/next/gskglprogram.c | 70 +--------
gsk/next/gskglprogramprivate.h | 14 +-
gsk/next/gskgluniformstate.c | 24 ++-
gsk/next/gskgluniformstateprivate.h | 158 +++++++-------------
7 files changed, 235 insertions(+), 348 deletions(-)
---
diff --git a/gsk/next/gskglcommandqueue.c b/gsk/next/gskglcommandqueue.c
index 6fdda74aff..2db79e2b13 100644
--- a/gsk/next/gskglcommandqueue.c
+++ b/gsk/next/gskglcommandqueue.c
@@ -36,6 +36,8 @@
#include "gskglcommandqueueprivate.h"
#include "gskgluniformstateprivate.h"
+#include "inlinearray.h"
+
G_DEFINE_TYPE (GskGLCommandQueue, gsk_gl_command_queue, G_TYPE_OBJECT)
static inline void
@@ -166,13 +168,13 @@ gsk_gl_command_queue_print_batch (GskGLCommandQueue *self,
for (guint i = 0; i < batch->draw.bind_count; i++)
{
- const GskGLCommandBind *bind = &g_array_index (self->batch_binds, GskGLCommandBind,
batch->draw.bind_offset + i);
+ const GskGLCommandBind *bind = &self->batch_binds.elements[batch->draw.bind_offset + i];
g_print (" Bind[%d]: %u\n", bind->texture, bind->id);
}
for (guint i = 0; i < batch->draw.uniform_count; i++)
{
- const GskGLCommandUniform *uniform = &g_array_index (self->batch_uniforms, GskGLCommandUniform,
batch->draw.uniform_offset + i);
+ const GskGLCommandUniform *uniform = &self->batch_uniforms.elements[batch->draw.uniform_offset +
i];
g_printerr (" Uniform[%02d]: ", uniform->location);
print_uniform (uniform->info.format,
uniform->info.array_count,
@@ -227,6 +229,56 @@ gsk_gl_command_queue_capture_png (GskGLCommandQueue *self,
g_free (data);
}
+static inline guint
+snapshot_attachments (const GskGLAttachmentState *state,
+ GskGLCommandBindArray *array)
+{
+ GskGLCommandBind *bind = gsk_gl_command_bind_array_append_n (array, G_N_ELEMENTS (state->textures));
+ guint count = 0;
+
+ for (guint i = 0; i < G_N_ELEMENTS (state->textures); i++)
+ {
+ if (state->textures[i].id)
+ {
+ bind[count].id = state->textures[i].id;
+ bind[count].texture = state->textures[i].texture;
+ count++;
+ }
+ }
+
+ if (count != G_N_ELEMENTS (state->textures))
+ array->len -= G_N_ELEMENTS (state->textures) - count;
+
+ return count;
+}
+
+static inline guint
+snapshot_uniforms (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ GskGLCommandUniformArray *array)
+{
+ GskGLCommandUniform *uniform = gsk_gl_command_uniform_array_append_n (array, program->n_sparse);
+ guint count = 0;
+
+ for (guint i = 0; i < program->n_sparse; i++)
+ {
+ guint location = program->sparse[i];
+ const GskGLUniformInfo *info = &program->uniforms[location].info;
+
+ if (!info->initial)
+ {
+ uniform[count].location = location;
+ uniform[count].info = *info;
+ count++;
+ }
+ }
+
+ if (count != program->n_sparse)
+ array->len -= program->n_sparse - count;
+
+ return count;
+}
+
static void
gsk_gl_command_queue_dispose (GObject *object)
{
@@ -237,12 +289,12 @@ gsk_gl_command_queue_dispose (GObject *object)
g_clear_object (&self->profiler);
g_clear_object (&self->gl_profiler);
g_clear_object (&self->context);
- g_clear_pointer (&self->batches, g_free);
g_clear_pointer (&self->attachments, gsk_gl_attachment_state_unref);
g_clear_pointer (&self->uniforms, gsk_gl_uniform_state_unref);
- g_clear_pointer (&self->batch_draws, g_array_unref);
- g_clear_pointer (&self->batch_binds, g_array_unref);
- g_clear_pointer (&self->batch_uniforms, g_array_unref);
+
+ gsk_gl_command_batch_array_clear (&self->batches);
+ gsk_gl_command_bind_array_clear (&self->batch_binds);
+ gsk_gl_command_uniform_array_clear (&self->batch_uniforms);
gsk_gl_buffer_destroy (&self->vertices);
@@ -262,11 +314,10 @@ gsk_gl_command_queue_init (GskGLCommandQueue *self)
{
self->max_texture_size = -1;
- self->batches_len = 128;
- self->batches = g_new0 (GskGLCommandBatch, self->batches_len);
- self->batch_draws = g_array_new (FALSE, FALSE, sizeof (GskGLCommandDraw));
- self->batch_binds = g_array_new (FALSE, FALSE, sizeof (GskGLCommandBind));
- self->batch_uniforms = g_array_new (FALSE, FALSE, sizeof (GskGLCommandUniform));
+ gsk_gl_command_batch_array_init (&self->batches, 128);
+ gsk_gl_command_bind_array_init (&self->batch_binds, 1024);
+ gsk_gl_command_uniform_array_init (&self->batch_uniforms, 2048);
+
self->debug_groups = g_string_chunk_new (4096);
gsk_gl_buffer_init (&self->vertices, GL_ARRAY_BUFFER, sizeof (GskGLDrawVertex));
@@ -304,13 +355,7 @@ begin_next_batch (GskGLCommandQueue *self)
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
- if G_UNLIKELY (self->n_batches == self->batches_len)
- {
- self->batches_len *= 2;
- self->batches = g_realloc_n (self->batches, self->batches_len, sizeof (GskGLCommandBatch));
- }
-
- batch = &self->batches[self->n_batches++];
+ batch = gsk_gl_command_batch_array_append (&self->batches);
batch->any.next_batch_index = -1;
batch->any.prev_batch_index = self->tail_batch_index;
@@ -323,16 +368,16 @@ enqueue_batch (GskGLCommandQueue *self)
guint index;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
- g_assert (self->n_batches > 0);
+ g_assert (self->batches.len > 0);
- index = self->n_batches - 1;
+ index = self->batches.len - 1;
if (self->head_batch_index == -1)
self->head_batch_index = index;
if (self->tail_batch_index != -1)
{
- GskGLCommandBatch *prev = &self->batches[self->tail_batch_index];
+ GskGLCommandBatch *prev = &self->batches.elements[self->tail_batch_index];
prev->any.next_batch_index = index;
}
@@ -344,9 +389,9 @@ static void
discard_batch (GskGLCommandQueue *self)
{
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
- g_assert (self->n_batches > 0);
+ g_assert (self->batches.len > 0);
- self->n_batches--;
+ self->batches.len--;
}
void
@@ -360,7 +405,10 @@ gsk_gl_command_queue_begin_draw (GskGLCommandQueue *self,
g_assert (self->in_draw == FALSE);
g_assert (viewport != NULL);
- if (self->n_batches == G_MAXINT16)
+ /* Our internal links use 16-bits, so that is our max number
+ * of batches we can have in one frame.
+ */
+ if (self->batches.len == G_MAXINT16)
return;
self->program_info = program;
@@ -373,9 +421,9 @@ gsk_gl_command_queue_begin_draw (GskGLCommandQueue *self,
batch->any.viewport.height = viewport->size.height;
batch->draw.framebuffer = 0;
batch->draw.uniform_count = 0;
- batch->draw.uniform_offset = self->batch_uniforms->len;
+ batch->draw.uniform_offset = self->batch_uniforms.len;
batch->draw.bind_count = 0;
- batch->draw.bind_offset = self->batch_binds->len;
+ batch->draw.bind_offset = self->batch_binds.len;
batch->draw.vbo_count = 0;
batch->draw.vbo_offset = gsk_gl_buffer_get_offset (&self->vertices);
@@ -384,41 +432,20 @@ gsk_gl_command_queue_begin_draw (GskGLCommandQueue *self,
self->in_draw = TRUE;
}
-static inline void
-gsk_gl_command_queue_uniform_snapshot_cb (const GskGLUniformInfo *info,
- guint location,
- gpointer user_data)
-{
- GArray *uniforms = user_data;
-
- g_assert (info != NULL);
- g_assert (info->format > 0);
- g_assert (location < GL_MAX_UNIFORM_LOCATIONS);
-
- /* To avoid calling g_array_set_size() a bunch in this callback,
- * we've already "set_size()" before the callback was called and
- * so we can instead be certain the size is large enough and use
- * ++ on length directly.
- */
- g_array_index (uniforms, GskGLCommandUniform, uniforms->len).location = location;
- g_array_index (uniforms, GskGLCommandUniform, uniforms->len).info = *info;
- uniforms->len++;
-}
-
void
gsk_gl_command_queue_end_draw (GskGLCommandQueue *self)
{
GskGLCommandBatch *last_batch;
GskGLCommandBatch *batch;
- guint n_changed;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
- g_assert (self->n_batches > 0);
+ g_assert (self->batches.len > 0);
- if (self->n_batches == G_MAXINT16)
+ /* Max batches is 16-bit */
+ if (self->batches.len == G_MAXINT16)
return;
- batch = &self->batches[self->n_batches - 1];
+ batch = gsk_gl_command_batch_array_tail (&self->batches);
g_assert (self->in_draw == TRUE);
g_assert (batch->any.kind == GSK_GL_COMMAND_KIND_DRAW);
@@ -435,67 +462,32 @@ gsk_gl_command_queue_end_draw (GskGLCommandQueue *self)
self->attachments->fbo.changed = FALSE;
self->fbo_max = MAX (self->fbo_max, self->attachments->fbo.id);
- /* To avoid many g_array_set_size() calls, we first resize the
- * array to be large enough for all our changes. Then we just ++
- * from the callback.
+ /* Save our full uniform state for this draw so we can possibly
+ * reorder the draw later.
*/
- n_changed = self->program_info->n_changed;
+ batch->draw.uniform_offset = self->batch_uniforms.len;
+ batch->draw.uniform_count = snapshot_uniforms (self->uniforms, self->program_info, &self->batch_uniforms);
- if (n_changed)
+ /* Track the bind attachments that changed */
+ if (self->program_info->has_attachments)
{
- g_array_set_size (self->batch_uniforms, self->batch_uniforms->len + n_changed);
- self->batch_uniforms->len -= n_changed;
-
- /* Store information about uniforms that changed */
- batch->draw.uniform_offset = self->batch_uniforms->len;
- gsk_gl_uniform_state_snapshot (self->uniforms,
- self->program_info,
- gsk_gl_command_queue_uniform_snapshot_cb,
- self->batch_uniforms);
- batch->draw.uniform_count = n_changed;
+ batch->draw.bind_offset = self->batch_binds.len;
+ batch->draw.bind_count = snapshot_attachments (self->attachments, &self->batch_binds);
}
else
{
- batch->draw.uniform_offset = 0;
- batch->draw.uniform_count = 0;
- }
-
- /* Track the bind attachments that changed */
- if (self->attachments->n_changed > 0)
- {
- GskGLCommandBind *bind;
-
- batch->draw.bind_offset = self->batch_binds->len;
- batch->draw.bind_count = self->attachments->n_changed;
-
- g_array_set_size (self->batch_binds, self->batch_binds->len + batch->draw.bind_count);
- bind = &g_array_index (self->batch_binds, GskGLCommandBind, self->batch_binds->len -
batch->draw.bind_count);
-
- for (guint i = 0;
- (self->attachments->n_changed > 0 &&
- i < G_N_ELEMENTS (self->attachments->textures));
- i++)
- {
- GskGLBindTexture *texture = &self->attachments->textures[i];
-
- if (texture->changed)
- {
- texture->changed = FALSE;
- bind->texture = texture->texture;
- bind->id = texture->id;
- bind++;
- self->attachments->n_changed--;
- }
- }
+ batch->draw.bind_offset = 0;
+ batch->draw.bind_count = 0;
}
- if (self->n_batches > 1)
- last_batch = &self->batches[self->n_batches - 2];
+ if (self->batches.len > 1)
+ last_batch = &self->batches.elements[self->batches.len - 2];
else
last_batch = NULL;
/* Do simple chaining of draw to last batch. */
/* TODO: Use merging capabilities for out-or-order batching */
+#if 0
if (batch->draw.uniform_count == 0 &&
batch->draw.bind_count == 0 &&
last_batch != NULL &&
@@ -513,6 +505,9 @@ gsk_gl_command_queue_end_draw (GskGLCommandQueue *self)
{
enqueue_batch (self);
}
+#else
+ enqueue_batch (self);
+#endif
self->in_draw = FALSE;
self->program_info = NULL;
@@ -540,12 +535,12 @@ gsk_gl_command_queue_split_draw (GskGLCommandQueue *self)
graphene_rect_t viewport;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
- g_assert (self->n_batches > 0);
+ g_assert (self->batches.len > 0);
g_assert (self->in_draw == TRUE);
program = self->program_info;
- batch = &self->batches[self->n_batches - 1];
+ batch = gsk_gl_command_batch_array_tail (&self->batches);
g_assert (batch->any.kind == GSK_GL_COMMAND_KIND_DRAW);
@@ -568,7 +563,7 @@ gsk_gl_command_queue_clear (GskGLCommandQueue *self,
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
g_assert (self->in_draw == FALSE);
- if (self->n_batches == G_MAXINT16)
+ if (self->batches.len == G_MAXINT16)
return;
if (clear_bits == 0)
@@ -600,7 +595,7 @@ gsk_gl_command_queue_push_debug_group (GskGLCommandQueue *self,
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
g_assert (self->in_draw == FALSE);
- if (self->n_batches == G_MAXINT16)
+ if (self->batches.len == G_MAXINT16)
return;
batch = begin_next_batch (self);
@@ -622,7 +617,7 @@ gsk_gl_command_queue_pop_debug_group (GskGLCommandQueue *self)
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
g_assert (self->in_draw == FALSE);
- if (self->n_batches == G_MAXINT16)
+ if (self->batches.len == G_MAXINT16)
return;
batch = begin_next_batch (self);
@@ -744,10 +739,10 @@ apply_uniform (gconstpointer dataptr,
break;
case GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT:
- if (info.send_corners)
+ //if (info.send_corners)
glUniform4fv (location, 3, dataptr);
- else
- glUniform4fv (location, 1, dataptr);
+ //else
+ //glUniform4fv (location, 1, dataptr);
break;
default:
@@ -818,12 +813,12 @@ gsk_gl_command_queue_unlink (GskGLCommandQueue *self,
if (batch->any.prev_batch_index == -1)
self->head_batch_index = batch->any.next_batch_index;
else
- self->batches[batch->any.prev_batch_index].any.next_batch_index = batch->any.next_batch_index;
+ self->batches.elements[batch->any.prev_batch_index].any.next_batch_index = batch->any.next_batch_index;
if (batch->any.next_batch_index == -1)
self->tail_batch_index = batch->any.prev_batch_index;
else
- self->batches[batch->any.next_batch_index].any.prev_batch_index = batch->any.prev_batch_index;
+ self->batches.elements[batch->any.next_batch_index].any.prev_batch_index = batch->any.prev_batch_index;
batch->any.prev_batch_index = -1;
batch->any.next_batch_index = -1;
@@ -834,19 +829,22 @@ gsk_gl_command_queue_insert_before (GskGLCommandQueue *self,
GskGLCommandBatch *batch,
GskGLCommandBatch *sibling)
{
- int sibling_index = sibling - self->batches;
- int index = batch - self->batches;
+ int sibling_index;
+ int index;
+
+ g_assert (batch >= self->batches.elements);
+ g_assert (batch < &self->batches.elements[self->batches.len]);
+ g_assert (sibling >= self->batches.elements);
+ g_assert (sibling < &self->batches.elements[self->batches.len]);
- g_assert (batch >= self->batches);
- g_assert (batch < &self->batches[self->n_batches]);
- g_assert (sibling >= self->batches);
- g_assert (sibling < &self->batches[self->n_batches]);
+ index = gsk_gl_command_batch_array_index_of (&self->batches, batch);
+ sibling_index = gsk_gl_command_batch_array_index_of (&self->batches, sibling);
batch->any.next_batch_index = sibling_index;
batch->any.prev_batch_index = sibling->any.prev_batch_index;
if (batch->any.prev_batch_index > -1)
- self->batches[batch->any.prev_batch_index].any.next_batch_index = index;
+ self->batches.elements[batch->any.prev_batch_index].any.next_batch_index = index;
sibling->any.prev_batch_index = index;
@@ -883,12 +881,12 @@ gsk_gl_command_queue_sort_batches (GskGLCommandQueue *self)
while (index >= 0)
{
- GskGLCommandBatch *batch = &self->batches[index];
+ GskGLCommandBatch *batch = &self->batches.elements[index];
int cur_index = index;
int fbo = -1;
g_assert (index > -1);
- g_assert (index < self->n_batches);
+ g_assert (index < self->batches.len);
switch (batch->any.kind)
{
@@ -911,7 +909,7 @@ gsk_gl_command_queue_sort_batches (GskGLCommandQueue *self)
index = batch->any.prev_batch_index;
g_assert (index >= -1);
- g_assert (index < (int)self->n_batches);
+ g_assert (index < (int)self->batches.len);
g_assert (fbo >= -1);
if (fbo == -1)
@@ -919,12 +917,12 @@ gsk_gl_command_queue_sort_batches (GskGLCommandQueue *self)
g_assert (fbo <= self->fbo_max);
g_assert (seen[fbo] >= -1);
- g_assert (seen[fbo] < (int)self->n_batches);
+ g_assert (seen[fbo] < (int)self->batches.len);
if (seen[fbo] != -1 && seen[fbo] != batch->any.next_batch_index)
{
int mru_index = seen[fbo];
- GskGLCommandBatch *mru = &self->batches[mru_index];
+ GskGLCommandBatch *mru = &self->batches.elements[mru_index];
g_assert (mru_index > -1);
@@ -968,6 +966,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
gboolean has_scissor = scissor != NULL;
gboolean scissor_state = -1;
graphene_rect_t scissor_test;
+ int textures[8];
int framebuffer = -1;
GLuint vao_id;
int next_batch_index;
@@ -983,10 +982,13 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
g_assert (self->in_draw == FALSE);
- if (self->n_batches == 0)
+ if (self->batches.len == 0)
return;
-#if 0
+ for (guint i = 0; i < G_N_ELEMENTS (textures); i++)
+ textures[i] = -1;
+
+#if 1
/* TODO: For batch sorting to work, we need to snapshot the whole uniform
* state with each batch so that we can re-apply all uniforms since what
* we captured may not reflect the current state.
@@ -1046,10 +1048,10 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
while (next_batch_index >= 0)
{
- const GskGLCommandBatch *batch = &self->batches[next_batch_index];
+ const GskGLCommandBatch *batch = &self->batches.elements[next_batch_index];
g_assert (next_batch_index >= 0);
- g_assert (next_batch_index < self->n_batches);
+ g_assert (next_batch_index < self->batches.len);
g_assert (batch->any.next_batch_index != next_batch_index);
count++;
@@ -1074,13 +1076,13 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
case GSK_GL_COMMAND_KIND_PUSH_DEBUG_GROUP:
#ifdef G_ENABLE_DEBUG
- gdk_gl_context_push_debug_group (self->context, batch->debug_group.debug_group);
+ //gdk_gl_context_push_debug_group (self->context, batch->debug_group.debug_group);
#endif
break;
case GSK_GL_COMMAND_KIND_POP_DEBUG_GROUP:
#ifdef G_ENABLE_DEBUG
- gdk_gl_context_pop_debug_group (self->context);
+ //gdk_gl_context_pop_debug_group (self->context);
#endif
break;
@@ -1104,31 +1106,37 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
if G_UNLIKELY (batch->draw.bind_count > 0)
{
- const GskGLCommandBind *bind = &g_array_index (self->batch_binds, GskGLCommandBind,
batch->draw.bind_offset);
+ const GskGLCommandBind *bind = &self->batch_binds.elements[batch->draw.bind_offset];
for (guint i = 0; i < batch->draw.bind_count; i++)
{
- if (active != bind->texture)
+ if (textures[bind->texture] != bind->id)
{
- active = bind->texture;
- glActiveTexture (GL_TEXTURE0 + bind->texture);
+ if (active != bind->texture)
+ {
+ active = bind->texture;
+ glActiveTexture (GL_TEXTURE0 + bind->texture);
+ }
+
+ glBindTexture (GL_TEXTURE_2D, bind->id);
+ textures[bind->texture] = bind->id;
}
- glBindTexture (GL_TEXTURE_2D, bind->id);
bind++;
}
+
+ n_binds += batch->draw.bind_count;
}
if (batch->draw.uniform_count > 0)
{
- const GskGLCommandUniform *u = &g_array_index (self->batch_uniforms, GskGLCommandUniform,
batch->draw.uniform_offset);
+ const GskGLCommandUniform *u = &self->batch_uniforms.elements[batch->draw.uniform_offset];
for (guint i = 0; i < batch->draw.uniform_count; i++, u++)
apply_uniform (gsk_gl_uniform_state_get_uniform_data (self->uniforms, u->info.offset),
u->info, u->location);
n_uniforms += batch->draw.uniform_count;
- n_binds += batch->draw.bind_count;
}
glDrawArrays (GL_TRIANGLES, batch->draw.vbo_offset, batch->draw.vbo_count);
@@ -1187,7 +1195,7 @@ void
gsk_gl_command_queue_begin_frame (GskGLCommandQueue *self)
{
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
- g_assert (self->n_batches == 0);
+ g_assert (self->batches.len == 0);
gsk_gl_command_queue_make_current (self);
@@ -1235,10 +1243,9 @@ gsk_gl_command_queue_end_frame (GskGLCommandQueue *self)
g_string_chunk_clear (self->debug_groups);
- self->n_batches = 0;
- self->batch_draws->len = 0;
- self->batch_uniforms->len = 0;
- self->batch_binds->len = 0;
+ self->batches.len = 0;
+ self->batch_binds.len = 0;
+ self->batch_uniforms.len = 0;
self->n_uploads = 0;
self->tail_batch_index = -1;
self->in_frame = FALSE;
diff --git a/gsk/next/gskglcommandqueueprivate.h b/gsk/next/gskglcommandqueueprivate.h
index 98d2f03e56..6402d878f6 100644
--- a/gsk/next/gskglcommandqueueprivate.h
+++ b/gsk/next/gskglcommandqueueprivate.h
@@ -28,6 +28,8 @@
#include "gskglattachmentstateprivate.h"
#include "gskgluniformstateprivate.h"
+#include "inlinearray.h"
+
#include "../gl/gskglprofilerprivate.h"
G_BEGIN_DECLS
@@ -180,6 +182,10 @@ typedef union _GskGLCommandBatch
G_STATIC_ASSERT (sizeof (GskGLCommandBatch) == 32);
+DEFINE_INLINE_ARRAY (GskGLCommandBatch, gsk_gl_command_batch_array)
+DEFINE_INLINE_ARRAY (GskGLCommandBind, gsk_gl_command_bind_array)
+DEFINE_INLINE_ARRAY (GskGLCommandUniform, gsk_gl_command_uniform_array)
+
struct _GskGLCommandQueue
{
GObject parent_instance;
@@ -192,9 +198,7 @@ struct _GskGLCommandQueue
* together. The idea here is that we reduce the need for pointers so that
* using g_realloc()'d arrays is fine.
*/
- GskGLCommandBatch *batches;
- gsize batches_len;
- gsize n_batches;
+ GskGLCommandBatchArray batches;
/* Contains array of vertices and some wrapper code to help upload them
* to the GL driver. We can also tweak this to use double buffered arrays
@@ -224,24 +228,17 @@ struct _GskGLCommandQueue
GskProfiler *profiler;
GskGLProfiler *gl_profiler;
- /* Array of GskGLCommandDraw which allows us to have a static size field
- * in GskGLCommandBatch to coalesce draws. Multiple GskGLCommandDraw may
- * be processed together (and out-of-order) to reduce the number of state
- * changes when submitting commands.
- */
- GArray *batch_draws;
-
/* Array of GskGLCommandBind which denote what textures need to be attached
* to which slot. GskGLCommandDraw.bind_offset and bind_count reference this
* array to determine what to attach.
*/
- GArray *batch_binds;
+ GskGLCommandBindArray batch_binds;
/* Array of GskGLCommandUniform denoting which uniforms must be updated
* before the glDrawArrays() may be called. These are referenced from the
* GskGLCommandDraw.uniform_offset and uniform_count fields.
*/
- GArray *batch_uniforms;
+ GskGLCommandUniformArray batch_uniforms;
/* String storage for debug groups */
GStringChunk *debug_groups;
@@ -333,13 +330,13 @@ void gsk_gl_command_queue_split_draw (GskGLCommandQueue
static inline GskGLCommandBatch *
gsk_gl_command_queue_get_batch (GskGLCommandQueue *self)
{
- return &self->batches[self->n_batches - 1];
+ return gsk_gl_command_batch_array_tail (&self->batches);
}
static inline GskGLDrawVertex *
gsk_gl_command_queue_add_vertices (GskGLCommandQueue *self)
{
- self->batches[self->n_batches - 1].draw.vbo_count += GSK_GL_N_VERTICES;
+ gsk_gl_command_queue_get_batch (self)->draw.vbo_count += GSK_GL_N_VERTICES;
return gsk_gl_buffer_advance (&self->vertices, GSK_GL_N_VERTICES);
}
diff --git a/gsk/next/gskgldriver.c b/gsk/next/gskgldriver.c
index 5f089d2cb9..626e84f457 100644
--- a/gsk/next/gskgldriver.c
+++ b/gsk/next/gskgldriver.c
@@ -364,6 +364,7 @@ gsk_next_driver_load_programs (GskNextDriver *self,
G_STMT_START { \
GskGLProgram *program; \
gboolean have_alpha; \
+ gboolean have_source; \
\
gsk_gl_compiler_set_source_from_resource (compiler, GSK_GL_COMPILER_ALL, resource); \
\
@@ -371,7 +372,7 @@ gsk_next_driver_load_programs (GskNextDriver *self,
goto failure; \
\
have_alpha = gsk_gl_program_add_uniform (program, "u_alpha", UNIFORM_SHARED_ALPHA); \
- gsk_gl_program_add_uniform (program, "u_source", UNIFORM_SHARED_SOURCE); \
+ have_source = gsk_gl_program_add_uniform (program, "u_source", UNIFORM_SHARED_SOURCE); \
gsk_gl_program_add_uniform (program, "u_clip_rect", UNIFORM_SHARED_CLIP_RECT); \
gsk_gl_program_add_uniform (program, "u_viewport", UNIFORM_SHARED_VIEWPORT); \
gsk_gl_program_add_uniform (program, "u_projection", UNIFORM_SHARED_PROJECTION); \
@@ -379,7 +380,7 @@ gsk_next_driver_load_programs (GskNextDriver *self,
\
uniforms \
\
- gsk_gl_program_uniforms_added (program); \
+ gsk_gl_program_uniforms_added (program, have_source); \
\
if (have_alpha) \
gsk_gl_program_set_uniform1f (program, UNIFORM_SHARED_ALPHA, 0, 1.0f); \
@@ -1129,7 +1130,7 @@ gsk_next_driver_lookup_shader (GskNextDriver *self,
for (guint i = n_uniforms; i < G_N_ELEMENTS (program->args_locations); i++)
program->args_locations[i] = -1;
- gsk_gl_program_uniforms_added (program);
+ gsk_gl_program_uniforms_added (program, TRUE);
if (have_alpha)
gsk_gl_program_set_uniform1f (program, UNIFORM_SHARED_ALPHA, 0, 1.0f);
diff --git a/gsk/next/gskglprogram.c b/gsk/next/gskglprogram.c
index eb7c7af128..679a704f7a 100644
--- a/gsk/next/gskglprogram.c
+++ b/gsk/next/gskglprogram.c
@@ -151,74 +151,10 @@ gsk_gl_program_delete (GskGLProgram *self)
self->id = -1;
}
-void
-gsk_gl_program_begin_draw (GskGLProgram *self,
- const graphene_rect_t *viewport,
- const graphene_matrix_t *projection,
- const graphene_matrix_t *modelview,
- const GskRoundedRect *clip,
- float alpha)
-{
- g_assert (GSK_IS_GL_PROGRAM (self));
- g_assert (viewport != NULL);
- g_assert (projection != NULL);
- g_assert (modelview != NULL);
- g_assert (clip != NULL);
-
- gsk_gl_command_queue_begin_draw (self->driver->command_queue, self->program_info, viewport);
-
- if (self->uniform_locations[UNIFORM_SHARED_VIEWPORT] > -1)
- gsk_gl_uniform_state_set4fv (self->uniforms,
- self->program_info,
- self->uniform_locations[UNIFORM_SHARED_VIEWPORT],
- 0,
- 1,
- (const float *)viewport);
-
- if (self->uniform_locations[UNIFORM_SHARED_MODELVIEW] > -1)
- gsk_gl_uniform_state_set_matrix (self->uniforms,
- self->program_info,
- self->uniform_locations[UNIFORM_SHARED_MODELVIEW],
- 0,
- modelview);
-
- if (self->uniform_locations[UNIFORM_SHARED_PROJECTION] > -1)
- gsk_gl_uniform_state_set_matrix (self->uniforms,
- self->program_info,
- self->uniform_locations[UNIFORM_SHARED_PROJECTION],
- 0,
- projection);
-
- if (self->uniform_locations[UNIFORM_SHARED_CLIP_RECT] > -1)
- {
- if (clip != NULL)
- gsk_gl_uniform_state_set_rounded_rect (self->uniforms,
- self->program_info,
- self->uniform_locations[UNIFORM_SHARED_CLIP_RECT],
- 0,
- clip);
- else
- gsk_gl_uniform_state_set_rounded_rect (self->uniforms,
- self->program_info,
- self->uniform_locations[UNIFORM_SHARED_CLIP_RECT],
- 0,
- &GSK_ROUNDED_RECT_INIT (0,
- 0,
- viewport->size.width,
- viewport->size.height));
- }
-
- if (self->uniform_locations[UNIFORM_SHARED_ALPHA] > -1)
- gsk_gl_uniform_state_set1f (self->uniforms,
- self->program_info,
- self->uniform_locations[UNIFORM_SHARED_ALPHA],
- 0,
- alpha);
-}
-
/**
* gsk_gl_program_uniforms_added:
* @self: a #GskGLProgram
+ * @has_attachments: if any uniform is for a bind/texture attachment
*
* This function should be called after all of the uniforms ahve
* been added with gsk_gl_program_add_uniform().
@@ -228,11 +164,13 @@ gsk_gl_program_begin_draw (GskGLProgram *self,
* runtime for comparison data.
*/
void
-gsk_gl_program_uniforms_added (GskGLProgram *self)
+gsk_gl_program_uniforms_added (GskGLProgram *self,
+ gboolean has_attachments)
{
g_return_if_fail (GSK_IS_GL_PROGRAM (self));
g_return_if_fail (self->uniforms == NULL);
self->uniforms = self->driver->command_queue->uniforms;
self->program_info = gsk_gl_uniform_state_get_program (self->uniforms, self->id, self->n_uniforms);
+ self->program_info->has_attachments = has_attachments;
}
diff --git a/gsk/next/gskglprogramprivate.h b/gsk/next/gskglprogramprivate.h
index f5e04395f6..beadf48758 100644
--- a/gsk/next/gskglprogramprivate.h
+++ b/gsk/next/gskglprogramprivate.h
@@ -55,10 +55,7 @@ struct _GskGLProgram
int args_locations[8];
int size_location;
- /* Used to avoid comparing shared state */
- guint last_shared_state;
-
- /* Static array for uniform locations (only support up to 32) */
+ /* Static array for key->location transforms */
int uniform_locations[32];
};
@@ -68,14 +65,9 @@ GskGLProgram *gsk_gl_program_new (GskNextDriver *driver,
gboolean gsk_gl_program_add_uniform (GskGLProgram *self,
const char *name,
guint key);
-void gsk_gl_program_uniforms_added (GskGLProgram *self);
+void gsk_gl_program_uniforms_added (GskGLProgram *self,
+ gboolean has_attachments);
void gsk_gl_program_delete (GskGLProgram *self);
-void gsk_gl_program_begin_draw (GskGLProgram *self,
- const graphene_rect_t *viewport,
- const graphene_matrix_t *projection,
- const graphene_matrix_t *modelview,
- const GskRoundedRect *clip,
- float alpha);
#define gsk_gl_program_get_uniform_location(s,k) ((s)->uniform_locations[(k)])
diff --git a/gsk/next/gskgluniformstate.c b/gsk/next/gskgluniformstate.c
index 6e85853375..8bda3acf48 100644
--- a/gsk/next/gskgluniformstate.c
+++ b/gsk/next/gskgluniformstate.c
@@ -152,13 +152,14 @@ setup_info:
uniform_sizes[format] * MAX (1, array_count),
&offset);
- info->info.changed = FALSE;
info->info.format = format;
info->info.offset = offset;
info->info.array_count = array_count;
info->info.initial = TRUE;
info->stamp = 0;
+ program->sparse[program->n_sparse++] = location;
+
*infoptr = info;
return state->values_buf + offset;
@@ -182,13 +183,13 @@ gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
g_hash_table_iter_init (&iter, state->programs);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&program))
{
- for (guint j = 0; j < program->n_uniforms; j++)
+ for (guint j = 0; j < program->n_sparse; j++)
{
- GskGLUniformInfoElement *info = &program->uniforms[j];
+ guint location = program->sparse[j];
+ GskGLUniformInfoElement *info = &program->uniforms[location];
guint size;
- if (info->info.format == 0)
- continue;
+ g_assert (info->info.format > 0);
/* Calculate how much size is needed for the uniform, including arrays */
size = uniform_sizes[info->info.format] * MAX (1, info->info.array_count);
@@ -197,15 +198,12 @@ gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
allocator += gsk_gl_uniform_state_align (allocator, size);
info->info.offset = allocator;
- info->info.changed = FALSE;
info->info.initial = TRUE;
- info->info.send_corners = FALSE;
+ info->stamp = 0;
/* Now advance for this items data */
allocator += size;
}
-
- program->n_changed = 0;
}
state->values_pos = allocator;
@@ -238,14 +236,14 @@ gsk_gl_uniform_state_get_program (GskGLUniformState *state,
if (ret == NULL)
{
gsize uniform_size = n_uniforms * sizeof (GskGLUniformInfoElement);
- gsize changed_size = n_uniforms * sizeof (guint);
- gsize size = sizeof (GskGLUniformProgram) + uniform_size + changed_size;
+ gsize sparse_size = n_uniforms * sizeof (guint);
+ gsize size = sizeof (GskGLUniformProgram) + uniform_size + sparse_size;
ret = g_malloc0 (size);
ret->program_id = program;
ret->n_uniforms = n_uniforms;
- ret->n_changed = 0;
- ret->changed = (guint *)&ret->uniforms[n_uniforms];
+ ret->n_sparse = 0;
+ ret->sparse = (guint *)&ret->uniforms[n_uniforms];
for (guint i = 0; i < n_uniforms; i++)
ret->uniforms[i].info.initial = TRUE;
diff --git a/gsk/next/gskgluniformstateprivate.h b/gsk/next/gskgluniformstateprivate.h
index bc5ad197d4..b29f969b7b 100644
--- a/gsk/next/gskgluniformstateprivate.h
+++ b/gsk/next/gskgluniformstateprivate.h
@@ -39,13 +39,10 @@ typedef struct { guint v0; } Uniform1ui;
typedef struct _GskGLUniformInfo
{
- guint changed : 1;
guint format : 5;
guint array_count : 6;
guint initial : 1;
- guint send_corners : 1;
- guint unused : 2;
- guint offset : 16;
+ guint offset : 20;
} GskGLUniformInfo;
G_STATIC_ASSERT (sizeof (GskGLUniformInfo) == 4);
@@ -61,14 +58,14 @@ G_STATIC_ASSERT (sizeof (GskGLUniformInfoElement) == 8);
typedef struct _GskGLUniformProgram
{
guint program_id;
- guint n_uniforms;
+ guint n_uniforms : 12;
+ guint has_attachments : 1;
- /* To avoid walking unchanged locations in @uniform_info (or sparse
- * elements used to map location->info), we use this to determine the
- * specific uniforms that changed this frame.
+ /* To avoid walking our 1:1 array of location->uniform slots, we have
+ * a sparse index that allows us to skip the empty zones.
*/
- guint *changed;
- guint n_changed;
+ guint *sparse;
+ guint n_sparse;
/* Uniforms are provided inline at the end of structure to avoid
* an extra dereference.
@@ -133,10 +130,6 @@ GskGLUniformProgram *gsk_gl_uniform_state_get_program (GskGLUniformState
guint program,
guint n_uniforms);
void gsk_gl_uniform_state_end_frame (GskGLUniformState *state);
-void gsk_gl_uniform_state_snapshot (GskGLUniformState *self,
- guint program_id,
- GskGLUniformStateCallback callback,
- gpointer user_data);
gsize gsk_gl_uniform_format_size (GskGLUniformFormat format);
gpointer gsk_gl_uniform_state_init_value (GskGLUniformState *state,
GskGLUniformProgram *program,
@@ -150,23 +143,17 @@ gpointer gsk_gl_uniform_state_init_value (GskGLUniformState
#define gsk_gl_uniform_state_snapshot(state, program_info, callback, user_data) \
G_STMT_START { \
- if (program_info->n_changed) \
+ for (guint z = 0; z < program_info->n_sparse; z++) \
{ \
- for (guint z = 0; z < program_info->n_changed; z++) \
- { \
- guint location = program_info->changed[z]; \
- GskGLUniformInfo *info = &program_info->uniforms[location].info; \
+ guint location = program_info->sparse[z]; \
+ GskGLUniformInfoElement *info = &program_info->uniforms[location]; \
\
- g_assert (info->changed); \
+ g_assert (location < GL_MAX_UNIFORM_LOCATIONS); \
+ g_assert (location < program_info->n_uniforms); \
\
- callback (info, location, user_data); \
- \
- info->changed = FALSE; \
- info->send_corners = FALSE; \
- } \
+ if (info->info.format > 0) \
+ callback (&info->info, location, user_data); \
} \
- \
- program_info->n_changed = 0; \
} G_STMT_END
static inline gpointer
@@ -251,20 +238,12 @@ gsk_gl_uniform_state_realloc (GskGLUniformState *state,
} G_STMT_END
static inline void
-gsk_gl_uniform_program_changed (GskGLUniformProgram *program,
- GskGLUniformInfoElement *info,
- guint location,
- guint stamp)
+gsk_gl_uniform_info_changed (GskGLUniformInfoElement *info,
+ guint location,
+ guint stamp)
{
info->stamp = stamp;
-
- if (info->info.changed == FALSE)
- {
- info->info.changed = TRUE;
- info->info.initial = FALSE;
-
- program->changed[program->n_changed++] = location;
- }
+ info->info.initial = FALSE;
}
static inline void
@@ -282,11 +261,11 @@ gsk_gl_uniform_state_set1f (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1F, 1, location, stamp,
&info)))
{
- if (info->info.initial || u->v0 != value0)
+ if (stamp || info->info.initial || u->v0 != value0)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1f , 1);
u->v0 = value0;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -307,12 +286,12 @@ gsk_gl_uniform_state_set2f (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_2F, 1, location, stamp,
&info)))
{
- if (info->info.initial || u->v0 != value0 || u->v1 != value1)
+ if (stamp || info->info.initial || u->v0 != value0 || u->v1 != value1)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, 1);
u->v0 = value0;
u->v1 = value1;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -334,13 +313,13 @@ gsk_gl_uniform_state_set3f (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_3F, 1, location, stamp,
&info)))
{
- if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
+ if (stamp || info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, 1);
u->v0 = value0;
u->v1 = value1;
u->v2 = value2;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -363,14 +342,14 @@ gsk_gl_uniform_state_set4f (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_4F, 1, location, stamp,
&info)))
{
- if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
+ if (stamp || info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 !=
value3)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, 1);
u->v0 = value0;
u->v1 = value1;
u->v2 = value2;
u->v3 = value3;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -390,11 +369,11 @@ gsk_gl_uniform_state_set1ui (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1UI, 1, location, stamp,
&info)))
{
- if (info->info.initial || u->v0 != value0)
+ if (stamp || info->info.initial || u->v0 != value0)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1ui, 1);
u->v0 = value0;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -414,11 +393,11 @@ gsk_gl_uniform_state_set1i (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1I, 1, location, stamp,
&info)))
{
- if (info->info.initial || u->v0 != value0)
+ if (stamp || info->info.initial || u->v0 != value0)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1i, 1);
u->v0 = value0;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -439,12 +418,12 @@ gsk_gl_uniform_state_set2i (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_2I, 1, location, stamp,
&info)))
{
- if (info->info.initial || u->v0 != value0 || u->v1 != value1)
+ if (stamp || info->info.initial || u->v0 != value0 || u->v1 != value1)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform2i, 1);
u->v0 = value0;
u->v1 = value1;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -466,13 +445,13 @@ gsk_gl_uniform_state_set3i (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_3I, 1, location, stamp,
&info)))
{
- if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
+ if (stamp || info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform3i, 1);
u->v0 = value0;
u->v1 = value1;
u->v2 = value2;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -495,14 +474,14 @@ gsk_gl_uniform_state_set4i (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_4I, 1, location, stamp,
&info)))
{
- if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
+ if (stamp || info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 !=
value3)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform4i, 1);
u->v0 = value0;
u->v1 = value1;
u->v2 = value2;
u->v3 = value3;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -515,13 +494,6 @@ rounded_rect_equal (const GskRoundedRect *r1,
* should allow us to compare without any gaps using memcmp().
*/
G_STATIC_ASSERT (sizeof *r1 == (sizeof (float) * 12));
-
- if (r1 == r2)
- return TRUE;
-
- if (r1 == NULL)
- return FALSE;
-
return memcmp (r1, r2, sizeof *r1) == 0;
}
@@ -541,21 +513,11 @@ gsk_gl_uniform_state_set_rounded_rect (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT, 1, location,
stamp, &info)))
{
- if (info->info.initial || !rounded_rect_equal (rounded_rect, u))
+ if (stamp || info->info.initial || !rounded_rect_equal (rounded_rect, u))
{
- g_assert (!info->info.send_corners || info->info.changed);
-
- if (!info->info.send_corners)
- {
- if (info->info.initial ||
- memcmp (u->corner, rounded_rect->corner, sizeof u->corner) != 0)
- info->info.send_corners = TRUE;
- }
-
GSK_GL_UNIFORM_STATE_REPLACE (info, u, GskRoundedRect, 1);
-
memcpy (u, rounded_rect, sizeof *rounded_rect);
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -576,12 +538,12 @@ gsk_gl_uniform_state_set_matrix (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_MATRIX, 1, location, stamp,
&info)))
{
- if (!info->info.initial && memcmp (u, matrix, sizeof *u) == 0)
- return;
-
- GSK_GL_UNIFORM_STATE_REPLACE (info, u, graphene_matrix_t, 1);
- memcpy (u, matrix, sizeof *matrix);
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ if (stamp || info->info.initial || memcmp (u, matrix, sizeof *u) != 0)
+ {
+ GSK_GL_UNIFORM_STATE_REPLACE (info, u, graphene_matrix_t, 1);
+ memcpy (u, matrix, sizeof *matrix);
+ gsk_gl_uniform_info_changed (info, location, stamp);
+ }
}
}
@@ -616,11 +578,11 @@ gsk_gl_uniform_state_set_texture (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_TEXTURE, 1, location,
stamp, &info)))
{
- if (info->info.initial || *u != texture_slot)
+ if (stamp || info->info.initial || *u != texture_slot)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, guint, 1);
*u = texture_slot;
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -655,11 +617,11 @@ gsk_gl_uniform_state_set_color (GskGLUniformState *state,
if (color == NULL)
color = &transparent;
- if (info->info.initial || memcmp (color, u, sizeof *color) != 0)
+ if (stamp || info->info.initial || memcmp (color, u, sizeof *color) != 0)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, GdkRGBA, 1);
memcpy (u, color, sizeof *color);
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -681,13 +643,11 @@ gsk_gl_uniform_state_set1fv (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1FV, count, location,
stamp, &info)))
{
- gboolean changed = info->info.initial || memcmp (u, value, sizeof *u * count) != 0;
-
- if (changed)
+ if (stamp || info->info.initial || memcmp (u, value, sizeof *u * count) != 0)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1f, count);
memcpy (u, value, sizeof (Uniform1f) * count);
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -709,13 +669,11 @@ gsk_gl_uniform_state_set2fv (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_2FV, count, location,
stamp, &info)))
{
- gboolean changed = info->info.initial || memcmp (u, value, sizeof *u * count) != 0;
-
- if (changed)
+ if (stamp || info->info.initial || memcmp (u, value, sizeof *u * count) != 0)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, count);
memcpy (u, value, sizeof (Uniform2f) * count);
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -737,13 +695,11 @@ gsk_gl_uniform_state_set3fv (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_3FV, count, location,
stamp, &info)))
{
- gboolean changed = info->info.initial || memcmp (u, value, sizeof *u * count) != 0;
-
- if (changed)
+ if (stamp || info->info.initial || memcmp (u, value, sizeof *u * count) != 0)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, count);
memcpy (u, value, sizeof (Uniform3f) * count);
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
@@ -765,13 +721,11 @@ gsk_gl_uniform_state_set4fv (GskGLUniformState *state,
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_4FV, count, location,
stamp, &info)))
{
- gboolean changed = info->info.initial || memcmp (u, value, sizeof *u * count) != 0;
-
- if (changed)
+ if (stamp || info->info.initial || memcmp (u, value, sizeof *u * count) != 0)
{
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, count);
memcpy (u, value, sizeof (Uniform4f) * count);
- gsk_gl_uniform_program_changed (program, info, location, stamp);
+ gsk_gl_uniform_info_changed (info, location, stamp);
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]