diff options
Diffstat (limited to 'gsk/gskgldriver.c')
-rw-r--r-- | gsk/gskgldriver.c | 88 |
1 files changed, 64 insertions, 24 deletions
diff --git a/gsk/gskgldriver.c b/gsk/gskgldriver.c index da21f6ae72..edb6653135 100644 --- a/gsk/gskgldriver.c +++ b/gsk/gskgldriver.c @@ -3,6 +3,7 @@ #include "gskgldriverprivate.h" #include "gskdebugprivate.h" +#include "gsktextureprivate.h" #include <gdk/gdk.h> #include <epoxy/gl.h> @@ -14,8 +15,8 @@ typedef struct { GLuint min_filter; GLuint mag_filter; GArray *fbos; + GskTexture *user; gboolean in_use : 1; - gboolean reserved : 1; } Texture; typedef struct { @@ -76,7 +77,8 @@ texture_free (gpointer data) { Texture *t = data; - g_warn_if_fail (!t->reserved); + if (t->user) + gsk_texture_clear_render_data (t->user); g_clear_pointer (&t->fbos, g_array_unref); glDeleteTextures (1, &t->texture_id); @@ -272,7 +274,7 @@ gsk_gl_driver_collect_textures (GskGLDriver *driver) { Texture *t = value_p; - if (t->reserved) + if (t->user) continue; if (t->in_use) @@ -383,17 +385,14 @@ find_texture_by_size (GHashTable *textures, return NULL; } -int -gsk_gl_driver_create_texture (GskGLDriver *driver, - gboolean reserve, - int width, - int height) +static Texture * +create_texture (GskGLDriver *driver, + int width, + int height) { guint texture_id; Texture *t; - g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), -1); - if (width >= driver->max_texture_size || height >= driver->max_texture_size) { @@ -406,13 +405,12 @@ gsk_gl_driver_create_texture (GskGLDriver *driver, } t = find_texture_by_size (driver->textures, width, height); - if (t != NULL && !t->in_use) + if (t != NULL && !t->in_use && t->user == NULL) { GSK_NOTE (OPENGL, g_print ("Reusing Texture(%d) for size %dx%d\n", t->texture_id, t->width, t->height)); t->in_use = TRUE; - t->reserved = reserve; - return t->texture_id; + return t; } glGenTextures (1, &texture_id); @@ -424,25 +422,67 @@ gsk_gl_driver_create_texture (GskGLDriver *driver, t->min_filter = GL_NEAREST; t->mag_filter = GL_NEAREST; t->in_use = TRUE; - t->reserved = reserve; g_hash_table_insert (driver->textures, GINT_TO_POINTER (texture_id), t); - return t->texture_id; + return t; } -void -gsk_gl_driver_release_texture (GskGLDriver *driver, - int texture_id) +static void +gsk_gl_driver_release_texture (gpointer data) +{ + Texture *t = data; + + t->user = NULL; +} + +int +gsk_gl_driver_get_texture_for_texture (GskGLDriver *driver, + GskTexture *texture, + int min_filter, + int mag_filter) { Texture *t; + cairo_surface_t *surface; + + g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), -1); + g_return_val_if_fail (GSK_IS_TEXTURE (texture), -1); + + t = gsk_texture_get_render_data (texture, driver); + + if (t) + { + if (t->min_filter == min_filter && t->mag_filter == mag_filter) + return t->texture_id; + } - g_return_if_fail (GSK_IS_GL_DRIVER (driver)); - - t = gsk_gl_driver_get_texture (driver, texture_id); - g_return_if_fail (t != NULL); - g_return_if_fail (t->reserved); + t = create_texture (driver, gsk_texture_get_width (texture), gsk_texture_get_height (texture)); + + if (gsk_texture_set_render_data (texture, driver, t, gsk_gl_driver_release_texture)) + t->user = texture; - t->reserved = FALSE; + surface = gsk_texture_download (texture); + gsk_gl_driver_bind_source_texture (driver, t->texture_id); + gsk_gl_driver_init_texture_with_surface (driver, + t->texture_id, + surface, + min_filter, + mag_filter); + + return t->texture_id; +} + +int +gsk_gl_driver_create_texture (GskGLDriver *driver, + int width, + int height) +{ + Texture *t; + + g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), -1); + + t = create_texture (driver, width, height); + + return t->texture_id; } static Vao * |