summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2016-12-21 22:11:52 +0100
committerBenjamin Otte <otte@redhat.com>2016-12-22 04:28:11 +0100
commitf2848737a2d906a33bd0e934766115d202d8db18 (patch)
tree0961285e8f278680fcca219ba29010c7cd348d1f
parent8b7261df40bf65a334edf73faaaca3b668e7b2b0 (diff)
downloadgtk+-wip/otte/rendernode.tar.gz
gsk: Add gsk_texture_download() APIwip/otte/rendernode
Now users can download pixels and make everything slooooooow.
-rw-r--r--docs/reference/gsk/gsk4-sections.txt1
-rw-r--r--gsk/gskrenderer.c1
-rw-r--r--gsk/gsktexture.c99
-rw-r--r--gsk/gsktexture.h5
-rw-r--r--gsk/gsktextureprivate.h3
5 files changed, 106 insertions, 3 deletions
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt
index e27385c442..eebc74d57d 100644
--- a/docs/reference/gsk/gsk4-sections.txt
+++ b/docs/reference/gsk/gsk4-sections.txt
@@ -79,6 +79,7 @@ gsk_texture_new_for_data
gsk_texture_new_for_pixbuf
gsk_texture_get_width
gsk_texture_get_height
+gsk_texture_download
<SUBSECTION Standard>
GskTexture
gsk_texture_get_type
diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c
index 87a4074735..623e395bc4 100644
--- a/gsk/gskrenderer.c
+++ b/gsk/gskrenderer.c
@@ -650,7 +650,6 @@ gsk_renderer_render_texture (GskRenderer *renderer,
g_return_val_if_fail (priv->root_node == NULL, NULL);
priv->root_node = gsk_render_node_ref (root);
- gsk_render_node_make_immutable (priv->root_node);
if (viewport == NULL)
{
diff --git a/gsk/gsktexture.c b/gsk/gsktexture.c
index aabc805f0d..cc8cdedfce 100644
--- a/gsk/gsktexture.c
+++ b/gsk/gsktexture.c
@@ -37,6 +37,8 @@
#include "gskdebugprivate.h"
#include "gskrenderer.h"
+#include "gdk/gdkinternals.h"
+
/**
* GskTexture: (ref-func gsk_texture_ref) (unref-func gsk_texture_unref)
*
@@ -142,10 +144,35 @@ gsk_texture_cairo_download_surface (GskTexture *texture)
return cairo_surface_reference (cairo->surface);
}
+static void
+gsk_texture_cairo_download (GskTexture *texture,
+ guchar *data,
+ gsize stride)
+{
+ GskCairoTexture *cairo = (GskCairoTexture *) texture;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create_for_data (data,
+ CAIRO_FORMAT_ARGB32,
+ texture->width, texture->height,
+ stride);
+ cr = cairo_create (surface);
+
+ cairo_set_source_surface (cr, cairo->surface, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_finish (surface);
+ cairo_surface_destroy (surface);
+}
+
static const GskTextureClass GSK_TEXTURE_CLASS_CAIRO = {
"cairo",
sizeof (GskCairoTexture),
gsk_texture_cairo_finalize,
+ gsk_texture_cairo_download,
gsk_texture_cairo_download_surface
};
@@ -208,6 +235,23 @@ gsk_texture_pixbuf_finalize (GskTexture *texture)
g_object_unref (pixbuf->pixbuf);
}
+static void
+gsk_texture_pixbuf_download (GskTexture *texture,
+ guchar *data,
+ gsize stride)
+{
+ GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture;
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data (data,
+ CAIRO_FORMAT_ARGB32,
+ texture->width, texture->height,
+ stride);
+ gdk_cairo_surface_paint_pixbuf (surface, pixbuf->pixbuf);
+ cairo_surface_finish (surface);
+ cairo_surface_destroy (surface);
+}
+
static cairo_surface_t *
gsk_texture_pixbuf_download_surface (GskTexture *texture)
{
@@ -220,7 +264,8 @@ static const GskTextureClass GSK_TEXTURE_CLASS_PIXBUF = {
"pixbuf",
sizeof (GskPixbufTexture),
gsk_texture_pixbuf_finalize,
- gsk_texture_pixbuf_download_surface,
+ gsk_texture_pixbuf_download,
+ gsk_texture_pixbuf_download_surface
};
GskTexture *
@@ -278,7 +323,57 @@ gsk_texture_get_height (GskTexture *texture)
cairo_surface_t *
gsk_texture_download_surface (GskTexture *texture)
{
- return texture->klass->download_surface (texture);
+ cairo_surface_t *surface;
+
+ if (texture->klass->download_surface)
+ return texture->klass->download_surface (texture);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ texture->width, texture->height);
+ gsk_texture_download (texture,
+ cairo_image_surface_get_data (surface),
+ cairo_image_surface_get_stride (surface));
+ cairo_surface_mark_dirty (surface);
+
+ return surface;
+}
+
+/**
+ * gsk_texture_download:
+ * @texture: a #GskTexture
+ * @data: pointer to enough memory to be filled with the
+ * downloaded data of @texture
+ * @stride: rowstride in bytes
+ *
+ * Downloads the @texture into local memory. This may be
+ * an expensive operation, as the actual texture data may
+ * reside on a GPU or on a remote display server.
+ *
+ * The data format of the downloaded data is equivalent to
+ * %CAIRO_FORMAT_ARGB32, so every downloaded pixel requires
+ * 4 bytes of memory.
+ *
+ * Downloading a texture into a Cairo image surface:
+ * |[<!-- language="C" -->
+ * surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ * gsk_texture_get_width (texture),
+ * gsk_texture_get_height (texture));
+ * gsk_texture_download (texture,
+ * cairo_image_surface_get_data (surface),
+ * cairo_image_surface_get_stride (surface));
+ * cairo_surface_mark_dirty (surface);
+ * ]|
+ **/
+void
+gsk_texture_download (GskTexture *texture,
+ guchar *data,
+ gsize stride)
+{
+ g_return_if_fail (GSK_IS_TEXTURE (texture));
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (stride >= gsk_texture_get_width (texture) * 4);
+
+ return texture->klass->download (texture, data, stride);
}
gboolean
diff --git a/gsk/gsktexture.h b/gsk/gsktexture.h
index 317cb3c34c..67cbe718c4 100644
--- a/gsk/gsktexture.h
+++ b/gsk/gsktexture.h
@@ -52,6 +52,11 @@ int gsk_texture_get_width (GskTexture
GDK_AVAILABLE_IN_3_90
int gsk_texture_get_height (GskTexture *texture);
+GDK_AVAILABLE_IN_3_90
+void gsk_texture_download (GskTexture *texture,
+ guchar *data,
+ gsize stride);
+
G_END_DECLS
#endif /* __GSK_TEXTURE_H__ */
diff --git a/gsk/gsktextureprivate.h b/gsk/gsktextureprivate.h
index 13eba48eae..637bc74343 100644
--- a/gsk/gsktextureprivate.h
+++ b/gsk/gsktextureprivate.h
@@ -30,6 +30,9 @@ struct _GskTextureClass {
gsize size;
void (* finalize) (GskTexture *texture);
+ void (* download) (GskTexture *texture,
+ guchar *data,
+ gsize stride);
cairo_surface_t * (* download_surface) (GskTexture *texture);
};