[gtk+/wip/otte/rendernode: 29/29] gsk: Add gsk_texture_download() API
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/rendernode: 29/29] gsk: Add gsk_texture_download() API
- Date: Thu, 22 Dec 2016 03:30:28 +0000 (UTC)
commit f2848737a2d906a33bd0e934766115d202d8db18
Author: Benjamin Otte <otte redhat com>
Date: Wed Dec 21 22:11:52 2016 +0100
gsk: Add gsk_texture_download() API
Now users can download pixels and make everything slooooooow.
docs/reference/gsk/gsk4-sections.txt | 1 +
gsk/gskrenderer.c | 1 -
gsk/gsktexture.c | 99 +++++++++++++++++++++++++++++++++-
gsk/gsktexture.h | 5 ++
gsk/gsktextureprivate.h | 3 +
5 files changed, 106 insertions(+), 3 deletions(-)
---
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt
index e27385c..eebc74d 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 87a4074..623e395 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 aabc805..cc8cded 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 317cb3c..67cbe71 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 13eba48..637bc74 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);
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]