summaryrefslogtreecommitdiff
path: root/gsk/gskcairorenderer.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2016-11-07 18:23:38 +0100
committerBenjamin Otte <otte@redhat.com>2016-11-08 20:31:34 +0100
commit09359197a7645fd554f99516e129d709c44f0e69 (patch)
tree8bf9f903cc644ef3a10b09c1b2bd1c41e8642b75 /gsk/gskcairorenderer.c
parent46eb2c1be9e92e9e41d86367d88a826f97c3d7ce (diff)
downloadgtk+-09359197a7645fd554f99516e129d709c44f0e69.tar.gz
gsk: Implement textures for the Cairo renderer
Diffstat (limited to 'gsk/gskcairorenderer.c')
-rw-r--r--gsk/gskcairorenderer.c99
1 files changed, 96 insertions, 3 deletions
diff --git a/gsk/gskcairorenderer.c b/gsk/gskcairorenderer.c
index 281587d958..360a25020d 100644
--- a/gsk/gskcairorenderer.c
+++ b/gsk/gskcairorenderer.c
@@ -6,6 +6,7 @@
#include "gskrendererprivate.h"
#include "gskrendernodeiter.h"
#include "gskrendernodeprivate.h"
+#include "gsktextureprivate.h"
struct _GskCairoRenderer
{
@@ -19,6 +20,12 @@ 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
@@ -50,7 +57,8 @@ gsk_cairo_renderer_render_node (GskCairoRenderer *self,
cairo_save (cr);
- if (!gsk_render_node_has_surface (node))
+ if (!gsk_render_node_has_surface (node) &&
+ !gsk_render_node_has_texture (node))
goto out;
gsk_render_node_get_world_matrix (node, &mvp);
@@ -89,8 +97,18 @@ gsk_cairo_renderer_render_node (GskCairoRenderer *self,
node->name,
node,
frame.origin.x, frame.origin.y));
- cairo_set_source_surface (cr, gsk_render_node_get_surface (node), frame.origin.x, frame.origin.y);
- cairo_paint (cr);
+ if (gsk_render_node_has_texture (node))
+ {
+ GskCairoTexture *cairo_texture = (GskCairoTexture *) gsk_render_node_get_texture (node);
+
+ cairo_set_source_surface (cr, cairo_texture->surface, frame.origin.x, frame.origin.y);
+ cairo_paint (cr);
+ }
+ else
+ {
+ cairo_set_source_surface (cr, gsk_render_node_get_surface (node), frame.origin.x, frame.origin.y);
+ cairo_paint (cr);
+ }
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
{
@@ -168,6 +186,77 @@ 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)
{
@@ -176,6 +265,10 @@ 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