forked from AuroraMiddleware/gtk
gsk: Add gsk_renderer_render_texture()
... and implement it for the Cairo renderer. It's an API that instructs a renderer to render to a texture. So far this is mostly meant to be used for testing, but I could imagine it being useful for rendering DND icons.
This commit is contained in:
parent
98086014d8
commit
373e08d6d4
@ -12,6 +12,7 @@ gsk_renderer_unrealize
|
||||
gsk_renderer_begin_draw_frame
|
||||
gsk_renderer_end_draw_frame
|
||||
gsk_renderer_render
|
||||
gsk_renderer_render_texture
|
||||
<SUBSECTION Standard>
|
||||
GSK_IS_RENDERER
|
||||
GSK_RENDERER
|
||||
|
@ -45,17 +45,62 @@ gsk_cairo_renderer_unrealize (GskRenderer *renderer)
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
GskRenderNode *root)
|
||||
gsk_cairo_renderer_do_render (GskRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
GskRenderNode *root)
|
||||
{
|
||||
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
||||
GdkDrawingContext *context = gsk_renderer_get_drawing_context (renderer);
|
||||
graphene_rect_t viewport;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
||||
GskProfiler *profiler;
|
||||
gint64 cpu_time;
|
||||
#endif
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
profiler = gsk_renderer_get_profiler (renderer);
|
||||
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
|
||||
#endif
|
||||
|
||||
gsk_render_node_draw (root, cr);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
|
||||
gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
|
||||
|
||||
gsk_profiler_push_samples (profiler);
|
||||
#endif
|
||||
}
|
||||
|
||||
static GskTexture *
|
||||
gsk_cairo_renderer_render_texture (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
GskTexture *texture;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ceil (viewport->size.width), ceil (viewport->size.height));
|
||||
cr = cairo_create (surface);
|
||||
|
||||
cairo_translate (cr, - viewport->origin.x, - viewport->origin.y);
|
||||
|
||||
gsk_cairo_renderer_do_render (renderer, cr, root);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
texture = gsk_texture_new_for_surface (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
GskRenderNode *root)
|
||||
{
|
||||
GdkDrawingContext *context = gsk_renderer_get_drawing_context (renderer);
|
||||
graphene_rect_t viewport;
|
||||
|
||||
cairo_t *cr;
|
||||
|
||||
cr = gdk_drawing_context_get_cairo_context (context);
|
||||
@ -78,19 +123,7 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
profiler = gsk_renderer_get_profiler (renderer);
|
||||
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
|
||||
#endif
|
||||
|
||||
gsk_render_node_draw (root, cr);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
|
||||
gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
|
||||
|
||||
gsk_profiler_push_samples (profiler);
|
||||
#endif
|
||||
gsk_cairo_renderer_do_render (renderer, cr, root);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -101,6 +134,7 @@ gsk_cairo_renderer_class_init (GskCairoRendererClass *klass)
|
||||
renderer_class->realize = gsk_cairo_renderer_realize;
|
||||
renderer_class->unrealize = gsk_cairo_renderer_unrealize;
|
||||
renderer_class->render = gsk_cairo_renderer_render;
|
||||
renderer_class->render_texture = gsk_cairo_renderer_render_texture;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -113,6 +113,15 @@ gsk_renderer_real_unrealize (GskRenderer *self)
|
||||
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, unrealize);
|
||||
}
|
||||
|
||||
static GskTexture *
|
||||
gsk_renderer_real_render_texture (GskRenderer *self,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, render_texture);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkDrawingContext *
|
||||
gsk_renderer_real_begin_draw_frame (GskRenderer *self,
|
||||
const cairo_region_t *region)
|
||||
@ -259,6 +268,7 @@ gsk_renderer_class_init (GskRendererClass *klass)
|
||||
klass->begin_draw_frame = gsk_renderer_real_begin_draw_frame;
|
||||
klass->end_draw_frame = gsk_renderer_real_end_draw_frame;
|
||||
klass->render = gsk_renderer_real_render;
|
||||
klass->render_texture = gsk_renderer_real_render_texture;
|
||||
klass->create_cairo_surface = gsk_renderer_real_create_cairo_surface;
|
||||
|
||||
gobject_class->constructed = gsk_renderer_constructed;
|
||||
@ -606,6 +616,76 @@ gsk_renderer_unrealize (GskRenderer *renderer)
|
||||
priv->is_realized = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_renderer_render_texture:
|
||||
* @renderer: a realized #GdkRenderer
|
||||
* @root: a #GskRenderNode
|
||||
* @viewport: (allow-none): the section to draw or %NULL to use @root's bounds
|
||||
*
|
||||
* Renders the scene graph, described by a tree of #GskRenderNode instances,
|
||||
* to a #GskTexture.
|
||||
*
|
||||
* The @renderer will acquire a reference on the #GskRenderNode tree while
|
||||
* the rendering is in progress, and will make the tree immutable.
|
||||
*
|
||||
* If you want to apply any transformations to @root, you should put it into a
|
||||
* transform node and pass that node instead.
|
||||
*
|
||||
* Returns: (transfer full): a #GskTexture with the rendered contents of @root.
|
||||
*
|
||||
* Since: 3.90
|
||||
*/
|
||||
GskTexture *
|
||||
gsk_renderer_render_texture (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||
graphene_rect_t real_viewport;
|
||||
GskTexture *texture;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
||||
g_return_val_if_fail (priv->is_realized, NULL);
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (root), NULL);
|
||||
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)
|
||||
{
|
||||
gsk_render_node_get_bounds (root, &real_viewport);
|
||||
viewport = &real_viewport;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gsk_profiler_reset (priv->profiler);
|
||||
#endif
|
||||
|
||||
texture = GSK_RENDERER_GET_CLASS (renderer)->render_texture (renderer, root, viewport);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_DEBUG_CHECK (RENDERER))
|
||||
{
|
||||
GString *buf = g_string_new ("*** Texture stats ***\n\n");
|
||||
|
||||
gsk_profiler_append_counters (priv->profiler, buf);
|
||||
g_string_append_c (buf, '\n');
|
||||
|
||||
gsk_profiler_append_timers (priv->profiler, buf);
|
||||
g_string_append_c (buf, '\n');
|
||||
|
||||
g_print ("%s\n***\n\n", buf->str);
|
||||
|
||||
g_string_free (buf, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_clear_pointer (&priv->root_node, gsk_render_node_unref);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_renderer_render:
|
||||
* @renderer: a #GskRenderer
|
||||
|
@ -65,6 +65,11 @@ gboolean gsk_renderer_realize (GskRenderer
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gsk_renderer_unrealize (GskRenderer *renderer);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GskTexture * gsk_renderer_render_texture (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GdkDrawingContext * gsk_renderer_begin_draw_frame (GskRenderer *renderer,
|
||||
const cairo_region_t *region);
|
||||
|
@ -42,6 +42,9 @@ struct _GskRendererClass
|
||||
GError **error);
|
||||
void (* unrealize) (GskRenderer *renderer);
|
||||
|
||||
GskTexture * (* render_texture) (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport);
|
||||
GdkDrawingContext * (* begin_draw_frame) (GskRenderer *renderer,
|
||||
const cairo_region_t *region);
|
||||
void (* end_draw_frame) (GskRenderer *renderer,
|
||||
|
Loading…
Reference in New Issue
Block a user