forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
455ce80ff7
commit
40565fb030
@ -20,12 +20,6 @@ struct _GskCairoRendererClass
|
|||||||
GskRendererClass parent_class;
|
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)
|
G_DEFINE_TYPE (GskCairoRenderer, gsk_cairo_renderer, GSK_TYPE_RENDERER)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -99,10 +93,12 @@ gsk_cairo_renderer_render_node (GskCairoRenderer *self,
|
|||||||
frame.origin.x, frame.origin.y));
|
frame.origin.x, frame.origin.y));
|
||||||
if (gsk_render_node_has_texture (node))
|
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_paint (cr);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -186,77 +182,6 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
|
|||||||
gsk_cairo_renderer_render_node (self, root, cr);
|
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
|
static void
|
||||||
gsk_cairo_renderer_class_init (GskCairoRendererClass *klass)
|
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->realize = gsk_cairo_renderer_realize;
|
||||||
renderer_class->unrealize = gsk_cairo_renderer_unrealize;
|
renderer_class->unrealize = gsk_cairo_renderer_unrealize;
|
||||||
renderer_class->render = gsk_cairo_renderer_render;
|
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
|
static void
|
||||||
|
@ -90,13 +90,6 @@ typedef struct {
|
|||||||
} ProfileTimers;
|
} ProfileTimers;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct _GskGLTexture GskGLTexture;
|
|
||||||
struct _GskGLTexture {
|
|
||||||
GskTexture texture;
|
|
||||||
|
|
||||||
int texture_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GskGLRenderer
|
struct _GskGLRenderer
|
||||||
{
|
{
|
||||||
GskRenderer parent_instance;
|
GskRenderer parent_instance;
|
||||||
@ -136,86 +129,6 @@ struct _GskGLRendererClass
|
|||||||
|
|
||||||
G_DEFINE_TYPE (GskGLRenderer, gsk_gl_renderer, GSK_TYPE_RENDERER)
|
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
|
static void
|
||||||
gsk_gl_renderer_dispose (GObject *gobject)
|
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))
|
if (gsk_render_node_has_texture (node))
|
||||||
{
|
{
|
||||||
GskTexture *texture = gsk_render_node_get_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))
|
get_gl_scaling_filters (node, &gl_min_filter, &gl_mag_filter);
|
||||||
{
|
|
||||||
g_warning ("Given Texture belongs to wrong renderer, ignoring.");
|
/* Upload the Cairo surface to a GL texture */
|
||||||
goto out;
|
item.render_data.texture_id = gsk_gl_driver_create_texture (self->gl_driver,
|
||||||
}
|
FALSE,
|
||||||
item.render_data.texture_id = ((GskGLTexture *) texture)->texture_id;
|
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))
|
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->realize = gsk_gl_renderer_realize;
|
||||||
renderer_class->unrealize = gsk_gl_renderer_unrealize;
|
renderer_class->unrealize = gsk_gl_renderer_unrealize;
|
||||||
renderer_class->render = gsk_gl_renderer_render;
|
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
|
static void
|
||||||
|
@ -134,44 +134,6 @@ gsk_renderer_real_create_cairo_surface (GskRenderer *self,
|
|||||||
return res;
|
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
|
static void
|
||||||
gsk_renderer_dispose (GObject *gobject)
|
gsk_renderer_dispose (GObject *gobject)
|
||||||
{
|
{
|
||||||
@ -278,9 +240,6 @@ gsk_renderer_class_init (GskRendererClass *klass)
|
|||||||
klass->unrealize = gsk_renderer_real_unrealize;
|
klass->unrealize = gsk_renderer_real_unrealize;
|
||||||
klass->render = gsk_renderer_real_render;
|
klass->render = gsk_renderer_real_render;
|
||||||
klass->create_cairo_surface = gsk_renderer_real_create_cairo_surface;
|
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->constructed = gsk_renderer_constructed;
|
||||||
gobject_class->set_property = gsk_renderer_set_property;
|
gobject_class->set_property = gsk_renderer_set_property;
|
||||||
|
@ -47,15 +47,6 @@ struct _GskRendererClass
|
|||||||
cairo_format_t,
|
cairo_format_t,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
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);
|
gboolean gsk_renderer_is_realized (GskRenderer *renderer);
|
||||||
|
155
gsk/gsktexture.c
155
gsk/gsktexture.c
@ -23,9 +23,6 @@
|
|||||||
*
|
*
|
||||||
* #GskTexture is the basic element used to refer to pixel data.
|
* #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.
|
* 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 structure: That means you cannot change
|
||||||
@ -38,7 +35,6 @@
|
|||||||
#include "gsktextureprivate.h"
|
#include "gsktextureprivate.h"
|
||||||
|
|
||||||
#include "gskdebugprivate.h"
|
#include "gskdebugprivate.h"
|
||||||
#include "gskrendererprivate.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GskTexture: (ref-func gsk_texture_ref) (unref-func gsk_texture_unref)
|
* 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
|
static void
|
||||||
gsk_texture_finalize (GskTexture *self)
|
gsk_texture_finalize (GskTexture *self)
|
||||||
{
|
{
|
||||||
GSK_RENDERER_GET_CLASS (self->renderer)->texture_destroy (self);
|
self->klass->finalize (self);
|
||||||
|
|
||||||
g_object_unref (self->renderer);
|
|
||||||
|
|
||||||
g_free (self);
|
g_free (self);
|
||||||
}
|
}
|
||||||
@ -100,63 +94,146 @@ gsk_texture_unref (GskTexture *texture)
|
|||||||
gsk_texture_finalize (texture);
|
gsk_texture_finalize (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
GskTexture *
|
gpointer
|
||||||
gsk_texture_alloc (gsize size,
|
gsk_texture_new (const GskTextureClass *klass,
|
||||||
GskRenderer *renderer,
|
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
GskTexture *self;
|
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->ref_count = 1;
|
||||||
|
|
||||||
self->renderer = g_object_ref (renderer);
|
|
||||||
self->width = width;
|
self->width = width;
|
||||||
self->height = height;
|
self->height = height;
|
||||||
|
|
||||||
return self;
|
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 *
|
GskTexture *
|
||||||
gsk_texture_new_for_data (GskRenderer *renderer,
|
gsk_texture_new_for_surface (cairo_surface_t *surface)
|
||||||
const guchar *data,
|
{
|
||||||
|
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 (const guchar *data,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int stride)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* GskPixbufTexture */
|
||||||
|
|
||||||
|
typedef struct _GskPixbufTexture GskPixbufTexture;
|
||||||
|
|
||||||
|
struct _GskPixbufTexture {
|
||||||
|
GskTexture texture;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_texture_pixbuf_finalize (GskTexture *texture)
|
||||||
|
{
|
||||||
|
GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture;
|
||||||
|
|
||||||
|
g_object_unref (pixbuf->pixbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
gsk_texture_pixbuf_download (GskTexture *texture)
|
||||||
|
{
|
||||||
|
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 *
|
GskTexture *
|
||||||
gsk_texture_new_for_pixbuf (GskRenderer *renderer,
|
gsk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||||
GdkPixbuf *pixbuf)
|
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
GskPixbufTexture *texture;
|
||||||
|
|
||||||
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
|
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
|
||||||
|
|
||||||
return GSK_RENDERER_GET_CLASS (renderer)->texture_new_for_pixbuf (renderer, pixbuf);
|
texture = gsk_texture_new (&GSK_TEXTURE_CLASS_PIXBUF,
|
||||||
}
|
gdk_pixbuf_get_width (pixbuf),
|
||||||
|
gdk_pixbuf_get_height (pixbuf));
|
||||||
|
|
||||||
/**
|
texture->pixbuf = g_object_ref (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)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (GSK_IS_TEXTURE (texture), NULL);
|
|
||||||
|
|
||||||
return texture->renderer;
|
return &texture->texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -195,3 +272,9 @@ gsk_texture_get_height (GskTexture *texture)
|
|||||||
return texture->height;
|
return texture->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_surface_t *
|
||||||
|
gsk_texture_download (GskTexture *texture)
|
||||||
|
{
|
||||||
|
return texture->klass->download (texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -40,17 +40,13 @@ GDK_AVAILABLE_IN_3_90
|
|||||||
void gsk_texture_unref (GskTexture *texture);
|
void gsk_texture_unref (GskTexture *texture);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_3_90
|
GDK_AVAILABLE_IN_3_90
|
||||||
GskTexture * gsk_texture_new_for_data (GskRenderer *renderer,
|
GskTexture * gsk_texture_new_for_data (const guchar *data,
|
||||||
const guchar *data,
|
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int stride);
|
int stride);
|
||||||
GDK_AVAILABLE_IN_3_90
|
GDK_AVAILABLE_IN_3_90
|
||||||
GskTexture * gsk_texture_new_for_pixbuf (GskRenderer *renderer,
|
GskTexture * gsk_texture_new_for_pixbuf (GdkPixbuf *pixbuf);
|
||||||
GdkPixbuf *pixbuf);
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_3_90
|
|
||||||
GskRenderer * gsk_texture_get_renderer (GskTexture *texture);
|
|
||||||
GDK_AVAILABLE_IN_3_90
|
GDK_AVAILABLE_IN_3_90
|
||||||
int gsk_texture_get_width (GskTexture *texture);
|
int gsk_texture_get_width (GskTexture *texture);
|
||||||
GDK_AVAILABLE_IN_3_90
|
GDK_AVAILABLE_IN_3_90
|
||||||
|
@ -9,21 +9,31 @@ G_BEGIN_DECLS
|
|||||||
#define GSK_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_TEXTURE))
|
#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))
|
#define GSK_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_TEXTURE, GskTextureClass))
|
||||||
|
|
||||||
|
typedef struct _GskTextureClass GskTextureClass;
|
||||||
|
|
||||||
struct _GskTexture
|
struct _GskTexture
|
||||||
{
|
{
|
||||||
|
const GskTextureClass *klass;
|
||||||
|
|
||||||
volatile int ref_count;
|
volatile int ref_count;
|
||||||
|
|
||||||
GskRenderer *renderer;
|
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gsk_texture_new(type,renderer,width,height) \
|
struct _GskTextureClass {
|
||||||
(type *) gsk_texture_alloc(sizeof (type),(renderer),(width),(height))
|
const char *name;
|
||||||
GskTexture *gsk_texture_alloc (gsize size,
|
gsize size;
|
||||||
GskRenderer *renderer,
|
|
||||||
|
void (* finalize) (GskTexture *texture);
|
||||||
|
cairo_surface_t * (* download) (GskTexture *texture);
|
||||||
|
};
|
||||||
|
|
||||||
|
gpointer gsk_texture_new (const GskTextureClass *klass,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
|
GskTexture * gsk_texture_new_for_surface (cairo_surface_t *surface);
|
||||||
|
cairo_surface_t * gsk_texture_download (GskTexture *texture);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -577,8 +577,7 @@ gtk_icon_helper_ensure_texture (GtkIconHelper *self,
|
|||||||
map = cairo_surface_map_to_image (self->priv->rendered_surface,
|
map = cairo_surface_map_to_image (self->priv->rendered_surface,
|
||||||
&(GdkRectangle) { 0, 0, width * scale, height * scale});
|
&(GdkRectangle) { 0, 0, width * scale, height * scale});
|
||||||
|
|
||||||
self->priv->texture = gsk_texture_new_for_data (renderer,
|
self->priv->texture = gsk_texture_new_for_data (cairo_image_surface_get_data (map),
|
||||||
cairo_image_surface_get_data (map),
|
|
||||||
width * scale,
|
width * scale,
|
||||||
height * scale,
|
height * scale,
|
||||||
cairo_image_surface_get_stride (map));
|
cairo_image_surface_get_stride (map));
|
||||||
|
@ -400,7 +400,7 @@ gtk_snapshot_render_icon (GtkSnapshot *snapshot,
|
|||||||
{
|
{
|
||||||
GskTexture *texture;
|
GskTexture *texture;
|
||||||
|
|
||||||
texture = gsk_texture_new_for_pixbuf (snapshot->renderer, pixbuf);
|
texture = gsk_texture_new_for_pixbuf (pixbuf);
|
||||||
gtk_snapshot_translate_2d (snapshot, x, y);
|
gtk_snapshot_translate_2d (snapshot, x, y);
|
||||||
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
|
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
|
||||||
snapshot,
|
snapshot,
|
||||||
|
Loading…
Reference in New Issue
Block a user