[gtk/wip/chergert/glproto: 298/526] allow for multiple command queues with shared state
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glproto: 298/526] allow for multiple command queues with shared state
- Date: Tue, 16 Feb 2021 01:14:32 +0000 (UTC)
commit 5bc57ee7ce720b77930a8312ee2559bea664cb87
Author: Christian Hergert <chergert redhat com>
Date: Fri Jan 22 14:40:07 2021 -0800
allow for multiple command queues with shared state
this hoists the attachment/uniforms up a layer from the command queue so
that we can have multiple while sharing state. Doing so allows us to use
the driver more for the top-level object and ensure that programs may
indirectly use the drivers command queue (which can change as we process
frames for each surface). When a render completes, the queue is reverted
to the shared command queue for out-of-band operations.
gsk/next/gskglattachmentstate.c | 14 ++++++++---
gsk/next/gskglattachmentstateprivate.h | 2 ++
gsk/next/gskglcommandqueue.c | 29 +++++++++++++--------
gsk/next/gskglcommandqueueprivate.h | 4 ++-
gsk/next/gskglcompiler.c | 23 +++++++++--------
gsk/next/gskglcompilerprivate.h | 2 +-
gsk/next/gskgldriver.c | 46 +++++++++++++++++++++++++++++-----
gsk/next/gskgldriverprivate.h | 6 ++++-
gsk/next/gskglprogram.c | 32 +++++++++++------------
gsk/next/gskglprogramprivate.h | 33 ++++++++++++------------
gsk/next/gskglrenderer.c | 40 +++++++++++++++++++----------
gsk/next/gskglrenderjob.c | 42 ++++++++-----------------------
gsk/next/gskglrenderjobprivate.h | 1 -
gsk/next/gskgluniformstate.c | 21 +++++++++++++---
gsk/next/gskgluniformstateprivate.h | 3 ++-
15 files changed, 180 insertions(+), 118 deletions(-)
---
diff --git a/gsk/next/gskglattachmentstate.c b/gsk/next/gskglattachmentstate.c
index 404bf3c11c..5cb8f0b2d9 100644
--- a/gsk/next/gskglattachmentstate.c
+++ b/gsk/next/gskglattachmentstate.c
@@ -27,7 +27,7 @@ gsk_gl_attachment_state_new (void)
{
GskGLAttachmentState *self;
- self = g_new0 (GskGLAttachmentState, 1);
+ self = g_atomic_rc_box_new0 (GskGLAttachmentState);
self->fbo.changed = FALSE;
self->fbo.id = 0;
@@ -48,10 +48,16 @@ gsk_gl_attachment_state_new (void)
return self;
}
+GskGLAttachmentState *
+gsk_gl_attachment_state_ref (GskGLAttachmentState *self)
+{
+ return g_atomic_rc_box_acquire (self);
+}
+
void
-gsk_gl_attachment_state_free (GskGLAttachmentState *self)
+gsk_gl_attachment_state_unref (GskGLAttachmentState *self)
{
- g_free (self);
+ g_atomic_rc_box_release (self);
}
void
@@ -104,7 +110,7 @@ gsk_gl_attachment_state_bind_framebuffer (GskGLAttachmentState *self,
* This can be used to restore state later, such as after running
* various GL commands that are external to the GL renderer.
*
- * This must be freed by calling either gsk_gl_attachment_state_free()
+ * This must be freed by calling either gsk_gl_attachment_state_unref()
* or gsk_gl_attachment_state_restore().
*
* Returns: (transfer full): a new #GskGLAttachmentState or %NULL
diff --git a/gsk/next/gskglattachmentstateprivate.h b/gsk/next/gskglattachmentstateprivate.h
index 77b0f9bf53..5decdcd615 100644
--- a/gsk/next/gskglattachmentstateprivate.h
+++ b/gsk/next/gskglattachmentstateprivate.h
@@ -56,6 +56,8 @@ struct _GskGLAttachmentState
};
GskGLAttachmentState *gsk_gl_attachment_state_new (void);
+GskGLAttachmentState *gsk_gl_attachment_state_ref (GskGLAttachmentState *self);
+void gsk_gl_attachment_state_unref (GskGLAttachmentState *self);
GskGLAttachmentState *gsk_gl_attachment_state_save (GskGLAttachmentState *self);
void gsk_gl_attachment_state_restore (GskGLAttachmentState *self);
void gsk_gl_attachment_state_free (GskGLAttachmentState *self);
diff --git a/gsk/next/gskglcommandqueue.c b/gsk/next/gskglcommandqueue.c
index c2653c8c46..88f0c18904 100644
--- a/gsk/next/gskglcommandqueue.c
+++ b/gsk/next/gskglcommandqueue.c
@@ -221,8 +221,8 @@ gsk_gl_command_queue_dispose (GObject *object)
g_clear_object (&self->context);
g_clear_pointer (&self->batches, g_array_unref);
- g_clear_pointer (&self->attachments, gsk_gl_attachment_state_free);
- g_clear_pointer (&self->uniforms, gsk_gl_uniform_state_free);
+ g_clear_pointer (&self->attachments, gsk_gl_attachment_state_unref);
+ g_clear_pointer (&self->uniforms, gsk_gl_uniform_state_unref);
g_clear_pointer (&self->vertices, gsk_gl_buffer_free);
g_clear_pointer (&self->batch_draws, g_array_unref);
g_clear_pointer (&self->batch_binds, g_array_unref);
@@ -249,32 +249,39 @@ gsk_gl_command_queue_init (GskGLCommandQueue *self)
self->batch_draws = g_array_new (FALSE, FALSE, sizeof (GskGLCommandDraw));
self->batch_binds = g_array_new (FALSE, FALSE, sizeof (GskGLCommandBind));
self->batch_uniforms = g_array_new (FALSE, FALSE, sizeof (GskGLCommandUniform));
- self->attachments = gsk_gl_attachment_state_new ();
self->vertices = gsk_gl_buffer_new (GL_ARRAY_BUFFER, sizeof (GskGLDrawVertex));
- self->uniforms = gsk_gl_uniform_state_new ();
- self->saved_state = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_attachment_state_free);
+ self->saved_state = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_attachment_state_unref);
self->debug_groups = g_string_chunk_new (4096);
}
GskGLCommandQueue *
-gsk_gl_command_queue_new (GdkGLContext *context)
+gsk_gl_command_queue_new (GdkGLContext *context,
+ GskGLUniformState *uniforms,
+ GskGLAttachmentState *attachments)
{
GskGLCommandQueue *self;
- GdkGLContext *previous_context;
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
self = g_object_new (GSK_TYPE_GL_COMMAND_QUEUE, NULL);
self->context = g_object_ref (context);
- previous_context = gdk_gl_context_get_current ();
+ /* Use shared attachment state if we're provided one */
+ if (attachments != NULL)
+ self->attachments = gsk_gl_attachment_state_ref (attachments);
+ else
+ self->attachments = gsk_gl_attachment_state_new ();
+
+ /* Use shared uniform state if we're provided one */
+ if (uniforms != NULL)
+ self->uniforms = gsk_gl_uniform_state_ref (uniforms);
+ else
+ self->uniforms = gsk_gl_uniform_state_new ();
+ /* Determine max texture size immediately and restore context */
gdk_gl_context_make_current (context);
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &self->max_texture_size);
- if (previous_context != NULL)
- gdk_gl_context_make_current (previous_context);
-
return g_steal_pointer (&self);
}
diff --git a/gsk/next/gskglcommandqueueprivate.h b/gsk/next/gskglcommandqueueprivate.h
index 6e406a274e..c136e0ea58 100644
--- a/gsk/next/gskglcommandqueueprivate.h
+++ b/gsk/next/gskglcommandqueueprivate.h
@@ -110,7 +110,9 @@ struct _GskGLCommandQueue
guint in_draw : 1;
};
-GskGLCommandQueue *gsk_gl_command_queue_new (GdkGLContext *context);
+GskGLCommandQueue *gsk_gl_command_queue_new (GdkGLContext *context,
+ GskGLUniformState *uniforms,
+ GskGLAttachmentState *attachments);
GdkGLContext *gsk_gl_command_queue_get_context (GskGLCommandQueue *self);
void gsk_gl_command_queue_make_current (GskGLCommandQueue *self);
void gsk_gl_command_queue_begin_frame (GskGLCommandQueue *self);
diff --git a/gsk/next/gskglcompiler.c b/gsk/next/gskglcompiler.c
index 9c3038634f..023b469a01 100644
--- a/gsk/next/gskglcompiler.c
+++ b/gsk/next/gskglcompiler.c
@@ -38,7 +38,7 @@ struct _GskGLCompiler
{
GObject parent_instance;
- GskGLCommandQueue *command_queue;
+ GskNextDriver *driver;
GBytes *all_preamble;
GBytes *fragment_preamble;
@@ -81,7 +81,7 @@ gsk_gl_compiler_finalize (GObject *object)
g_clear_pointer (&self->fragment_suffix, g_bytes_unref);
g_clear_pointer (&self->vertex_source, g_bytes_unref);
g_clear_pointer (&self->attrib_locations, g_array_unref);
- g_clear_object (&self->command_queue);
+ g_clear_object (&self->driver);
G_OBJECT_CLASS (gsk_gl_compiler_parent_class)->finalize (object);
}
@@ -111,19 +111,20 @@ gsk_gl_compiler_init (GskGLCompiler *self)
}
GskGLCompiler *
-gsk_gl_compiler_new (GskGLCommandQueue *command_queue,
- gboolean debug_shaders)
+gsk_gl_compiler_new (GskNextDriver *driver,
+ gboolean debug_shaders)
{
GskGLCompiler *self;
GdkGLContext *context;
- g_return_val_if_fail (GSK_IS_GL_COMMAND_QUEUE (command_queue), NULL);
+ g_return_val_if_fail (GSK_IS_NEXT_DRIVER (driver), NULL);
+ g_return_val_if_fail (driver->shared_command_queue != NULL, NULL);
self = g_object_new (GSK_TYPE_GL_COMPILER, NULL);
- self->command_queue = g_object_ref (command_queue);
+ self->driver = g_object_ref (driver);
self->debug_shaders = !!debug_shaders;
- context = gsk_gl_command_queue_get_context (command_queue);
+ context = gsk_gl_command_queue_get_context (self->driver->shared_command_queue);
if (gdk_gl_context_get_use_es (context))
{
@@ -149,7 +150,7 @@ gsk_gl_compiler_new (GskGLCommandQueue *command_queue,
self->gl3 = TRUE;
}
- gsk_gl_command_queue_make_current (command_queue);
+ gsk_gl_command_queue_make_current (self->driver->shared_command_queue);
return g_steal_pointer (&self);
}
@@ -541,9 +542,9 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
g_return_val_if_fail (self->vertex_preamble != NULL, NULL);
g_return_val_if_fail (self->fragment_source != NULL, NULL);
g_return_val_if_fail (self->vertex_source != NULL, NULL);
- g_return_val_if_fail (self->command_queue != NULL, NULL);
+ g_return_val_if_fail (self->driver != NULL, NULL);
- gsk_gl_command_queue_make_current (self->command_queue);
+ gsk_gl_command_queue_make_current (self->driver->command_queue);
g_snprintf (version, sizeof version, "#version %d\n", self->glsl_version);
@@ -674,5 +675,5 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
return NULL;
}
- return gsk_gl_program_new (self->command_queue, name, program_id);
+ return gsk_gl_program_new (self->driver, name, program_id);
}
diff --git a/gsk/next/gskglcompilerprivate.h b/gsk/next/gskglcompilerprivate.h
index c26ab8563b..6f3a2774b3 100644
--- a/gsk/next/gskglcompilerprivate.h
+++ b/gsk/next/gskglcompilerprivate.h
@@ -36,7 +36,7 @@ typedef enum _GskGLCompilerKind
G_DECLARE_FINAL_TYPE (GskGLCompiler, gsk_gl_compiler, GSK, GL_COMPILER, GObject)
-GskGLCompiler *gsk_gl_compiler_new (GskGLCommandQueue *command_queue,
+GskGLCompiler *gsk_gl_compiler_new (GskNextDriver *driver,
gboolean debug);
void gsk_gl_compiler_set_preamble (GskGLCompiler *self,
GskGLCompilerKind kind,
diff --git a/gsk/next/gskgldriver.c b/gsk/next/gskgldriver.c
index 77bde80552..d9d4935859 100644
--- a/gsk/next/gskgldriver.c
+++ b/gsk/next/gskgldriver.c
@@ -279,6 +279,9 @@ gsk_next_driver_dispose (GObject *object)
g_clear_pointer (&self->render_targets, g_ptr_array_unref);
g_clear_pointer (&self->shader_cache, g_hash_table_unref);
+ g_clear_object (&self->command_queue);
+ g_clear_object (&self->shared_command_queue);
+
G_OBJECT_CLASS (gsk_next_driver_parent_class)->dispose (object);
}
@@ -319,7 +322,7 @@ gsk_next_driver_load_programs (GskNextDriver *self,
g_assert (GSK_IS_NEXT_DRIVER (self));
g_assert (GSK_IS_GL_COMMAND_QUEUE (self->command_queue));
- compiler = gsk_gl_compiler_new (self->command_queue, self->debug);
+ compiler = gsk_gl_compiler_new (self, self->debug);
/* Setup preambles that are shared by all shaders */
gsk_gl_compiler_set_preamble_from_resource (compiler,
@@ -409,6 +412,7 @@ gsk_next_driver_new (GskGLCommandQueue *command_queue,
self = g_object_new (GSK_TYPE_NEXT_DRIVER, NULL);
self->command_queue = g_object_ref (command_queue);
+ self->shared_command_queue = g_object_ref (command_queue);
self->debug = !!debug_shaders;
if (!gsk_next_driver_load_programs (self, error))
@@ -451,7 +455,13 @@ gsk_next_driver_from_shared_context (GdkGLContext *context,
gdk_gl_context_make_current (context);
- command_queue = gsk_gl_command_queue_new (context);
+ /* Initially we create a command queue using the shared context. However,
+ * as frames are processed this will be replaced with the command queue
+ * for a given renderer. But since the programs are compiled into the
+ * shared context, all other contexts sharing with it will have access
+ * to those programs.
+ */
+ command_queue = gsk_gl_command_queue_new (context, NULL, NULL);
if (!(driver = gsk_next_driver_new (command_queue, debug_shaders, error)))
goto failure;
@@ -470,21 +480,27 @@ failure:
/**
* gsk_next_driver_begin_frame:
* @self: a #GskNextDriver
+ * @command_queue: A #GskGLCommandQueue from the renderer
*
* Begin a new frame.
*
- * Texture atlases, pools, and other resources will be prepared to
- * draw the next frame.
+ * Texture atlases, pools, and other resources will be prepared to draw the
+ * next frame. The command queue should be one that was created for the
+ * target context to be drawn into (the context of the renderer's surface).
*/
void
-gsk_next_driver_begin_frame (GskNextDriver *self)
+gsk_next_driver_begin_frame (GskNextDriver *self,
+ GskGLCommandQueue *command_queue)
{
g_return_if_fail (GSK_IS_NEXT_DRIVER (self));
+ g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (command_queue));
g_return_if_fail (self->in_frame == FALSE);
self->in_frame = TRUE;
self->current_frame_id++;
+ g_set_object (&self->command_queue, command_queue);
+
gsk_gl_command_queue_make_current (self->command_queue);
gsk_gl_command_queue_begin_frame (self->command_queue);
@@ -543,6 +559,12 @@ gsk_next_driver_end_frame (GskNextDriver *self)
gsk_gl_texture_pool_clear (&self->texture_pool);
self->in_frame = FALSE;
+
+ /* Reset command queue to our shared queue incase we have operations
+ * that need to be processed outside of a frame (such as callbacks
+ * from external systems such as GDK).
+ */
+ g_set_object (&self->command_queue, self->shared_command_queue);
}
GdkGLContext *
@@ -1005,7 +1027,7 @@ gsk_next_driver_lookup_shader (GskNextDriver *self,
return NULL;
}
- compiler = gsk_gl_compiler_new (self->command_queue, FALSE);
+ compiler = gsk_gl_compiler_new (self, FALSE);
suffix = gsk_gl_shader_get_source (shader);
gsk_gl_compiler_set_preamble_from_resource (compiler,
@@ -1084,3 +1106,15 @@ gsk_next_driver_save_atlases_to_png (GskNextDriver *self,
g_free (filename);
}
}
+
+GskGLCommandQueue *
+gsk_next_driver_create_command_queue (GskNextDriver *self,
+ GdkGLContext *context)
+{
+ g_return_val_if_fail (GSK_IS_NEXT_DRIVER (self), NULL);
+ g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
+
+ return gsk_gl_command_queue_new (context,
+ self->shared_command_queue->uniforms,
+ self->shared_command_queue->attachments);
+}
diff --git a/gsk/next/gskgldriverprivate.h b/gsk/next/gskgldriverprivate.h
index 18b10a66be..b23cbdd649 100644
--- a/gsk/next/gskgldriverprivate.h
+++ b/gsk/next/gskgldriverprivate.h
@@ -83,6 +83,7 @@ struct _GskNextDriver
{
GObject parent_instance;
+ GskGLCommandQueue *shared_command_queue;
GskGLCommandQueue *command_queue;
GskGLTexturePool texture_pool;
@@ -119,6 +120,8 @@ struct _GskNextDriver
GskNextDriver *gsk_next_driver_from_shared_context (GdkGLContext *context,
gboolean debug_shaders,
GError **error);
+GskGLCommandQueue *gsk_next_driver_create_command_queue (GskNextDriver *self,
+ GdkGLContext *context);
GdkGLContext *gsk_next_driver_get_context (GskNextDriver *self);
gboolean gsk_next_driver_create_render_target (GskNextDriver *self,
int width,
@@ -129,7 +132,8 @@ gboolean gsk_next_driver_create_render_target (GskNextDriver *
guint gsk_next_driver_release_render_target (GskNextDriver *self,
GskGLRenderTarget *render_target,
gboolean release_texture);
-void gsk_next_driver_begin_frame (GskNextDriver *self);
+void gsk_next_driver_begin_frame (GskNextDriver *self,
+ GskGLCommandQueue *command_queue);
void gsk_next_driver_end_frame (GskNextDriver *self);
guint gsk_next_driver_lookup_texture (GskNextDriver *self,
const GskTextureKey *key);
diff --git a/gsk/next/gskglprogram.c b/gsk/next/gskglprogram.c
index f577e66be7..ff5e434d1a 100644
--- a/gsk/next/gskglprogram.c
+++ b/gsk/next/gskglprogram.c
@@ -21,25 +21,25 @@
#include "config.h"
#include "gskglcommandqueueprivate.h"
-#include "gskgldriverprivate.h"
#include "gskglprogramprivate.h"
#include "gskgluniformstateprivate.h"
G_DEFINE_TYPE (GskGLProgram, gsk_gl_program, G_TYPE_OBJECT)
GskGLProgram *
-gsk_gl_program_new (GskGLCommandQueue *command_queue,
- const char *name,
- int program_id)
+gsk_gl_program_new (GskNextDriver *driver,
+ const char *name,
+ int program_id)
{
GskGLProgram *self;
+ g_return_val_if_fail (GSK_IS_NEXT_DRIVER (driver), NULL);
g_return_val_if_fail (program_id >= -1, NULL);
self = g_object_new (GSK_TYPE_GL_PROGRAM, NULL);
self->id = program_id;
self->name = g_strdup (name);
- self->command_queue = g_object_ref (command_queue);
+ self->driver = g_object_ref (driver);
return self;
}
@@ -56,7 +56,7 @@ gsk_gl_program_finalize (GObject *object)
g_clear_pointer (&self->name, g_free);
g_clear_pointer (&self->uniform_locations, g_array_unref);
- g_clear_object (&self->command_queue);
+ g_clear_object (&self->driver);
G_OBJECT_CLASS (gsk_gl_program_parent_class)->finalize (object);
}
@@ -159,9 +159,9 @@ void
gsk_gl_program_delete (GskGLProgram *self)
{
g_return_if_fail (GSK_IS_GL_PROGRAM (self));
- g_return_if_fail (self->command_queue != NULL);
+ g_return_if_fail (self->driver->command_queue != NULL);
- gsk_gl_command_queue_delete_program (self->command_queue, self->id);
+ gsk_gl_command_queue_delete_program (self->driver->command_queue, self->id);
self->id = -1;
}
@@ -180,7 +180,7 @@ gsk_gl_program_begin_draw (GskGLProgram *self,
g_assert (clip != NULL);
if (self->viewport_location > -1)
- gsk_gl_command_queue_set_uniform4f (self->command_queue,
+ gsk_gl_command_queue_set_uniform4f (self->driver->command_queue,
self->id,
self->viewport_location,
viewport->origin.x,
@@ -189,13 +189,13 @@ gsk_gl_program_begin_draw (GskGLProgram *self,
viewport->size.height);
if (self->modelview_location > -1)
- gsk_gl_command_queue_set_uniform_matrix (self->command_queue,
+ gsk_gl_command_queue_set_uniform_matrix (self->driver->command_queue,
self->id,
self->modelview_location,
modelview);
if (self->projection_location > -1)
- gsk_gl_command_queue_set_uniform_matrix (self->command_queue,
+ gsk_gl_command_queue_set_uniform_matrix (self->driver->command_queue,
self->id,
self->projection_location,
projection);
@@ -203,12 +203,12 @@ gsk_gl_program_begin_draw (GskGLProgram *self,
if (self->clip_rect_location > -1)
{
if (clip != NULL)
- gsk_gl_command_queue_set_uniform_rounded_rect (self->command_queue,
+ gsk_gl_command_queue_set_uniform_rounded_rect (self->driver->command_queue,
self->id,
self->clip_rect_location,
clip);
else
- gsk_gl_command_queue_set_uniform_rounded_rect (self->command_queue,
+ gsk_gl_command_queue_set_uniform_rounded_rect (self->driver->command_queue,
self->id,
self->clip_rect_location,
&GSK_ROUNDED_RECT_INIT (0,
@@ -218,12 +218,12 @@ gsk_gl_program_begin_draw (GskGLProgram *self,
}
if (self->alpha_location > -1)
- gsk_gl_command_queue_set_uniform1f (self->command_queue,
+ gsk_gl_command_queue_set_uniform1f (self->driver->command_queue,
self->id,
self->alpha_location,
alpha);
- gsk_gl_command_queue_begin_draw (self->command_queue, self->id, viewport);
+ gsk_gl_command_queue_begin_draw (self->driver->command_queue, self->id, viewport);
}
void
@@ -231,5 +231,5 @@ gsk_gl_program_end_draw (GskGLProgram *self)
{
g_assert (GSK_IS_GL_PROGRAM (self));
- gsk_gl_command_queue_end_draw (self->command_queue);
+ gsk_gl_command_queue_end_draw (self->driver->command_queue);
}
diff --git a/gsk/next/gskglprogramprivate.h b/gsk/next/gskglprogramprivate.h
index 1149002bfc..fbf7e01fc9 100644
--- a/gsk/next/gskglprogramprivate.h
+++ b/gsk/next/gskglprogramprivate.h
@@ -24,6 +24,7 @@
#include "gskgltypesprivate.h"
#include "gskglcommandqueueprivate.h"
+#include "gskgldriverprivate.h"
G_BEGIN_DECLS
@@ -38,7 +39,7 @@ struct _GskGLProgram
int id;
char *name;
GArray *uniform_locations;
- GskGLCommandQueue *command_queue;
+ GskNextDriver *driver;
/* Cached shared locations */
int projection_location;
@@ -53,7 +54,7 @@ struct _GskGLProgram
int size_location;
};
-GskGLProgram *gsk_gl_program_new (GskGLCommandQueue *command_queue,
+GskGLProgram *gsk_gl_program_new (GskNextDriver *driver,
const char *name,
int program_id);
gboolean gsk_gl_program_add_uniform (GskGLProgram *self,
@@ -84,7 +85,7 @@ gsk_gl_program_set_uniform1fv (GskGLProgram *self,
guint count,
const float *values)
{
- gsk_gl_command_queue_set_uniform1fv (self->command_queue, self->id,
+ gsk_gl_command_queue_set_uniform1fv (self->driver->command_queue, self->id,
gsk_gl_program_get_uniform_location (self, key),
count, values);
}
@@ -95,7 +96,7 @@ gsk_gl_program_set_uniform4fv (GskGLProgram *self,
guint count,
const float *values)
{
- gsk_gl_command_queue_set_uniform4fv (self->command_queue, self->id,
+ gsk_gl_command_queue_set_uniform4fv (self->driver->command_queue, self->id,
gsk_gl_program_get_uniform_location (self, key),
count, values);
}
@@ -105,7 +106,7 @@ gsk_gl_program_set_uniform_rounded_rect (GskGLProgram *self,
guint key,
const GskRoundedRect *rounded_rect)
{
- gsk_gl_command_queue_set_uniform_rounded_rect (self->command_queue, self->id,
+ gsk_gl_command_queue_set_uniform_rounded_rect (self->driver->command_queue, self->id,
gsk_gl_program_get_uniform_location (self, key),
rounded_rect);
}
@@ -115,7 +116,7 @@ gsk_gl_program_set_uniform1i (GskGLProgram *self,
guint key,
int value0)
{
- gsk_gl_command_queue_set_uniform1i (self->command_queue,
+ gsk_gl_command_queue_set_uniform1i (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
value0);
@@ -127,7 +128,7 @@ gsk_gl_program_set_uniform2i (GskGLProgram *self,
int value0,
int value1)
{
- gsk_gl_command_queue_set_uniform2i (self->command_queue,
+ gsk_gl_command_queue_set_uniform2i (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
value0,
@@ -141,7 +142,7 @@ gsk_gl_program_set_uniform3i (GskGLProgram *self,
int value1,
int value2)
{
- gsk_gl_command_queue_set_uniform3i (self->command_queue,
+ gsk_gl_command_queue_set_uniform3i (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
value0,
@@ -157,7 +158,7 @@ gsk_gl_program_set_uniform4i (GskGLProgram *self,
int value2,
int value3)
{
- gsk_gl_command_queue_set_uniform4i (self->command_queue,
+ gsk_gl_command_queue_set_uniform4i (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
value0,
@@ -171,7 +172,7 @@ gsk_gl_program_set_uniform1f (GskGLProgram *self,
guint key,
float value0)
{
- gsk_gl_command_queue_set_uniform1f (self->command_queue,
+ gsk_gl_command_queue_set_uniform1f (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
value0);
@@ -183,7 +184,7 @@ gsk_gl_program_set_uniform2f (GskGLProgram *self,
float value0,
float value1)
{
- gsk_gl_command_queue_set_uniform2f (self->command_queue,
+ gsk_gl_command_queue_set_uniform2f (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
value0,
@@ -197,7 +198,7 @@ gsk_gl_program_set_uniform3f (GskGLProgram *self,
float value1,
float value2)
{
- gsk_gl_command_queue_set_uniform3f (self->command_queue,
+ gsk_gl_command_queue_set_uniform3f (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
value0,
@@ -213,7 +214,7 @@ gsk_gl_program_set_uniform4f (GskGLProgram *self,
float value2,
float value3)
{
- gsk_gl_command_queue_set_uniform4f (self->command_queue,
+ gsk_gl_command_queue_set_uniform4f (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
value0,
@@ -227,7 +228,7 @@ gsk_gl_program_set_uniform_color (GskGLProgram *self,
guint key,
const GdkRGBA *color)
{
- gsk_gl_command_queue_set_uniform_color (self->command_queue,
+ gsk_gl_command_queue_set_uniform_color (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
color);
@@ -240,7 +241,7 @@ gsk_gl_program_set_uniform_texture (GskGLProgram *self,
GLenum texture_slot,
guint texture_id)
{
- gsk_gl_command_queue_set_uniform_texture (self->command_queue,
+ gsk_gl_command_queue_set_uniform_texture (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
texture_target,
@@ -253,7 +254,7 @@ gsk_gl_program_set_uniform_matrix (GskGLProgram *self,
guint key,
const graphene_matrix_t *matrix)
{
- gsk_gl_command_queue_set_uniform_matrix (self->command_queue,
+ gsk_gl_command_queue_set_uniform_matrix (self->driver->command_queue,
self->id,
gsk_gl_program_get_uniform_location (self, key),
matrix);
diff --git a/gsk/next/gskglrenderer.c b/gsk/next/gskglrenderer.c
index 59db1fea46..6db031f161 100644
--- a/gsk/next/gskglrenderer.c
+++ b/gsk/next/gskglrenderer.c
@@ -45,6 +45,14 @@ struct _GskNextRenderer
*/
GdkGLContext *context;
+ /* Our command queue is private to this renderer and talks to the GL
+ * context for our target surface. This ensure that framebuffer 0 matches
+ * the surface we care about. Since the context is shared with other
+ * contexts from other renderers on the display, texture atlases,
+ * programs, and other objects are available to them all.
+ */
+ GskGLCommandQueue *command_queue;
+
/* The driver manages our program state and command queues. It also
* deals with caching textures, shaders, shadows, glyph, and icon
* caches through various helpers.
@@ -80,6 +88,7 @@ gsk_next_renderer_realize (GskRenderer *renderer,
g_assert (self->driver == NULL);
g_assert (self->context == NULL);
+ g_assert (self->command_queue == NULL);
if (!(context = gdk_surface_create_gl_context (surface, error)) ||
!gdk_gl_context_realize (context, error))
@@ -102,6 +111,7 @@ gsk_next_renderer_realize (GskRenderer *renderer,
if (!(driver = gsk_next_driver_from_shared_context (shared_context, debug_shaders, error)))
goto failure;
+ self->command_queue = gsk_next_driver_create_command_queue (driver, context);
self->context = g_steal_pointer (&context);
self->driver = g_steal_pointer (&driver);
@@ -122,6 +132,8 @@ gsk_next_renderer_unrealize (GskRenderer *renderer)
g_assert (GSK_IS_NEXT_RENDERER (renderer));
g_clear_object (&self->driver);
+ g_clear_object (&self->context);
+ g_clear_object (&self->command_queue);
}
typedef struct _GskGLTextureState
@@ -230,20 +242,19 @@ gsk_gl_renderer_render (GskRenderer *renderer,
gdk_gl_context_make_current (self->context);
gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->context), update_area);
- job = gsk_gl_render_job_new (self->driver, &viewport, scale_factor, render_region, self->context, 0);
-
+ gsk_next_driver_begin_frame (self->driver, self->command_queue);
+ job = gsk_gl_render_job_new (self->driver, &viewport, scale_factor, render_region, 0);
#ifdef G_ENABLE_DEBUG
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
gsk_gl_render_job_set_debug_fallback (job, TRUE);
#endif
-
gsk_gl_render_job_render (job, root);
+ gsk_next_driver_end_frame (self->driver);
+ gsk_gl_render_job_free (job);
gdk_gl_context_make_current (self->context);
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->context));
- gsk_gl_render_job_free (job);
-
cairo_region_destroy (render_region);
}
@@ -255,7 +266,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
GskNextRenderer *self = (GskNextRenderer *)renderer;
GskGLRenderTarget *render_target;
GskGLRenderJob *job;
- GdkGLContext *context;
+ GdkTexture *texture;
guint texture_id;
int width;
int height;
@@ -263,25 +274,28 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
g_assert (GSK_IS_NEXT_RENDERER (renderer));
g_assert (root != NULL);
- context = gsk_gl_command_queue_get_context (self->driver->command_queue);
width = ceilf (viewport->size.width);
height = ceilf (viewport->size.height);
- gdk_gl_context_make_current (context);
-
if (!gsk_next_driver_create_render_target (self->driver,
width, height,
GL_NEAREST, GL_NEAREST,
&render_target))
return NULL;
- job = gsk_gl_render_job_new (self->driver, viewport, 1, NULL, context, render_target->framebuffer_id);
+ gsk_next_driver_begin_frame (self->driver, self->command_queue);
+ job = gsk_gl_render_job_new (self->driver, viewport, 1, NULL, render_target->framebuffer_id);
+#ifdef G_ENABLE_DEBUG
+ if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
+ gsk_gl_render_job_set_debug_fallback (job, TRUE);
+#endif
gsk_gl_render_job_render_flipped (job, root);
- gsk_gl_render_job_free (job);
-
texture_id = gsk_next_driver_release_render_target (self->driver, render_target, FALSE);
+ texture = create_texture_from_texture (self->context, texture_id, width, height);
+ gsk_next_driver_end_frame (self->driver);
+ gsk_gl_render_job_free (job);
- return create_texture_from_texture (context, texture_id, width, height);
+ return g_steal_pointer (&texture);
}
static void
diff --git a/gsk/next/gskglrenderjob.c b/gsk/next/gskglrenderjob.c
index a88f411082..cbcbf3e0ef 100644
--- a/gsk/next/gskglrenderjob.c
+++ b/gsk/next/gskglrenderjob.c
@@ -3502,7 +3502,6 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
GskRenderNode *root)
{
graphene_matrix_t proj;
- GdkGLContext *context;
guint framebuffer_id;
guint texture_id;
guint surface_height;
@@ -3511,11 +3510,8 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
g_return_if_fail (root != NULL);
g_return_if_fail (GSK_IS_NEXT_DRIVER (job->driver));
- context = gsk_next_driver_get_context (job->driver);
surface_height = job->viewport.size.height;
- gdk_gl_context_make_current (context);
-
graphene_matrix_init_ortho (&proj,
job->viewport.origin.x,
job->viewport.origin.x + job->viewport.size.width,
@@ -3532,16 +3528,14 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
&framebuffer_id, &texture_id))
return;
- gsk_next_driver_begin_frame (job->driver);
-
/* Setup drawing to our offscreen texture/framebuffer which is flipped */
gsk_gl_command_queue_bind_framebuffer (job->command_queue, framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
/* Visit all nodes creating batches */
- gdk_gl_context_push_debug_group (context, "Building command queue");
+ gdk_gl_context_push_debug_group (job->command_queue->context, "Building command queue");
gsk_gl_render_job_visit_node (job, root);
- gdk_gl_context_pop_debug_group (context);
+ gdk_gl_context_pop_debug_group (job->command_queue->context);
/* Now draw to our real destination, but flipped */
gsk_gl_command_queue_bind_framebuffer (job->command_queue, job->framebuffer);
@@ -3560,13 +3554,9 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
gsk_gl_render_job_draw_rect (job, &job->viewport);
gsk_gl_program_end_draw (job->driver->blit);
- gdk_gl_context_push_debug_group (context, "Executing command queue");
+ gdk_gl_context_push_debug_group (job->command_queue->context, "Executing command queue");
gsk_gl_command_queue_execute (job->command_queue, surface_height, 1, NULL);
- gdk_gl_context_pop_debug_group (context);
-
- gsk_next_driver_end_frame (job->driver);
-
- gdk_gl_context_make_current (context);
+ gdk_gl_context_pop_debug_group (job->command_queue->context);
glDeleteFramebuffers (1, &framebuffer_id);
glDeleteTextures (1, &texture_id);
@@ -3576,7 +3566,6 @@ void
gsk_gl_render_job_render (GskGLRenderJob *job,
GskRenderNode *root)
{
- GdkGLContext *context;
guint scale_factor;
guint surface_height;
@@ -3584,22 +3573,18 @@ gsk_gl_render_job_render (GskGLRenderJob *job,
g_return_if_fail (root != NULL);
g_return_if_fail (GSK_IS_NEXT_DRIVER (job->driver));
- context = gsk_gl_command_queue_get_context (job->command_queue);
scale_factor = MAX (job->scale_x, job->scale_y);
surface_height = job->viewport.size.height;
- /* Do initial frame setup using shared GL context */
- gsk_next_driver_begin_frame (job->driver);
-
/* Build the command queue using the shared GL context for all renderers
* on the same display.
*/
- gdk_gl_context_push_debug_group (context, "Building command queue");
+ gdk_gl_context_push_debug_group (job->command_queue->context, "Building command queue");
if (job->framebuffer != 0)
gsk_gl_command_queue_bind_framebuffer (job->command_queue, job->framebuffer);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
gsk_gl_render_job_visit_node (job, root);
- gdk_gl_context_pop_debug_group (context);
+ gdk_gl_context_pop_debug_group (job->command_queue->context);
#if 0
/* At this point the atlases have uploaded content while we processed
@@ -3612,13 +3597,10 @@ gsk_gl_render_job_render (GskGLRenderJob *job,
* that was provided to us when creating the render job as framebuffer 0
* is bound to that context.
*/
- gdk_gl_context_make_current (job->context);
- gdk_gl_context_push_debug_group (job->context, "Executing command queue");
+ gdk_gl_context_make_current (job->command_queue->context);
+ gdk_gl_context_push_debug_group (job->command_queue->context, "Executing command queue");
gsk_gl_command_queue_execute (job->command_queue, surface_height, scale_factor, job->region);
- gdk_gl_context_pop_debug_group (job->context);
-
- /* Do frame cleanup using shared GL context */
- gsk_next_driver_end_frame (job->driver);
+ gdk_gl_context_pop_debug_group (job->command_queue->context);
}
void
@@ -3635,7 +3617,6 @@ gsk_gl_render_job_new (GskNextDriver *driver,
const graphene_rect_t *viewport,
float scale_factor,
const cairo_region_t *region,
- GdkGLContext *context,
guint framebuffer)
{
const graphene_rect_t *clip_rect = viewport;
@@ -3643,14 +3624,12 @@ gsk_gl_render_job_new (GskNextDriver *driver,
GskGLRenderJob *job;
g_return_val_if_fail (GSK_IS_NEXT_DRIVER (driver), NULL);
- g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
g_return_val_if_fail (viewport != NULL, NULL);
g_return_val_if_fail (scale_factor > 0, NULL);
job = g_slice_new0 (GskGLRenderJob);
job->driver = g_object_ref (driver);
- job->command_queue = driver->command_queue;
- job->context = g_object_ref (context);
+ job->command_queue = job->driver->command_queue;
job->clip = g_array_new (FALSE, FALSE, sizeof (GskGLRenderClip));
job->modelview = g_array_new (FALSE, FALSE, sizeof (GskGLRenderModelview));
job->framebuffer = framebuffer;
@@ -3704,7 +3683,6 @@ gsk_gl_render_job_free (GskGLRenderJob *job)
}
g_clear_object (&job->driver);
- g_clear_object (&job->context);
g_clear_pointer (&job->region, cairo_region_destroy);
g_clear_pointer (&job->modelview, g_array_unref);
g_clear_pointer (&job->clip, g_array_unref);
diff --git a/gsk/next/gskglrenderjobprivate.h b/gsk/next/gskglrenderjobprivate.h
index 02cfee5737..2a8c01fa71 100644
--- a/gsk/next/gskglrenderjobprivate.h
+++ b/gsk/next/gskglrenderjobprivate.h
@@ -27,7 +27,6 @@ GskGLRenderJob *gsk_gl_render_job_new (GskNextDriver *dr
const graphene_rect_t *viewport,
float scale_factor,
const cairo_region_t *region,
- GdkGLContext *context,
guint framebuffer);
void gsk_gl_render_job_free (GskGLRenderJob *job);
void gsk_gl_render_job_render (GskGLRenderJob *job,
diff --git a/gsk/next/gskgluniformstate.c b/gsk/next/gskgluniformstate.c
index b4e41261df..a75255b4e3 100644
--- a/gsk/next/gskgluniformstate.c
+++ b/gsk/next/gskgluniformstate.c
@@ -86,19 +86,32 @@ gsk_gl_uniform_state_new (void)
{
GskGLUniformState *state;
- state = g_new0 (GskGLUniformState, 1);
+ state = g_atomic_rc_box_new0 (GskGLUniformState);
state->program_info = g_array_new (FALSE, TRUE, sizeof (ProgramInfo));
state->uniform_data = g_byte_array_new ();
return g_steal_pointer (&state);
}
-void
-gsk_gl_uniform_state_free (GskGLUniformState *state)
+GskGLUniformState *
+gsk_gl_uniform_state_ref (GskGLUniformState *state)
+{
+ return g_atomic_rc_box_acquire (state);
+}
+
+static void
+gsk_gl_uniform_state_finalize (gpointer data)
{
+ GskGLUniformState *state = data;
+
g_clear_pointer (&state->program_info, g_array_unref);
g_clear_pointer (&state->uniform_data, g_byte_array_unref);
- g_free (state);
+}
+
+void
+gsk_gl_uniform_state_unref (GskGLUniformState *state)
+{
+ g_atomic_rc_box_release_full (state, gsk_gl_uniform_state_finalize);
}
static inline void
diff --git a/gsk/next/gskgluniformstateprivate.h b/gsk/next/gskgluniformstateprivate.h
index 63bfd84f5f..609bba87d0 100644
--- a/gsk/next/gskgluniformstateprivate.h
+++ b/gsk/next/gskgluniformstateprivate.h
@@ -87,6 +87,8 @@ typedef enum _GskGLUniformKind
} 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);
@@ -178,7 +180,6 @@ void gsk_gl_uniform_state_snapshot (GskGLUniformState
guint program_id,
GskGLUniformStateCallback callback,
gpointer user_data);
-void gsk_gl_uniform_state_free (GskGLUniformState *state);
static inline gconstpointer
gsk_gl_uniform_state_get_uniform_data (GskGLUniformState *state,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]