[gtk/wip/chergert/glproto] reduce allocations and lookups in uniform state
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glproto] reduce allocations and lookups in uniform state
- Date: Wed, 10 Feb 2021 22:00:04 +0000 (UTC)
commit 998b6e61a18d852b0a76080f2271cb4f83fc3e29
Author: Christian Hergert <chergert redhat com>
Date: Wed Feb 10 14:10:52 2021 -0800
reduce allocations and lookups in uniform state
this makes programs have an "uniforms added" function which is used to
cache information about accesses into the program. doing so allows us to
avoid some allocations during frames as well as keeping informaion in cachelines
close to where we're using them.
also, it lets us avoid going through arrays which cost extra pointer dereferences.
gsk/next/gskglcommandqueue.c | 18 +-
gsk/next/gskglcommandqueueprivate.h | 202 +----------------
gsk/next/gskgldriver.c | 12 +-
gsk/next/gskglprogram.c | 83 ++++---
gsk/next/gskglprogramprivate.h | 187 +++++++--------
gsk/next/gskglrenderjob.c | 58 ++---
gsk/next/gskgltypesprivate.h | 2 +
gsk/next/gskgluniformstate.c | 440 +++++++++++++++---------------------
gsk/next/gskgluniformstateprivate.h | 258 +++++++++++----------
9 files changed, 522 insertions(+), 738 deletions(-)
---
diff --git a/gsk/next/gskglcommandqueue.c b/gsk/next/gskglcommandqueue.c
index 30bff3ef68..a17ca72adc 100644
--- a/gsk/next/gskglcommandqueue.c
+++ b/gsk/next/gskglcommandqueue.c
@@ -344,7 +344,7 @@ discard_batch (GskGLCommandQueue *self)
void
gsk_gl_command_queue_begin_draw (GskGLCommandQueue *self,
- guint program,
+ GskGLUniformProgram *program,
const graphene_rect_t *viewport)
{
GskGLCommandBatch *batch;
@@ -353,9 +353,11 @@ gsk_gl_command_queue_begin_draw (GskGLCommandQueue *self,
g_assert (self->in_draw == FALSE);
g_assert (viewport != NULL);
+ self->program_info = program;
+
batch = begin_next_batch (self);
batch->any.kind = GSK_GL_COMMAND_KIND_DRAW;
- batch->any.program = program;
+ batch->any.program = program->program_id;
batch->any.next_batch_index = -1;
batch->any.viewport.width = viewport->size.width;
batch->any.viewport.height = viewport->size.height;
@@ -417,7 +419,7 @@ gsk_gl_command_queue_end_draw (GskGLCommandQueue *self)
* array to be large enough for all our changes. Then we just ++
* from the callback.
*/
- n_changed = gsk_gl_uniform_state_get_n_changed (self->uniforms, batch->any.program);
+ n_changed = self->program_info->n_changed;
if (n_changed)
{
@@ -427,7 +429,7 @@ gsk_gl_command_queue_end_draw (GskGLCommandQueue *self)
/* Store information about uniforms that changed */
batch->draw.uniform_offset = self->batch_uniforms->len;
gsk_gl_uniform_state_snapshot (self->uniforms,
- batch->any.program,
+ self->program_info,
gsk_gl_command_queue_uniform_snapshot_cb,
self->batch_uniforms);
batch->draw.uniform_count = n_changed;
@@ -493,6 +495,7 @@ gsk_gl_command_queue_end_draw (GskGLCommandQueue *self)
}
self->in_draw = FALSE;
+ self->program_info = NULL;
}
/**
@@ -513,19 +516,19 @@ void
gsk_gl_command_queue_split_draw (GskGLCommandQueue *self)
{
GskGLCommandBatch *batch;
+ GskGLUniformProgram *program;
graphene_rect_t viewport;
- guint program;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
g_assert (self->batches->len > 0);
g_assert (self->in_draw == TRUE);
+ program = self->program_info;
+
batch = &g_array_index (self->batches, GskGLCommandBatch, self->batches->len-1);
g_assert (batch->any.kind == GSK_GL_COMMAND_KIND_DRAW);
- program = batch->any.program;
-
viewport.origin.x = 0;
viewport.origin.y = 0;
viewport.size.width = batch->any.viewport.width;
@@ -628,7 +631,6 @@ gsk_gl_command_queue_delete_program (GskGLCommandQueue *self,
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
glDeleteProgram (program);
- gsk_gl_uniform_state_clear_program (self->uniforms, program);
}
static inline void
diff --git a/gsk/next/gskglcommandqueueprivate.h b/gsk/next/gskglcommandqueueprivate.h
index 21cd84d0e1..b073556d6f 100644
--- a/gsk/next/gskglcommandqueueprivate.h
+++ b/gsk/next/gskglcommandqueueprivate.h
@@ -198,6 +198,11 @@ struct _GskGLCommandQueue
*/
GskGLUniformState *uniforms;
+ /* Current program if we are in a draw so that we can send commands
+ * to the uniform state as needed.
+ */
+ GskGLUniformProgram *program_info;
+
/* The profiler instance to deliver timing/etc data */
GskProfiler *profiler;
GskGLProfiler *gl_profiler;
@@ -299,7 +304,7 @@ void gsk_gl_command_queue_push_debug_group (GskGLCommandQueue
const char *message);
void gsk_gl_command_queue_pop_debug_group (GskGLCommandQueue *self);
void gsk_gl_command_queue_begin_draw (GskGLCommandQueue *self,
- guint program,
+ GskGLUniformProgram *program_info,
const graphene_rect_t *viewport);
void gsk_gl_command_queue_end_draw (GskGLCommandQueue *self);
void gsk_gl_command_queue_split_draw (GskGLCommandQueue *self);
@@ -323,201 +328,6 @@ gsk_gl_command_queue_bind_framebuffer (GskGLCommandQueue *self,
gsk_gl_attachment_state_bind_framebuffer (self->attachments, framebuffer);
}
-static inline void
-gsk_gl_command_queue_set_uniform1ui (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0)
-{
- gsk_gl_uniform_state_set1ui (self->uniforms, program, location, value0);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform1i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0)
-{
- gsk_gl_uniform_state_set1i (self->uniforms, program, location, value0);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform2i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0,
- int value1)
-{
- gsk_gl_uniform_state_set2i (self->uniforms, program, location, value0, value1);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform3i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2)
-{
- gsk_gl_uniform_state_set3i (self->uniforms, program, location, value0, value1, value2);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform4i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2,
- int value3)
-{
- gsk_gl_uniform_state_set4i (self->uniforms, program, location, value0, value1, value2, value3);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform1f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0)
-{
- gsk_gl_uniform_state_set1f (self->uniforms, program, location, value0);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform2f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0,
- float value1)
-{
- gsk_gl_uniform_state_set2f (self->uniforms, program, location, value0, value1);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform3f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2)
-{
- gsk_gl_uniform_state_set3f (self->uniforms, program, location, value0, value1, value2);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform4f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2,
- float value3)
-{
- gsk_gl_uniform_state_set4f (self->uniforms, program, location, value0, value1, value2, value3);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform1fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value)
-{
- gsk_gl_uniform_state_set1fv (self->uniforms, program, location, count, value);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform2fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value)
-{
- gsk_gl_uniform_state_set2fv (self->uniforms, program, location, count, value);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform3fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value)
-{
- gsk_gl_uniform_state_set3fv (self->uniforms, program, location, count, value);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform4fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value)
-{
- gsk_gl_uniform_state_set4fv (self->uniforms, program, location, count, value);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform_matrix (GskGLCommandQueue *self,
- guint program,
- guint location,
- const graphene_matrix_t *matrix)
-{
- gsk_gl_uniform_state_set_matrix (self->uniforms, program, location, matrix);
-}
-
-static inline void
-gsk_gl_command_queue_set_uniform_color (GskGLCommandQueue *self,
- guint program,
- guint location,
- const GdkRGBA *color)
-{
- gsk_gl_uniform_state_set_color (self->uniforms, program, location, color);
-}
-
-/**
- * gsk_gl_command_queue_set_uniform_texture:
- * @self: A #GskGLCommandQueue
- * @program: the program id
- * @location: the location of the uniform
- * @texture_target: a texture target such as %GL_TEXTURE_2D
- * @texture_slot: the texture slot such as %GL_TEXTURE0 or %GL_TEXTURE1
- * @texture_id: the id of the texture from glGenTextures()
- *
- * This sets the value of a uniform to map to @texture_slot (after subtracting
- * GL_TEXTURE0 from the value) and ensures that @texture_id is available in the
- * same texturing slot, ensuring @texture_target.
- */
-static inline void
-gsk_gl_command_queue_set_uniform_texture (GskGLCommandQueue *self,
- guint program,
- guint location,
- GLenum texture_target,
- GLenum texture_slot,
- guint texture_id)
-{
- gsk_gl_attachment_state_bind_texture (self->attachments, texture_target, texture_slot, texture_id);
- gsk_gl_uniform_state_set_texture (self->uniforms, program, location, texture_slot);
-}
-
-/**
- * gsk_gl_command_queue_set_uniform_rounded_rect:
- * @self: a #GskGLCommandQueue
- * @program: the program to execute
- * @location: the location of the uniform
- * @rounded_rect: the rounded rect to apply
- *
- * Sets a uniform that is expecting a rounded rect. This is stored as a
- * 4fv using glUniform4fv() when uniforms are applied to the progrma.
- */
-static inline void
-gsk_gl_command_queue_set_uniform_rounded_rect (GskGLCommandQueue *self,
- guint program,
- guint location,
- const GskRoundedRect *rounded_rect)
-{
- gsk_gl_uniform_state_set_rounded_rect (self->uniforms, program, location, rounded_rect);
-}
-
G_END_DECLS
#endif /* __GSK_GL_COMMAND_QUEUE_PRIVATE_H__ */
diff --git a/gsk/next/gskgldriver.c b/gsk/next/gskgldriver.c
index ac49620939..bd60570393 100644
--- a/gsk/next/gskgldriver.c
+++ b/gsk/next/gskgldriver.c
@@ -380,6 +380,8 @@ gsk_next_driver_load_programs (GskNextDriver *self,
\
uniforms \
\
+ gsk_gl_program_uniforms_added (program); \
+ \
if (have_alpha) \
gsk_gl_program_set_uniform1f (program, UNIFORM_SHARED_ALPHA, 1.0f); \
\
@@ -1101,13 +1103,14 @@ gsk_next_driver_lookup_shader (GskNextDriver *self,
if ((program = gsk_gl_compiler_compile (compiler, NULL, error)))
{
+ gboolean have_alpha;
+
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);
gsk_gl_program_add_uniform (program, "u_modelview", UNIFORM_SHARED_MODELVIEW);
- if (gsk_gl_program_add_uniform (program, "u_alpha", UNIFORM_SHARED_ALPHA))
- gsk_gl_program_set_uniform1f (program, UNIFORM_SHARED_ALPHA, 1.0f);
+ have_alpha = gsk_gl_program_add_uniform (program, "u_alpha", UNIFORM_SHARED_ALPHA);
gsk_gl_program_add_uniform (program, "u_size", UNIFORM_CUSTOM_SIZE);
gsk_gl_program_add_uniform (program, "u_texture1", UNIFORM_CUSTOM_TEXTURE1);
@@ -1127,6 +1130,11 @@ 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);
+
+ if (have_alpha)
+ gsk_gl_program_set_uniform1f (program, UNIFORM_SHARED_ALPHA, 1.0f);
+
g_hash_table_insert (self->shader_cache, shader, program);
g_object_weak_ref (G_OBJECT (shader),
gsk_next_driver_shader_weak_cb,
diff --git a/gsk/next/gskglprogram.c b/gsk/next/gskglprogram.c
index 2a4339693b..23dad322c3 100644
--- a/gsk/next/gskglprogram.c
+++ b/gsk/next/gskglprogram.c
@@ -40,6 +40,7 @@ gsk_gl_program_new (GskNextDriver *driver,
self->id = program_id;
self->name = g_strdup (name);
self->driver = g_object_ref (driver);
+ self->n_uniforms = 0;
return self;
}
@@ -120,6 +121,9 @@ gsk_gl_program_add_uniform (GskGLProgram *self,
self->uniform_locations[key] = location;
+ if (location >= self->n_uniforms)
+ self->n_uniforms = location + 1;
+
#if 0
g_print ("program [%d] %s uniform %s at location %d.\n",
self->id, self->name, name, location);
@@ -161,47 +165,68 @@ gsk_gl_program_begin_draw (GskGLProgram *self,
g_assert (modelview != NULL);
g_assert (clip != NULL);
- gsk_gl_command_queue_begin_draw (self->driver->command_queue, self->id, viewport);
+ gsk_gl_command_queue_begin_draw (self->driver->command_queue, self->program_info, viewport);
if (self->uniform_locations[UNIFORM_SHARED_VIEWPORT] > -1)
- gsk_gl_command_queue_set_uniform4fv (self->driver->command_queue,
- self->id,
- self->uniform_locations[UNIFORM_SHARED_VIEWPORT],
- 1,
- (const float *)viewport);
+ gsk_gl_uniform_state_set4fv (self->uniforms,
+ self->program_info,
+ self->uniform_locations[UNIFORM_SHARED_VIEWPORT],
+ 1,
+ (const float *)viewport);
if (self->uniform_locations[UNIFORM_SHARED_MODELVIEW] > -1)
- gsk_gl_command_queue_set_uniform_matrix (self->driver->command_queue,
- self->id,
- self->uniform_locations[UNIFORM_SHARED_MODELVIEW],
- modelview);
+ gsk_gl_uniform_state_set_matrix (self->uniforms,
+ self->program_info,
+ self->uniform_locations[UNIFORM_SHARED_MODELVIEW],
+ modelview);
if (self->uniform_locations[UNIFORM_SHARED_PROJECTION] > -1)
- gsk_gl_command_queue_set_uniform_matrix (self->driver->command_queue,
- self->id,
- self->uniform_locations[UNIFORM_SHARED_PROJECTION],
- projection);
+ gsk_gl_uniform_state_set_matrix (self->uniforms,
+ self->program_info,
+ self->uniform_locations[UNIFORM_SHARED_PROJECTION],
+ projection);
if (self->uniform_locations[UNIFORM_SHARED_CLIP_RECT] > -1)
{
if (clip != NULL)
- gsk_gl_command_queue_set_uniform_rounded_rect (self->driver->command_queue,
- self->id,
- self->uniform_locations[UNIFORM_SHARED_CLIP_RECT],
- clip);
+ gsk_gl_uniform_state_set_rounded_rect (self->uniforms,
+ self->program_info,
+ self->uniform_locations[UNIFORM_SHARED_CLIP_RECT],
+ clip);
else
- gsk_gl_command_queue_set_uniform_rounded_rect (self->driver->command_queue,
- self->id,
- self->uniform_locations[UNIFORM_SHARED_CLIP_RECT],
- &GSK_ROUNDED_RECT_INIT (0,
- 0,
- viewport->size.width,
- viewport->size.height));
+ gsk_gl_uniform_state_set_rounded_rect (self->uniforms,
+ self->program_info,
+ self->uniform_locations[UNIFORM_SHARED_CLIP_RECT],
+ &GSK_ROUNDED_RECT_INIT (0,
+ 0,
+ viewport->size.width,
+ viewport->size.height));
}
if (self->uniform_locations[UNIFORM_SHARED_ALPHA] > -1)
- gsk_gl_command_queue_set_uniform1f (self->driver->command_queue,
- self->id,
- self->uniform_locations[UNIFORM_SHARED_ALPHA],
- alpha);
+ gsk_gl_uniform_state_set1f (self->uniforms,
+ self->program_info,
+ self->uniform_locations[UNIFORM_SHARED_ALPHA],
+ alpha);
+}
+
+/**
+ * gsk_gl_program_uniforms_added:
+ * @self: a #GskGLProgram
+ *
+ * This function should be called after all of the uniforms ahve
+ * been added with gsk_gl_program_add_uniform().
+ *
+ * This function will setup the uniform state so that the program
+ * has fast access to the data buffers without as many lookups at
+ * runtime for comparison data.
+ */
+void
+gsk_gl_program_uniforms_added (GskGLProgram *self)
+{
+ 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);
}
diff --git a/gsk/next/gskglprogramprivate.h b/gsk/next/gskglprogramprivate.h
index b7ef6ec5f6..c66f6dabe2 100644
--- a/gsk/next/gskglprogramprivate.h
+++ b/gsk/next/gskglprogramprivate.h
@@ -40,6 +40,16 @@ struct _GskGLProgram
char *name;
GskNextDriver *driver;
+ /* In reality, this is the largest uniform position
+ * as returned after linking so that we can use direct
+ * indexes based on location.
+ */
+ guint n_uniforms;
+
+ /* Cached pointer to avoid lots of pointer chasing/lookups */
+ GskGLUniformState *uniforms;
+ GskGLUniformProgram *program_info;
+
/* For custom programs */
int texture_locations[4];
int args_locations[8];
@@ -52,19 +62,20 @@ struct _GskGLProgram
int uniform_locations[32];
};
-GskGLProgram *gsk_gl_program_new (GskNextDriver *driver,
- const char *name,
- int program_id);
-gboolean gsk_gl_program_add_uniform (GskGLProgram *self,
- const char *name,
- guint key);
-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);
+GskGLProgram *gsk_gl_program_new (GskNextDriver *driver,
+ const char *name,
+ int program_id);
+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_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);
static inline void
gsk_gl_program_end_draw (GskGLProgram *self)
@@ -78,13 +89,7 @@ gsk_gl_program_split_draw (GskGLProgram *self)
gsk_gl_command_queue_split_draw (self->driver->command_queue);
}
-static inline int
-gsk_gl_program_get_uniform_location (GskGLProgram *self,
- guint key)
-{
- g_assert (key < 32);
- return self->uniform_locations[key];
-}
+#define gsk_gl_program_get_uniform_location(s,k) ((s)->uniform_locations[(k)])
static inline void
gsk_gl_program_set_uniform1fv (GskGLProgram *self,
@@ -92,9 +97,9 @@ gsk_gl_program_set_uniform1fv (GskGLProgram *self,
guint count,
const float *values)
{
- gsk_gl_command_queue_set_uniform1fv (self->driver->command_queue, self->id,
- gsk_gl_program_get_uniform_location (self, key),
- count, values);
+ gsk_gl_uniform_state_set1fv (self->uniforms, self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ count, values);
}
static inline void
@@ -103,9 +108,9 @@ gsk_gl_program_set_uniform2fv (GskGLProgram *self,
guint count,
const float *values)
{
- gsk_gl_command_queue_set_uniform2fv (self->driver->command_queue, self->id,
- gsk_gl_program_get_uniform_location (self, key),
- count, values);
+ gsk_gl_uniform_state_set2fv (self->uniforms, self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ count, values);
}
static inline void
@@ -114,9 +119,9 @@ gsk_gl_program_set_uniform4fv (GskGLProgram *self,
guint count,
const float *values)
{
- gsk_gl_command_queue_set_uniform4fv (self->driver->command_queue, self->id,
- gsk_gl_program_get_uniform_location (self, key),
- count, values);
+ gsk_gl_uniform_state_set4fv (self->uniforms, self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ count, values);
}
static inline void
@@ -124,9 +129,9 @@ gsk_gl_program_set_uniform_rounded_rect (GskGLProgram *self,
guint key,
const GskRoundedRect *rounded_rect)
{
- gsk_gl_command_queue_set_uniform_rounded_rect (self->driver->command_queue, self->id,
- gsk_gl_program_get_uniform_location (self, key),
- rounded_rect);
+ gsk_gl_uniform_state_set_rounded_rect (self->uniforms, self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ rounded_rect);
}
static inline void
@@ -134,10 +139,10 @@ gsk_gl_program_set_uniform1i (GskGLProgram *self,
guint key,
int value0)
{
- gsk_gl_command_queue_set_uniform1i (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- value0);
+ gsk_gl_uniform_state_set1i (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ value0);
}
static inline void
@@ -146,11 +151,11 @@ gsk_gl_program_set_uniform2i (GskGLProgram *self,
int value0,
int value1)
{
- gsk_gl_command_queue_set_uniform2i (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- value0,
- value1);
+ gsk_gl_uniform_state_set2i (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ value0,
+ value1);
}
static inline void
@@ -160,12 +165,12 @@ gsk_gl_program_set_uniform3i (GskGLProgram *self,
int value1,
int value2)
{
- gsk_gl_command_queue_set_uniform3i (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- value0,
- value1,
- value2);
+ gsk_gl_uniform_state_set3i (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ value0,
+ value1,
+ value2);
}
static inline void
@@ -176,13 +181,13 @@ gsk_gl_program_set_uniform4i (GskGLProgram *self,
int value2,
int value3)
{
- gsk_gl_command_queue_set_uniform4i (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- value0,
- value1,
- value2,
- value3);
+ gsk_gl_uniform_state_set4i (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ value0,
+ value1,
+ value2,
+ value3);
}
static inline void
@@ -190,10 +195,10 @@ gsk_gl_program_set_uniform1f (GskGLProgram *self,
guint key,
float value0)
{
- gsk_gl_command_queue_set_uniform1f (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- value0);
+ gsk_gl_uniform_state_set1f (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ value0);
}
static inline void
@@ -202,11 +207,11 @@ gsk_gl_program_set_uniform2f (GskGLProgram *self,
float value0,
float value1)
{
- gsk_gl_command_queue_set_uniform2f (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- value0,
- value1);
+ gsk_gl_uniform_state_set2f (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ value0,
+ value1);
}
static inline void
@@ -216,12 +221,12 @@ gsk_gl_program_set_uniform3f (GskGLProgram *self,
float value1,
float value2)
{
- gsk_gl_command_queue_set_uniform3f (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- value0,
- value1,
- value2);
+ gsk_gl_uniform_state_set3f (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ value0,
+ value1,
+ value2);
}
static inline void
@@ -232,13 +237,13 @@ gsk_gl_program_set_uniform4f (GskGLProgram *self,
float value2,
float value3)
{
- gsk_gl_command_queue_set_uniform4f (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- value0,
- value1,
- value2,
- value3);
+ gsk_gl_uniform_state_set4f (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ value0,
+ value1,
+ value2,
+ value3);
}
static inline void
@@ -246,10 +251,10 @@ gsk_gl_program_set_uniform_color (GskGLProgram *self,
guint key,
const GdkRGBA *color)
{
- gsk_gl_command_queue_set_uniform_color (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- color);
+ gsk_gl_uniform_state_set_color (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ color);
}
static inline void
@@ -259,12 +264,14 @@ gsk_gl_program_set_uniform_texture (GskGLProgram *self,
GLenum texture_slot,
guint texture_id)
{
- gsk_gl_command_queue_set_uniform_texture (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- texture_target,
- texture_slot,
- texture_id);
+ gsk_gl_attachment_state_bind_texture (self->driver->command_queue->attachments,
+ texture_target,
+ texture_slot,
+ texture_id);
+ gsk_gl_uniform_state_set_texture (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ texture_slot);
}
static inline void
@@ -272,10 +279,10 @@ gsk_gl_program_set_uniform_matrix (GskGLProgram *self,
guint key,
const graphene_matrix_t *matrix)
{
- gsk_gl_command_queue_set_uniform_matrix (self->driver->command_queue,
- self->id,
- gsk_gl_program_get_uniform_location (self, key),
- matrix);
+ gsk_gl_uniform_state_set_matrix (self->uniforms,
+ self->program_info,
+ gsk_gl_program_get_uniform_location (self, key),
+ matrix);
}
G_END_DECLS
diff --git a/gsk/next/gskglrenderjob.c b/gsk/next/gskglrenderjob.c
index e05758d0e3..b6a91d8e90 100644
--- a/gsk/next/gskglrenderjob.c
+++ b/gsk/next/gskglrenderjob.c
@@ -202,7 +202,7 @@ gsk_gl_render_job_begin_draw (GskGLRenderJob *job,
*/
if G_LIKELY (program->last_shared_state == job->driver->last_shared_state)
{
- gsk_gl_command_queue_begin_draw (job->command_queue, program->id, &job->viewport);
+ gsk_gl_command_queue_begin_draw (job->command_queue, program->program_info, &job->viewport);
}
else
{
@@ -2984,45 +2984,45 @@ gsk_gl_render_job_visit_gl_shader_node (GskGLRenderJob *job,
case GSK_GL_UNIFORM_TYPE_NONE:
break;
case GSK_GL_UNIFORM_TYPE_FLOAT:
- gsk_gl_command_queue_set_uniform1fv (job->command_queue,
- program->id,
- program->args_locations[i],
- 1,
- (const float *)data);
+ gsk_gl_uniform_state_set1fv (job->command_queue->uniforms,
+ program->program_info,
+ program->args_locations[i],
+ 1,
+ (const float *)data);
break;
case GSK_GL_UNIFORM_TYPE_INT:
- gsk_gl_command_queue_set_uniform1i (job->command_queue,
- program->id,
- program->args_locations[i],
- *(const gint32 *)data);
+ gsk_gl_uniform_state_set1i (job->command_queue->uniforms,
+ program->program_info,
+ program->args_locations[i],
+ *(const gint32 *)data);
break;
case GSK_GL_UNIFORM_TYPE_UINT:
case GSK_GL_UNIFORM_TYPE_BOOL:
- gsk_gl_command_queue_set_uniform1ui (job->command_queue,
- program->id,
- program->args_locations[i],
- *(const guint32 *)data);
+ gsk_gl_uniform_state_set1ui (job->command_queue->uniforms,
+ program->program_info,
+ program->args_locations[i],
+ *(const guint32 *)data);
break;
case GSK_GL_UNIFORM_TYPE_VEC2:
- gsk_gl_command_queue_set_uniform2fv (job->command_queue,
- program->id,
- program->args_locations[i],
- 1,
- (const float *)data);
+ gsk_gl_uniform_state_set2fv (job->command_queue->uniforms,
+ program->program_info,
+ program->args_locations[i],
+ 1,
+ (const float *)data);
break;
case GSK_GL_UNIFORM_TYPE_VEC3:
- gsk_gl_command_queue_set_uniform3fv (job->command_queue,
- program->id,
- program->args_locations[i],
- 1,
- (const float *)data);
+ gsk_gl_uniform_state_set3fv (job->command_queue->uniforms,
+ program->program_info,
+ program->args_locations[i],
+ 1,
+ (const float *)data);
break;
case GSK_GL_UNIFORM_TYPE_VEC4:
- gsk_gl_command_queue_set_uniform4fv (job->command_queue,
- program->id,
- program->args_locations[i],
- 1,
- (const float *)data);
+ gsk_gl_uniform_state_set4fv (job->command_queue->uniforms,
+ program->program_info,
+ program->args_locations[i],
+ 1,
+ (const float *)data);
break;
}
}
diff --git a/gsk/next/gskgltypesprivate.h b/gsk/next/gskgltypesprivate.h
index b8571a59af..044f350850 100644
--- a/gsk/next/gskgltypesprivate.h
+++ b/gsk/next/gskgltypesprivate.h
@@ -46,6 +46,8 @@ typedef struct _GskGLTextureSlice GskGLTextureSlice;
typedef struct _GskGLTextureAtlas GskGLTextureAtlas;
typedef struct _GskGLTextureLibrary GskGLTextureLibrary;
typedef struct _GskGLTextureNineSlice GskGLTextureNineSlice;
+typedef struct _GskGLUniformInfo GskGLUniformInfo;
+typedef struct _GskGLUniformProgram GskGLUniformProgram;
typedef struct _GskGLUniformState GskGLUniformState;
typedef struct _GskNextDriver GskNextDriver;
diff --git a/gsk/next/gskgluniformstate.c b/gsk/next/gskgluniformstate.c
index 9a7686f9b5..0c6c010d67 100644
--- a/gsk/next/gskgluniformstate.c
+++ b/gsk/next/gskgluniformstate.c
@@ -101,28 +101,17 @@ rounded_rect_equal (const GskRoundedRect *r1,
return memcmp (r1, r2, sizeof *r1) == 0;
}
-static void
-clear_program_info (gpointer data)
-{
- GskGLUniformProgram *program_info = data;
-
- g_clear_pointer (&program_info->uniform_info, g_free);
- g_clear_pointer (&program_info->changed, g_free);
-}
-
GskGLUniformState *
gsk_gl_uniform_state_new (void)
{
GskGLUniformState *state;
state = g_atomic_rc_box_new0 (GskGLUniformState);
- state->program_info = g_array_new (FALSE, TRUE, sizeof (GskGLUniformProgram));
+ state->programs = g_hash_table_new_full (NULL, NULL, NULL, g_free);
state->values_len = 4096;
state->values_pos = 0;
state->values_buf = g_malloc (4096);
- g_array_set_clear_func (state->program_info, clear_program_info);
-
return g_steal_pointer (&state);
}
@@ -137,7 +126,7 @@ gsk_gl_uniform_state_finalize (gpointer data)
{
GskGLUniformState *state = data;
- g_clear_pointer (&state->program_info, g_array_unref);
+ g_clear_pointer (&state->programs, g_hash_table_unref);
g_clear_pointer (&state->values_buf, g_free);
}
@@ -148,45 +137,20 @@ gsk_gl_uniform_state_unref (GskGLUniformState *state)
}
static inline void
-program_changed (GskGLUniformState *state,
- GskGLUniformInfo *info,
- guint program,
- guint location)
+program_changed (GskGLUniformState *state,
+ GskGLUniformInfo *info,
+ GskGLUniformProgram *program,
+ guint location)
{
if (info->changed == FALSE)
{
- GskGLUniformProgram *program_info = &g_array_index (state->program_info, GskGLUniformProgram, program);
-
- g_assert (program < state->program_info->len);
-
info->changed = TRUE;
info->initial = FALSE;
- program_info->changed[program_info->n_changed++] = location;
+ program->changed[program->n_changed++] = location;
}
}
-void
-gsk_gl_uniform_state_clear_program (GskGLUniformState *state,
- guint program)
-{
- GskGLUniformProgram *program_info;
-
- g_return_if_fail (state != NULL);
-
- if (program == 0 || program >= state->program_info->len)
- return;
-
- program_info = &g_array_index (state->program_info, GskGLUniformProgram, program);
-
- g_clear_pointer (&program_info->uniform_info, g_free);
- program_info->uniform_info_len = 0;
-
- program_info->n_changed = 0;
- program_info->changed_len = 0;
- g_clear_pointer (&program_info->changed, g_free);
-}
-
static inline guint
alloc_alignment (guint current_pos,
guint size)
@@ -221,169 +185,109 @@ alloc_uniform_data (GskGLUniformState *state,
}
static gpointer
-create_uniform (GskGLUniformState *state,
- guint program,
- GskGLUniformFormat format,
- guint array_count,
- guint location,
- GskGLUniformInfo **infoptr)
+create_uniform (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ GskGLUniformFormat format,
+ guint array_count,
+ guint location,
+ GskGLUniformInfo **infoptr)
{
- GskGLUniformProgram *program_info;
GskGLUniformInfo *info;
guint offset;
g_assert (state != NULL);
- g_assert (program > 0);
g_assert (array_count < 256);
g_assert ((int)format >= 0 && format < GSK_GL_UNIFORM_FORMAT_LAST);
g_assert (format > 0);
+ g_assert (program != NULL);
g_assert (location < GL_MAX_UNIFORM_LOCATIONS || location == (guint)-1);
/* Handle unused uniforms gracefully */
if G_UNLIKELY (location == (guint)-1)
return NULL;
- /* Fast path for common case (state already initialized) */
- if G_LIKELY (program < state->program_info->len &&
- (program_info = &g_array_index (state->program_info, GskGLUniformProgram, program)) &&
- location < program_info->uniform_info_len)
- {
- info = &program_info->uniform_info[location];
-
- if G_LIKELY (format == info->format)
- {
- if G_LIKELY (array_count <= info->array_count)
- {
- *infoptr = info;
- return state->values_buf + info->offset;
- }
+ info = &program->uniforms[location];
- /* We found the uniform, but there is not enough space for the
- * amount that was requested. Instead, allocate new space and
- * set the value to "initial" so that the caller just writes
- * over the previous value.
- *
- * This can happen when using dynamic array lengths like the
- * "n_color_stops" in gradient shaders.
- */
- goto setup_info;
- }
- else if (info->format == 0)
- {
- goto setup_info;
- }
- else
+ if G_LIKELY (format == info->format)
+ {
+ if G_LIKELY (array_count <= info->array_count)
{
- g_critical ("Attempt to access uniform with different type of value "
- "than it was initialized with. Program %u Location %u. "
- "Was %d now %d (array length %d now %d).",
- program, location, info->format, format,
- info->array_count, array_count);
- *infoptr = NULL;
- return NULL;
+ *infoptr = info;
+ return state->values_buf + info->offset;
}
- }
-setup_info:
-
- if (program >= state->program_info->len ||
- g_array_index (state->program_info, GskGLUniformProgram, program).uniform_info == NULL)
+ /* We found the uniform, but there is not enough space for the
+ * amount that was requested. Instead, allocate new space and
+ * set the value to "initial" so that the caller just writes
+ * over the previous value.
+ *
+ * This can happen when using dynamic array lengths like the
+ * "n_color_stops" in gradient shaders.
+ */
+ goto setup_info;
+ }
+ else if (info->format == 0)
{
- if (program >= state->program_info->len)
- g_array_set_size (state->program_info, program + 1);
-
- program_info = &g_array_index (state->program_info, GskGLUniformProgram, program);
- program_info->uniform_info = g_new0 (GskGLUniformInfo, location + 1);
- program_info->uniform_info_len = location + 1;
- program_info->changed = NULL;
- program_info->n_changed = 0;
- program_info->changed_len = 0;
-
- for (guint i = 0; i < program_info->uniform_info_len; i++)
- program_info->uniform_info[i].initial = TRUE;
+ goto setup_info;
}
-
- g_assert (program_info != NULL);
- g_assert (program_info->uniform_info != NULL);
-
- if (location >= program_info->uniform_info_len)
+ else
{
- guint prev = program_info->uniform_info_len;
-
- program_info->uniform_info = g_realloc_n (program_info->uniform_info, location + 1, sizeof
(GskGLUniformInfo));
- program_info->uniform_info_len = location + 1;
-
- memset (&program_info->uniform_info[prev], 0,
- (program_info->uniform_info_len - prev) * sizeof (GskGLUniformInfo));
- for (guint i = prev; i < program_info->uniform_info_len; i++)
- program_info->uniform_info[i].initial = TRUE;
+ g_critical ("Attempt to access uniform with different type of value "
+ "than it was initialized with. Program %u Location %u. "
+ "Was %d now %d (array length %d now %d).",
+ program->program_id, location, info->format, format,
+ info->array_count, array_count);
+ *infoptr = NULL;
+ return NULL;
}
+setup_info:
+
alloc_uniform_data (state,
uniform_sizes[format] * MAX (1, array_count),
&offset);
- info = &program_info->uniform_info[location];
info->changed = FALSE;
info->format = format;
info->offset = offset;
info->array_count = array_count;
info->initial = TRUE;
- /* Ensure we have enough space in program_info->changed to hold
- * values up to this location so that we never have to allocate
- * when marking a program changed.
- */
- if (location >= program_info->changed_len)
- {
- program_info->changed_len = location + 1;
- program_info->changed = g_realloc_n (program_info->changed, program_info->changed_len, sizeof (guint));
- }
-
*infoptr = info;
return state->values_buf + offset;
}
static inline gpointer
-get_uniform (GskGLUniformState *state,
- guint program,
- GskGLUniformFormat format,
- guint array_count,
- guint location,
- GskGLUniformInfo **infoptr)
+get_uniform (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ GskGLUniformFormat format,
+ guint array_count,
+ guint location,
+ GskGLUniformInfo **infoptr)
{
- /* Fast path for common case (state already initialized) */
- if G_LIKELY (program < state->program_info->len)
- {
- const GskGLUniformProgram *program_info = &g_array_index (state->program_info, GskGLUniformProgram,
program);
-
- if G_LIKELY (location < program_info->uniform_info_len)
- {
- GskGLUniformInfo *info = &program_info->uniform_info[location];
+ GskGLUniformInfo *info = &program->uniforms[location];
- if G_LIKELY (format == info->format && array_count <= info->array_count)
- {
- *infoptr = info;
- return state->values_buf + info->offset;
- }
- }
+ if G_LIKELY (format == info->format && array_count <= info->array_count)
+ {
+ *infoptr = info;
+ return state->values_buf + info->offset;
}
return create_uniform (state, program, format, array_count, location, infoptr);
}
void
-gsk_gl_uniform_state_set1f (GskGLUniformState *state,
- guint program,
- guint location,
- float value0)
+gsk_gl_uniform_state_set1f (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ float value0)
{
Uniform1f *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != 0);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_1F, 1, location, &info)))
{
@@ -397,17 +301,17 @@ gsk_gl_uniform_state_set1f (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set2f (GskGLUniformState *state,
- guint program,
- guint location,
- float value0,
- float value1)
+gsk_gl_uniform_state_set2f (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ float value0,
+ float value1)
{
Uniform2f *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_2F, 1, location, &info)))
{
@@ -422,18 +326,18 @@ gsk_gl_uniform_state_set2f (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set3f (GskGLUniformState *state,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2)
+gsk_gl_uniform_state_set3f (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ float value0,
+ float value1,
+ float value2)
{
Uniform3f *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_3F, 1, location, &info)))
{
@@ -449,19 +353,19 @@ gsk_gl_uniform_state_set3f (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set4f (GskGLUniformState *state,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2,
- float value3)
+gsk_gl_uniform_state_set4f (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ float value0,
+ float value1,
+ float value2,
+ float value3)
{
Uniform4f *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_4F, 1, location, &info)))
{
@@ -478,16 +382,16 @@ gsk_gl_uniform_state_set4f (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set1ui (GskGLUniformState *state,
- guint program,
- guint location,
- guint value0)
+gsk_gl_uniform_state_set1ui (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint value0)
{
Uniform1ui *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_1UI, 1, location, &info)))
{
@@ -501,16 +405,16 @@ gsk_gl_uniform_state_set1ui (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set1i (GskGLUniformState *state,
- guint program,
- guint location,
- int value0)
+gsk_gl_uniform_state_set1i (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ int value0)
{
Uniform1i *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_1I, 1, location, &info)))
{
@@ -524,17 +428,17 @@ gsk_gl_uniform_state_set1i (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set2i (GskGLUniformState *state,
- guint program,
- guint location,
- int value0,
- int value1)
+gsk_gl_uniform_state_set2i (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ int value0,
+ int value1)
{
Uniform2i *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_2I, 1, location, &info)))
{
@@ -549,18 +453,18 @@ gsk_gl_uniform_state_set2i (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set3i (GskGLUniformState *state,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2)
+gsk_gl_uniform_state_set3i (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ int value0,
+ int value1,
+ int value2)
{
Uniform3i *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_3I, 1, location, &info)))
{
@@ -576,19 +480,19 @@ gsk_gl_uniform_state_set3i (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set4i (GskGLUniformState *state,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2,
- int value3)
+gsk_gl_uniform_state_set4i (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ int value0,
+ int value1,
+ int value2,
+ int value3)
{
Uniform4i *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_4I, 1, location, &info)))
{
@@ -606,7 +510,7 @@ gsk_gl_uniform_state_set4i (GskGLUniformState *state,
void
gsk_gl_uniform_state_set_rounded_rect (GskGLUniformState *state,
- guint program,
+ GskGLUniformProgram *program,
guint location,
const GskRoundedRect *rounded_rect)
{
@@ -614,7 +518,7 @@ gsk_gl_uniform_state_set_rounded_rect (GskGLUniformState *state,
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
g_assert (rounded_rect != NULL);
g_assert (uniform_sizes[GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT] == sizeof *rounded_rect);
@@ -641,7 +545,7 @@ gsk_gl_uniform_state_set_rounded_rect (GskGLUniformState *state,
void
gsk_gl_uniform_state_set_matrix (GskGLUniformState *state,
- guint program,
+ GskGLUniformProgram *program,
guint location,
const graphene_matrix_t *matrix)
{
@@ -649,7 +553,7 @@ gsk_gl_uniform_state_set_matrix (GskGLUniformState *state,
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
g_assert (matrix != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_MATRIX, 1, location, &info)))
@@ -678,10 +582,10 @@ gsk_gl_uniform_state_set_matrix (GskGLUniformState *state,
* 1 for GL_TEXTURE1, and so on.
*/
void
-gsk_gl_uniform_state_set_texture (GskGLUniformState *state,
- guint program,
- guint location,
- guint texture_slot)
+gsk_gl_uniform_state_set_texture (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint texture_slot)
{
GskGLUniformInfo *info;
guint *u;
@@ -714,17 +618,17 @@ gsk_gl_uniform_state_set_texture (GskGLUniformState *state,
* in other portions of the renderer.
*/
void
-gsk_gl_uniform_state_set_color (GskGLUniformState *state,
- guint program,
- guint location,
- const GdkRGBA *color)
+gsk_gl_uniform_state_set_color (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ const GdkRGBA *color)
{
static const GdkRGBA transparent = {0};
GskGLUniformInfo *info;
GdkRGBA *u;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_COLOR, 1, location, &info)))
{
@@ -741,17 +645,17 @@ gsk_gl_uniform_state_set_color (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set1fv (GskGLUniformState *state,
- guint program,
- guint location,
- guint count,
- const float *value)
+gsk_gl_uniform_state_set1fv (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint count,
+ const float *value)
{
Uniform1f *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
g_assert (count > 0);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_1FV, count, location, &info)))
@@ -768,17 +672,17 @@ gsk_gl_uniform_state_set1fv (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set2fv (GskGLUniformState *state,
- guint program,
- guint location,
- guint count,
- const float *value)
+gsk_gl_uniform_state_set2fv (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint count,
+ const float *value)
{
Uniform2f *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
g_assert (count > 0);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_2FV, count, location, &info)))
@@ -795,17 +699,17 @@ gsk_gl_uniform_state_set2fv (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set3fv (GskGLUniformState *state,
- guint program,
- guint location,
- guint count,
- const float *value)
+gsk_gl_uniform_state_set3fv (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint count,
+ const float *value)
{
Uniform3f *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
g_assert (count > 0);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_3FV, count, location, &info)))
@@ -822,17 +726,17 @@ gsk_gl_uniform_state_set3fv (GskGLUniformState *state,
}
void
-gsk_gl_uniform_state_set4fv (GskGLUniformState *state,
- guint program,
- guint location,
- guint count,
- const float *value)
+gsk_gl_uniform_state_set4fv (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint count,
+ const float *value)
{
Uniform4f *u;
GskGLUniformInfo *info;
g_assert (state != NULL);
- g_assert (program > 0);
+ g_assert (program != NULL);
g_assert (count > 0);
if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_4FV, count, location, &info)))
@@ -851,6 +755,8 @@ gsk_gl_uniform_state_set4fv (GskGLUniformState *state,
void
gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
{
+ GHashTableIter iter;
+ GskGLUniformProgram *program;
guint allocator = 0;
g_return_if_fail (state != NULL);
@@ -861,16 +767,12 @@ gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
* discard it but keep an allocation around to reuse.
*/
- for (guint i = 0; i < state->program_info->len; i++)
+ g_hash_table_iter_init (&iter, state->programs);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&program))
{
- GskGLUniformProgram *program_info = &g_array_index (state->program_info, GskGLUniformProgram, i);
-
- if (program_info->uniform_info == NULL)
- continue;
-
- for (guint j = 0; j < program_info->uniform_info_len; j++)
+ for (guint j = 0; j < program->n_uniforms; j++)
{
- GskGLUniformInfo *info = &program_info->uniform_info[j];
+ GskGLUniformInfo *info = &program->uniforms[j];
guint size;
if (info->format == 0)
@@ -891,7 +793,7 @@ gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
allocator += size;
}
- program_info->n_changed = 0;
+ program->n_changed = 0;
}
state->values_pos = allocator;
@@ -907,3 +809,37 @@ gsk_gl_uniform_format_size (GskGLUniformFormat format)
return uniform_sizes[format];
}
+
+GskGLUniformProgram *
+gsk_gl_uniform_state_get_program (GskGLUniformState *state,
+ guint program,
+ guint n_uniforms)
+{
+ GskGLUniformProgram *ret;
+
+ g_return_val_if_fail (state != NULL, NULL);
+ g_return_val_if_fail (program > 0, NULL);
+ g_return_val_if_fail (program < G_MAXUINT, NULL);
+
+ ret = g_hash_table_lookup (state->programs, GUINT_TO_POINTER (program));
+
+ if (ret == NULL)
+ {
+ gsize uniform_size = n_uniforms * sizeof (GskGLUniformInfo);
+ gsize changed_size = n_uniforms * sizeof (guint);
+ gsize size = sizeof (GskGLUniformProgram) + uniform_size + changed_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];
+
+ for (guint i = 0; i < n_uniforms; i++)
+ ret->uniforms[i].initial = TRUE;
+
+ g_hash_table_insert (state->programs, GUINT_TO_POINTER (program), ret);
+ }
+
+ return ret;
+}
diff --git a/gsk/next/gskgluniformstateprivate.h b/gsk/next/gskgluniformstateprivate.h
index c08f568cb3..29c3104a18 100644
--- a/gsk/next/gskgluniformstateprivate.h
+++ b/gsk/next/gskgluniformstateprivate.h
@@ -40,25 +40,28 @@ G_STATIC_ASSERT (sizeof (GskGLUniformInfo) == 4);
typedef struct _GskGLUniformProgram
{
- /* Array of GskGLUniformInfo, index is GLSL location */
- GskGLUniformInfo *uniform_info;
- guint uniform_info_len;
+ guint program_id;
+ guint n_uniforms;
/* 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.
*/
guint *changed;
- guint changed_len : 16;
- guint n_changed : 16;
+ guint n_changed;
+
+ /* Uniforms are provided inline at the end of structure to avoid
+ * an extra dereference.
+ */
+ GskGLUniformInfo uniforms[0];
} GskGLUniformProgram;
typedef struct _GskGLUniformState
{
- GArray *program_info;
+ GHashTable *programs;
guint8 *values_buf;
- guint values_pos;
- guint values_len;
+ guint values_pos;
+ guint values_len;
} GskGLUniformState;
/**
@@ -103,101 +106,102 @@ typedef enum _GskGLUniformKind
GSK_GL_UNIFORM_FORMAT_LAST
} GskGLUniformFormat;
-GskGLUniformState *gsk_gl_uniform_state_new (void);
-GskGLUniformState *gsk_gl_uniform_state_ref (GskGLUniformState *state);
-void gsk_gl_uniform_state_unref (GskGLUniformState *state);
-void gsk_gl_uniform_state_clear_program (GskGLUniformState *state,
- guint program);
-void gsk_gl_uniform_state_end_frame (GskGLUniformState *state);
-void gsk_gl_uniform_state_set1f (GskGLUniformState *state,
- guint program,
- guint location,
- float value0);
-void gsk_gl_uniform_state_set2f (GskGLUniformState *state,
- guint program,
- guint location,
- float value0,
- float value1);
-void gsk_gl_uniform_state_set3f (GskGLUniformState *state,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2);
-void gsk_gl_uniform_state_set4f (GskGLUniformState *state,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2,
- float value3);
-void gsk_gl_uniform_state_set1fv (GskGLUniformState *state,
- guint program,
- guint location,
- guint count,
- const float *value);
-void gsk_gl_uniform_state_set2fv (GskGLUniformState *state,
- guint program,
- guint location,
- guint count,
- const float *value);
-void gsk_gl_uniform_state_set3fv (GskGLUniformState *state,
- guint program,
- guint location,
- guint count,
- const float *value);
-void gsk_gl_uniform_state_set4fv (GskGLUniformState *state,
- guint program,
- guint location,
- guint count,
- const float *value);
-void gsk_gl_uniform_state_set1ui (GskGLUniformState *state,
- guint program,
- guint location,
- guint value0);
-void gsk_gl_uniform_state_set1i (GskGLUniformState *state,
- guint program,
- guint location,
- int value0);
-void gsk_gl_uniform_state_set2i (GskGLUniformState *state,
- guint program,
- guint location,
- int value0,
- int value1);
-void gsk_gl_uniform_state_set3i (GskGLUniformState *state,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2);
-void gsk_gl_uniform_state_set4i (GskGLUniformState *state,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2,
- int value3);
-void gsk_gl_uniform_state_set_rounded_rect (GskGLUniformState *self,
- guint program,
- guint location,
- const GskRoundedRect *rect);
-void gsk_gl_uniform_state_set_matrix (GskGLUniformState *self,
- guint program,
- guint location,
- const graphene_matrix_t *value);
-void gsk_gl_uniform_state_set_texture (GskGLUniformState *self,
- guint program,
- guint location,
- guint texture_slot);
-void gsk_gl_uniform_state_set_color (GskGLUniformState *self,
- guint program,
- guint location,
- const GdkRGBA *color);
-void gsk_gl_uniform_state_snapshot (GskGLUniformState *self,
- guint program_id,
- GskGLUniformStateCallback callback,
- gpointer user_data);
-gsize gsk_gl_uniform_format_size (GskGLUniformFormat format);
+GskGLUniformState *gsk_gl_uniform_state_new (void);
+GskGLUniformState *gsk_gl_uniform_state_ref (GskGLUniformState *state);
+void gsk_gl_uniform_state_unref (GskGLUniformState *state);
+GskGLUniformProgram *gsk_gl_uniform_state_get_program (GskGLUniformState *state,
+ guint program,
+ guint n_uniforms);
+void gsk_gl_uniform_state_end_frame (GskGLUniformState *state);
+void gsk_gl_uniform_state_set1f (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ float value0);
+void gsk_gl_uniform_state_set2f (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ float value0,
+ float value1);
+void gsk_gl_uniform_state_set3f (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ float value0,
+ float value1,
+ float value2);
+void gsk_gl_uniform_state_set4f (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ float value0,
+ float value1,
+ float value2,
+ float value3);
+void gsk_gl_uniform_state_set1fv (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint count,
+ const float *value);
+void gsk_gl_uniform_state_set2fv (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint count,
+ const float *value);
+void gsk_gl_uniform_state_set3fv (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint count,
+ const float *value);
+void gsk_gl_uniform_state_set4fv (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint count,
+ const float *value);
+void gsk_gl_uniform_state_set1ui (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint value0);
+void gsk_gl_uniform_state_set1i (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ int value0);
+void gsk_gl_uniform_state_set2i (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ int value0,
+ int value1);
+void gsk_gl_uniform_state_set3i (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ int value0,
+ int value1,
+ int value2);
+void gsk_gl_uniform_state_set4i (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ int value0,
+ int value1,
+ int value2,
+ int value3);
+void gsk_gl_uniform_state_set_rounded_rect (GskGLUniformState *self,
+ GskGLUniformProgram *program,
+ guint location,
+ const GskRoundedRect *rect);
+void gsk_gl_uniform_state_set_matrix (GskGLUniformState *self,
+ GskGLUniformProgram *program,
+ guint location,
+ const graphene_matrix_t *value);
+void gsk_gl_uniform_state_set_texture (GskGLUniformState *self,
+ GskGLUniformProgram *program,
+ guint location,
+ guint texture_slot);
+void gsk_gl_uniform_state_set_color (GskGLUniformState *self,
+ GskGLUniformProgram *program,
+ guint location,
+ const GdkRGBA *color);
+void gsk_gl_uniform_state_snapshot (GskGLUniformState *self,
+ guint program_id,
+ GskGLUniformStateCallback callback,
+ gpointer user_data);
+gsize gsk_gl_uniform_format_size (GskGLUniformFormat format);
static inline gconstpointer
gsk_gl_uniform_state_get_uniform_data (const GskGLUniformState *state,
@@ -206,37 +210,27 @@ gsk_gl_uniform_state_get_uniform_data (const GskGLUniformState *state,
return (gconstpointer)(state->values_buf + offset);
}
-#define gsk_gl_uniform_state_snapshot(state, program_id, callback, user_data) \
- G_STMT_START { \
- GskGLUniformProgram *program_info; \
- \
- program_info = &g_array_index (state->program_info, GskGLUniformProgram, program_id); \
- if (program_info->n_changed == 0) \
- break; \
- \
- for (guint z = 0; z < program_info->n_changed; z++) \
- { \
- guint location = program_info->changed[z]; \
- GskGLUniformInfo *info = &program_info->uniform_info[location]; \
- \
- g_assert (info->changed); \
- \
- callback (info, location, user_data); \
- \
- info->changed = FALSE; \
- info->send_corners = FALSE; \
- } \
- \
- program_info->n_changed = 0; \
+#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_changed; z++) \
+ { \
+ guint location = program_info->changed[z]; \
+ GskGLUniformInfo *info = &program_info->uniforms[location]; \
+ \
+ g_assert (info->changed); \
+ \
+ callback (info, location, user_data); \
+ \
+ info->changed = FALSE; \
+ info->send_corners = FALSE; \
+ } \
+ } \
+ \
+ program_info->n_changed = 0; \
} G_STMT_END
-static inline guint
-gsk_gl_uniform_state_get_n_changed (GskGLUniformState *self,
- guint program_id)
-{
- return g_array_index (self->program_info, GskGLUniformProgram, program_id).n_changed;
-}
-
G_END_DECLS
#endif /* GSK_GL_UNIFORM_STATE_PRIVATE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]