gsk: Add GskTexture
This commit is contained in:
@@ -27,6 +27,7 @@ gsk_public_source_h = \
|
|||||||
gskrenderer.h \
|
gskrenderer.h \
|
||||||
gskrendernode.h \
|
gskrendernode.h \
|
||||||
gskrendernodeiter.h \
|
gskrendernodeiter.h \
|
||||||
|
gsktexture.h \
|
||||||
gsktypes.h
|
gsktypes.h
|
||||||
gsk_private_source_h = \
|
gsk_private_source_h = \
|
||||||
gskcairorendererprivate.h \
|
gskcairorendererprivate.h \
|
||||||
@@ -38,11 +39,13 @@ gsk_private_source_h = \
|
|||||||
gskprofilerprivate.h \
|
gskprofilerprivate.h \
|
||||||
gskrendererprivate.h \
|
gskrendererprivate.h \
|
||||||
gskrendernodeprivate.h \
|
gskrendernodeprivate.h \
|
||||||
gskshaderbuilderprivate.h
|
gskshaderbuilderprivate.h \
|
||||||
|
gsktextureprivate.h
|
||||||
gsk_public_source_c = \
|
gsk_public_source_c = \
|
||||||
gskrenderer.c \
|
gskrenderer.c \
|
||||||
gskrendernode.c \
|
gskrendernode.c \
|
||||||
gskrendernodeiter.c
|
gskrendernodeiter.c \
|
||||||
|
gsktexture.c
|
||||||
gsk_private_source_c = \
|
gsk_private_source_c = \
|
||||||
gskcairorenderer.c \
|
gskcairorenderer.c \
|
||||||
gskdebug.c \
|
gskdebug.c \
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <gsk/gskrenderer.h>
|
#include <gsk/gskrenderer.h>
|
||||||
#include <gsk/gskrendernode.h>
|
#include <gsk/gskrendernode.h>
|
||||||
#include <gsk/gskrendernodeiter.h>
|
#include <gsk/gskrendernodeiter.h>
|
||||||
|
#include <gsk/gsktexture.h>
|
||||||
|
|
||||||
#include <gsk/gsktypes.h>
|
#include <gsk/gsktypes.h>
|
||||||
#include <gsk/gskenumtypes.h>
|
#include <gsk/gskenumtypes.h>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ typedef struct {
|
|||||||
GLuint mag_filter;
|
GLuint mag_filter;
|
||||||
GArray *fbos;
|
GArray *fbos;
|
||||||
gboolean in_use : 1;
|
gboolean in_use : 1;
|
||||||
|
gboolean reserved : 1;
|
||||||
} Texture;
|
} Texture;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -75,6 +76,8 @@ texture_free (gpointer data)
|
|||||||
{
|
{
|
||||||
Texture *t = data;
|
Texture *t = data;
|
||||||
|
|
||||||
|
g_warn_if_fail (!t->reserved);
|
||||||
|
|
||||||
g_clear_pointer (&t->fbos, g_array_unref);
|
g_clear_pointer (&t->fbos, g_array_unref);
|
||||||
glDeleteTextures (1, &t->texture_id);
|
glDeleteTextures (1, &t->texture_id);
|
||||||
g_slice_free (Texture, t);
|
g_slice_free (Texture, t);
|
||||||
@@ -269,6 +272,9 @@ gsk_gl_driver_collect_textures (GskGLDriver *driver)
|
|||||||
{
|
{
|
||||||
Texture *t = value_p;
|
Texture *t = value_p;
|
||||||
|
|
||||||
|
if (t->reserved)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (t->in_use)
|
if (t->in_use)
|
||||||
{
|
{
|
||||||
t->in_use = FALSE;
|
t->in_use = FALSE;
|
||||||
@@ -379,6 +385,7 @@ find_texture_by_size (GHashTable *textures,
|
|||||||
|
|
||||||
int
|
int
|
||||||
gsk_gl_driver_create_texture (GskGLDriver *driver,
|
gsk_gl_driver_create_texture (GskGLDriver *driver,
|
||||||
|
gboolean reserve,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
@@ -404,6 +411,7 @@ gsk_gl_driver_create_texture (GskGLDriver *driver,
|
|||||||
GSK_NOTE (OPENGL, g_print ("Reusing Texture(%d) for size %dx%d\n",
|
GSK_NOTE (OPENGL, g_print ("Reusing Texture(%d) for size %dx%d\n",
|
||||||
t->texture_id, t->width, t->height));
|
t->texture_id, t->width, t->height));
|
||||||
t->in_use = TRUE;
|
t->in_use = TRUE;
|
||||||
|
t->reserved = reserve;
|
||||||
return t->texture_id;
|
return t->texture_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,11 +424,27 @@ gsk_gl_driver_create_texture (GskGLDriver *driver,
|
|||||||
t->min_filter = GL_NEAREST;
|
t->min_filter = GL_NEAREST;
|
||||||
t->mag_filter = GL_NEAREST;
|
t->mag_filter = GL_NEAREST;
|
||||||
t->in_use = TRUE;
|
t->in_use = TRUE;
|
||||||
|
t->reserved = reserve;
|
||||||
g_hash_table_insert (driver->textures, GINT_TO_POINTER (texture_id), t);
|
g_hash_table_insert (driver->textures, GINT_TO_POINTER (texture_id), t);
|
||||||
|
|
||||||
return t->texture_id;
|
return t->texture_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsk_gl_driver_release_texture (GskGLDriver *driver,
|
||||||
|
int texture_id)
|
||||||
|
{
|
||||||
|
Texture *t;
|
||||||
|
|
||||||
|
g_return_if_fail (GSK_IS_GL_DRIVER (driver));
|
||||||
|
|
||||||
|
t = gsk_gl_driver_get_texture (driver, texture_id);
|
||||||
|
g_return_if_fail (t != NULL);
|
||||||
|
g_return_if_fail (t->reserved);
|
||||||
|
|
||||||
|
t->reserved = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static Vao *
|
static Vao *
|
||||||
find_vao (GHashTable *vaos,
|
find_vao (GHashTable *vaos,
|
||||||
int position_id,
|
int position_id,
|
||||||
|
|||||||
@@ -24,8 +24,11 @@ void gsk_gl_driver_begin_frame (GskGLDriver *driver
|
|||||||
void gsk_gl_driver_end_frame (GskGLDriver *driver);
|
void gsk_gl_driver_end_frame (GskGLDriver *driver);
|
||||||
|
|
||||||
int gsk_gl_driver_create_texture (GskGLDriver *driver,
|
int gsk_gl_driver_create_texture (GskGLDriver *driver,
|
||||||
|
gboolean reserved,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
|
void gsk_gl_driver_release_texture (GskGLDriver *driver,
|
||||||
|
int texture_id);
|
||||||
int gsk_gl_driver_create_vao_for_quad (GskGLDriver *driver,
|
int gsk_gl_driver_create_vao_for_quad (GskGLDriver *driver,
|
||||||
int position_id,
|
int position_id,
|
||||||
int uv_id,
|
int uv_id,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "gskrendernodeprivate.h"
|
#include "gskrendernodeprivate.h"
|
||||||
#include "gskrendernodeiter.h"
|
#include "gskrendernodeiter.h"
|
||||||
#include "gskshaderbuilderprivate.h"
|
#include "gskshaderbuilderprivate.h"
|
||||||
|
#include "gsktextureprivate.h"
|
||||||
|
|
||||||
#include "gskprivate.h"
|
#include "gskprivate.h"
|
||||||
|
|
||||||
@@ -89,6 +90,13 @@ 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;
|
||||||
@@ -128,6 +136,86 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -152,6 +240,7 @@ gsk_gl_renderer_create_buffers (GskGLRenderer *self,
|
|||||||
if (self->texture_id == 0)
|
if (self->texture_id == 0)
|
||||||
{
|
{
|
||||||
self->texture_id = gsk_gl_driver_create_texture (self->gl_driver,
|
self->texture_id = gsk_gl_driver_create_texture (self->gl_driver,
|
||||||
|
FALSE,
|
||||||
width * scale_factor,
|
width * scale_factor,
|
||||||
height * scale_factor);
|
height * scale_factor);
|
||||||
gsk_gl_driver_bind_source_texture (self->gl_driver, self->texture_id);
|
gsk_gl_driver_bind_source_texture (self->gl_driver, self->texture_id);
|
||||||
@@ -693,7 +782,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
|||||||
if (render_node_needs_render_target (node))
|
if (render_node_needs_render_target (node))
|
||||||
{
|
{
|
||||||
item.render_data.render_target_id =
|
item.render_data.render_target_id =
|
||||||
gsk_gl_driver_create_texture (self->gl_driver, item.size.width, item.size.height);
|
gsk_gl_driver_create_texture (self->gl_driver, FALSE, item.size.width, item.size.height);
|
||||||
gsk_gl_driver_init_texture_empty (self->gl_driver, item.render_data.render_target_id);
|
gsk_gl_driver_init_texture_empty (self->gl_driver, item.render_data.render_target_id);
|
||||||
gsk_gl_driver_create_render_target (self->gl_driver, item.render_data.render_target_id, TRUE, TRUE);
|
gsk_gl_driver_create_render_target (self->gl_driver, item.render_data.render_target_id, TRUE, TRUE);
|
||||||
|
|
||||||
@@ -708,7 +797,14 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
|||||||
|
|
||||||
if (gsk_render_node_has_texture (node))
|
if (gsk_render_node_has_texture (node))
|
||||||
{
|
{
|
||||||
item.render_data.texture_id = gsk_render_node_get_texture (node);
|
GskTexture *texture = gsk_render_node_get_texture (node);
|
||||||
|
|
||||||
|
if (gsk_texture_get_renderer (texture) != GSK_RENDERER (self))
|
||||||
|
{
|
||||||
|
g_warning ("Given Texture belongs to wrong renderer, ignoring.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
item.render_data.texture_id = ((GskGLTexture *) texture)->texture_id;
|
||||||
}
|
}
|
||||||
else if (gsk_render_node_has_surface (node))
|
else if (gsk_render_node_has_surface (node))
|
||||||
{
|
{
|
||||||
@@ -719,6 +815,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
|||||||
|
|
||||||
/* Upload the Cairo surface to a GL texture */
|
/* Upload the Cairo surface to a GL texture */
|
||||||
item.render_data.texture_id = gsk_gl_driver_create_texture (self->gl_driver,
|
item.render_data.texture_id = gsk_gl_driver_create_texture (self->gl_driver,
|
||||||
|
FALSE,
|
||||||
item.size.width,
|
item.size.width,
|
||||||
item.size.height);
|
item.size.height);
|
||||||
gsk_gl_driver_bind_source_texture (self->gl_driver, item.render_data.texture_id);
|
gsk_gl_driver_bind_source_texture (self->gl_driver, item.render_data.texture_id);
|
||||||
@@ -965,6 +1062,10 @@ 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
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include "gskglrendererprivate.h"
|
#include "gskglrendererprivate.h"
|
||||||
#include "gskprofilerprivate.h"
|
#include "gskprofilerprivate.h"
|
||||||
#include "gskrendernodeprivate.h"
|
#include "gskrendernodeprivate.h"
|
||||||
|
#include "gsktexture.h"
|
||||||
|
|
||||||
#include "gskenumtypes.h"
|
#include "gskenumtypes.h"
|
||||||
|
|
||||||
@@ -133,6 +134,44 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -239,6 +278,9 @@ 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,6 +47,15 @@ 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);
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include "gskdebugprivate.h"
|
#include "gskdebugprivate.h"
|
||||||
#include "gskrendernodeiter.h"
|
#include "gskrendernodeiter.h"
|
||||||
#include "gskrendererprivate.h"
|
#include "gskrendererprivate.h"
|
||||||
|
#include "gsktexture.h"
|
||||||
|
|
||||||
#include <graphene-gobject.h>
|
#include <graphene-gobject.h>
|
||||||
|
|
||||||
@@ -1204,33 +1205,42 @@ gsk_render_node_has_texture (GskRenderNode *node)
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), FALSE);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), FALSE);
|
||||||
|
|
||||||
return node->texture_id != 0;
|
return node->texture != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
GskTexture *
|
||||||
gsk_render_node_get_texture (GskRenderNode *node)
|
gsk_render_node_get_texture (GskRenderNode *node)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), 0);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), 0);
|
||||||
|
|
||||||
return node->texture_id;
|
return node->texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_render_node_set_texture:
|
* gsk_render_node_set_texture:
|
||||||
* @node: a #GskRenderNode
|
* @node: a #GskRenderNode
|
||||||
* @texture_id: the object id of a GL texture
|
* @texture: the #GskTexture
|
||||||
*
|
*
|
||||||
* Associates a @texture_id to a #GskRenderNode.
|
* Associates a #GskTexture to a #GskRenderNode.
|
||||||
*
|
*
|
||||||
* Since: 3.90
|
* Since: 3.90
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gsk_render_node_set_texture (GskRenderNode *node,
|
gsk_render_node_set_texture (GskRenderNode *node,
|
||||||
int texture_id)
|
GskTexture *texture)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||||
|
|
||||||
node->texture_id = texture_id;
|
if (node->texture == texture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (node->texture)
|
||||||
|
gsk_texture_unref (node->texture);
|
||||||
|
|
||||||
|
node->texture = texture;
|
||||||
|
|
||||||
|
if (texture)
|
||||||
|
gsk_texture_ref (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ void gsk_render_node_set_blend_mode (GskRenderNode *
|
|||||||
GskBlendMode blend_mode);
|
GskBlendMode blend_mode);
|
||||||
GDK_AVAILABLE_IN_3_90
|
GDK_AVAILABLE_IN_3_90
|
||||||
void gsk_render_node_set_texture (GskRenderNode *node,
|
void gsk_render_node_set_texture (GskRenderNode *node,
|
||||||
int texture_id);
|
GskTexture *texture);
|
||||||
GDK_AVAILABLE_IN_3_90
|
GDK_AVAILABLE_IN_3_90
|
||||||
void gsk_render_node_set_scaling_filter (GskRenderNode *node,
|
void gsk_render_node_set_scaling_filter (GskRenderNode *node,
|
||||||
GskScalingFilter min_filter,
|
GskScalingFilter min_filter,
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ struct _GskRenderNode
|
|||||||
/* The contents of the node as a Cairo surface */
|
/* The contents of the node as a Cairo surface */
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
/* The contents of the node as a GL surface */
|
/* The contents of the node as a texture */
|
||||||
int texture_id;
|
GskTexture *texture;
|
||||||
|
|
||||||
/* Paint opacity */
|
/* Paint opacity */
|
||||||
double opacity;
|
double opacity;
|
||||||
@@ -85,7 +85,7 @@ double gsk_render_node_get_opacity (GskRenderNode *node);
|
|||||||
|
|
||||||
cairo_surface_t *gsk_render_node_get_surface (GskRenderNode *node);
|
cairo_surface_t *gsk_render_node_get_surface (GskRenderNode *node);
|
||||||
|
|
||||||
int gsk_render_node_get_texture (GskRenderNode *node);
|
GskTexture *gsk_render_node_get_texture (GskRenderNode *node);
|
||||||
|
|
||||||
gboolean gsk_render_node_has_surface (GskRenderNode *node);
|
gboolean gsk_render_node_has_surface (GskRenderNode *node);
|
||||||
gboolean gsk_render_node_has_texture (GskRenderNode *node);
|
gboolean gsk_render_node_has_texture (GskRenderNode *node);
|
||||||
|
|||||||
197
gsk/gsktexture.c
Normal file
197
gsk/gsktexture.c
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
/* GSK - The GTK Scene Kit
|
||||||
|
*
|
||||||
|
* Copyright 2016 Benjamin Otte
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:GskTexture
|
||||||
|
* @Title: GskTexture
|
||||||
|
* @Short_description: Pixel data uploaded to a #GskRenderer
|
||||||
|
*
|
||||||
|
* #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.
|
||||||
|
*
|
||||||
|
* #GskTexture is an immutable structure: That means you cannot change
|
||||||
|
* anything about it other than increasing the reference count via
|
||||||
|
* gsk_texture_ref().
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gsktextureprivate.h"
|
||||||
|
|
||||||
|
#include "gskdebugprivate.h"
|
||||||
|
#include "gskrendererprivate.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GskTexture: (ref-func gsk_texture_ref) (unref-func gsk_texture_unref)
|
||||||
|
*
|
||||||
|
* The `GskTexture` structure contains only private data.
|
||||||
|
*
|
||||||
|
* Since: 3.90
|
||||||
|
*/
|
||||||
|
|
||||||
|
G_DEFINE_BOXED_TYPE(GskTexture, gsk_texture, gsk_texture_ref, gsk_texture_unref)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_texture_finalize (GskTexture *self)
|
||||||
|
{
|
||||||
|
GSK_RENDERER_GET_CLASS (self->renderer)->texture_destroy (self);
|
||||||
|
|
||||||
|
g_object_unref (self->renderer);
|
||||||
|
|
||||||
|
g_free (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GSK_IS_TEXTURE (texture), NULL);
|
||||||
|
|
||||||
|
g_atomic_int_inc (&texture->ref_count);
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GSK_IS_TEXTURE (texture));
|
||||||
|
|
||||||
|
if (g_atomic_int_dec_and_test (&texture->ref_count))
|
||||||
|
gsk_texture_finalize (texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
GskTexture *
|
||||||
|
gsk_texture_alloc (gsize size,
|
||||||
|
GskRenderer *renderer,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
GskTexture *self;
|
||||||
|
|
||||||
|
g_assert (size >= sizeof (GskTexture));
|
||||||
|
|
||||||
|
self = g_malloc0 (size);
|
||||||
|
|
||||||
|
self->ref_count = 1;
|
||||||
|
|
||||||
|
self->renderer = g_object_ref (renderer);
|
||||||
|
self->width = width;
|
||||||
|
self->height = height;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
GskTexture *
|
||||||
|
gsk_texture_new_for_data (GskRenderer *renderer,
|
||||||
|
const guchar *data,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int stride)
|
||||||
|
{
|
||||||
|
return GSK_RENDERER_GET_CLASS (renderer)->texture_new_for_data (renderer, data, width, height, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
GskTexture *
|
||||||
|
gsk_texture_new_for_pixbuf (GskRenderer *renderer,
|
||||||
|
GdkPixbuf *pixbuf)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
||||||
|
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
|
||||||
|
|
||||||
|
return GSK_RENDERER_GET_CLASS (renderer)->texture_new_for_pixbuf (renderer, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_texture_get_width:
|
||||||
|
* @texture: a #GskTexture
|
||||||
|
*
|
||||||
|
* Returns the width of @texture.
|
||||||
|
*
|
||||||
|
* Returns: the width of the #GskTexture
|
||||||
|
*
|
||||||
|
* Since: 3.90
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
gsk_texture_get_width (GskTexture *texture)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GSK_IS_TEXTURE (texture), 0);
|
||||||
|
|
||||||
|
return texture->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_texture_get_height:
|
||||||
|
* @texture: a #GskTexture
|
||||||
|
*
|
||||||
|
* Returns the height of the @texture.
|
||||||
|
*
|
||||||
|
* Returns: the height of the #GskTexture
|
||||||
|
*
|
||||||
|
* Since: 3.90
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
gsk_texture_get_height (GskTexture *texture)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GSK_IS_TEXTURE (texture), 0);
|
||||||
|
|
||||||
|
return texture->height;
|
||||||
|
}
|
||||||
|
|
||||||
61
gsk/gsktexture.h
Normal file
61
gsk/gsktexture.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* GSK - The GTK Scene Kit
|
||||||
|
*
|
||||||
|
* Copyright 2016 Benjamin Otte
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_TEXTURE_H__
|
||||||
|
#define __GSK_TEXTURE_H__
|
||||||
|
|
||||||
|
#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
|
||||||
|
#error "Only <gsk/gsk.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gsk/gsktypes.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_TYPE_TEXTURE (gsk_texture_get_type ())
|
||||||
|
|
||||||
|
#define GSK_IS_TEXTURE(texture) ((texture) != NULL)
|
||||||
|
|
||||||
|
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 (GskRenderer *renderer,
|
||||||
|
const guchar *data,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int stride);
|
||||||
|
GDK_AVAILABLE_IN_3_90
|
||||||
|
GskTexture * gsk_texture_new_for_pixbuf (GskRenderer *renderer,
|
||||||
|
GdkPixbuf *pixbuf);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_90
|
||||||
|
GskRenderer * gsk_texture_get_renderer (GskTexture *texture);
|
||||||
|
GDK_AVAILABLE_IN_3_90
|
||||||
|
int gsk_texture_get_width (GskTexture *texture);
|
||||||
|
GDK_AVAILABLE_IN_3_90
|
||||||
|
int gsk_texture_get_height (GskTexture *texture);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_TEXTURE_H__ */
|
||||||
30
gsk/gsktextureprivate.h
Normal file
30
gsk/gsktextureprivate.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef __GSK_TEXTURE_PRIVATE_H__
|
||||||
|
#define __GSK_TEXTURE_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "gsktexture.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_TEXTURE, GskTextureClass))
|
||||||
|
#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))
|
||||||
|
|
||||||
|
struct _GskTexture
|
||||||
|
{
|
||||||
|
volatile int ref_count;
|
||||||
|
|
||||||
|
GskRenderer *renderer;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define gsk_texture_new(type,renderer,width,height) \
|
||||||
|
(type *) gsk_texture_alloc(sizeof (type),(renderer),(width),(height))
|
||||||
|
GskTexture *gsk_texture_alloc (gsize size,
|
||||||
|
GskRenderer *renderer,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_TEXTURE_PRIVATE_H__ */
|
||||||
@@ -27,5 +27,6 @@
|
|||||||
#include <gsk/gskenums.h>
|
#include <gsk/gskenums.h>
|
||||||
|
|
||||||
typedef struct _GskRenderer GskRenderer;
|
typedef struct _GskRenderer GskRenderer;
|
||||||
|
typedef struct _GskTexture GskTexture;
|
||||||
|
|
||||||
#endif /* __GSK_TYPES_H__ */
|
#endif /* __GSK_TYPES_H__ */
|
||||||
|
|||||||
Reference in New Issue
Block a user