[gtk/wip/chergert/glproto: 435/493] give uniform usage a chance to be inlined
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glproto: 435/493] give uniform usage a chance to be inlined
- Date: Fri, 19 Feb 2021 02:25:23 +0000 (UTC)
commit eb78e4b750c36a8a93a4d18eff55c9b382021c7b
Author: Christian Hergert <chergert redhat com>
Date: Wed Feb 10 15:12:48 2021 -0800
give uniform usage a chance to be inlined
gsk/next/gskgluniformstate.c | 613 +------------------------------
gsk/next/gskgluniformstateprivate.h | 711 ++++++++++++++++++++++++++++++------
2 files changed, 620 insertions(+), 704 deletions(-)
---
diff --git a/gsk/next/gskgluniformstate.c b/gsk/next/gskgluniformstate.c
index 0c6c010d67..6e7b46641a 100644
--- a/gsk/next/gskgluniformstate.c
+++ b/gsk/next/gskgluniformstate.c
@@ -25,19 +25,7 @@
#include "gskgluniformstateprivate.h"
-typedef struct { float v0; } Uniform1f;
-typedef struct { float v0; float v1; } Uniform2f;
-typedef struct { float v0; float v1; float v2; } Uniform3f;
-typedef struct { float v0; float v1; float v2; float v3; } Uniform4f;
-
-typedef struct { int v0; } Uniform1i;
-typedef struct { int v0; int v1; } Uniform2i;
-typedef struct { int v0; int v1; int v2; } Uniform3i;
-typedef struct { int v0; int v1; int v2; int v3; } Uniform4i;
-
-typedef struct { guint v0; } Uniform1ui;
-
-static guint8 uniform_sizes[] = {
+static const guint8 uniform_sizes[] = {
0,
sizeof (Uniform1f),
@@ -66,41 +54,6 @@ static guint8 uniform_sizes[] = {
0,
};
-#define REPLACE_UNIFORM(info, u, format, count) \
- G_STMT_START { \
- guint offset; \
- if ((info)->initial && count == (info)->array_count) \
- { \
- u = (gpointer)(state->values_buf + (info)->offset); \
- } \
- else \
- { \
- g_assert (uniform_sizes[format] > 0); \
- u = alloc_uniform_data(state, uniform_sizes[format] * MAX (1, count), &offset); \
- (info)->offset = offset; \
- /* We might have increased array length */ \
- (info)->array_count = count; \
- } \
- } G_STMT_END
-
-static inline gboolean
-rounded_rect_equal (const GskRoundedRect *r1,
- const GskRoundedRect *r2)
-{
- /* Ensure we're dealing with tightly packed floats that
- * 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;
-}
-
GskGLUniformState *
gsk_gl_uniform_state_new (void)
{
@@ -136,61 +89,13 @@ gsk_gl_uniform_state_unref (GskGLUniformState *state)
g_atomic_rc_box_release_full (state, gsk_gl_uniform_state_finalize);
}
-static inline void
-program_changed (GskGLUniformState *state,
- GskGLUniformInfo *info,
- GskGLUniformProgram *program,
- guint location)
-{
- if (info->changed == FALSE)
- {
- info->changed = TRUE;
- info->initial = FALSE;
-
- program->changed[program->n_changed++] = location;
- }
-}
-
-static inline guint
-alloc_alignment (guint current_pos,
- guint size)
-{
- guint align = size > 8 ? 16 : (size > 4 ? 8 : 4);
- guint masked = current_pos & (align - 1);
-
- g_assert (size > 0);
- g_assert (align == 4 || align == 8 || align == 16);
- g_assert (masked < align);
-
- return align - masked;
-}
-
-static inline gpointer
-alloc_uniform_data (GskGLUniformState *state,
- guint size,
- guint *offset)
-{
- guint padding = alloc_alignment (state->values_pos, size);
-
- if G_UNLIKELY (state->values_len - padding - size < state->values_pos)
- {
- state->values_len *= 2;
- state->values_buf = g_realloc (state->values_buf, state->values_len);
- }
-
- *offset = state->values_pos + padding;
- state->values_pos += padding + size;
-
- return state->values_buf + *offset;
-}
-
-static gpointer
-create_uniform (GskGLUniformState *state,
- GskGLUniformProgram *program,
- GskGLUniformFormat format,
- guint array_count,
- guint location,
- GskGLUniformInfo **infoptr)
+gpointer
+gsk_gl_uniform_state_init_value (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ GskGLUniformFormat format,
+ guint array_count,
+ guint location,
+ GskGLUniformInfo **infoptr)
{
GskGLUniformInfo *info;
guint offset;
@@ -243,9 +148,9 @@ create_uniform (GskGLUniformState *state,
setup_info:
- alloc_uniform_data (state,
- uniform_sizes[format] * MAX (1, array_count),
- &offset);
+ gsk_gl_uniform_state_realloc (state,
+ uniform_sizes[format] * MAX (1, array_count),
+ &offset);
info->changed = FALSE;
info->format = format;
@@ -258,500 +163,6 @@ setup_info:
return state->values_buf + offset;
}
-static inline gpointer
-get_uniform (GskGLUniformState *state,
- GskGLUniformProgram *program,
- GskGLUniformFormat format,
- guint array_count,
- guint location,
- GskGLUniformInfo **infoptr)
-{
- GskGLUniformInfo *info = &program->uniforms[location];
-
- 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,
- GskGLUniformProgram *program,
- guint location,
- float value0)
-{
- Uniform1f *u;
- GskGLUniformInfo *info;
-
- g_assert (state != NULL);
- g_assert (program != 0);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_1F, 1, location, &info)))
- {
- if (info->initial || u->v0 != value0)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_1F, 1);
- u->v0 = value0;
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_2F, 1, location, &info)))
- {
- if (info->initial || u->v0 != value0 || u->v1 != value1)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_2F, 1);
- u->v0 = value0;
- u->v1 = value1;
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_3F, 1, location, &info)))
- {
- if (info->initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_3F, 1);
- u->v0 = value0;
- u->v1 = value1;
- u->v2 = value2;
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_4F, 1, location, &info)))
- {
- if (info->initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_4F, 1);
- u->v0 = value0;
- u->v1 = value1;
- u->v2 = value2;
- u->v3 = value3;
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-gsk_gl_uniform_state_set1ui (GskGLUniformState *state,
- GskGLUniformProgram *program,
- guint location,
- guint value0)
-{
- Uniform1ui *u;
- GskGLUniformInfo *info;
-
- g_assert (state != NULL);
- g_assert (program != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_1UI, 1, location, &info)))
- {
- if (info->initial || u->v0 != value0)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_1UI, 1);
- u->v0 = value0;
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-gsk_gl_uniform_state_set1i (GskGLUniformState *state,
- GskGLUniformProgram *program,
- guint location,
- int value0)
-{
- Uniform1i *u;
- GskGLUniformInfo *info;
-
- g_assert (state != NULL);
- g_assert (program != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_1I, 1, location, &info)))
- {
- if (info->initial || u->v0 != value0)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_1I, 1);
- u->v0 = value0;
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_2I, 1, location, &info)))
- {
- if (info->initial || u->v0 != value0 || u->v1 != value1)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_2I, 1);
- u->v0 = value0;
- u->v1 = value1;
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_3I, 1, location, &info)))
- {
- if (info->initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_3I, 1);
- u->v0 = value0;
- u->v1 = value1;
- u->v2 = value2;
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_4I, 1, location, &info)))
- {
- if (info->initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_4I, 1);
- u->v0 = value0;
- u->v1 = value1;
- u->v2 = value2;
- u->v3 = value3;
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-gsk_gl_uniform_state_set_rounded_rect (GskGLUniformState *state,
- GskGLUniformProgram *program,
- guint location,
- const GskRoundedRect *rounded_rect)
-{
- GskRoundedRect *u;
- GskGLUniformInfo *info;
-
- g_assert (state != NULL);
- g_assert (program != NULL);
- g_assert (rounded_rect != NULL);
- g_assert (uniform_sizes[GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT] == sizeof *rounded_rect);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT, 1, location, &info)))
- {
- if (info->initial || !rounded_rect_equal (rounded_rect, u))
- {
- g_assert (!info->send_corners || info->changed);
-
- if (!info->send_corners)
- {
- if (info->initial ||
- memcmp (u->corner, rounded_rect->corner, sizeof u->corner) != 0)
- info->send_corners = TRUE;
- }
-
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT, 1);
-
- memcpy (u, rounded_rect, sizeof *rounded_rect);
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-gsk_gl_uniform_state_set_matrix (GskGLUniformState *state,
- GskGLUniformProgram *program,
- guint location,
- const graphene_matrix_t *matrix)
-{
- graphene_matrix_t *u;
- GskGLUniformInfo *info;
-
- g_assert (state != NULL);
- g_assert (program != NULL);
- g_assert (matrix != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_MATRIX, 1, location, &info)))
- {
- if (!info->initial && memcmp (u, matrix, sizeof *u) == 0)
- return;
-
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_MATRIX, 1);
- memcpy (u, matrix, sizeof *matrix);
- program_changed (state, info, program, location);
- }
-}
-
-/**
- * gsk_gl_uniform_state_set_texture:
- * @state: a #GskGLUniformState
- * @program: the program id
- * @location: the location of the texture
- * @texture_slot: a texturing slot such as GL_TEXTURE0
- *
- * Sets the uniform expecting a texture to @texture_slot. This API
- * expects a texture slot such as GL_TEXTURE0 to reduce chances of
- * miss-use by the caller.
- *
- * The value stored to the uniform is in the form of 0 for GL_TEXTURE0,
- * 1 for GL_TEXTURE1, and so on.
- */
-void
-gsk_gl_uniform_state_set_texture (GskGLUniformState *state,
- GskGLUniformProgram *program,
- guint location,
- guint texture_slot)
-{
- GskGLUniformInfo *info;
- guint *u;
-
- g_assert (texture_slot >= GL_TEXTURE0);
- g_assert (texture_slot < GL_TEXTURE16);
-
- texture_slot -= GL_TEXTURE0;
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_TEXTURE, 1, location, &info)))
- {
- if (*u != texture_slot || info->initial)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_TEXTURE, 1);
- *u = texture_slot;
- program_changed (state, info, program, location);
- }
- }
-}
-
-/**
- * gsk_gl_uniform_state_set_color:
- * @state: a #GskGLUniformState
- * @program: a program id > 0
- * @location: the uniform location
- * @color: a color to set or %NULL for transparent
- *
- * Sets a uniform to the color described by @color. This is a convenience
- * function to allow callers to avoid having to translate colors to floats
- * in other portions of the renderer.
- */
-void
-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 != NULL);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_COLOR, 1, location, &info)))
- {
- if (color == NULL)
- color = &transparent;
-
- if (info->initial || memcmp (color, u, sizeof *color) != 0)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_COLOR, 1);
- memcpy (u, color, sizeof *color);
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
- g_assert (count > 0);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_1FV, count, location, &info)))
- {
- gboolean changed = info->initial || memcmp (u, value, sizeof *u * count) != 0;
-
- if (changed)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_1FV, count);
- memcpy (u, value, sizeof (Uniform1f) * count);
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
- g_assert (count > 0);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_2FV, count, location, &info)))
- {
- gboolean changed = info->initial || memcmp (u, value, sizeof *u * count) != 0;
-
- if (changed)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_2FV, count);
- memcpy (u, value, sizeof (Uniform2f) * count);
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
- g_assert (count > 0);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_3FV, count, location, &info)))
- {
- gboolean changed = info->initial || memcmp (u, value, sizeof *u * count) != 0;
-
- if (changed)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_3FV, count);
- memcpy (u, value, sizeof (Uniform3f) * count);
- program_changed (state, info, program, location);
- }
- }
-}
-
-void
-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 != NULL);
- g_assert (count > 0);
-
- if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_4FV, count, location, &info)))
- {
- gboolean changed = info->initial || memcmp (u, value, sizeof *u * count) != 0;
-
- if (changed)
- {
- REPLACE_UNIFORM (info, u, GSK_GL_UNIFORM_FORMAT_4FV, count);
- memcpy (u, value, sizeof (Uniform4f) * count);
- program_changed (state, info, program, location);
- }
- }
-}
-
void
gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
{
@@ -782,7 +193,7 @@ gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
size = uniform_sizes[info->format] * MAX (1, info->array_count);
/* Adjust alignment for value */
- allocator += alloc_alignment (allocator, size);
+ allocator += gsk_gl_uniform_state_align (allocator, size);
info->offset = allocator;
info->changed = FALSE;
diff --git a/gsk/next/gskgluniformstateprivate.h b/gsk/next/gskgluniformstateprivate.h
index 29c3104a18..ba9a64ffae 100644
--- a/gsk/next/gskgluniformstateprivate.h
+++ b/gsk/next/gskgluniformstateprivate.h
@@ -25,6 +25,18 @@
G_BEGIN_DECLS
+typedef struct { float v0; } Uniform1f;
+typedef struct { float v0; float v1; } Uniform2f;
+typedef struct { float v0; float v1; float v2; } Uniform3f;
+typedef struct { float v0; float v1; float v2; float v3; } Uniform4f;
+
+typedef struct { int v0; } Uniform1i;
+typedef struct { int v0; int v1; } Uniform2i;
+typedef struct { int v0; int v1; int v2; } Uniform3i;
+typedef struct { int v0; int v1; int v2; int v3; } Uniform4i;
+
+typedef struct { guint v0; } Uniform1ui;
+
typedef struct _GskGLUniformInfo
{
guint changed : 1;
@@ -106,109 +118,27 @@ 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);
-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,
- guint offset)
-{
- return (gconstpointer)(state->values_buf + offset);
-}
+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_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,
+ GskGLUniformFormat format,
+ guint array_count,
+ guint location,
+ GskGLUniformInfo **infoptr);
+
+#define gsk_gl_uniform_state_get_uniform_data(state,offset) \
+ ((gconstpointer)(state->values_buf + offset))
#define gsk_gl_uniform_state_snapshot(state, program_info, callback, user_data) \
G_STMT_START { \
@@ -231,6 +161,581 @@ gsk_gl_uniform_state_get_uniform_data (const GskGLUniformState *state,
program_info->n_changed = 0; \
} G_STMT_END
+static inline gpointer
+gsk_gl_uniform_state_get_value (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ GskGLUniformFormat format,
+ guint array_count,
+ guint location,
+ GskGLUniformInfo **infoptr)
+{
+ GskGLUniformInfo *info = &program->uniforms[location];
+
+ if G_LIKELY (format == info->format && array_count <= info->array_count)
+ {
+ *infoptr = info;
+ return state->values_buf + info->offset;
+ }
+
+ return gsk_gl_uniform_state_init_value (state, program, format, array_count, location, infoptr);
+}
+
+static inline guint
+gsk_gl_uniform_state_align (guint current_pos,
+ guint size)
+{
+ guint align = size > 8 ? 16 : (size > 4 ? 8 : 4);
+ guint masked = current_pos & (align - 1);
+
+ g_assert (size > 0);
+ g_assert (align == 4 || align == 8 || align == 16);
+ g_assert (masked < align);
+
+ return align - masked;
+}
+
+static inline gpointer
+gsk_gl_uniform_state_realloc (GskGLUniformState *state,
+ guint size,
+ guint *offset)
+{
+ guint padding = gsk_gl_uniform_state_align (state->values_pos, size);
+
+ if G_UNLIKELY (state->values_len - padding - size < state->values_pos)
+ {
+ state->values_len *= 2;
+ state->values_buf = g_realloc (state->values_buf, state->values_len);
+ }
+
+ *offset = state->values_pos + padding;
+ state->values_pos += padding + size;
+
+ return state->values_buf + *offset;
+}
+
+#define GSK_GL_UNIFORM_STATE_REPLACE(info, u, type, count) \
+ G_STMT_START { \
+ if ((info)->initial && count == (info)->array_count) \
+ { \
+ u = (gpointer)(state->values_buf + (info)->offset); \
+ } \
+ else \
+ { \
+ guint offset; \
+ u = gsk_gl_uniform_state_realloc (state, sizeof(type) * MAX (1, count), &offset); \
+ (info)->offset = offset; \
+ /* We might have increased array length */ \
+ (info)->array_count = count; \
+ } \
+ } G_STMT_END
+
+static inline void
+gsk_gl_uniform_program_changed (GskGLUniformProgram *program,
+ GskGLUniformInfo *info,
+ guint location)
+{
+ if (info->changed == FALSE)
+ {
+ info->changed = TRUE;
+ info->initial = FALSE;
+
+ program->changed[program->n_changed++] = location;
+ }
+}
+
+
+static inline void
+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);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1F, 1, location, &info)))
+ {
+ if (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);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_2F, 1, location, &info)))
+ {
+ if (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);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_3F, 1, location, &info)))
+ {
+ if (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);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_4F, 1, location, &info)))
+ {
+ if (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);
+ }
+ }
+}
+
+static inline void
+gsk_gl_uniform_state_set1ui (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint value0)
+{
+ Uniform1ui *u;
+ GskGLUniformInfo *info;
+
+ g_assert (state != NULL);
+ g_assert (program != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1UI, 1, location, &info)))
+ {
+ if (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);
+ }
+ }
+}
+
+static inline void
+gsk_gl_uniform_state_set1i (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ int value0)
+{
+ Uniform1i *u;
+ GskGLUniformInfo *info;
+
+ g_assert (state != NULL);
+ g_assert (program != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1I, 1, location, &info)))
+ {
+ if (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);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_2I, 1, location, &info)))
+ {
+ if (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);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_3I, 1, location, &info)))
+ {
+ if (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);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_4I, 1, location, &info)))
+ {
+ if (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);
+ }
+ }
+}
+
+static inline gboolean
+rounded_rect_equal (const GskRoundedRect *r1,
+ const GskRoundedRect *r2)
+{
+ /* Ensure we're dealing with tightly packed floats that
+ * 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;
+}
+
+static inline void
+gsk_gl_uniform_state_set_rounded_rect (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ const GskRoundedRect *rounded_rect)
+{
+ GskRoundedRect *u;
+ GskGLUniformInfo *info;
+
+ g_assert (state != NULL);
+ g_assert (program != NULL);
+ g_assert (rounded_rect != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT, 1, location,
&info)))
+ {
+ if (info->initial || !rounded_rect_equal (rounded_rect, u))
+ {
+ g_assert (!info->send_corners || info->changed);
+
+ if (!info->send_corners)
+ {
+ if (info->initial ||
+ memcmp (u->corner, rounded_rect->corner, sizeof u->corner) != 0)
+ 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);
+ }
+ }
+}
+
+static inline void
+gsk_gl_uniform_state_set_matrix (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ const graphene_matrix_t *matrix)
+{
+ graphene_matrix_t *u;
+ GskGLUniformInfo *info;
+
+ g_assert (state != NULL);
+ g_assert (program != NULL);
+ g_assert (matrix != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_MATRIX, 1, location,
&info)))
+ {
+ if (!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);
+ }
+}
+
+/**
+ * gsk_gl_uniform_state_set_texture:
+ * @state: a #GskGLUniformState
+ * @program: the program id
+ * @location: the location of the texture
+ * @texture_slot: a texturing slot such as GL_TEXTURE0
+ *
+ * Sets the uniform expecting a texture to @texture_slot. This API
+ * expects a texture slot such as GL_TEXTURE0 to reduce chances of
+ * miss-use by the caller.
+ *
+ * The value stored to the uniform is in the form of 0 for GL_TEXTURE0,
+ * 1 for GL_TEXTURE1, and so on.
+ */
+static inline void
+gsk_gl_uniform_state_set_texture (GskGLUniformState *state,
+ GskGLUniformProgram *program,
+ guint location,
+ guint texture_slot)
+{
+ GskGLUniformInfo *info;
+ guint *u;
+
+ g_assert (texture_slot >= GL_TEXTURE0);
+ g_assert (texture_slot < GL_TEXTURE16);
+
+ texture_slot -= GL_TEXTURE0;
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_TEXTURE, 1, location,
&info)))
+ {
+ if (*u != texture_slot || info->initial)
+ {
+ GSK_GL_UNIFORM_STATE_REPLACE (info, u, guint, 1);
+ *u = texture_slot;
+ gsk_gl_uniform_program_changed (program, info, location);
+ }
+ }
+}
+
+/**
+ * gsk_gl_uniform_state_set_color:
+ * @state: a #GskGLUniformState
+ * @program: a program id > 0
+ * @location: the uniform location
+ * @color: a color to set or %NULL for transparent
+ *
+ * Sets a uniform to the color described by @color. This is a convenience
+ * function to allow callers to avoid having to translate colors to floats
+ * in other portions of the renderer.
+ */
+static inline void
+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 != NULL);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_COLOR, 1, location, &info)))
+ {
+ if (color == NULL)
+ color = &transparent;
+
+ if (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);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+ g_assert (count > 0);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1FV, count, location,
&info)))
+ {
+ gboolean changed = info->initial || memcmp (u, value, sizeof *u * count) != 0;
+
+ if (changed)
+ {
+ GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1f, count);
+ memcpy (u, value, sizeof (Uniform1f) * count);
+ gsk_gl_uniform_program_changed (program, info, location);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+ g_assert (count > 0);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_2FV, count, location,
&info)))
+ {
+ gboolean changed = info->initial || memcmp (u, value, sizeof *u * count) != 0;
+
+ if (changed)
+ {
+ GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, count);
+ memcpy (u, value, sizeof (Uniform2f) * count);
+ gsk_gl_uniform_program_changed (program, info, location);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+ g_assert (count > 0);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_3FV, count, location,
&info)))
+ {
+ gboolean changed = info->initial || memcmp (u, value, sizeof *u * count) != 0;
+
+ if (changed)
+ {
+ GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, count);
+ memcpy (u, value, sizeof (Uniform3f) * count);
+ gsk_gl_uniform_program_changed (program, info, location);
+ }
+ }
+}
+
+static inline void
+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 != NULL);
+ g_assert (count > 0);
+
+ if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_4FV, count, location,
&info)))
+ {
+ gboolean changed = info->initial || memcmp (u, value, sizeof *u * count) != 0;
+
+ if (changed)
+ {
+ GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, count);
+ memcpy (u, value, sizeof (Uniform4f) * count);
+ gsk_gl_uniform_program_changed (program, info, location);
+ }
+ }
+}
+
G_END_DECLS
#endif /* GSK_GL_UNIFORM_STATE_PRIVATE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]