[gtk/wip/chergert/glproto: 626/920] reduce overhead for setting uniforms
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glproto: 626/920] reduce overhead for setting uniforms
- Date: Mon, 8 Feb 2021 19:15:33 +0000 (UTC)
commit b832b61f02d64106c378389f612b25a319ef65ba
Author: Christian Hergert <chergert redhat com>
Date: Fri Jan 1 23:45:51 2021 -0800
reduce overhead for setting uniforms
now we have inlines for program->cmdqueue->state tracker so that our
compiled overhead is a few dereferences into the CoW slot.
gsk/next/gskglcommandqueue.c | 314 --------------------------------
gsk/next/gskglcommandqueueprivate.h | 344 ++++++++++++++++++++++++++++--------
gsk/next/gskgltypes.h | 1 +
3 files changed, 268 insertions(+), 391 deletions(-)
---
diff --git a/gsk/next/gskglcommandqueue.c b/gsk/next/gskglcommandqueue.c
index 03012624e6..560bbd5fe4 100644
--- a/gsk/next/gskglcommandqueue.c
+++ b/gsk/next/gskglcommandqueue.c
@@ -30,94 +30,6 @@
#include "gskglcommandqueueprivate.h"
#include "gskgluniformstateprivate.h"
-struct _GskGLCommandQueue
-{
- GObject parent_instance;
-
- /* The GdkGLContext we make current before executing GL commands. */
- GdkGLContext *context;
-
- /* Array of GskGLCommandBatch which is a fixed size structure that will
- * point into offsets of other arrays so that all similar data is stored
- * together. The idea here is that we reduce the need for pointers so that
- * using g_realloc()'d arrays is fine.
- */
- GArray *batches;
-
- /* Contains array of vertices and some wrapper code to help upload them
- * to the GL driver. We can also tweak this to use double buffered arrays
- * if we find that to be faster on some hardware and/or drivers.
- */
- GskGLBuffer *vertices;
-
- /* The GskGLAttachmentState contains information about our FBO and texture
- * attachments as we process incoming operations. We snapshot them into
- * various batches so that we can compare differences between merge
- * candidates.
- */
- GskGLAttachmentState *attachments;
-
- /* The uniform state across all programs. We snapshot this into batches so
- * that we can compare uniform state between batches to give us more
- * chances at merging draw commands.
- */
- GskGLUniformState *uniforms;
-
- /* Array of GskGLCommandDraw which allows us to have a static size field
- * in GskGLCommandBatch to coalesce draws. Multiple GskGLCommandDraw may
- * be processed together (and out-of-order) to reduce the number of state
- * changes when submitting commands.
- */
- GArray *batch_draws;
-
- /* Array of GskGLCommandBind which denote what textures need to be attached
- * to which slot. GskGLCommandDraw.bind_offset and bind_count reference this
- * array to determine what to attach.
- */
- GArray *batch_binds;
-
- /* Array of GskGLCommandUniform denoting which uniforms must be updated
- * before the glDrawArrays() may be called. These are referenced from the
- * GskGLCommandDraw.uniform_offset and uniform_count fields.
- */
- GArray *batch_uniforms;
-
- /* Sometimes we want to save attachment state so that operations we do
- * cannot affect anything that is known to the command queue. We call
- * gsk_gl_command_queue_save()/restore() which stashes attachment state
- * into this pointer array.
- */
- GPtrArray *saved_state;
-
- /* Sometimes it is handy to keep a number of textures or framebuffers
- * around until the frame has finished drawing. That way some objects can
- * be used immediately even though they won't have any rendering until the
- * frame has finished.
- *
- * When end_frame is called, we remove these resources.
- */
- GArray *autorelease_framebuffers;
- GArray *autorelease_textures;
-
- /* String storage for debug groups */
- GStringChunk *debug_groups;
-
- /* Discovered max texture size when loading the command queue so that we
- * can either scale down or slice textures to fit within this size. Assumed
- * to be both height and width.
- */
- int max_texture_size;
-
- /* The index of the last batch in @batches, which may not be the element
- * at the end of the array, as batches can be reordered. This is used to
- * update the "next" index when adding a new batch.
- */
- int tail_batch_index;
-
- /* If we're inside of a begin_draw()/end_draw() pair. */
- guint in_draw : 1;
-};
-
typedef enum _GskGLCommandKind
{
/* The batch will perform a glClear() */
@@ -567,232 +479,6 @@ gsk_gl_command_queue_delete_program (GskGLCommandQueue *self,
gsk_gl_uniform_state_clear_program (self->uniforms, program);
}
-void
-gsk_gl_command_queue_set_uniform1i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set1i (self->uniforms, program, location, value0);
-}
-
-void
-gsk_gl_command_queue_set_uniform2i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0,
- int value1)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set2i (self->uniforms, program, location, value0, value1);
-}
-
-void
-gsk_gl_command_queue_set_uniform3i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set3i (self->uniforms, program, location, value0, value1, value2);
-}
-
-void
-gsk_gl_command_queue_set_uniform4i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2,
- int value3)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set4i (self->uniforms, program, location, value0, value1, value2, value3);
-}
-
-void
-gsk_gl_command_queue_set_uniform1f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set1f (self->uniforms, program, location, value0);
-}
-
-void
-gsk_gl_command_queue_set_uniform2f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0,
- float value1)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set2f (self->uniforms, program, location, value0, value1);
-}
-
-void
-gsk_gl_command_queue_set_uniform3f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set3f (self->uniforms, program, location, value0, value1, value2);
-}
-
-void
-gsk_gl_command_queue_set_uniform4f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2,
- float value3)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set4f (self->uniforms, program, location, value0, value1, value2, value3);
-}
-
-void
-gsk_gl_command_queue_set_uniform2fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set2fv (self->uniforms, program, location, count, value);
-}
-
-void
-gsk_gl_command_queue_set_uniform1fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set1fv (self->uniforms, program, location, count, value);
-}
-
-void
-gsk_gl_command_queue_set_uniform4fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- gsk_gl_uniform_state_set4fv (self->uniforms, program, location, count, value);
-}
-
-void
-gsk_gl_command_queue_set_uniform_matrix (GskGLCommandQueue *self,
- guint program,
- guint location,
- const graphene_matrix_t *matrix)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
- g_return_if_fail (program > 0);
- g_return_if_fail (matrix != NULL);
-
- gsk_gl_uniform_state_set_matrix (self->uniforms, program, location, matrix);
-}
-
-void
-gsk_gl_command_queue_set_uniform_color (GskGLCommandQueue *self,
- guint program,
- guint location,
- const GdkRGBA *color)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
-
- 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.
- */
-void
-gsk_gl_command_queue_set_uniform_texture (GskGLCommandQueue *self,
- guint program,
- guint location,
- GLenum texture_target,
- GLenum texture_slot,
- guint texture_id)
-{
- g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
- g_assert (program > 0);
- g_assert (texture_target == GL_TEXTURE_1D ||
- texture_target == GL_TEXTURE_2D ||
- texture_target == GL_TEXTURE_3D);
- g_assert (texture_slot >= GL_TEXTURE0);
- g_assert (texture_slot < GL_TEXTURE16);
-
- 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.
- */
-void
-gsk_gl_command_queue_set_uniform_rounded_rect (GskGLCommandQueue *self,
- guint program,
- guint location,
- const GskRoundedRect *rounded_rect)
-{
- g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (self));
- g_return_if_fail (program > 0);
- g_return_if_fail (rounded_rect != NULL);
-
- gsk_gl_uniform_state_set_rounded_rect (self->uniforms,
- program,
- location,
- rounded_rect);
-}
-
static void
apply_uniform (GskGLUniformState *state,
const GskGLUniformInfo *info,
diff --git a/gsk/next/gskglcommandqueueprivate.h b/gsk/next/gskglcommandqueueprivate.h
index 34784089ab..9bc70601f0 100644
--- a/gsk/next/gskglcommandqueueprivate.h
+++ b/gsk/next/gskglcommandqueueprivate.h
@@ -23,12 +23,103 @@
#include "gskgltypes.h"
+#include "gskglattachmentstateprivate.h"
+#include "gskgluniformstateprivate.h"
+
G_BEGIN_DECLS
#define GSK_TYPE_GL_COMMAND_QUEUE (gsk_gl_command_queue_get_type())
G_DECLARE_FINAL_TYPE (GskGLCommandQueue, gsk_gl_command_queue, GSK, GL_COMMAND_QUEUE, GObject)
+struct _GskGLCommandQueue
+{
+ GObject parent_instance;
+
+ /* The GdkGLContext we make current before executing GL commands. */
+ GdkGLContext *context;
+
+ /* Array of GskGLCommandBatch which is a fixed size structure that will
+ * point into offsets of other arrays so that all similar data is stored
+ * together. The idea here is that we reduce the need for pointers so that
+ * using g_realloc()'d arrays is fine.
+ */
+ GArray *batches;
+
+ /* Contains array of vertices and some wrapper code to help upload them
+ * to the GL driver. We can also tweak this to use double buffered arrays
+ * if we find that to be faster on some hardware and/or drivers.
+ */
+ GskGLBuffer *vertices;
+
+ /* The GskGLAttachmentState contains information about our FBO and texture
+ * attachments as we process incoming operations. We snapshot them into
+ * various batches so that we can compare differences between merge
+ * candidates.
+ */
+ GskGLAttachmentState *attachments;
+
+ /* The uniform state across all programs. We snapshot this into batches so
+ * that we can compare uniform state between batches to give us more
+ * chances at merging draw commands.
+ */
+ GskGLUniformState *uniforms;
+
+ /* Array of GskGLCommandDraw which allows us to have a static size field
+ * in GskGLCommandBatch to coalesce draws. Multiple GskGLCommandDraw may
+ * be processed together (and out-of-order) to reduce the number of state
+ * changes when submitting commands.
+ */
+ GArray *batch_draws;
+
+ /* Array of GskGLCommandBind which denote what textures need to be attached
+ * to which slot. GskGLCommandDraw.bind_offset and bind_count reference this
+ * array to determine what to attach.
+ */
+ GArray *batch_binds;
+
+ /* Array of GskGLCommandUniform denoting which uniforms must be updated
+ * before the glDrawArrays() may be called. These are referenced from the
+ * GskGLCommandDraw.uniform_offset and uniform_count fields.
+ */
+ GArray *batch_uniforms;
+
+ /* Sometimes we want to save attachment state so that operations we do
+ * cannot affect anything that is known to the command queue. We call
+ * gsk_gl_command_queue_save()/restore() which stashes attachment state
+ * into this pointer array.
+ */
+ GPtrArray *saved_state;
+
+ /* Sometimes it is handy to keep a number of textures or framebuffers
+ * around until the frame has finished drawing. That way some objects can
+ * be used immediately even though they won't have any rendering until the
+ * frame has finished.
+ *
+ * When end_frame is called, we remove these resources.
+ */
+ GArray *autorelease_framebuffers;
+ GArray *autorelease_textures;
+
+ /* String storage for debug groups */
+ GStringChunk *debug_groups;
+
+ /* Discovered max texture size when loading the command queue so that we
+ * can either scale down or slice textures to fit within this size. Assumed
+ * to be both height and width.
+ */
+ int max_texture_size;
+
+ /* The index of the last batch in @batches, which may not be the element
+ * at the end of the array, as batches can be reordered. This is used to
+ * update the "next" index when adding a new batch.
+ */
+ int tail_batch_index;
+
+ /* If we're inside of a begin_draw()/end_draw() pair. */
+ guint in_draw : 1;
+};
+
GskGLCommandQueue *gsk_gl_command_queue_new (GdkGLContext *context);
GdkGLContext *gsk_gl_command_queue_get_context (GskGLCommandQueue *self);
void gsk_gl_command_queue_make_current (GskGLCommandQueue *self);
@@ -56,83 +147,6 @@ void gsk_gl_command_queue_bind_framebuffer (GskGLCommandQu
void gsk_gl_command_queue_clear (GskGLCommandQueue *self,
guint clear_bits,
const graphene_rect_t *viewport);
-void gsk_gl_command_queue_set_uniform1i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0);
-void gsk_gl_command_queue_set_uniform2i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0,
- int value1);
-void gsk_gl_command_queue_set_uniform3i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2);
-void gsk_gl_command_queue_set_uniform4i (GskGLCommandQueue *self,
- guint program,
- guint location,
- int value0,
- int value1,
- int value2,
- int value3);
-void gsk_gl_command_queue_set_uniform1f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0);
-void gsk_gl_command_queue_set_uniform2f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0,
- float value1);
-void gsk_gl_command_queue_set_uniform3f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2);
-void gsk_gl_command_queue_set_uniform4f (GskGLCommandQueue *self,
- guint program,
- guint location,
- float value0,
- float value1,
- float value2,
- float value3);
-void gsk_gl_command_queue_set_uniform2fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value);
-void gsk_gl_command_queue_set_uniform1fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value);
-void gsk_gl_command_queue_set_uniform4fv (GskGLCommandQueue *self,
- guint program,
- guint location,
- gsize count,
- const float *value);
-void gsk_gl_command_queue_set_uniform_matrix (GskGLCommandQueue *self,
- guint program,
- guint location,
- const graphene_matrix_t *matrix);
-void gsk_gl_command_queue_set_uniform_color (GskGLCommandQueue *self,
- guint program,
- guint location,
- const GdkRGBA *color);
-void gsk_gl_command_queue_set_uniform_texture (GskGLCommandQueue *self,
- guint program,
- guint location,
- GLenum texture_target,
- GLenum texture_slot,
- guint texture_id);
-void gsk_gl_command_queue_set_uniform_rounded_rect (GskGLCommandQueue *self,
- guint program,
- guint location,
- const GskRoundedRect *rounded_rect);
void gsk_gl_command_queue_push_debug_group (GskGLCommandQueue *self,
const char *message);
void gsk_gl_command_queue_pop_debug_group (GskGLCommandQueue *self);
@@ -147,6 +161,182 @@ void gsk_gl_command_queue_end_draw (GskGLCommandQu
GskGLDrawVertex *gsk_gl_command_queue_add_vertices (GskGLCommandQueue *self,
const GskGLDrawVertex
vertices[GSK_GL_N_VERTICES]);
+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_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_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_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/gskgltypes.h b/gsk/next/gskgltypes.h
index d4d48e74d4..f580870575 100644
--- a/gsk/next/gskgltypes.h
+++ b/gsk/next/gskgltypes.h
@@ -31,6 +31,7 @@ G_BEGIN_DECLS
#define GSK_GL_N_VERTICES 6
typedef struct _GskGLAttachmentState GskGLAttachmentState;
+typedef struct _GskGLBuffer GskGLBuffer;
typedef struct _GskGLCommandQueue GskGLCommandQueue;
typedef struct _GskGLCompiler GskGLCompiler;
typedef struct _GskGLDrawVertex GskGLDrawVertex;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]