[gtk+] gsk: Move resource handling inside GskGLDriver
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] gsk: Move resource handling inside GskGLDriver
- Date: Tue, 18 Oct 2016 10:55:27 +0000 (UTC)
commit 24a6f3c055e749bc077093c7fd90ce357695dd52
Author: Emmanuele Bassi <ebassi gnome org>
Date: Wed Jul 20 17:55:35 2016 +0100
gsk: Move resource handling inside GskGLDriver
We want the GL driver to cache as many resources as possible, so we can
always ensure that we're in a consistent state, and we can handle state
transitions more appropriately.
gsk/gskgldriver.c | 267 ++++++++++++++++++++++++++++++++++------------
gsk/gskgldriverprivate.h | 13 ++-
gsk/gskglrenderer.c | 120 +++++++++------------
gsk/gskshaderbuilder.c | 6 +-
4 files changed, 262 insertions(+), 144 deletions(-)
---
diff --git a/gsk/gskgldriver.c b/gsk/gskgldriver.c
index 634cb54..52d8631 100644
--- a/gsk/gskgldriver.c
+++ b/gsk/gskgldriver.c
@@ -23,21 +23,26 @@ typedef struct {
GLuint uv_id;
} Vao;
+typedef struct {
+ GLuint fbo_id;
+ GLuint depth_stencil_id;
+} Fbo;
+
struct _GskGLDriver
{
GObject parent_instance;
GdkGLContext *gl_context;
- GLuint default_fbo;
+ Fbo default_fbo;
GHashTable *textures;
- GArray *vaos;
+ GHashTable *vaos;
Texture *bound_source_texture;
Texture *bound_mask_texture;
Vao *bound_vao;
- GLuint bound_fbo;
+ Fbo *bound_fbo;
gboolean in_frame : 1;
};
@@ -72,18 +77,28 @@ texture_free (gpointer data)
static void
fbo_clear (gpointer data)
{
- GLuint fbo_id = GPOINTER_TO_UINT (data);
+ Fbo *f = data;
+
+ if (f->depth_stencil_id != 0)
+ glDeleteRenderbuffers (1, &f->depth_stencil_id);
+
+ glDeleteFramebuffers (1, &f->fbo_id);
+}
- glDeleteFramebuffers (1, &fbo_id);
+static Vao *
+vao_new (void)
+{
+ return g_slice_new0 (Vao);
}
static void
-vao_clear (gpointer data)
+vao_free (gpointer data)
{
Vao *v = data;
glDeleteBuffers (1, &v->buffer_id);
glDeleteVertexArrays (1, &v->vao_id);
+ g_slice_free (Vao, v);
}
static void
@@ -92,7 +107,7 @@ gsk_gl_driver_finalize (GObject *gobject)
GskGLDriver *self = GSK_GL_DRIVER (gobject);
g_clear_pointer (&self->textures, g_hash_table_unref);
- g_clear_pointer (&self->vaos, g_array_unref);
+ g_clear_pointer (&self->vaos, g_hash_table_unref);
g_clear_object (&self->gl_context);
@@ -158,9 +173,7 @@ static void
gsk_gl_driver_init (GskGLDriver *self)
{
self->textures = g_hash_table_new_full (NULL, NULL, NULL, texture_free);
-
- self->vaos = g_array_new (FALSE, FALSE, sizeof (Vao));
- g_array_set_clear_func (self->vaos, vao_clear);
+ self->vaos = g_hash_table_new_full (NULL, NULL, NULL, vao_free);
}
GskGLDriver *
@@ -181,8 +194,8 @@ gsk_gl_driver_begin_frame (GskGLDriver *driver)
driver->in_frame = TRUE;
- glGetIntegerv (GL_FRAMEBUFFER_BINDING, (GLint *) &driver->default_fbo);
- driver->bound_fbo = driver->default_fbo;
+ glGetIntegerv (GL_FRAMEBUFFER_BINDING, (GLint *) &(driver->default_fbo.fbo_id));
+ driver->bound_fbo = &driver->default_fbo;
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, 0);
@@ -209,10 +222,12 @@ gsk_gl_driver_end_frame (GskGLDriver *driver)
driver->bound_source_texture = NULL;
driver->bound_mask_texture = NULL;
driver->bound_vao = NULL;
- driver->bound_fbo = driver->default_fbo;
+ driver->bound_fbo = NULL;
- g_hash_table_remove_all (driver->textures);
- g_array_set_size (driver->vaos, 0);
+ GSK_NOTE (OPENGL,
+ g_print ("*** Frame end: textures=%d, vaos=%d\n",
+ g_hash_table_size (driver->textures),
+ g_hash_table_size (driver->vaos)));
driver->in_frame = FALSE;
}
@@ -221,29 +236,42 @@ static Texture *
gsk_gl_driver_get_texture (GskGLDriver *driver,
int texture_id)
{
- return g_hash_table_lookup (driver->textures, GINT_TO_POINTER (texture_id));
+ Texture *t;
+
+ if (g_hash_table_lookup_extended (driver->textures, GINT_TO_POINTER (texture_id), NULL, (gpointer *) &t))
+ return t;
+
+ return NULL;
}
static Vao *
gsk_gl_driver_get_vao (GskGLDriver *driver,
int vao_id)
{
- int i;
+ Vao *v;
- for (i = 0; i < driver->vaos->len; i++)
- {
- Vao *v = &g_array_index (driver->vaos, Vao, i);
- if (v->vao_id == vao_id)
- return v;
- }
+ if (g_hash_table_lookup_extended (driver->vaos, GINT_TO_POINTER (vao_id), NULL, (gpointer *) &v))
+ return v;
return NULL;
}
+static Fbo *
+gsk_gl_driver_get_fbo (GskGLDriver *driver,
+ int texture_id)
+{
+ Texture *t = gsk_gl_driver_get_texture (driver, texture_id);
+
+ if (t->fbos == NULL)
+ return &driver->default_fbo;
+
+ return &g_array_index (t->fbos, Fbo, 0);
+}
+
int
-gsk_gl_driver_create_texture (GskGLDriver *driver,
- int width,
- int height)
+gsk_gl_driver_create_texture (GskGLDriver *driver,
+ int width,
+ int height)
{
guint texture_id;
Texture *t;
@@ -251,12 +279,6 @@ gsk_gl_driver_create_texture (GskGLDriver *driver,
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), -1);
glGenTextures (1, &texture_id);
- glBindTexture (GL_TEXTURE_2D, texture_id);
-
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
t = texture_new ();
t->texture_id = texture_id;
@@ -264,9 +286,9 @@ gsk_gl_driver_create_texture (GskGLDriver *driver,
t->height = height;
t->min_filter = GL_NEAREST;
t->mag_filter = GL_NEAREST;
- g_hash_table_insert (driver->textures, GUINT_TO_POINTER (texture_id), t);
+ g_hash_table_insert (driver->textures, GINT_TO_POINTER (texture_id), t);
- return texture_id;
+ return t->texture_id;
}
int
@@ -278,9 +300,10 @@ gsk_gl_driver_create_vao_for_quad (GskGLDriver *driver,
{
GLuint vao_id, buffer_id;
- Vao v;
+ Vao *v;
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), -1);
+ g_return_val_if_fail (driver->in_frame, -1);
glGenVertexArrays (1, &vao_id);
glBindVertexArray (vao_id);
@@ -302,23 +325,28 @@ gsk_gl_driver_create_vao_for_quad (GskGLDriver *driver,
glBindBuffer (GL_ARRAY_BUFFER, 0);
glBindVertexArray (0);
- v.vao_id = vao_id;
- v.buffer_id = buffer_id;
- v.position_id = position_id;
- v.uv_id = uv_id;
- g_array_append_val (driver->vaos, v);
+ v = vao_new ();
+ v->vao_id = vao_id;
+ v->buffer_id = buffer_id;
+ v->position_id = position_id;
+ v->uv_id = uv_id;
+ g_hash_table_insert (driver->vaos, GINT_TO_POINTER (vao_id), v);
return vao_id;
}
int
gsk_gl_driver_create_render_target (GskGLDriver *driver,
- int texture_id)
+ int texture_id,
+ gboolean add_depth_buffer,
+ gboolean add_stencil_buffer)
{
+ GLuint fbo_id, depth_stencil_buffer_id;
Texture *t;
- GLuint fbo_id;
+ Fbo f;
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), -1);
+ g_return_val_if_fail (driver->in_frame, -1);
t = gsk_gl_driver_get_texture (driver, texture_id);
if (t == NULL)
@@ -326,7 +354,7 @@ gsk_gl_driver_create_render_target (GskGLDriver *driver,
if (t->fbos == NULL)
{
- t->fbos = g_array_new (FALSE, FALSE, sizeof (GLuint));
+ t->fbos = g_array_new (FALSE, FALSE, sizeof (Fbo));
g_array_set_clear_func (t->fbos, fbo_clear);
}
@@ -334,9 +362,35 @@ gsk_gl_driver_create_render_target (GskGLDriver *driver,
glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t->texture_id, 0);
- g_array_append_val (t->fbos, fbo_id);
+ if (add_depth_buffer || add_stencil_buffer)
+ glGenRenderbuffersEXT (1, &depth_stencil_buffer_id);
+ else
+ depth_stencil_buffer_id = 0;
+
+ glBindRenderbuffer (GL_RENDERBUFFER, depth_stencil_buffer_id);
+
+ if (add_depth_buffer || add_stencil_buffer)
+ {
+ if (add_stencil_buffer)
+ glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, t->width, t->height);
+ else
+ glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, t->width, t->height);
+
+ if (add_depth_buffer)
+ glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, depth_stencil_buffer_id);
+
+ if (add_stencil_buffer)
+ glFramebufferRenderbufferEXT (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, depth_stencil_buffer_id);
+ }
+
+ f.fbo_id = fbo_id;
+ f.depth_stencil_id = depth_stencil_buffer_id;
- glBindFramebuffer (GL_FRAMEBUFFER, driver->default_fbo);
+ g_array_append_val (t->fbos, f);
+
+ glBindFramebuffer (GL_FRAMEBUFFER, driver->default_fbo.fbo_id);
return fbo_id;
}
@@ -352,7 +406,10 @@ gsk_gl_driver_bind_source_texture (GskGLDriver *driver,
t = gsk_gl_driver_get_texture (driver, texture_id);
if (t == NULL)
- return;
+ {
+ g_critical ("No texture %d found.", texture_id);
+ return;
+ }
if (driver->bound_source_texture != t)
{
@@ -374,7 +431,10 @@ gsk_gl_driver_bind_mask_texture (GskGLDriver *driver,
t = gsk_gl_driver_get_texture (driver, texture_id);
if (t == NULL)
- return;
+ {
+ g_critical ("No texture %d found.", texture_id);
+ return;
+ }
if (driver->bound_mask_texture != t)
{
@@ -398,7 +458,10 @@ gsk_gl_driver_bind_vao (GskGLDriver *driver,
v = gsk_gl_driver_get_vao (driver, vao_id);
if (v == NULL)
- return;
+ {
+ g_critical ("No VAO %d found.", vao_id);
+ return;
+ }
if (driver->bound_vao != v)
{
@@ -411,31 +474,94 @@ gsk_gl_driver_bind_vao (GskGLDriver *driver,
}
}
-void
+gboolean
gsk_gl_driver_bind_render_target (GskGLDriver *driver,
int texture_id)
{
- GLuint fbo_id;
+ int status;
+ Fbo *f;
+
+ g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), FALSE);
+ g_return_val_if_fail (driver->in_frame, FALSE);
+
+ f = gsk_gl_driver_get_fbo (driver, texture_id);
+ if (f == NULL)
+ {
+ g_critical ("No render target associated to texture %d found.", texture_id);
+ return FALSE;
+ }
+
+ if (f != driver->bound_fbo)
+ {
+ glBindFramebuffer (GL_FRAMEBUFFER, f->fbo_id);
+
+ driver->bound_fbo = f;
+ }
+
+ status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
+
+ return status == GL_FRAMEBUFFER_COMPLETE;
+}
+
+void
+gsk_gl_driver_destroy_texture (GskGLDriver *driver,
+ int texture_id)
+{
+ g_return_if_fail (GSK_IS_GL_DRIVER (driver));
+
+ g_hash_table_remove (driver->textures, GINT_TO_POINTER (texture_id));
+}
+
+void
+gsk_gl_driver_destroy_vao (GskGLDriver *driver,
+ int vao_id)
+{
+ g_return_if_fail (GSK_IS_GL_DRIVER (driver));
+
+ g_hash_table_remove (driver->vaos, GINT_TO_POINTER (vao_id));
+}
+
+static void
+gsk_gl_driver_set_texture_parameters (GskGLDriver *driver,
+ int min_filter,
+ int mag_filter)
+{
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
+void
+gsk_gl_driver_init_texture_empty (GskGLDriver *driver,
+ int texture_id)
+{
Texture *t;
g_return_if_fail (GSK_IS_GL_DRIVER (driver));
- g_return_if_fail (driver->in_frame);
t = gsk_gl_driver_get_texture (driver, texture_id);
if (t == NULL)
- return;
-
- if (t->fbos == NULL)
- fbo_id = driver->default_fbo;
- else
- fbo_id = g_array_index (t->fbos, GLuint, 0);
-
- if (fbo_id != driver->bound_fbo)
{
- glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
+ g_critical ("No texture %d found.", texture_id);
+ return;
+ }
- driver->bound_fbo = fbo_id;
+ if (!(driver->bound_source_texture == t || driver->bound_mask_texture == t))
+ {
+ g_critical ("You must bind the texture before initializing it.");
+ return;
}
+
+ gsk_gl_driver_set_texture_parameters (driver, t->min_filter, t->mag_filter);
+
+ if (gdk_gl_context_get_use_es (driver->gl_context))
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, t->width, t->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ else
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, t->width, t->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+
+ glBindTexture (GL_TEXTURE_2D, 0);
}
void
@@ -451,15 +577,18 @@ gsk_gl_driver_init_texture_with_surface (GskGLDriver *driver,
t = gsk_gl_driver_get_texture (driver, texture_id);
if (t == NULL)
- return;
-
- glBindTexture (GL_TEXTURE_2D, t->texture_id);
+ {
+ g_critical ("No texture %d found.", texture_id);
+ return;
+ }
- if (min_filter != t->min_filter)
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
+ if (!(driver->bound_source_texture == t || driver->bound_mask_texture == t))
+ {
+ g_critical ("You must bind the texture before initializing it.");
+ return;
+ }
- if (mag_filter != t->mag_filter)
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
+ gsk_gl_driver_set_texture_parameters (driver, min_filter, mag_filter);
gdk_cairo_surface_upload_to_gl (surface, GL_TEXTURE_2D, t->width, t->height, NULL);
@@ -468,4 +597,6 @@ gsk_gl_driver_init_texture_with_surface (GskGLDriver *driver,
if (t->min_filter != GL_NEAREST)
glGenerateMipmap (GL_TEXTURE_2D);
+
+ glBindTexture (GL_TEXTURE_2D, 0);
}
diff --git a/gsk/gskgldriverprivate.h b/gsk/gskgldriverprivate.h
index 27d7966..30eaffa 100644
--- a/gsk/gskgldriverprivate.h
+++ b/gsk/gskgldriverprivate.h
@@ -30,7 +30,9 @@ int gsk_gl_driver_create_vao_for_quad (GskGLDriver *driver
int n_vertices,
GskQuadVertex *vertices);
int gsk_gl_driver_create_render_target (GskGLDriver *driver,
- int texture_id);
+ int texture_id,
+ gboolean add_depth_buffer,
+ gboolean add_stencil_buffer);
void gsk_gl_driver_bind_source_texture (GskGLDriver *driver,
int texture_id);
@@ -38,13 +40,22 @@ void gsk_gl_driver_bind_mask_texture (GskGLDriver *driver
int texture_id);
void gsk_gl_driver_bind_vao (GskGLDriver *driver,
int vao_id);
+gboolean gsk_gl_driver_bind_render_target (GskGLDriver *driver,
+ int texture_id);
+void gsk_gl_driver_init_texture_empty (GskGLDriver *driver,
+ int texture_id);
void gsk_gl_driver_init_texture_with_surface (GskGLDriver *driver,
int texture_id,
cairo_surface_t *surface,
int min_filter,
int mag_filter);
+void gsk_gl_driver_destroy_texture (GskGLDriver *driver,
+ int texture_id);
+void gsk_gl_driver_destroy_vao (GskGLDriver *driver,
+ int vao_id);
+
G_END_DECLS
#endif /* __GSK_GL_DRIVER_PRIVATE_H__ */
diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c
index 15f32fb..ac156ca 100644
--- a/gsk/gskglrenderer.c
+++ b/gsk/gskglrenderer.c
@@ -20,18 +20,18 @@
#define SHADER_VERSION_GL3 150
typedef struct {
- guint vao_id;
- guint buffer_id;
- guint texture_id;
- guint program_id;
-
- guint mvp_location;
- guint map_location;
- guint parentMap_location;
- guint uv_location;
- guint position_location;
- guint alpha_location;
- guint blendMode_location;
+ int vao_id;
+ int buffer_id;
+ int texture_id;
+ int program_id;
+
+ int mvp_location;
+ int map_location;
+ int parentMap_location;
+ int uv_location;
+ int position_location;
+ int alpha_location;
+ int blendMode_location;
} RenderData;
typedef struct {
@@ -131,54 +131,19 @@ gsk_gl_renderer_create_buffers (GskGLRenderer *self,
GSK_NOTE (OPENGL, g_print ("Creating buffers\n"));
- glGenFramebuffersEXT (1, &self->frame_buffer);
-
if (self->texture_id == 0)
{
- glGenTextures (1, &self->texture_id);
-
- glBindTexture (GL_TEXTURE_2D, self->texture_id);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- if (gdk_gl_context_get_use_es (self->context))
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- else
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+ self->texture_id = gsk_gl_driver_create_texture (self->gl_driver, width, height);
+ gsk_gl_driver_bind_source_texture (self->gl_driver, self->texture_id);
+ gsk_gl_driver_init_texture_empty (self->gl_driver, self->texture_id);
}
- if (self->depth_stencil_buffer == 0)
- glGenRenderbuffersEXT (1, &self->depth_stencil_buffer);
-
- glBindRenderbuffer (GL_RENDERBUFFER, self->depth_stencil_buffer);
- glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
+ gsk_gl_driver_create_render_target (self->gl_driver, self->texture_id, TRUE, TRUE);
self->has_buffers = TRUE;
}
static void
-gsk_gl_renderer_attach_buffers (GskGLRenderer *self)
-{
- GSK_NOTE (OPENGL, g_print ("Attaching buffers\n"));
-
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, self->frame_buffer);
-
- if (self->texture_id != 0)
- {
- glFramebufferTexture2D (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, self->texture_id, 0);
- }
-
- glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT, self->depth_stencil_buffer);
-
- glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT, self->depth_stencil_buffer);
-}
-
-static void
gsk_gl_renderer_destroy_buffers (GskGLRenderer *self)
{
if (self->context == NULL)
@@ -191,25 +156,12 @@ gsk_gl_renderer_destroy_buffers (GskGLRenderer *self)
gdk_gl_context_make_current (self->context);
- if (self->depth_stencil_buffer != 0)
- {
- glDeleteRenderbuffersEXT (1, &self->depth_stencil_buffer);
- self->depth_stencil_buffer = 0;
- }
-
if (self->texture_id != 0)
{
- glDeleteTextures (1, &self->texture_id);
+ gsk_gl_driver_destroy_texture (self->gl_driver, self->texture_id);
self->texture_id = 0;
}
- if (self->frame_buffer != 0)
- {
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
- glDeleteFramebuffersEXT (1, &self->frame_buffer);
- self->frame_buffer = 0;
- }
-
self->has_buffers = FALSE;
}
@@ -355,6 +307,9 @@ gsk_gl_renderer_unrealize (GskRenderer *renderer)
gdk_gl_context_make_current (self->context);
+ /* We don't need to iterate to destroy the associated GL resources,
+ * as they will be dropped when we finalize the GskGLDriver
+ */
g_clear_pointer (&self->opaque_render_items, g_array_unref);
g_clear_pointer (&self->transparent_render_items, g_array_unref);
@@ -633,6 +588,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
item.render_data.texture_id = gsk_gl_driver_create_texture (self->gl_driver,
bounds.size.width,
bounds.size.height);
+ gsk_gl_driver_bind_source_texture (self->gl_driver, item.render_data.texture_id);
gsk_gl_driver_init_texture_with_surface (self->gl_driver,
item.render_data.texture_id,
surface,
@@ -682,6 +638,8 @@ gsk_gl_renderer_validate_tree (GskGLRenderer *self,
self->opaque_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), n_nodes);
self->transparent_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), n_nodes);
+ gsk_gl_driver_begin_frame (self->gl_driver);
+
GSK_NOTE (OPENGL, g_print ("RenderNode -> RenderItem\n"));
gsk_gl_renderer_add_render_item (self, root, NULL);
@@ -691,15 +649,37 @@ gsk_gl_renderer_validate_tree (GskGLRenderer *self,
self->opaque_render_items->len,
self->transparent_render_items->len));
+ gsk_gl_driver_end_frame (self->gl_driver);
+
return TRUE;
}
static void
gsk_gl_renderer_clear_tree (GskGLRenderer *self)
{
+ int i;
+
if (self->context == NULL)
return;
+ gdk_gl_context_make_current (self->context);
+
+ for (i = 0; i < self->opaque_render_items->len; i++)
+ {
+ RenderItem *item = &g_array_index (self->opaque_render_items, RenderItem, i);
+
+ gsk_gl_driver_destroy_texture (self->gl_driver, item->render_data.texture_id);
+ gsk_gl_driver_destroy_vao (self->gl_driver, item->render_data.vao_id);
+ }
+
+ for (i = 0; i < self->transparent_render_items->len; i++)
+ {
+ RenderItem *item = &g_array_index (self->transparent_render_items, RenderItem, i);
+
+ gsk_gl_driver_destroy_texture (self->gl_driver, item->render_data.texture_id);
+ gsk_gl_driver_destroy_vao (self->gl_driver, item->render_data.vao_id);
+ }
+
g_clear_pointer (&self->opaque_render_items, g_array_unref);
g_clear_pointer (&self->transparent_render_items, g_array_unref);
}
@@ -720,7 +700,6 @@ gsk_gl_renderer_render (GskRenderer *renderer,
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
graphene_matrix_t modelview, projection;
graphene_rect_t viewport;
- int status;
guint i;
guint64 gpu_time;
@@ -731,8 +710,9 @@ gsk_gl_renderer_render (GskRenderer *renderer,
gsk_renderer_get_viewport (renderer, &viewport);
+ gsk_gl_driver_begin_frame (self->gl_driver);
gsk_gl_renderer_create_buffers (self, viewport.size.width, viewport.size.height);
- gsk_gl_renderer_attach_buffers (self);
+ gsk_gl_driver_end_frame (self->gl_driver);
gsk_renderer_get_modelview (renderer, &modelview);
gsk_renderer_get_projection (renderer, &projection);
@@ -744,13 +724,11 @@ gsk_gl_renderer_render (GskRenderer *renderer,
if (!gsk_gl_renderer_validate_tree (self, root))
goto out;
- gsk_gl_profiler_begin_gpu_region (self->gl_profiler);
-
gsk_gl_driver_begin_frame (self->gl_driver);
+ gsk_gl_profiler_begin_gpu_region (self->gl_profiler);
/* Ensure that the viewport is up to date */
- status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
- if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
+ if (gsk_gl_driver_bind_render_target (self->gl_driver, self->texture_id))
gsk_gl_renderer_resize_viewport (self, &viewport);
gsk_gl_renderer_clear (self);
diff --git a/gsk/gskshaderbuilder.c b/gsk/gskshaderbuilder.c
index c37a203..f5a66a9 100644
--- a/gsk/gskshaderbuilder.c
+++ b/gsk/gskshaderbuilder.c
@@ -449,8 +449,7 @@ gsk_shader_builder_get_uniform_location (GskShaderBuilder *builder,
if (builder->uniforms->len == 0)
return -1;
- p = g_hash_table_lookup (builder->programs, GINT_TO_POINTER (program_id));
- if (p == NULL)
+ if (!g_hash_table_lookup_extended (builder->programs, GINT_TO_POINTER (program_id), NULL, (gpointer *) &p))
return -1;
if (g_hash_table_lookup_extended (p->uniform_locations, GINT_TO_POINTER (uniform_quark), NULL, &loc_p))
@@ -473,8 +472,7 @@ gsk_shader_builder_get_attribute_location (GskShaderBuilder *builder,
if (builder->attributes->len == 0)
return -1;
- p = g_hash_table_lookup (builder->programs, GINT_TO_POINTER (program_id));
- if (p == NULL)
+ if (!g_hash_table_lookup_extended (builder->programs, GINT_TO_POINTER (program_id), NULL, (gpointer *) &p))
return -1;
if (g_hash_table_lookup_extended (p->attribute_locations, GINT_TO_POINTER (attribute_quark), NULL, &loc_p))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]