diff options
author | Benjamin Otte <otte@redhat.com> | 2016-11-16 04:14:32 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2016-11-16 17:36:33 +0100 |
commit | 40565fb0308ba2e8a91a853af024bff49bd84a38 (patch) | |
tree | 828edcad15753dc51fd9e02b32eb91c07959eae7 /gsk | |
parent | 455ce80ff7a98f3ef7591ac789ea2ea4e6a42053 (diff) | |
download | gtk+-40565fb0308ba2e8a91a853af024bff49bd84a38.tar.gz |
gsk: Rework GskTexture
We do no longer bind textures to a renderer, instead they are a way for
applications to provide texture data.
For now, that's it. We've reverted to uploading it from scratch every
frame.
Diffstat (limited to 'gsk')
-rw-r--r-- | gsk/gskcairorenderer.c | 87 | ||||
-rw-r--r-- | gsk/gskglrenderer.c | 112 | ||||
-rw-r--r-- | gsk/gskrenderer.c | 41 | ||||
-rw-r--r-- | gsk/gskrendererprivate.h | 9 | ||||
-rw-r--r-- | gsk/gsktexture.c | 159 | ||||
-rw-r--r-- | gsk/gsktexture.h | 8 | ||||
-rw-r--r-- | gsk/gsktextureprivate.h | 24 |
7 files changed, 159 insertions, 281 deletions
diff --git a/gsk/gskcairorenderer.c b/gsk/gskcairorenderer.c index 360a25020d..501b5407e9 100644 --- a/gsk/gskcairorenderer.c +++ b/gsk/gskcairorenderer.c @@ -20,12 +20,6 @@ struct _GskCairoRendererClass GskRendererClass parent_class; }; -typedef struct _GskCairoTexture GskCairoTexture; -struct _GskCairoTexture { - GskTexture texture; - cairo_surface_t *surface; -}; - G_DEFINE_TYPE (GskCairoRenderer, gsk_cairo_renderer, GSK_TYPE_RENDERER) static gboolean @@ -99,10 +93,12 @@ gsk_cairo_renderer_render_node (GskCairoRenderer *self, frame.origin.x, frame.origin.y)); if (gsk_render_node_has_texture (node)) { - GskCairoTexture *cairo_texture = (GskCairoTexture *) gsk_render_node_get_texture (node); + GskTexture *texture = gsk_render_node_get_texture (node); + cairo_surface_t *surface = gsk_texture_download (texture); - cairo_set_source_surface (cr, cairo_texture->surface, frame.origin.x, frame.origin.y); + cairo_set_source_surface (cr, surface, frame.origin.x, frame.origin.y); cairo_paint (cr); + cairo_surface_destroy (surface); } else { @@ -186,77 +182,6 @@ gsk_cairo_renderer_render (GskRenderer *renderer, gsk_cairo_renderer_render_node (self, root, cr); } -static GskTexture * -gsk_cairo_texture_new_for_surface (GskRenderer *renderer, - cairo_surface_t *surface, - int width, - int height) -{ - GskCairoTexture *texture; - - texture = gsk_texture_new (GskCairoTexture, renderer, width, height); - - texture->surface = cairo_surface_reference (surface); - - return (GskTexture *) texture; -} - -static GskTexture * -gsk_cairo_renderer_texture_new_for_data (GskRenderer *renderer, - const guchar *data, - int width, - int height, - int stride) -{ - GskTexture *texture; - cairo_surface_t *original, *copy; - cairo_t *cr; - - original = cairo_image_surface_create_for_data ((guchar *) data, CAIRO_FORMAT_ARGB32, width, height, stride); - copy = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); - - cr = cairo_create (copy); - cairo_set_source_surface (cr, original, 0, 0); - cairo_paint (cr); - cairo_destroy (cr); - - texture = gsk_cairo_texture_new_for_surface (renderer, - copy, - width, height); - - cairo_surface_destroy (copy); - cairo_surface_destroy (original); - - return texture; -} - -static GskTexture * -gsk_cairo_renderer_texture_new_for_pixbuf (GskRenderer *renderer, - GdkPixbuf *pixbuf) -{ - GskTexture *texture; - cairo_surface_t *surface; - - surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL); - - texture = gsk_cairo_texture_new_for_surface (renderer, - surface, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf)); - - cairo_surface_destroy (surface); - - return texture; -} - -static void -gsk_cairo_renderer_texture_destroy (GskTexture *texture) -{ - GskCairoTexture *cairo_texture = (GskCairoTexture *) texture; - - cairo_surface_destroy (cairo_texture->surface); -} - static void gsk_cairo_renderer_class_init (GskCairoRendererClass *klass) { @@ -265,10 +190,6 @@ gsk_cairo_renderer_class_init (GskCairoRendererClass *klass) renderer_class->realize = gsk_cairo_renderer_realize; renderer_class->unrealize = gsk_cairo_renderer_unrealize; renderer_class->render = gsk_cairo_renderer_render; - - renderer_class->texture_new_for_data = gsk_cairo_renderer_texture_new_for_data; - renderer_class->texture_new_for_pixbuf = gsk_cairo_renderer_texture_new_for_pixbuf; - renderer_class->texture_destroy = gsk_cairo_renderer_texture_destroy; } static void diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c index be9479944b..c6824acac9 100644 --- a/gsk/gskglrenderer.c +++ b/gsk/gskglrenderer.c @@ -90,13 +90,6 @@ typedef struct { } ProfileTimers; #endif -typedef struct _GskGLTexture GskGLTexture; -struct _GskGLTexture { - GskTexture texture; - - int texture_id; -}; - struct _GskGLRenderer { GskRenderer parent_instance; @@ -136,86 +129,6 @@ struct _GskGLRendererClass G_DEFINE_TYPE (GskGLRenderer, gsk_gl_renderer, GSK_TYPE_RENDERER) -static GskTexture * -gsk_gl_renderer_texture_new_for_data (GskRenderer *renderer, - const guchar *data, - int width, - int height, - int stride) -{ - GskGLRenderer *self = GSK_GL_RENDERER (renderer); - GskGLTexture *texture; - cairo_surface_t *surface; - - gdk_gl_context_make_current (self->gl_context); - gsk_gl_driver_begin_frame (self->gl_driver); - - /* XXX: Make this work without having to create cairo surfaces */ - surface = cairo_image_surface_create_for_data ((guchar *) data, CAIRO_FORMAT_ARGB32, width, height, stride); - - texture = gsk_texture_new (GskGLTexture, renderer, width, height); - - texture->texture_id = gsk_gl_driver_create_texture (self->gl_driver, - TRUE, - width, height); - gsk_gl_driver_bind_source_texture (self->gl_driver, texture->texture_id); - gsk_gl_driver_init_texture_with_surface (self->gl_driver, - texture->texture_id, - surface, - GL_NEAREST, - GL_NEAREST); - - cairo_surface_destroy (surface); - - gsk_gl_driver_end_frame (self->gl_driver); - - return &texture->texture; -} - -static GskTexture * -gsk_gl_renderer_texture_new_for_pixbuf (GskRenderer *renderer, - GdkPixbuf *pixbuf) -{ - GskGLRenderer *self = GSK_GL_RENDERER (renderer); - GskGLTexture *texture; - cairo_surface_t *surface; - int width, height; - - gdk_gl_context_make_current (self->gl_context); - gsk_gl_driver_begin_frame (self->gl_driver); - - surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - texture = gsk_texture_new (GskGLTexture, renderer, width, height); - - texture->texture_id = gsk_gl_driver_create_texture (self->gl_driver, - TRUE, - width, height); - gsk_gl_driver_bind_source_texture (self->gl_driver, texture->texture_id); - gsk_gl_driver_init_texture_with_surface (self->gl_driver, - texture->texture_id, - surface, - GL_NEAREST, - GL_NEAREST); - - gsk_gl_driver_end_frame (self->gl_driver); - - cairo_surface_destroy (surface); - - return &texture->texture; -} - -static void -gsk_gl_renderer_texture_destroy (GskTexture *texture) -{ - GskGLTexture *gltexture = (GskGLTexture *) texture; - GskGLRenderer *self = GSK_GL_RENDERER (gsk_texture_get_renderer (texture)); - - gsk_gl_driver_release_texture (self->gl_driver, gltexture->texture_id); -} - static void gsk_gl_renderer_dispose (GObject *gobject) { @@ -798,13 +711,22 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self, if (gsk_render_node_has_texture (node)) { GskTexture *texture = gsk_render_node_get_texture (node); + cairo_surface_t *surface = gsk_texture_download (texture); + int gl_min_filter = GL_NEAREST, gl_mag_filter = GL_NEAREST; - if (gsk_texture_get_renderer (texture) != GSK_RENDERER (self)) - { - g_warning ("Given Texture belongs to wrong renderer, ignoring."); - goto out; - } - item.render_data.texture_id = ((GskGLTexture *) texture)->texture_id; + get_gl_scaling_filters (node, &gl_min_filter, &gl_mag_filter); + + /* Upload the Cairo surface to a GL texture */ + item.render_data.texture_id = gsk_gl_driver_create_texture (self->gl_driver, + FALSE, + item.size.width, + item.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, + gl_min_filter, + gl_mag_filter); } else if (gsk_render_node_has_surface (node)) { @@ -1062,10 +984,6 @@ gsk_gl_renderer_class_init (GskGLRendererClass *klass) renderer_class->realize = gsk_gl_renderer_realize; renderer_class->unrealize = gsk_gl_renderer_unrealize; renderer_class->render = gsk_gl_renderer_render; - - renderer_class->texture_new_for_data = gsk_gl_renderer_texture_new_for_data; - renderer_class->texture_new_for_pixbuf = gsk_gl_renderer_texture_new_for_pixbuf; - renderer_class->texture_destroy = gsk_gl_renderer_texture_destroy; } static void diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index de2867fea5..edf4633e58 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -134,44 +134,6 @@ gsk_renderer_real_create_cairo_surface (GskRenderer *self, return res; } -static GskTexture * -gsk_renderer_real_texture_new_for_data (GskRenderer *self, - const guchar *data, - int width, - int height, - int stride) -{ - GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, texture_new_for_data); - - return NULL; -} - -static GskTexture * -gsk_renderer_real_texture_new_for_pixbuf (GskRenderer *renderer, - GdkPixbuf *pixbuf) -{ - GskTexture *texture; - cairo_surface_t *surface; - - surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL); - - texture = gsk_texture_new_for_data (renderer, - cairo_image_surface_get_data (surface), - cairo_image_surface_get_width (surface), - cairo_image_surface_get_height (surface), - cairo_image_surface_get_stride (surface)); - - cairo_surface_destroy (surface); - - return texture; -} - -static void -gsk_renderer_real_texture_destroy (GskTexture *texture) -{ - GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (gsk_texture_get_renderer (texture), texture_destroy); -} - static void gsk_renderer_dispose (GObject *gobject) { @@ -278,9 +240,6 @@ gsk_renderer_class_init (GskRendererClass *klass) klass->unrealize = gsk_renderer_real_unrealize; klass->render = gsk_renderer_real_render; klass->create_cairo_surface = gsk_renderer_real_create_cairo_surface; - klass->texture_new_for_data = gsk_renderer_real_texture_new_for_data; - klass->texture_new_for_pixbuf = gsk_renderer_real_texture_new_for_pixbuf; - klass->texture_destroy = gsk_renderer_real_texture_destroy; gobject_class->constructed = gsk_renderer_constructed; gobject_class->set_property = gsk_renderer_set_property; diff --git a/gsk/gskrendererprivate.h b/gsk/gskrendererprivate.h index 5fdc130e4c..57f7e861f3 100644 --- a/gsk/gskrendererprivate.h +++ b/gsk/gskrendererprivate.h @@ -47,15 +47,6 @@ struct _GskRendererClass cairo_format_t, int width, int height); - /* called from gsktexture.c */ - GskTexture * (* texture_new_for_data) (GskRenderer *renderer, - const guchar *data, - int width, - int height, - int stride); - GskTexture * (* texture_new_for_pixbuf) (GskRenderer *renderer, - GdkPixbuf *pixbuf); - void (* texture_destroy) (GskTexture *texture); }; gboolean gsk_renderer_is_realized (GskRenderer *renderer); diff --git a/gsk/gsktexture.c b/gsk/gsktexture.c index 956625b787..8ccfcbac1a 100644 --- a/gsk/gsktexture.c +++ b/gsk/gsktexture.c @@ -23,9 +23,6 @@ * * #GskTexture is the basic element used to refer to pixel data. * - * It can only be created for an existing realized #GskRenderer and becomes - * invalid when the renderer gets unrealized. - * * You cannot get your pixel data back once you've uploaded it. * * #GskTexture is an immutable structure: That means you cannot change @@ -38,7 +35,6 @@ #include "gsktextureprivate.h" #include "gskdebugprivate.h" -#include "gskrendererprivate.h" /** * GskTexture: (ref-func gsk_texture_ref) (unref-func gsk_texture_unref) @@ -53,9 +49,7 @@ G_DEFINE_BOXED_TYPE(GskTexture, gsk_texture, gsk_texture_ref, gsk_texture_unref) static void gsk_texture_finalize (GskTexture *self) { - GSK_RENDERER_GET_CLASS (self->renderer)->texture_destroy (self); - - g_object_unref (self->renderer); + self->klass->finalize (self); g_free (self); } @@ -100,63 +94,146 @@ gsk_texture_unref (GskTexture *texture) gsk_texture_finalize (texture); } -GskTexture * -gsk_texture_alloc (gsize size, - GskRenderer *renderer, - int width, - int height) +gpointer +gsk_texture_new (const GskTextureClass *klass, + int width, + int height) { GskTexture *self; - g_assert (size >= sizeof (GskTexture)); + g_assert (klass->size >= sizeof (GskTexture)); - self = g_malloc0 (size); + self = g_malloc0 (klass->size); + self->klass = klass; self->ref_count = 1; - self->renderer = g_object_ref (renderer); self->width = width; self->height = height; return self; } +/* GskCairoTexture */ + +typedef struct _GskCairoTexture GskCairoTexture; + +struct _GskCairoTexture { + GskTexture texture; + cairo_surface_t *surface; +}; + +static void +gsk_texture_cairo_finalize (GskTexture *texture) +{ + GskCairoTexture *cairo = (GskCairoTexture *) texture; + + cairo_surface_destroy (cairo->surface); +} + +static cairo_surface_t * +gsk_texture_cairo_download (GskTexture *texture) +{ + GskCairoTexture *cairo = (GskCairoTexture *) texture; + + return cairo_surface_reference (cairo->surface); +} + +static const GskTextureClass GSK_TEXTURE_CLASS_CAIRO = { + "cairo", + sizeof (GskCairoTexture), + gsk_texture_cairo_finalize, + gsk_texture_cairo_download +}; + +GskTexture * +gsk_texture_new_for_surface (cairo_surface_t *surface) +{ + GskCairoTexture *texture; + + g_return_val_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE, NULL); + + texture = gsk_texture_new (&GSK_TEXTURE_CLASS_CAIRO, + cairo_image_surface_get_width (surface), + cairo_image_surface_get_height (surface)); + + texture->surface = cairo_surface_reference (surface); + + return (GskTexture *) texture; +} + GskTexture * -gsk_texture_new_for_data (GskRenderer *renderer, - const guchar *data, +gsk_texture_new_for_data (const guchar *data, int width, int height, int stride) { - return GSK_RENDERER_GET_CLASS (renderer)->texture_new_for_data (renderer, data, width, height, stride); + GskTexture *texture; + cairo_surface_t *original, *copy; + cairo_t *cr; + + original = cairo_image_surface_create_for_data ((guchar *) data, CAIRO_FORMAT_ARGB32, width, height, stride); + copy = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + + cr = cairo_create (copy); + cairo_set_source_surface (cr, original, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); + + texture = gsk_texture_new_for_surface (copy); + + cairo_surface_destroy (copy); + cairo_surface_destroy (original); + + return texture; } -GskTexture * -gsk_texture_new_for_pixbuf (GskRenderer *renderer, - GdkPixbuf *pixbuf) +/* GskPixbufTexture */ + +typedef struct _GskPixbufTexture GskPixbufTexture; + +struct _GskPixbufTexture { + GskTexture texture; + GdkPixbuf *pixbuf; +}; + +static void +gsk_texture_pixbuf_finalize (GskTexture *texture) { - g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL); - g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture; - return GSK_RENDERER_GET_CLASS (renderer)->texture_new_for_pixbuf (renderer, pixbuf); + g_object_unref (pixbuf->pixbuf); } -/** - * gsk_texture_get_renderer: - * @texture: a #GskTexture - * - * Returns the renderer that @texture was created for. - * - * Returns: (transfer none): the renderer of the #GskTexture - * - * Since: 3.90 - */ -GskRenderer * -gsk_texture_get_renderer (GskTexture *texture) +static cairo_surface_t * +gsk_texture_pixbuf_download (GskTexture *texture) { - g_return_val_if_fail (GSK_IS_TEXTURE (texture), NULL); + GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture; + + return gdk_cairo_surface_create_from_pixbuf (pixbuf->pixbuf, 1, NULL); +} + +static const GskTextureClass GSK_TEXTURE_CLASS_PIXBUF = { + "pixbuf", + sizeof (GskPixbufTexture), + gsk_texture_pixbuf_finalize, + gsk_texture_pixbuf_download +}; + +GskTexture * +gsk_texture_new_for_pixbuf (GdkPixbuf *pixbuf) +{ + GskPixbufTexture *texture; - return texture->renderer; + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + + texture = gsk_texture_new (&GSK_TEXTURE_CLASS_PIXBUF, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); + + texture->pixbuf = g_object_ref (pixbuf); + + return &texture->texture; } /** @@ -195,3 +272,9 @@ gsk_texture_get_height (GskTexture *texture) return texture->height; } +cairo_surface_t * +gsk_texture_download (GskTexture *texture) +{ + return texture->klass->download (texture); +} + diff --git a/gsk/gsktexture.h b/gsk/gsktexture.h index 1d1c81e472..317cb3c34c 100644 --- a/gsk/gsktexture.h +++ b/gsk/gsktexture.h @@ -40,18 +40,14 @@ GDK_AVAILABLE_IN_3_90 void gsk_texture_unref (GskTexture *texture); GDK_AVAILABLE_IN_3_90 -GskTexture * gsk_texture_new_for_data (GskRenderer *renderer, - const guchar *data, +GskTexture * gsk_texture_new_for_data (const guchar *data, int width, int height, int stride); GDK_AVAILABLE_IN_3_90 -GskTexture * gsk_texture_new_for_pixbuf (GskRenderer *renderer, - GdkPixbuf *pixbuf); +GskTexture * gsk_texture_new_for_pixbuf (GdkPixbuf *pixbuf); GDK_AVAILABLE_IN_3_90 -GskRenderer * gsk_texture_get_renderer (GskTexture *texture); -GDK_AVAILABLE_IN_3_90 int gsk_texture_get_width (GskTexture *texture); GDK_AVAILABLE_IN_3_90 int gsk_texture_get_height (GskTexture *texture); diff --git a/gsk/gsktextureprivate.h b/gsk/gsktextureprivate.h index 887a03adcc..78d96de611 100644 --- a/gsk/gsktextureprivate.h +++ b/gsk/gsktextureprivate.h @@ -9,21 +9,31 @@ G_BEGIN_DECLS #define GSK_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_TEXTURE)) #define GSK_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_TEXTURE, GskTextureClass)) +typedef struct _GskTextureClass GskTextureClass; + struct _GskTexture { + const GskTextureClass *klass; + volatile int ref_count; - GskRenderer *renderer; int width; int height; }; -#define gsk_texture_new(type,renderer,width,height) \ - (type *) gsk_texture_alloc(sizeof (type),(renderer),(width),(height)) -GskTexture *gsk_texture_alloc (gsize size, - GskRenderer *renderer, - int width, - int height); +struct _GskTextureClass { + const char *name; + gsize size; + + void (* finalize) (GskTexture *texture); + cairo_surface_t * (* download) (GskTexture *texture); +}; + +gpointer gsk_texture_new (const GskTextureClass *klass, + int width, + int height); +GskTexture * gsk_texture_new_for_surface (cairo_surface_t *surface); +cairo_surface_t * gsk_texture_download (GskTexture *texture); G_END_DECLS |