gsk: Turn GskTexture into a GObject

This commit is contained in:
Benjamin Otte 2017-01-01 13:40:13 +01:00
parent 4ead5c3ba8
commit 2571036c07
10 changed files with 264 additions and 159 deletions

View File

@ -82,8 +82,6 @@ GSK_TYPE_SERIALIZATION_ERROR
<SECTION>
<FILE>GskTexture</FILE>
gsk_texture_ref
gsk_texture_unref
gsk_texture_new_for_data
gsk_texture_new_for_pixbuf
gsk_texture_get_width

View File

@ -664,7 +664,7 @@ gsk_texture_node_finalize (GskRenderNode *node)
{
GskTextureNode *self = (GskTextureNode *) node;
gsk_texture_unref (self->texture);
g_object_unref (self->texture);
}
static void
@ -745,7 +745,7 @@ gsk_texture_node_deserialize (GVariant *variant,
node = gsk_texture_node_new (texture, &GRAPHENE_RECT_INIT(bounds[0], bounds[1], bounds[2], bounds[3]));
gsk_texture_unref (texture);
g_object_unref (texture);
return node;
}
@ -793,7 +793,7 @@ gsk_texture_node_new (GskTexture *texture,
self = (GskTextureNode *) gsk_render_node_new (&GSK_TEXTURE_NODE_CLASS, 0);
self->texture = gsk_texture_ref (texture);
self->texture = g_object_ref (texture);
graphene_rect_init_from_rect (&self->render_node.bounds, bounds);
return &self->render_node;

View File

@ -25,9 +25,9 @@
*
* You cannot get your pixel data back once you've uploaded it.
*
* #GskTexture is an immutable structure: That means you cannot change
* #GskTexture is an immutable object: That means you cannot change
* anything about it other than increasing the reference count via
* gsk_texture_ref().
* g_object_ref().
*/
#include "config.h"
@ -40,116 +40,208 @@
#include "gdk/gdkinternals.h"
/**
* GskTexture: (ref-func gsk_texture_ref) (unref-func gsk_texture_unref)
* GskTexture:
*
* The `GskTexture` structure contains only private data.
*
* Since: 3.90
*/
G_DEFINE_BOXED_TYPE(GskTexture, gsk_texture, gsk_texture_ref, gsk_texture_unref)
enum {
PROP_0,
PROP_WIDTH,
PROP_HEIGHT,
N_PROPS
};
static GParamSpec *properties[N_PROPS];
G_DEFINE_ABSTRACT_TYPE (GskTexture, gsk_texture, G_TYPE_OBJECT)
#define GSK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD(obj,method) \
g_critical ("Texture of type '%s' does not implement GskTexture::" # method, G_OBJECT_TYPE_NAME (obj))
static void
gsk_texture_finalize (GskTexture *self)
gsk_texture_real_download (GskTexture *self,
guchar *data,
gsize stride)
{
GSK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD (self, download);
}
static cairo_surface_t *
gsk_texture_real_download_surface (GskTexture *texture)
{
cairo_surface_t *surface;
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;
}
static void
gsk_texture_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GskTexture *self = GSK_TEXTURE (gobject);
switch (prop_id)
{
case PROP_WIDTH:
self->width = g_value_get_int (value);
break;
case PROP_HEIGHT:
self->height = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
gsk_texture_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GskTexture *self = GSK_TEXTURE (gobject);
switch (prop_id)
{
case PROP_WIDTH:
g_value_set_int (value, self->width);
break;
case PROP_HEIGHT:
g_value_set_int (value, self->height);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
gsk_texture_dispose (GObject *object)
{
GskTexture *self = GSK_TEXTURE (object);
gsk_texture_clear_render_data (self);
self->klass->finalize (self);
g_free (self);
G_OBJECT_CLASS (gsk_texture_parent_class)->dispose (object);
}
/**
* gsk_texture_ref:
* @texture: a #GskTexture
*
* Acquires a reference on the given #GskTexture.
*
* Returns: (transfer none): the #GskTexture with an additional reference
*
* Since: 3.90
*/
GskTexture *
gsk_texture_ref (GskTexture *texture)
static void
gsk_texture_class_init (GskTextureClass *klass)
{
g_return_val_if_fail (GSK_IS_TEXTURE (texture), NULL);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_atomic_int_inc (&texture->ref_count);
klass->download = gsk_texture_real_download;
klass->download_surface = gsk_texture_real_download_surface;
return texture;
gobject_class->set_property = gsk_texture_set_property;
gobject_class->get_property = gsk_texture_get_property;
gobject_class->dispose = gsk_texture_dispose;
/**
* GskRenderer:width:
*
* The width of the texture.
*
* Since: 3.90
*/
properties[PROP_WIDTH] =
g_param_spec_int ("width",
"Width",
"The width of the texture",
1,
G_MAXINT,
1,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
/**
* GskRenderer:height:
*
* The height of the texture.
*
* Since: 3.90
*/
properties[PROP_HEIGHT] =
g_param_spec_int ("height",
"Height",
"The height of the texture",
1,
G_MAXINT,
1,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
/**
* gsk_texture_unref:
* @texture: a #GskTexture
*
* Releases a reference on the given #GskTexture.
*
* If the reference was the last, the resources associated to the @texture are
* freed.
*
* Since: 3.90
*/
void
gsk_texture_unref (GskTexture *texture)
static void
gsk_texture_init (GskTexture *self)
{
g_return_if_fail (GSK_IS_TEXTURE (texture));
if (g_atomic_int_dec_and_test (&texture->ref_count))
gsk_texture_finalize (texture);
}
gpointer
gsk_texture_new (const GskTextureClass *klass,
int width,
int height)
{
GskTexture *self;
g_assert (klass->size >= sizeof (GskTexture));
self = g_malloc0 (klass->size);
self->klass = klass;
self->ref_count = 1;
self->width = width;
self->height = height;
return self;
}
/* GskCairoTexture */
typedef struct _GskCairoTexture GskCairoTexture;
#define GSK_TYPE_CAIRO_TEXTURE (gsk_cairo_texture_get_type ())
G_DECLARE_FINAL_TYPE (GskCairoTexture, gsk_cairo_texture, GSK, CAIRO_TEXTURE, GskTexture)
struct _GskCairoTexture {
GskTexture texture;
GskTexture parent_instance;
cairo_surface_t *surface;
};
static void
gsk_texture_cairo_finalize (GskTexture *texture)
{
GskCairoTexture *cairo = (GskCairoTexture *) texture;
struct _GskCairoTextureClass {
GskTextureClass parent_class;
};
cairo_surface_destroy (cairo->surface);
G_DEFINE_TYPE (GskCairoTexture, gsk_cairo_texture, GSK_TYPE_TEXTURE)
static void
gsk_cairo_texture_finalize (GObject *object)
{
GskCairoTexture *self = GSK_CAIRO_TEXTURE (object);
cairo_surface_destroy (self->surface);
G_OBJECT_CLASS (gsk_cairo_texture_parent_class)->finalize (object);
}
static cairo_surface_t *
gsk_texture_cairo_download_surface (GskTexture *texture)
gsk_cairo_texture_download_surface (GskTexture *texture)
{
GskCairoTexture *cairo = (GskCairoTexture *) texture;
GskCairoTexture *self = GSK_CAIRO_TEXTURE (texture);
return cairo_surface_reference (cairo->surface);
return cairo_surface_reference (self->surface);
}
static void
gsk_texture_cairo_download (GskTexture *texture,
gsk_cairo_texture_download (GskTexture *texture,
guchar *data,
gsize stride)
{
GskCairoTexture *cairo = (GskCairoTexture *) texture;
GskCairoTexture *self = GSK_CAIRO_TEXTURE (texture);
cairo_surface_t *surface;
cairo_t *cr;
@ -159,7 +251,7 @@ gsk_texture_cairo_download (GskTexture *texture,
stride);
cr = cairo_create (surface);
cairo_set_source_surface (cr, cairo->surface, 0, 0);
cairo_set_source_surface (cr, self->surface, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
@ -168,28 +260,21 @@ gsk_texture_cairo_download (GskTexture *texture,
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
};
GskTexture *
gsk_texture_new_for_surface (cairo_surface_t *surface)
static void
gsk_cairo_texture_class_init (GskCairoTextureClass *klass)
{
GskCairoTexture *texture;
GskTextureClass *texture_class = GSK_TEXTURE_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_return_val_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE, NULL);
texture_class->download = gsk_cairo_texture_download;
texture_class->download_surface = gsk_cairo_texture_download_surface;
texture = gsk_texture_new (&GSK_TEXTURE_CLASS_CAIRO,
cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface));
gobject_class->finalize = gsk_cairo_texture_finalize;
}
texture->surface = cairo_surface_reference (surface);
return (GskTexture *) texture;
static void
gsk_cairo_texture_init (GskCairoTexture *self)
{
}
GskTexture *
@ -213,75 +298,114 @@ gsk_texture_new_for_data (const guchar *data,
texture = gsk_texture_new_for_surface (copy);
cairo_surface_destroy (copy);
cairo_surface_finish (original);
cairo_surface_destroy (original);
return texture;
}
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 = g_object_new (GSK_TYPE_CAIRO_TEXTURE,
"width", cairo_image_surface_get_width (surface),
"height", cairo_image_surface_get_height (surface),
NULL);
texture->surface = cairo_surface_reference (surface);
return (GskTexture *) texture;
}
/* GskPixbufTexture */
typedef struct _GskPixbufTexture GskPixbufTexture;
#define GSK_TYPE_PIXBUF_TEXTURE (gsk_pixbuf_texture_get_type ())
G_DECLARE_FINAL_TYPE (GskPixbufTexture, gsk_pixbuf_texture, GSK, PIXBUF_TEXTURE, GskTexture)
struct _GskPixbufTexture {
GskTexture texture;
GskTexture parent_instance;
GdkPixbuf *pixbuf;
};
static void
gsk_texture_pixbuf_finalize (GskTexture *texture)
{
GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture;
struct _GskPixbufTextureClass {
GskTextureClass parent_class;
};
g_object_unref (pixbuf->pixbuf);
G_DEFINE_TYPE (GskPixbufTexture, gsk_pixbuf_texture, GSK_TYPE_TEXTURE)
static void
gsk_pixbuf_texture_finalize (GObject *object)
{
GskPixbufTexture *self = GSK_PIXBUF_TEXTURE (object);
g_object_unref (self->pixbuf);
G_OBJECT_CLASS (gsk_pixbuf_texture_parent_class)->finalize (object);
}
static void
gsk_texture_pixbuf_download (GskTexture *texture,
gsk_pixbuf_texture_download (GskTexture *texture,
guchar *data,
gsize stride)
{
GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture;
GskPixbufTexture *self = GSK_PIXBUF_TEXTURE (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);
gdk_cairo_surface_paint_pixbuf (surface, self->pixbuf);
cairo_surface_finish (surface);
cairo_surface_destroy (surface);
}
static cairo_surface_t *
gsk_texture_pixbuf_download_surface (GskTexture *texture)
gsk_pixbuf_texture_download_surface (GskTexture *texture)
{
GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture;
GskPixbufTexture *self = GSK_PIXBUF_TEXTURE (texture);
return gdk_cairo_surface_create_from_pixbuf (pixbuf->pixbuf, 1, NULL);
return gdk_cairo_surface_create_from_pixbuf (self->pixbuf, 1, NULL);
}
static const GskTextureClass GSK_TEXTURE_CLASS_PIXBUF = {
"pixbuf",
sizeof (GskPixbufTexture),
gsk_texture_pixbuf_finalize,
gsk_texture_pixbuf_download,
gsk_texture_pixbuf_download_surface
};
static void
gsk_pixbuf_texture_class_init (GskPixbufTextureClass *klass)
{
GskTextureClass *texture_class = GSK_TEXTURE_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
texture_class->download = gsk_pixbuf_texture_download;
texture_class->download_surface = gsk_pixbuf_texture_download_surface;
gobject_class->finalize = gsk_pixbuf_texture_finalize;
}
static void
gsk_pixbuf_texture_init (GskPixbufTexture *self)
{
}
GskTexture *
gsk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
{
GskPixbufTexture *texture;
GskPixbufTexture *self;
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));
self = g_object_new (GSK_TYPE_PIXBUF_TEXTURE,
"width", gdk_pixbuf_get_width (pixbuf),
"height", gdk_pixbuf_get_height (pixbuf),
NULL);
texture->pixbuf = g_object_ref (pixbuf);
self->pixbuf = g_object_ref (pixbuf);
return &texture->texture;
return GSK_TEXTURE (self);
}
/**
@ -323,19 +447,7 @@ gsk_texture_get_height (GskTexture *texture)
cairo_surface_t *
gsk_texture_download_surface (GskTexture *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;
return GSK_TEXTURE_GET_CLASS (texture)->download_surface (texture);
}
/**
@ -373,7 +485,7 @@ gsk_texture_download (GskTexture *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);
return GSK_TEXTURE_GET_CLASS (texture)->download (texture, data, stride);
}
gboolean

View File

@ -29,16 +29,17 @@ G_BEGIN_DECLS
#define GSK_TYPE_TEXTURE (gsk_texture_get_type ())
#define GSK_IS_TEXTURE(texture) ((texture) != NULL)
#define GSK_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_TEXTURE, GskTexture))
#define GSK_IS_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_TEXTURE))
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskTexture, g_object_unref)
typedef struct _GskTextureClass GskTextureClass;
GDK_AVAILABLE_IN_3_90
GType gsk_texture_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_90
GskTexture * gsk_texture_ref (GskTexture *texture);
GDK_AVAILABLE_IN_3_90
void gsk_texture_unref (GskTexture *texture);
GDK_AVAILABLE_IN_3_90
GskTexture * gsk_texture_new_for_data (const guchar *data,
int width,

View File

@ -9,13 +9,9 @@ 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;
GObject parent_instance;
int width;
int height;
@ -26,10 +22,8 @@ struct _GskTexture
};
struct _GskTextureClass {
const char *name;
gsize size;
GObjectClass parent_class;
void (* finalize) (GskTexture *texture);
void (* download) (GskTexture *texture,
guchar *data,
gsize stride);

View File

@ -96,7 +96,7 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
),
"CssImageIconTheme<%s@%d>", icon_theme->name, icon_theme->scale);
gsk_texture_unref (texture);
g_object_unref (texture);
g_object_unref (pixbuf);
g_object_unref (icon_info);
}

View File

@ -76,7 +76,7 @@ gtk_css_image_surface_dispose (GObject *object)
{
GtkCssImageSurface *surface = GTK_CSS_IMAGE_SURFACE (object);
g_clear_pointer (&surface->texture, gsk_texture_unref);
g_clear_object (&surface->texture);
G_OBJECT_CLASS (_gtk_css_image_surface_parent_class)->dispose (object);
}
@ -108,7 +108,7 @@ gtk_css_image_surface_new (GskTexture *texture)
image = g_object_new (GTK_TYPE_CSS_IMAGE_SURFACE, NULL);
if (texture)
GTK_CSS_IMAGE_SURFACE (image)->texture = gsk_texture_ref (texture);
GTK_CSS_IMAGE_SURFACE (image)->texture = g_object_ref (texture);
return image;
}
@ -123,7 +123,7 @@ gtk_css_image_surface_new_for_pixbuf (GdkPixbuf *pixbuf)
texture = gsk_texture_new_for_pixbuf (pixbuf);
image = gtk_css_image_surface_new (texture);
gsk_texture_unref (texture);
g_object_unref (texture);
return image;
}

View File

@ -52,7 +52,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (GtkIconHelper, gtk_icon_helper, GTK_TYPE_CSS_GADGET)
void
gtk_icon_helper_invalidate (GtkIconHelper *self)
{
g_clear_pointer (&self->priv->texture, gsk_texture_unref);
g_clear_object (&self->priv->texture);
if (self->priv->rendered_surface != NULL)
{
@ -99,7 +99,7 @@ gtk_icon_helper_take_definition (GtkIconHelper *self,
void
_gtk_icon_helper_clear (GtkIconHelper *self)
{
g_clear_pointer (&self->priv->texture, gsk_texture_unref);
g_clear_object (&self->priv->texture);
g_clear_pointer (&self->priv->rendered_surface, cairo_surface_destroy);
gtk_image_definition_unref (self->priv->def);

View File

@ -1108,6 +1108,6 @@ gtk_snapshot_render_icon (GtkSnapshot *snapshot,
texture,
1);
gtk_snapshot_translate_2d (snapshot, -x, -y);
gsk_texture_unref (texture);
g_object_unref (texture);
}

View File

@ -119,7 +119,7 @@ main(int argc, char **argv)
for (run = 0; run < runs; run++)
{
if (run > 0)
gsk_texture_unref (texture);
g_object_unref (texture);
start = g_get_monotonic_time ();
texture = gsk_renderer_render_texture (renderer, node, NULL);
end = g_get_monotonic_time ();
@ -134,7 +134,7 @@ main(int argc, char **argv)
cairo_image_surface_get_data (surface),
cairo_image_surface_get_stride (surface));
cairo_surface_mark_dirty (surface);
gsk_texture_unref (texture);
g_object_unref (texture);
g_object_unref (window);
g_object_unref (renderer);
}