[gtk+/wip/ebassi/gsk-renderer: 46/58] gsk: Add GL driver API to create render targets
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/ebassi/gsk-renderer: 46/58] gsk: Add GL driver API to create render targets
- Date: Wed, 27 Jul 2016 10:49:49 +0000 (UTC)
commit 04292b8b2a4bf0d1d4bfb45598d1ce6f39d85f52
Author: Emmanuele Bassi <ebassi gnome org>
Date: Tue Jul 12 15:41:31 2016 +0100
gsk: Add GL driver API to create render targets
It's going to be used by the GL renderer to safely create and bind
FBOs when needed.
gsk/gskgldriver.c | 104 +++++++++++++++++++++++++++++++++++++++-------
gsk/gskgldriverprivate.h | 2 +
2 files changed, 91 insertions(+), 15 deletions(-)
---
diff --git a/gsk/gskgldriver.c b/gsk/gskgldriver.c
index 1a2a289..01caa00 100644
--- a/gsk/gskgldriver.c
+++ b/gsk/gskgldriver.c
@@ -13,6 +13,7 @@ typedef struct {
int height;
GLuint min_filter;
GLuint mag_filter;
+ GArray *fbos;
} Texture;
typedef struct {
@@ -28,12 +29,15 @@ struct _GskGLDriver
GdkGLContext *gl_context;
+ GLuint default_fbo;
+
GHashTable *textures;
GArray *vaos;
Texture *bound_source_texture;
Texture *bound_mask_texture;
Vao *bound_vao;
+ GLuint bound_fbo;
gboolean in_frame : 1;
};
@@ -60,11 +64,20 @@ texture_free (gpointer data)
{
Texture *t = data;
+ g_clear_pointer (&t->fbos, g_array_unref);
glDeleteTextures (1, &t->texture_id);
g_slice_free (Texture, t);
}
static void
+fbo_clear (gpointer data)
+{
+ GLuint fbo_id = GPOINTER_TO_UINT (data);
+
+ glDeleteFramebuffers (1, &fbo_id);
+}
+
+static void
vao_clear (gpointer data)
{
Vao *v = data;
@@ -168,6 +181,9 @@ 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;
+
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, 0);
@@ -193,6 +209,7 @@ 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;
g_hash_table_remove_all (driver->textures);
g_array_set_size (driver->vaos, 0);
@@ -200,6 +217,29 @@ gsk_gl_driver_end_frame (GskGLDriver *driver)
driver->in_frame = FALSE;
}
+static Texture *
+gsk_gl_driver_get_texture (GskGLDriver *driver,
+ int texture_id)
+{
+ return g_hash_table_lookup (driver->textures, GINT_TO_POINTER (texture_id));
+}
+
+static Vao *
+gsk_gl_driver_get_vao (GskGLDriver *driver,
+ int vao_id)
+{
+ int i;
+
+ 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;
+ }
+
+ return NULL;
+}
+
int
gsk_gl_driver_create_texture (GskGLDriver *driver,
int width,
@@ -273,27 +313,34 @@ gsk_gl_driver_create_vao_for_quad (GskGLDriver *driver,
return vao_id;
}
-static Texture *
-gsk_gl_driver_get_texture (GskGLDriver *driver,
- int texture_id)
+int
+gsk_gl_driver_create_render_target (GskGLDriver *driver,
+ int texture_id)
{
- return g_hash_table_lookup (driver->textures, GINT_TO_POINTER (texture_id));
-}
+ Texture *t;
+ GLuint fbo_id;
-static Vao *
-gsk_gl_driver_get_vao (GskGLDriver *driver,
- int vao_id)
-{
- int i;
+ g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), -1);
- for (i = 0; i < driver->vaos->len; i++)
+ t = gsk_gl_driver_get_texture (driver, texture_id);
+ if (t == NULL)
+ return -1;
+
+ if (t->fbos == NULL)
{
- Vao *v = &g_array_index (driver->vaos, Vao, i);
- if (v->vao_id == vao_id)
- return v;
+ t->fbos = g_array_new (FALSE, FALSE, sizeof (GLuint));
+ g_array_set_clear_func (t->fbos, fbo_clear);
}
- return NULL;
+ glGenFramebuffers (1, &fbo_id);
+ 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);
+
+ glBindFramebuffer (GL_FRAMEBUFFER, driver->default_fbo);
+
+ return fbo_id;
}
void
@@ -367,6 +414,33 @@ gsk_gl_driver_bind_vao (GskGLDriver *driver,
}
void
+gsk_gl_driver_bind_render_target (GskGLDriver *driver,
+ int texture_id)
+{
+ GLuint fbo_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);
+
+ driver->bound_fbo = fbo_id;
+ }
+}
+
+void
gsk_gl_driver_render_surface_to_texture (GskGLDriver *driver,
cairo_surface_t *surface,
int texture_id)
diff --git a/gsk/gskgldriverprivate.h b/gsk/gskgldriverprivate.h
index 9fc1d8a..d5ddf46 100644
--- a/gsk/gskgldriverprivate.h
+++ b/gsk/gskgldriverprivate.h
@@ -31,6 +31,8 @@ int gsk_gl_driver_create_vao_for_quad (GskGLDriver *driver
int uv_id,
int n_vertices,
GskQuadVertex *vertices);
+int gsk_gl_driver_create_render_target (GskGLDriver *driver,
+ int texture_id);
void gsk_gl_driver_bind_source_texture (GskGLDriver *driver,
int texture_id);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]