forked from AuroraMiddleware/gtk
gsk: Rework GskRenderer and GskRenderNode semantics
This commit changes the way GskRenderer and GskRenderNode interact and are meant to be used. GskRenderNode should represent a transient tree of rendering nodes, which are submitted to the GskRenderer at render time; this allows the renderer to take ownership of the render tree. Once the toolkit and application code have finished assembling it, the render tree ownership is transferred to the renderer.
This commit is contained in:
parent
d99f91f5fd
commit
074c77e7ac
@ -123,22 +123,29 @@ gsk_cairo_renderer_render_node (GskCairoRenderer *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_cairo_renderer_resize_viewport (GskRenderer *renderer,
|
gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||||
const graphene_rect_t *viewport)
|
GskRenderNode *root,
|
||||||
|
GdkDrawingContext *context)
|
||||||
{
|
{
|
||||||
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
||||||
|
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||||
|
|
||||||
self->viewport = *viewport;
|
gsk_renderer_get_viewport (renderer, &self->viewport);
|
||||||
|
|
||||||
|
if (gsk_renderer_get_auto_clear (renderer))
|
||||||
|
{
|
||||||
|
cairo_save (cr);
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||||
|
|
||||||
|
if (gsk_renderer_get_use_alpha (renderer))
|
||||||
|
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
||||||
|
else
|
||||||
|
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||||
|
|
||||||
|
cairo_paint (cr);
|
||||||
|
cairo_restore (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gsk_cairo_renderer_render (GskRenderer *renderer)
|
|
||||||
{
|
|
||||||
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
|
||||||
cairo_surface_t *target = gsk_renderer_get_surface (renderer);
|
|
||||||
GskRenderNode *root = gsk_renderer_get_root_node (renderer);
|
|
||||||
cairo_t *cr = cairo_create (target);
|
|
||||||
|
|
||||||
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
|
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
|
||||||
{
|
{
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
@ -154,26 +161,6 @@ gsk_cairo_renderer_render (GskRenderer *renderer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gsk_cairo_renderer_render_node (self, root, cr);
|
gsk_cairo_renderer_render_node (self, root, cr);
|
||||||
|
|
||||||
cairo_destroy (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gsk_cairo_renderer_clear (GskRenderer *renderer)
|
|
||||||
{
|
|
||||||
cairo_surface_t *surface = gsk_renderer_get_surface (renderer);
|
|
||||||
cairo_t *cr = cairo_create (surface);
|
|
||||||
|
|
||||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
|
||||||
|
|
||||||
if (gsk_renderer_get_use_alpha (renderer))
|
|
||||||
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
|
||||||
else
|
|
||||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
|
||||||
|
|
||||||
cairo_paint (cr);
|
|
||||||
|
|
||||||
cairo_destroy (cr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -183,8 +170,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->resize_viewport = gsk_cairo_renderer_resize_viewport;
|
|
||||||
renderer_class->clear = gsk_cairo_renderer_clear;
|
|
||||||
renderer_class->render = gsk_cairo_renderer_render;
|
renderer_class->render = gsk_cairo_renderer_render;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,16 +432,9 @@ gsk_gl_renderer_realize (GskRenderer *renderer)
|
|||||||
gdk_gl_context_make_current (self->context);
|
gdk_gl_context_make_current (self->context);
|
||||||
|
|
||||||
GSK_NOTE (OPENGL, g_print ("Creating buffers and programs\n"));
|
GSK_NOTE (OPENGL, g_print ("Creating buffers and programs\n"));
|
||||||
|
|
||||||
gsk_gl_renderer_create_buffers (self);
|
gsk_gl_renderer_create_buffers (self);
|
||||||
gsk_gl_renderer_create_program (self);
|
gsk_gl_renderer_create_program (self);
|
||||||
|
|
||||||
self->opaque_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), 16);
|
|
||||||
g_array_set_clear_func (self->opaque_render_items, render_item_clear);
|
|
||||||
|
|
||||||
self->transparent_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), 16);
|
|
||||||
g_array_set_clear_func (self->opaque_render_items, render_item_clear);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,18 +459,22 @@ gsk_gl_renderer_unrealize (GskRenderer *renderer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_gl_renderer_resize_viewport (GskRenderer *renderer,
|
gsk_gl_renderer_resize_viewport (GskGLRenderer *self,
|
||||||
const graphene_rect_t *viewport)
|
const graphene_rect_t *viewport)
|
||||||
{
|
{
|
||||||
|
GSK_NOTE (OPENGL, g_print ("glViewport(0, 0, %g, %g)\n",
|
||||||
|
viewport->size.width,
|
||||||
|
viewport->size.height));
|
||||||
|
|
||||||
|
glViewport (viewport->origin.x, viewport->origin.y,
|
||||||
|
viewport->size.width, viewport->size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_gl_renderer_update (GskRenderer *renderer,
|
gsk_gl_renderer_update_frustum (GskGLRenderer *self,
|
||||||
const graphene_matrix_t *modelview,
|
const graphene_matrix_t *modelview,
|
||||||
const graphene_matrix_t *projection)
|
const graphene_matrix_t *projection)
|
||||||
{
|
{
|
||||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
|
||||||
|
|
||||||
GSK_NOTE (OPENGL, g_print ("Updating the modelview/projection\n"));
|
GSK_NOTE (OPENGL, g_print ("Updating the modelview/projection\n"));
|
||||||
|
|
||||||
graphene_matrix_multiply (modelview, projection, &self->mvp);
|
graphene_matrix_multiply (modelview, projection, &self->mvp);
|
||||||
@ -662,6 +659,7 @@ get_gl_scaling_filters (GskRenderer *renderer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static gboolean
|
static gboolean
|
||||||
check_in_frustum (const graphene_frustum_t *frustum,
|
check_in_frustum (const graphene_frustum_t *frustum,
|
||||||
RenderItem *item)
|
RenderItem *item)
|
||||||
@ -673,6 +671,7 @@ check_in_frustum (const graphene_frustum_t *frustum,
|
|||||||
|
|
||||||
return graphene_frustum_intersects_box (frustum, &aabb);
|
return graphene_frustum_intersects_box (frustum, &aabb);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static float
|
static float
|
||||||
project_item (const graphene_matrix_t *projection,
|
project_item (const graphene_matrix_t *projection,
|
||||||
@ -748,19 +747,6 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
|||||||
gsk_renderer_get_projection (GSK_RENDERER (self), &projection);
|
gsk_renderer_get_projection (GSK_RENDERER (self), &projection);
|
||||||
item.z = project_item (&projection, &mv);
|
item.z = project_item (&projection, &mv);
|
||||||
|
|
||||||
/* Discard the item if it's outside of the frustum as determined by the
|
|
||||||
* viewport and the projection matrix
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
if (!check_in_frustum (&self->frustum, &item))
|
|
||||||
{
|
|
||||||
GSK_NOTE (OPENGL, g_print ("Node <%s>[%p] culled by frustum\n",
|
|
||||||
node->name != NULL ? node->name : "unnamed",
|
|
||||||
node));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* TODO: This should really be an asset atlas, to avoid uploading a ton
|
/* TODO: This should really be an asset atlas, to avoid uploading a ton
|
||||||
* of textures. Ideally we could use a single Cairo surface to get around
|
* of textures. Ideally we could use a single Cairo surface to get around
|
||||||
* the GL texture limits and reorder the texture data on the CPU side and
|
* the GL texture limits and reorder the texture data on the CPU side and
|
||||||
@ -787,7 +773,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
|||||||
if (gsk_render_node_is_opaque (node) && gsk_render_node_get_opacity (node) == 1.f)
|
if (gsk_render_node_is_opaque (node) && gsk_render_node_get_opacity (node) == 1.f)
|
||||||
g_array_append_val (self->opaque_render_items, item);
|
g_array_append_val (self->opaque_render_items, item);
|
||||||
else
|
else
|
||||||
g_array_append_val (self->transparent_render_items, item);
|
g_array_prepend_val (self->transparent_render_items, item);
|
||||||
|
|
||||||
recurse_children:
|
recurse_children:
|
||||||
gsk_render_node_iter_init (&iter, node);
|
gsk_render_node_iter_init (&iter, node);
|
||||||
@ -795,198 +781,72 @@ recurse_children:
|
|||||||
gsk_gl_renderer_add_render_item (self, child);
|
gsk_gl_renderer_add_render_item (self, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static gboolean
|
||||||
opaque_item_cmp (gconstpointer _a,
|
gsk_gl_renderer_validate_tree (GskGLRenderer *self,
|
||||||
gconstpointer _b)
|
|
||||||
{
|
|
||||||
const RenderItem *a = _a;
|
|
||||||
const RenderItem *b = _b;
|
|
||||||
|
|
||||||
if (a->z != b->z)
|
|
||||||
{
|
|
||||||
if (a->z > b->z)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a != b)
|
|
||||||
{
|
|
||||||
if ((gsize) a > (gsize) b)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
transparent_item_cmp (gconstpointer _a,
|
|
||||||
gconstpointer _b)
|
|
||||||
{
|
|
||||||
const RenderItem *a = _a;
|
|
||||||
const RenderItem *b = _b;
|
|
||||||
|
|
||||||
if (a->z != b->z)
|
|
||||||
{
|
|
||||||
if (a->z < b->z)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a != b)
|
|
||||||
{
|
|
||||||
if ((gsize) a < (gsize) b)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gsk_gl_renderer_validate_tree (GskRenderer *renderer,
|
|
||||||
GskRenderNode *root)
|
GskRenderNode *root)
|
||||||
{
|
{
|
||||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
int n_children;
|
||||||
gboolean clear_items = FALSE;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (self->context == NULL)
|
if (self->context == NULL)
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
|
n_children = gsk_render_node_get_n_children (root);
|
||||||
|
if (n_children == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
gdk_gl_context_make_current (self->context);
|
gdk_gl_context_make_current (self->context);
|
||||||
|
|
||||||
if (self->opaque_render_items->len > 0 || self->transparent_render_items->len > 0)
|
self->opaque_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), n_children);
|
||||||
{
|
self->transparent_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), n_children);
|
||||||
/* If we only changed the opacity and transformations then there is no
|
|
||||||
* reason to clear the render items
|
|
||||||
*/
|
|
||||||
for (i = 0; i < self->opaque_render_items->len; i++)
|
|
||||||
{
|
|
||||||
RenderItem *item = &g_array_index (self->opaque_render_items, RenderItem, i);
|
|
||||||
GskRenderNodeChanges changes = gsk_render_node_get_last_state (item->node);
|
|
||||||
|
|
||||||
if (changes == 0)
|
g_array_set_clear_func (self->opaque_render_items, render_item_clear);
|
||||||
continue;
|
g_array_set_clear_func (self->transparent_render_items, render_item_clear);
|
||||||
|
|
||||||
if ((changes & GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY) != 0)
|
|
||||||
{
|
|
||||||
item->opaque = gsk_render_node_is_opaque (item->node);
|
|
||||||
item->opacity = gsk_render_node_get_opacity (item->node);
|
|
||||||
changes &= ~GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changes & GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM)
|
|
||||||
{
|
|
||||||
gsk_render_node_get_world_matrix (item->node, &item->mvp);
|
|
||||||
changes &= ~ GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changes != 0)
|
|
||||||
{
|
|
||||||
clear_items = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < self->transparent_render_items->len; i++)
|
|
||||||
{
|
|
||||||
RenderItem *item = &g_array_index (self->transparent_render_items, RenderItem, i);
|
|
||||||
GskRenderNodeChanges changes = gsk_render_node_get_last_state (item->node);
|
|
||||||
|
|
||||||
if (changes == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((changes & GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY) != 0)
|
|
||||||
{
|
|
||||||
item->opaque = gsk_render_node_is_opaque (item->node);
|
|
||||||
item->opacity = gsk_render_node_get_opacity (item->node);
|
|
||||||
changes &= ~GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changes & GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM)
|
|
||||||
{
|
|
||||||
gsk_render_node_get_world_matrix (item->node, &item->mvp);
|
|
||||||
changes &= ~ GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changes != 0)
|
|
||||||
{
|
|
||||||
clear_items = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
clear_items = TRUE;
|
|
||||||
|
|
||||||
if (!clear_items)
|
|
||||||
{
|
|
||||||
GSK_NOTE (OPENGL, g_print ("Tree is still valid\n"));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < self->opaque_render_items->len; i++)
|
|
||||||
render_item_clear (&g_array_index (self->opaque_render_items, RenderItem, i));
|
|
||||||
for (i = 0; i < self->transparent_render_items->len; i++)
|
|
||||||
render_item_clear (&g_array_index (self->transparent_render_items, RenderItem, i));
|
|
||||||
|
|
||||||
g_array_set_size (self->opaque_render_items, 0);
|
|
||||||
g_array_set_size (self->transparent_render_items, 0);
|
|
||||||
|
|
||||||
GSK_NOTE (OPENGL, g_print ("RenderNode -> RenderItem\n"));
|
GSK_NOTE (OPENGL, g_print ("RenderNode -> RenderItem\n"));
|
||||||
gsk_gl_renderer_add_render_item (self, gsk_renderer_get_root_node (renderer));
|
gsk_gl_renderer_add_render_item (self, root);
|
||||||
|
|
||||||
GSK_NOTE (OPENGL, g_print ("Sorting render nodes\n"));
|
|
||||||
g_array_sort (self->opaque_render_items, opaque_item_cmp);
|
|
||||||
g_array_sort (self->transparent_render_items, transparent_item_cmp);
|
|
||||||
|
|
||||||
out:
|
|
||||||
GSK_NOTE (OPENGL, g_print ("Total render items: %d (opaque:%d, transparent:%d)\n",
|
GSK_NOTE (OPENGL, g_print ("Total render items: %d (opaque:%d, transparent:%d)\n",
|
||||||
self->opaque_render_items->len + self->transparent_render_items->len,
|
self->opaque_render_items->len + self->transparent_render_items->len,
|
||||||
self->opaque_render_items->len,
|
self->opaque_render_items->len,
|
||||||
self->transparent_render_items->len));
|
self->transparent_render_items->len));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_gl_renderer_clear_tree (GskRenderer *renderer,
|
gsk_gl_renderer_clear_tree (GskGLRenderer *self)
|
||||||
GskRenderNode *root_node)
|
|
||||||
{
|
{
|
||||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
|
||||||
|
|
||||||
if (self->context == NULL)
|
if (self->context == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gdk_gl_context_make_current (self->context);
|
|
||||||
|
|
||||||
g_clear_pointer (&self->opaque_render_items, g_array_unref);
|
g_clear_pointer (&self->opaque_render_items, g_array_unref);
|
||||||
g_clear_pointer (&self->transparent_render_items, g_array_unref);
|
g_clear_pointer (&self->transparent_render_items, g_array_unref);
|
||||||
|
|
||||||
if (gsk_renderer_is_realized (renderer))
|
|
||||||
{
|
|
||||||
self->opaque_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), 16);
|
|
||||||
g_array_set_clear_func (self->opaque_render_items, render_item_clear);
|
|
||||||
|
|
||||||
self->transparent_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), 16);
|
|
||||||
g_array_set_clear_func (self->opaque_render_items, render_item_clear);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_gl_renderer_clear (GskRenderer *renderer)
|
gsk_gl_renderer_clear (GskGLRenderer *self)
|
||||||
{
|
{
|
||||||
|
int clear_bits = GL_COLOR_BUFFER_BIT;
|
||||||
|
|
||||||
|
if (self->has_depth_buffer)
|
||||||
|
clear_bits |= GL_DEPTH_BUFFER_BIT;
|
||||||
|
if (self->has_stencil_buffer)
|
||||||
|
clear_bits |= GL_STENCIL_BUFFER_BIT;
|
||||||
|
|
||||||
|
GSK_NOTE (OPENGL, g_print ("Clearing viewport\n"));
|
||||||
|
glClearColor (0, 0, 0, 0);
|
||||||
|
glClear (clear_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_gl_renderer_render (GskRenderer *renderer)
|
gsk_gl_renderer_render (GskRenderer *renderer,
|
||||||
|
GskRenderNode *root,
|
||||||
|
GdkDrawingContext *context)
|
||||||
{
|
{
|
||||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
||||||
|
graphene_matrix_t modelview, projection;
|
||||||
graphene_rect_t viewport;
|
graphene_rect_t viewport;
|
||||||
int scale, status, clear_bits;
|
int status;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (self->context == NULL)
|
if (self->context == NULL)
|
||||||
@ -1008,22 +868,16 @@ gsk_gl_renderer_render (GskRenderer *renderer)
|
|||||||
/* Ensure that the viewport is up to date */
|
/* Ensure that the viewport is up to date */
|
||||||
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
|
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
|
||||||
if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
|
if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||||
{
|
gsk_gl_renderer_resize_viewport (self, &viewport);
|
||||||
GSK_NOTE (OPENGL, g_print ("glViewport(0, 0, %g, %g)\n",
|
|
||||||
viewport.size.width,
|
|
||||||
viewport.size.height));
|
|
||||||
glViewport (0, 0, viewport.size.width, viewport.size.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_bits = GL_COLOR_BUFFER_BIT;
|
gsk_gl_renderer_clear (self);
|
||||||
if (self->has_depth_buffer)
|
|
||||||
clear_bits |= GL_DEPTH_BUFFER_BIT;
|
|
||||||
if (self->has_stencil_buffer)
|
|
||||||
clear_bits |= GL_STENCIL_BUFFER_BIT;
|
|
||||||
|
|
||||||
GSK_NOTE (OPENGL, g_print ("Clearing viewport\n"));
|
gsk_renderer_get_modelview (renderer, &modelview);
|
||||||
glClearColor (0, 0, 0, 0);
|
gsk_renderer_get_projection (renderer, &projection);
|
||||||
glClear (clear_bits);
|
gsk_gl_renderer_update_frustum (self, &modelview, &projection);
|
||||||
|
|
||||||
|
if (!gsk_gl_renderer_validate_tree (self, root))
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* Opaque pass: front-to-back */
|
/* Opaque pass: front-to-back */
|
||||||
GSK_NOTE (OPENGL, g_print ("Rendering %u opaque items\n", self->opaque_render_items->len));
|
GSK_NOTE (OPENGL, g_print ("Rendering %u opaque items\n", self->opaque_render_items->len));
|
||||||
@ -1050,15 +904,18 @@ gsk_gl_renderer_render (GskRenderer *renderer)
|
|||||||
/* Draw the output of the GL rendering to the window */
|
/* Draw the output of the GL rendering to the window */
|
||||||
GSK_NOTE (OPENGL, g_print ("Drawing GL content on Cairo surface using a %s\n",
|
GSK_NOTE (OPENGL, g_print ("Drawing GL content on Cairo surface using a %s\n",
|
||||||
self->texture_id != 0 ? "texture" : "renderbuffer"));
|
self->texture_id != 0 ? "texture" : "renderbuffer"));
|
||||||
scale = 1;
|
|
||||||
gdk_cairo_draw_from_gl (gsk_renderer_get_draw_context (renderer),
|
out:
|
||||||
gsk_renderer_get_window (renderer),
|
gdk_cairo_draw_from_gl (gdk_drawing_context_get_cairo_context (context),
|
||||||
|
gdk_drawing_context_get_window (context),
|
||||||
self->texture_id != 0 ? self->texture_id : self->render_buffer,
|
self->texture_id != 0 ? self->texture_id : self->render_buffer,
|
||||||
self->texture_id != 0 ? GL_TEXTURE : GL_RENDERBUFFER,
|
self->texture_id != 0 ? GL_TEXTURE : GL_RENDERBUFFER,
|
||||||
scale,
|
gsk_renderer_get_scale_factor (renderer),
|
||||||
0, 0, viewport.size.width, viewport.size.height);
|
0, 0, viewport.size.width, viewport.size.height);
|
||||||
|
|
||||||
gdk_gl_context_make_current (self->context);
|
gdk_gl_context_make_current (self->context);
|
||||||
|
|
||||||
|
gsk_gl_renderer_clear_tree (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1071,11 +928,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->resize_viewport = gsk_gl_renderer_resize_viewport;
|
|
||||||
renderer_class->update = gsk_gl_renderer_update;
|
|
||||||
renderer_class->clear = gsk_gl_renderer_clear;
|
|
||||||
renderer_class->validate_tree = gsk_gl_renderer_validate_tree;
|
|
||||||
renderer_class->clear_tree = gsk_gl_renderer_clear_tree;
|
|
||||||
renderer_class->render = gsk_gl_renderer_render;
|
renderer_class->render = gsk_gl_renderer_render;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1089,27 +941,3 @@ gsk_gl_renderer_init (GskGLRenderer *self)
|
|||||||
self->has_depth_buffer = TRUE;
|
self->has_depth_buffer = TRUE;
|
||||||
self->has_stencil_buffer = TRUE;
|
self->has_stencil_buffer = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
gsk_gl_renderer_set_context (GskGLRenderer *renderer,
|
|
||||||
GdkGLContext *context)
|
|
||||||
{
|
|
||||||
g_return_if_fail (GSK_IS_GL_RENDERER (renderer));
|
|
||||||
g_return_if_fail (context == NULL || GDK_IS_GL_CONTEXT (context));
|
|
||||||
|
|
||||||
if (gsk_renderer_is_realized (GSK_RENDERER (renderer)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (gdk_gl_context_get_display (context) != gsk_renderer_get_display (GSK_RENDERER (renderer)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_set_object (&renderer->context, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
GdkGLContext *
|
|
||||||
gsk_gl_renderer_get_context (GskGLRenderer *renderer)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (GSK_IS_GL_RENDERER (renderer), NULL);
|
|
||||||
|
|
||||||
return renderer->context;
|
|
||||||
}
|
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#include "gskrendererprivate.h"
|
#include "gskrendererprivate.h"
|
||||||
|
|
||||||
#include "gskdebugprivate.h"
|
#include "gskdebugprivate.h"
|
||||||
#include "gskcairorendererprivate.h"
|
|
||||||
#include "gskglrendererprivate.h"
|
#include "gskglrendererprivate.h"
|
||||||
#include "gskrendernodeprivate.h"
|
#include "gskrendernodeprivate.h"
|
||||||
|
|
||||||
@ -50,9 +49,6 @@ typedef struct
|
|||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
GdkDisplay *display;
|
|
||||||
GdkWindow *window;
|
|
||||||
|
|
||||||
graphene_rect_t viewport;
|
graphene_rect_t viewport;
|
||||||
graphene_matrix_t modelview;
|
graphene_matrix_t modelview;
|
||||||
graphene_matrix_t projection;
|
graphene_matrix_t projection;
|
||||||
@ -60,16 +56,14 @@ typedef struct
|
|||||||
GskScalingFilter min_filter;
|
GskScalingFilter min_filter;
|
||||||
GskScalingFilter mag_filter;
|
GskScalingFilter mag_filter;
|
||||||
|
|
||||||
|
GdkWindow *window;
|
||||||
|
GdkDrawingContext *drawing_context;
|
||||||
GskRenderNode *root_node;
|
GskRenderNode *root_node;
|
||||||
|
GdkDisplay *display;
|
||||||
|
|
||||||
cairo_surface_t *surface;
|
int scale_factor;
|
||||||
cairo_t *draw_context;
|
|
||||||
|
|
||||||
gboolean is_realized : 1;
|
gboolean is_realized : 1;
|
||||||
gboolean needs_viewport_resize : 1;
|
|
||||||
gboolean needs_modelview_update : 1;
|
|
||||||
gboolean needs_projection_update : 1;
|
|
||||||
gboolean needs_tree_validation : 1;
|
|
||||||
gboolean auto_clear : 1;
|
gboolean auto_clear : 1;
|
||||||
gboolean use_alpha : 1;
|
gboolean use_alpha : 1;
|
||||||
} GskRendererPrivate;
|
} GskRendererPrivate;
|
||||||
@ -83,11 +77,12 @@ enum {
|
|||||||
PROP_MINIFICATION_FILTER,
|
PROP_MINIFICATION_FILTER,
|
||||||
PROP_MAGNIFICATION_FILTER,
|
PROP_MAGNIFICATION_FILTER,
|
||||||
PROP_AUTO_CLEAR,
|
PROP_AUTO_CLEAR,
|
||||||
|
PROP_USE_ALPHA,
|
||||||
|
PROP_SCALE_FACTOR,
|
||||||
|
PROP_WINDOW,
|
||||||
PROP_ROOT_NODE,
|
PROP_ROOT_NODE,
|
||||||
PROP_DISPLAY,
|
PROP_DISPLAY,
|
||||||
PROP_WINDOW,
|
PROP_DRAWING_CONTEXT,
|
||||||
PROP_SURFACE,
|
|
||||||
PROP_USE_ALPHA,
|
|
||||||
|
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
@ -111,36 +106,13 @@ gsk_renderer_real_unrealize (GskRenderer *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_renderer_real_render (GskRenderer *self)
|
gsk_renderer_real_render (GskRenderer *self,
|
||||||
|
GskRenderNode *root,
|
||||||
|
GdkDrawingContext *context)
|
||||||
{
|
{
|
||||||
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, render);
|
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, render);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gsk_renderer_real_resize_viewport (GskRenderer *self,
|
|
||||||
const graphene_rect_t *viewport)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gsk_renderer_real_update (GskRenderer *self,
|
|
||||||
const graphene_matrix_t *mv,
|
|
||||||
const graphene_matrix_t *proj)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gsk_renderer_real_validate_tree (GskRenderer *self,
|
|
||||||
GskRenderNode *root)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gsk_renderer_real_clear_tree (GskRenderer *self,
|
|
||||||
GskRenderNode *old_root)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_renderer_dispose (GObject *gobject)
|
gsk_renderer_dispose (GObject *gobject)
|
||||||
{
|
{
|
||||||
@ -149,11 +121,7 @@ gsk_renderer_dispose (GObject *gobject)
|
|||||||
|
|
||||||
gsk_renderer_unrealize (self);
|
gsk_renderer_unrealize (self);
|
||||||
|
|
||||||
g_clear_pointer (&priv->surface, cairo_surface_destroy);
|
|
||||||
g_clear_pointer (&priv->draw_context, cairo_destroy);
|
|
||||||
|
|
||||||
g_clear_object (&priv->window);
|
g_clear_object (&priv->window);
|
||||||
g_clear_object (&priv->root_node);
|
|
||||||
g_clear_object (&priv->display);
|
g_clear_object (&priv->display);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gsk_renderer_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (gsk_renderer_parent_class)->dispose (gobject);
|
||||||
@ -194,12 +162,12 @@ gsk_renderer_set_property (GObject *gobject,
|
|||||||
gsk_renderer_set_auto_clear (self, g_value_get_boolean (value));
|
gsk_renderer_set_auto_clear (self, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_ROOT_NODE:
|
case PROP_USE_ALPHA:
|
||||||
gsk_renderer_set_root_node (self, g_value_get_object (value));
|
gsk_renderer_set_use_alpha (self, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SURFACE:
|
case PROP_SCALE_FACTOR:
|
||||||
gsk_renderer_set_surface (self, g_value_get_boxed (value));
|
gsk_renderer_set_scale_factor (self, g_value_get_int (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_WINDOW:
|
case PROP_WINDOW:
|
||||||
@ -207,12 +175,9 @@ gsk_renderer_set_property (GObject *gobject,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_DISPLAY:
|
case PROP_DISPLAY:
|
||||||
|
/* Construct-only */
|
||||||
priv->display = g_value_dup_object (value);
|
priv->display = g_value_dup_object (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_USE_ALPHA:
|
|
||||||
gsk_renderer_set_use_alpha (self, g_value_get_boolean (value));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,24 +216,28 @@ gsk_renderer_get_property (GObject *gobject,
|
|||||||
g_value_set_boolean (value, priv->auto_clear);
|
g_value_set_boolean (value, priv->auto_clear);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_ROOT_NODE:
|
case PROP_USE_ALPHA:
|
||||||
g_value_set_object (value, priv->root_node);
|
g_value_set_boolean (value, priv->use_alpha);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SURFACE:
|
case PROP_SCALE_FACTOR:
|
||||||
g_value_set_boxed (value, priv->surface);
|
g_value_set_int (value, priv->scale_factor);
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_DISPLAY:
|
|
||||||
g_value_set_object (value, priv->display);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_WINDOW:
|
case PROP_WINDOW:
|
||||||
g_value_set_object (value, priv->window);
|
g_value_set_object (value, priv->window);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_USE_ALPHA:
|
case PROP_ROOT_NODE:
|
||||||
g_value_set_boolean (value, priv->use_alpha);
|
g_value_set_object (value, priv->root_node);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_DRAWING_CONTEXT:
|
||||||
|
g_value_set_object (value, priv->drawing_context);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_DISPLAY:
|
||||||
|
g_value_set_object (value, priv->display);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,10 +266,6 @@ gsk_renderer_class_init (GskRendererClass *klass)
|
|||||||
|
|
||||||
klass->realize = gsk_renderer_real_realize;
|
klass->realize = gsk_renderer_real_realize;
|
||||||
klass->unrealize = gsk_renderer_real_unrealize;
|
klass->unrealize = gsk_renderer_real_unrealize;
|
||||||
klass->resize_viewport = gsk_renderer_real_resize_viewport;
|
|
||||||
klass->update = gsk_renderer_real_update;
|
|
||||||
klass->validate_tree = gsk_renderer_real_validate_tree;
|
|
||||||
klass->clear_tree = gsk_renderer_real_clear_tree;
|
|
||||||
klass->render = gsk_renderer_real_render;
|
klass->render = gsk_renderer_real_render;
|
||||||
|
|
||||||
gobject_class->constructed = gsk_renderer_constructed;
|
gobject_class->constructed = gsk_renderer_constructed;
|
||||||
@ -448,27 +413,8 @@ gsk_renderer_class_init (GskRendererClass *klass)
|
|||||||
"Root Node",
|
"Root Node",
|
||||||
"The root render node to render",
|
"The root render node to render",
|
||||||
GSK_TYPE_RENDER_NODE,
|
GSK_TYPE_RENDER_NODE,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READABLE |
|
||||||
G_PARAM_STATIC_STRINGS |
|
G_PARAM_STATIC_STRINGS);
|
||||||
G_PARAM_EXPLICIT_NOTIFY);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GskRenderer:surface:
|
|
||||||
*
|
|
||||||
* The target rendering surface.
|
|
||||||
*
|
|
||||||
* See also: #GskRenderer:window.
|
|
||||||
*
|
|
||||||
* Since: 3.22
|
|
||||||
*/
|
|
||||||
gsk_renderer_properties[PROP_SURFACE] =
|
|
||||||
g_param_spec_boxed ("surface",
|
|
||||||
"Surface",
|
|
||||||
"The Cairo surface used to render to",
|
|
||||||
CAIRO_GOBJECT_TYPE_SURFACE,
|
|
||||||
G_PARAM_READWRITE |
|
|
||||||
G_PARAM_STATIC_STRINGS |
|
|
||||||
G_PARAM_EXPLICIT_NOTIFY);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GskRenderer:display:
|
* GskRenderer:display:
|
||||||
@ -486,23 +432,47 @@ gsk_renderer_class_init (GskRendererClass *klass)
|
|||||||
G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
/**
|
|
||||||
* GskRenderer:window:
|
|
||||||
*
|
|
||||||
* The #GdkWindow used to create a target surface, if #GskRenderer:surface
|
|
||||||
* is not explicitly set.
|
|
||||||
*
|
|
||||||
* Since: 3.22
|
|
||||||
*/
|
|
||||||
gsk_renderer_properties[PROP_WINDOW] =
|
gsk_renderer_properties[PROP_WINDOW] =
|
||||||
g_param_spec_object ("window",
|
g_param_spec_object ("window",
|
||||||
"Window",
|
"Window",
|
||||||
"The GdkWindow associated to the renderer",
|
"The window associated to the renderer",
|
||||||
GDK_TYPE_WINDOW,
|
GDK_TYPE_WINDOW,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GskRenderer:scale-factor:
|
||||||
|
*
|
||||||
|
* The scale factor used when rendering.
|
||||||
|
*
|
||||||
|
* Since: 3.22
|
||||||
|
*/
|
||||||
|
gsk_renderer_properties[PROP_SCALE_FACTOR] =
|
||||||
|
g_param_spec_int ("scale-factor",
|
||||||
|
"Scale Factor",
|
||||||
|
"The scaling factor of the renderer",
|
||||||
|
1, G_MAXINT,
|
||||||
|
1,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS |
|
G_PARAM_STATIC_STRINGS |
|
||||||
G_PARAM_EXPLICIT_NOTIFY);
|
G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GskRenderer:drawing-context:
|
||||||
|
*
|
||||||
|
* The drawing context used when rendering.
|
||||||
|
*
|
||||||
|
* Since: 3.22
|
||||||
|
*/
|
||||||
|
gsk_renderer_properties[PROP_DRAWING_CONTEXT] =
|
||||||
|
g_param_spec_object ("drawing-context",
|
||||||
|
"Drawing Context",
|
||||||
|
"The drawing context used by the renderer",
|
||||||
|
GDK_TYPE_DRAWING_CONTEXT,
|
||||||
|
G_PARAM_READABLE |
|
||||||
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GskRenderer:use-alpha:
|
* GskRenderer:use-alpha:
|
||||||
*
|
*
|
||||||
@ -531,6 +501,7 @@ gsk_renderer_init (GskRenderer *self)
|
|||||||
graphene_matrix_init_identity (&priv->projection);
|
graphene_matrix_init_identity (&priv->projection);
|
||||||
|
|
||||||
priv->auto_clear = TRUE;
|
priv->auto_clear = TRUE;
|
||||||
|
priv->scale_factor = 1;
|
||||||
|
|
||||||
priv->min_filter = GSK_SCALING_FILTER_LINEAR;
|
priv->min_filter = GSK_SCALING_FILTER_LINEAR;
|
||||||
priv->mag_filter = GSK_SCALING_FILTER_LINEAR;
|
priv->mag_filter = GSK_SCALING_FILTER_LINEAR;
|
||||||
@ -565,9 +536,6 @@ gsk_renderer_set_viewport (GskRenderer *renderer,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
graphene_rect_init_from_rect (&priv->viewport, viewport);
|
graphene_rect_init_from_rect (&priv->viewport, viewport);
|
||||||
priv->needs_viewport_resize = TRUE;
|
|
||||||
priv->needs_modelview_update = TRUE;
|
|
||||||
priv->needs_projection_update = TRUE;
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_VIEWPORT]);
|
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_VIEWPORT]);
|
||||||
}
|
}
|
||||||
@ -618,8 +586,6 @@ gsk_renderer_set_modelview (GskRenderer *renderer,
|
|||||||
else
|
else
|
||||||
graphene_matrix_init_from_matrix (&priv->modelview, modelview);
|
graphene_matrix_init_from_matrix (&priv->modelview, modelview);
|
||||||
|
|
||||||
priv->needs_modelview_update = TRUE;
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_MODELVIEW]);
|
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_MODELVIEW]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,8 +632,6 @@ gsk_renderer_set_projection (GskRenderer *renderer,
|
|||||||
else
|
else
|
||||||
graphene_matrix_init_from_matrix (&priv->projection, projection);
|
graphene_matrix_init_from_matrix (&priv->projection, projection);
|
||||||
|
|
||||||
priv->needs_projection_update = TRUE;
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_PROJECTION]);
|
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_PROJECTION]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,67 +656,6 @@ gsk_renderer_get_projection (GskRenderer *renderer,
|
|||||||
graphene_matrix_init_from_matrix (projection, &priv->projection);
|
graphene_matrix_init_from_matrix (projection, &priv->projection);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gsk_renderer_invalidate_tree (GskRenderNode *node,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GskRenderer *self = data;
|
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (self);
|
|
||||||
|
|
||||||
GSK_NOTE (RENDERER, g_print ("Invalidating tree.\n"));
|
|
||||||
|
|
||||||
/* Since the scene graph has changed in some way, we need to re-validate it. */
|
|
||||||
priv->needs_tree_validation = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gsk_renderer_set_root_node:
|
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
* @root: (nullable): a #GskRenderNode
|
|
||||||
*
|
|
||||||
* Sets the root node of the scene graph to be rendered.
|
|
||||||
*
|
|
||||||
* The #GskRenderer will acquire a reference on @root.
|
|
||||||
*
|
|
||||||
* Since: 3.22
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gsk_renderer_set_root_node (GskRenderer *renderer,
|
|
||||||
GskRenderNode *root)
|
|
||||||
{
|
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
|
||||||
GskRenderNode *old_root;
|
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_RENDERER (renderer));
|
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (root));
|
|
||||||
|
|
||||||
old_root = priv->root_node != NULL ? g_object_ref (priv->root_node) : NULL;
|
|
||||||
|
|
||||||
if (g_set_object (&priv->root_node, root))
|
|
||||||
{
|
|
||||||
/* We need to unset the invalidate function on the old instance */
|
|
||||||
if (old_root != NULL)
|
|
||||||
{
|
|
||||||
gsk_render_node_set_invalidate_func (old_root, NULL, NULL, NULL);
|
|
||||||
gsk_renderer_clear_tree (renderer, old_root);
|
|
||||||
g_object_unref (old_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->root_node != NULL)
|
|
||||||
gsk_render_node_set_invalidate_func (priv->root_node,
|
|
||||||
gsk_renderer_invalidate_tree,
|
|
||||||
renderer,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* If we don't have a root node, there's really no point in validating a
|
|
||||||
* tree that it's not going to be drawn
|
|
||||||
*/
|
|
||||||
priv->needs_tree_validation = priv->root_node != NULL;
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_ROOT_NODE]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_renderer_set_scaling_filters:
|
* gsk_renderer_set_scaling_filters:
|
||||||
* @renderer: a #GskRenderer
|
* @renderer: a #GskRenderer
|
||||||
@ -819,112 +722,100 @@ gsk_renderer_get_scaling_filters (GskRenderer *renderer,
|
|||||||
*mag_filter = priv->mag_filter;
|
*mag_filter = priv->mag_filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gsk_renderer_set_surface:
|
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
* @surface: (nullable): a Cairo surface
|
|
||||||
*
|
|
||||||
* Sets the #cairo_surface_t used as the target rendering surface.
|
|
||||||
*
|
|
||||||
* This function will acquire a reference to @surface.
|
|
||||||
*
|
|
||||||
* See also: gsk_renderer_set_window()
|
|
||||||
*
|
|
||||||
* Since: 3.22
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
gsk_renderer_set_surface (GskRenderer *renderer,
|
gsk_renderer_set_scale_factor (GskRenderer *renderer,
|
||||||
cairo_surface_t *surface)
|
int scale_factor)
|
||||||
{
|
{
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_RENDERER (renderer));
|
g_return_if_fail (GSK_IS_RENDERER (renderer));
|
||||||
|
|
||||||
if (priv->surface == surface)
|
if (priv->scale_factor != scale_factor)
|
||||||
return;
|
{
|
||||||
|
priv->scale_factor = scale_factor;
|
||||||
|
|
||||||
g_clear_pointer (&priv->surface, cairo_surface_destroy);
|
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_SCALE_FACTOR]);
|
||||||
|
}
|
||||||
if (surface != NULL)
|
|
||||||
priv->surface = cairo_surface_reference (surface);
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_SURFACE]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int
|
||||||
* gsk_renderer_get_surface:
|
gsk_renderer_get_scale_factor (GskRenderer *renderer)
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
*
|
|
||||||
* Retrieve the target rendering surface used by @renderer.
|
|
||||||
*
|
|
||||||
* If you did not use gsk_renderer_set_surface(), a compatible surface
|
|
||||||
* will be created by using the #GdkWindow passed to gsk_renderer_set_window().
|
|
||||||
*
|
|
||||||
* Returns: (transfer none) (nullable): a Cairo surface
|
|
||||||
*
|
|
||||||
* Since: 3.22
|
|
||||||
*/
|
|
||||||
cairo_surface_t *
|
|
||||||
gsk_renderer_get_surface (GskRenderer *renderer)
|
|
||||||
{
|
{
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
g_return_val_if_fail (GSK_IS_RENDERER (renderer), 1);
|
||||||
|
|
||||||
if (priv->surface != NULL)
|
return priv->scale_factor;
|
||||||
return priv->surface;
|
|
||||||
|
|
||||||
if (priv->window != NULL)
|
|
||||||
{
|
|
||||||
int scale = gdk_window_get_scale_factor (priv->window);
|
|
||||||
int width = gdk_window_get_width (priv->window);
|
|
||||||
int height = gdk_window_get_height (priv->window);
|
|
||||||
cairo_content_t content;
|
|
||||||
|
|
||||||
if (priv->use_alpha)
|
|
||||||
content = CAIRO_CONTENT_COLOR_ALPHA;
|
|
||||||
else
|
|
||||||
content = CAIRO_CONTENT_COLOR;
|
|
||||||
|
|
||||||
GSK_NOTE (RENDERER, g_print ("Creating surface from window [%p] (w:%d, h:%d, s:%d, a:%s)\n",
|
|
||||||
priv->window,
|
|
||||||
width, height, scale,
|
|
||||||
priv->use_alpha ? "y" : "n"));
|
|
||||||
|
|
||||||
priv->surface = gdk_window_create_similar_surface (priv->window,
|
|
||||||
content,
|
|
||||||
width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
return priv->surface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_renderer_set_draw_context (GskRenderer *renderer,
|
gsk_renderer_set_window (GskRenderer *renderer,
|
||||||
cairo_t *cr)
|
GdkWindow *window)
|
||||||
{
|
{
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_RENDERER (renderer));
|
g_return_if_fail (GSK_IS_RENDERER (renderer));
|
||||||
|
g_return_if_fail (!priv->is_realized);
|
||||||
|
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
|
||||||
|
|
||||||
if (priv->draw_context == cr)
|
if (g_set_object (&priv->window, window))
|
||||||
return;
|
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_WINDOW]);
|
||||||
|
|
||||||
g_clear_pointer (&priv->draw_context, cairo_destroy);
|
|
||||||
priv->draw_context = cr != NULL ? cairo_reference (cr) : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_t *
|
/**
|
||||||
gsk_renderer_get_draw_context (GskRenderer *renderer)
|
* gsk_renderer_get_window:
|
||||||
|
* @renderer: a #GskRenderer
|
||||||
|
*
|
||||||
|
* Retrieves the #GdkWindow set using gsk_renderer_set_window().
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (nullable): a #GdkWindow
|
||||||
|
*
|
||||||
|
* Since: 3.22
|
||||||
|
*/
|
||||||
|
GdkWindow *
|
||||||
|
gsk_renderer_get_window (GskRenderer *renderer)
|
||||||
{
|
{
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
||||||
|
|
||||||
if (priv->draw_context != NULL)
|
return priv->window;
|
||||||
return priv->draw_context;
|
}
|
||||||
|
|
||||||
return cairo_create (gsk_renderer_get_surface (renderer));
|
/*< private >
|
||||||
|
* gsk_renderer_get_root_node:
|
||||||
|
* @renderer: a #GskRenderer
|
||||||
|
*
|
||||||
|
* Retrieves the #GskRenderNode used by @renderer.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (nullable): a #GskRenderNode
|
||||||
|
*/
|
||||||
|
GskRenderNode *
|
||||||
|
gsk_renderer_get_root_node (GskRenderer *renderer)
|
||||||
|
{
|
||||||
|
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
||||||
|
|
||||||
|
return priv->root_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*< private >
|
||||||
|
* gsk_renderer_get_drawing_context:
|
||||||
|
* @renderer: a #GskRenderer
|
||||||
|
*
|
||||||
|
* Retrieves the #GdkDrawingContext used by @renderer.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (nullable): a #GdkDrawingContext
|
||||||
|
*/
|
||||||
|
GdkDrawingContext *
|
||||||
|
gsk_renderer_get_drawing_context (GskRenderer *renderer)
|
||||||
|
{
|
||||||
|
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
||||||
|
|
||||||
|
return priv->drawing_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -947,26 +838,6 @@ gsk_renderer_get_display (GskRenderer *renderer)
|
|||||||
return priv->display;
|
return priv->display;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gsk_renderer_get_root_node:
|
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
*
|
|
||||||
* Retrieves the root node of the scene graph.
|
|
||||||
*
|
|
||||||
* Returns: (transfer none) (nullable): a #GskRenderNode
|
|
||||||
*
|
|
||||||
* Since: 3.22
|
|
||||||
*/
|
|
||||||
GskRenderNode *
|
|
||||||
gsk_renderer_get_root_node (GskRenderer *renderer)
|
|
||||||
{
|
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
|
||||||
|
|
||||||
return priv->root_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
* gsk_renderer_is_realized:
|
* gsk_renderer_is_realized:
|
||||||
* @renderer: a #GskRenderer
|
* @renderer: a #GskRenderer
|
||||||
@ -987,51 +858,6 @@ gsk_renderer_is_realized (GskRenderer *renderer)
|
|||||||
return priv->is_realized;
|
return priv->is_realized;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gsk_renderer_set_window:
|
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
* @window: (nullable): a #GdkWindow
|
|
||||||
*
|
|
||||||
* Sets the #GdkWindow used to create the target rendering surface.
|
|
||||||
*
|
|
||||||
* See also: gsk_renderer_set_surface()
|
|
||||||
*
|
|
||||||
* Since: 3.22
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gsk_renderer_set_window (GskRenderer *renderer,
|
|
||||||
GdkWindow *window)
|
|
||||||
{
|
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_RENDERER (renderer));
|
|
||||||
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
|
|
||||||
g_return_if_fail (!priv->is_realized);
|
|
||||||
|
|
||||||
if (g_set_object (&priv->window, window))
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (renderer), gsk_renderer_properties[PROP_WINDOW]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gsk_renderer_get_window:
|
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
*
|
|
||||||
* Retrieves the #GdkWindow set with gsk_renderer_set_window().
|
|
||||||
*
|
|
||||||
* Returns: (transfer none) (nullable): a #GdkWindow
|
|
||||||
*
|
|
||||||
* Since: 3.22
|
|
||||||
*/
|
|
||||||
GdkWindow *
|
|
||||||
gsk_renderer_get_window (GskRenderer *renderer)
|
|
||||||
{
|
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
|
||||||
|
|
||||||
return priv->window;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_renderer_realize:
|
* gsk_renderer_realize:
|
||||||
* @renderer: a #GskRenderer
|
* @renderer: a #GskRenderer
|
||||||
@ -1051,12 +877,6 @@ gsk_renderer_realize (GskRenderer *renderer)
|
|||||||
if (priv->is_realized)
|
if (priv->is_realized)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (priv->window == NULL && priv->surface == NULL)
|
|
||||||
{
|
|
||||||
g_critical ("No rendering surface has been set.");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->is_realized = GSK_RENDERER_GET_CLASS (renderer)->realize (renderer);
|
priv->is_realized = GSK_RENDERER_GET_CLASS (renderer)->realize (renderer);
|
||||||
|
|
||||||
return priv->is_realized;
|
return priv->is_realized;
|
||||||
@ -1085,156 +905,41 @@ gsk_renderer_unrealize (GskRenderer *renderer)
|
|||||||
priv->is_realized = FALSE;
|
priv->is_realized = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*< private >
|
|
||||||
* gsk_renderer_maybe_resize_viewport:
|
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
*
|
|
||||||
* Optionally resize the viewport of @renderer.
|
|
||||||
*
|
|
||||||
* This function should be called by gsk_renderer_render().
|
|
||||||
*
|
|
||||||
* This function may call @GskRendererClass.resize_viewport().
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gsk_renderer_maybe_resize_viewport (GskRenderer *renderer)
|
|
||||||
{
|
|
||||||
GskRendererClass *renderer_class = GSK_RENDERER_GET_CLASS (renderer);
|
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
|
||||||
|
|
||||||
if (priv->needs_viewport_resize)
|
|
||||||
{
|
|
||||||
renderer_class->resize_viewport (renderer, &priv->viewport);
|
|
||||||
priv->needs_viewport_resize = FALSE;
|
|
||||||
|
|
||||||
GSK_NOTE (RENDERER, g_print ("Viewport size: %g x %g\n",
|
|
||||||
priv->viewport.size.width,
|
|
||||||
priv->viewport.size.height));
|
|
||||||
|
|
||||||
/* If the target surface has been created from a window, we need
|
|
||||||
* to clear it, so that it gets recreated with the right size
|
|
||||||
*/
|
|
||||||
if (priv->window != NULL && priv->surface != NULL)
|
|
||||||
g_clear_pointer (&priv->surface, cairo_surface_destroy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
|
||||||
* gsk_renderer_maybe_update:
|
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
*
|
|
||||||
* Optionally recomputes the modelview-projection matrix used by
|
|
||||||
* the @renderer.
|
|
||||||
*
|
|
||||||
* This function should be called by gsk_renderer_render().
|
|
||||||
*
|
|
||||||
* This function may call @GskRendererClass.update().
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gsk_renderer_maybe_update (GskRenderer *renderer)
|
|
||||||
{
|
|
||||||
GskRendererClass *renderer_class = GSK_RENDERER_GET_CLASS (renderer);
|
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
|
||||||
|
|
||||||
if (priv->needs_modelview_update || priv->needs_projection_update)
|
|
||||||
{
|
|
||||||
renderer_class->update (renderer, &priv->modelview, &priv->projection);
|
|
||||||
priv->needs_modelview_update = FALSE;
|
|
||||||
priv->needs_projection_update = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gsk_renderer_clear_tree (GskRenderer *renderer,
|
|
||||||
GskRenderNode *old_root)
|
|
||||||
{
|
|
||||||
GSK_RENDERER_GET_CLASS (renderer)->clear_tree (renderer, old_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
|
||||||
* gsk_renderer_maybe_validate_tree:
|
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
*
|
|
||||||
* Optionally validates the #GskRenderNode scene graph, and uses it
|
|
||||||
* to generate more efficient intermediate representations depending
|
|
||||||
* on the type of @renderer.
|
|
||||||
*
|
|
||||||
* This function should be called by gsk_renderer_render().
|
|
||||||
*
|
|
||||||
* This function may call @GskRendererClas.validate_tree().
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gsk_renderer_maybe_validate_tree (GskRenderer *renderer)
|
|
||||||
{
|
|
||||||
GskRendererClass *renderer_class = GSK_RENDERER_GET_CLASS (renderer);
|
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
|
||||||
|
|
||||||
if (priv->root_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Ensure that the render nodes are valid; this will change the
|
|
||||||
* needs_tree_validation flag on the renderer, if needed
|
|
||||||
*/
|
|
||||||
gsk_render_node_validate (priv->root_node);
|
|
||||||
|
|
||||||
if (priv->needs_tree_validation)
|
|
||||||
{
|
|
||||||
/* Ensure that the Renderer can update itself */
|
|
||||||
renderer_class->validate_tree (renderer, priv->root_node);
|
|
||||||
priv->needs_tree_validation = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
|
||||||
* gsk_renderer_maybe_clear:
|
|
||||||
* @renderer: a #GskRenderer
|
|
||||||
*
|
|
||||||
* Optionally calls @GskRendererClass.clear(), depending on the value
|
|
||||||
* of #GskRenderer:auto-clear.
|
|
||||||
*
|
|
||||||
* This function should be called by gsk_renderer_render().
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gsk_renderer_maybe_clear (GskRenderer *renderer)
|
|
||||||
{
|
|
||||||
GskRendererClass *renderer_class = GSK_RENDERER_GET_CLASS (renderer);
|
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
|
||||||
|
|
||||||
if (priv->auto_clear)
|
|
||||||
renderer_class->clear (renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_renderer_render:
|
* gsk_renderer_render:
|
||||||
* @renderer: a #GskRenderer
|
* @renderer: a #GskRenderer
|
||||||
|
* @root: a #GskRenderNode
|
||||||
|
* @context: a #GdkDrawingContext
|
||||||
*
|
*
|
||||||
* Renders the scene graph associated to @renderer, using the
|
* Renders the scene graph, described by a tree of #GskRenderNode instances,
|
||||||
* given target surface.
|
* using the given #GdkDrawingContext.
|
||||||
|
*
|
||||||
|
* The @renderer will acquire a reference on the #GskRenderNode tree while
|
||||||
|
* the rendering is in progress, and will make the tree immutable.
|
||||||
*
|
*
|
||||||
* Since: 3.22
|
* Since: 3.22
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gsk_renderer_render (GskRenderer *renderer)
|
gsk_renderer_render (GskRenderer *renderer,
|
||||||
|
GskRenderNode *root,
|
||||||
|
GdkDrawingContext *context)
|
||||||
{
|
{
|
||||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_RENDERER (renderer));
|
g_return_if_fail (GSK_IS_RENDERER (renderer));
|
||||||
g_return_if_fail (priv->is_realized);
|
g_return_if_fail (priv->is_realized);
|
||||||
g_return_if_fail (priv->root_node != NULL);
|
g_return_if_fail (GSK_IS_RENDER_NODE (root));
|
||||||
|
g_return_if_fail (GDK_IS_DRAWING_CONTEXT (context));
|
||||||
|
|
||||||
/* We need to update the viewport and the modelview, to allow renderers
|
g_set_object (&priv->root_node, root);
|
||||||
* to update their clip region and/or frustum; this allows them to cull
|
g_set_object (&priv->drawing_context, context);
|
||||||
* render nodes in the tree validation phase
|
|
||||||
*/
|
|
||||||
gsk_renderer_maybe_resize_viewport (renderer);
|
|
||||||
|
|
||||||
gsk_renderer_maybe_update (renderer);
|
gsk_render_node_make_immutable (root);
|
||||||
|
|
||||||
gsk_renderer_maybe_validate_tree (renderer);
|
GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root, context);
|
||||||
|
|
||||||
/* Clear the output surface */
|
g_clear_object (&priv->root_node);
|
||||||
gsk_renderer_maybe_clear (renderer);
|
g_clear_object (&priv->drawing_context);
|
||||||
|
|
||||||
GSK_RENDERER_GET_CLASS (renderer)->render (renderer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1345,7 +1050,7 @@ gsk_renderer_get_use_alpha (GskRenderer *renderer)
|
|||||||
*
|
*
|
||||||
* Creates an appropriate #GskRenderer instance for the given @display.
|
* Creates an appropriate #GskRenderer instance for the given @display.
|
||||||
*
|
*
|
||||||
* Returns: (transfer full): a #GskRenderer
|
* Returns: (transfer full) (nullable): a #GskRenderer
|
||||||
*
|
*
|
||||||
* Since: 3.22
|
* Since: 3.22
|
||||||
*/
|
*/
|
||||||
@ -1364,10 +1069,7 @@ gsk_renderer_get_for_display (GdkDisplay *display)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (use_software[0] != '0')
|
if (use_software[0] != '0')
|
||||||
{
|
return NULL;
|
||||||
renderer_type = GSK_TYPE_CAIRO_RENDERER;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
if (GDK_IS_X11_DISPLAY (display))
|
if (GDK_IS_X11_DISPLAY (display))
|
||||||
@ -1377,9 +1079,9 @@ gsk_renderer_get_for_display (GdkDisplay *display)
|
|||||||
#ifdef GDK_WINDOWING_WAYLAND
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
if (GDK_IS_WAYLAND_DISPLAY (display))
|
if (GDK_IS_WAYLAND_DISPLAY (display))
|
||||||
renderer_type = GSK_TYPE_GL_RENDERER;
|
renderer_type = GSK_TYPE_GL_RENDERER;
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
renderer_type = GSK_TYPE_CAIRO_RENDERER;
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
GSK_NOTE (RENDERER, g_print ("Creating renderer of type '%s' for display '%s'\n",
|
GSK_NOTE (RENDERER, g_print ("Creating renderer of type '%s' for display '%s'\n",
|
||||||
g_type_name (renderer_type),
|
g_type_name (renderer_type),
|
||||||
@ -1387,6 +1089,5 @@ gsk_renderer_get_for_display (GdkDisplay *display)
|
|||||||
|
|
||||||
g_assert (renderer_type != G_TYPE_INVALID);
|
g_assert (renderer_type != G_TYPE_INVALID);
|
||||||
|
|
||||||
out:
|
|
||||||
return g_object_new (renderer_type, "display", display, NULL);
|
return g_object_new (renderer_type, "display", display, NULL);
|
||||||
}
|
}
|
||||||
|
@ -69,44 +69,37 @@ void gsk_renderer_get_scaling_filters (GskRenderer
|
|||||||
GskScalingFilter *min_filter,
|
GskScalingFilter *min_filter,
|
||||||
GskScalingFilter *mag_filter);
|
GskScalingFilter *mag_filter);
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
|
void gsk_renderer_set_scale_factor (GskRenderer *renderer,
|
||||||
|
int scale_factor);
|
||||||
|
GDK_AVAILABLE_IN_3_22
|
||||||
|
int gsk_renderer_get_scale_factor (GskRenderer *renderer);
|
||||||
|
GDK_AVAILABLE_IN_3_22
|
||||||
void gsk_renderer_set_auto_clear (GskRenderer *renderer,
|
void gsk_renderer_set_auto_clear (GskRenderer *renderer,
|
||||||
gboolean clear);
|
gboolean clear);
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
gboolean gsk_renderer_get_auto_clear (GskRenderer *renderer);
|
gboolean gsk_renderer_get_auto_clear (GskRenderer *renderer);
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
void gsk_renderer_set_root_node (GskRenderer *renderer,
|
void gsk_renderer_set_use_alpha (GskRenderer *renderer,
|
||||||
GskRenderNode *root);
|
gboolean use_alpha);
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
GskRenderNode * gsk_renderer_get_root_node (GskRenderer *renderer);
|
gboolean gsk_renderer_get_use_alpha (GskRenderer *renderer);
|
||||||
GDK_AVAILABLE_IN_3_22
|
|
||||||
void gsk_renderer_set_surface (GskRenderer *renderer,
|
|
||||||
cairo_surface_t *surface);
|
|
||||||
GDK_AVAILABLE_IN_3_22
|
|
||||||
cairo_surface_t * gsk_renderer_get_surface (GskRenderer *renderer);
|
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
void gsk_renderer_set_window (GskRenderer *renderer,
|
void gsk_renderer_set_window (GskRenderer *renderer,
|
||||||
GdkWindow *window);
|
GdkWindow *window);
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
GdkWindow * gsk_renderer_get_window (GskRenderer *renderer);
|
GdkWindow * gsk_renderer_get_window (GskRenderer *renderer);
|
||||||
GDK_AVAILABLE_IN_3_22
|
|
||||||
void gsk_renderer_set_draw_context (GskRenderer *renderer,
|
|
||||||
cairo_t *cr);
|
|
||||||
GDK_AVAILABLE_IN_3_22
|
|
||||||
cairo_t * gsk_renderer_get_draw_context (GskRenderer *renderer);
|
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
GdkDisplay * gsk_renderer_get_display (GskRenderer *renderer);
|
GdkDisplay * gsk_renderer_get_display (GskRenderer *renderer);
|
||||||
GDK_AVAILABLE_IN_3_22
|
|
||||||
void gsk_renderer_set_use_alpha (GskRenderer *renderer,
|
|
||||||
gboolean use_alpha);
|
|
||||||
GDK_AVAILABLE_IN_3_22
|
|
||||||
gboolean gsk_renderer_get_use_alpha (GskRenderer *renderer);
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
gboolean gsk_renderer_realize (GskRenderer *renderer);
|
gboolean gsk_renderer_realize (GskRenderer *renderer);
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
void gsk_renderer_unrealize (GskRenderer *renderer);
|
void gsk_renderer_unrealize (GskRenderer *renderer);
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
void gsk_renderer_render (GskRenderer *renderer);
|
void gsk_renderer_render (GskRenderer *renderer,
|
||||||
|
GskRenderNode *root,
|
||||||
|
GdkDrawingContext *context);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -39,28 +39,15 @@ struct _GskRendererClass
|
|||||||
gboolean (* realize) (GskRenderer *renderer);
|
gboolean (* realize) (GskRenderer *renderer);
|
||||||
void (* unrealize) (GskRenderer *renderer);
|
void (* unrealize) (GskRenderer *renderer);
|
||||||
|
|
||||||
void (* resize_viewport) (GskRenderer *renderer,
|
void (* render) (GskRenderer *renderer,
|
||||||
const graphene_rect_t *viewport);
|
GskRenderNode *root,
|
||||||
void (* update) (GskRenderer *renderer,
|
GdkDrawingContext *context);
|
||||||
const graphene_matrix_t *modelview,
|
|
||||||
const graphene_matrix_t *projection);
|
|
||||||
void (* validate_tree) (GskRenderer *renderer,
|
|
||||||
GskRenderNode *root);
|
|
||||||
void (* clear_tree) (GskRenderer *renderer,
|
|
||||||
GskRenderNode *old_root);
|
|
||||||
void (* clear) (GskRenderer *renderer);
|
|
||||||
void (* render) (GskRenderer *renderer);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gboolean gsk_renderer_is_realized (GskRenderer *renderer);
|
gboolean gsk_renderer_is_realized (GskRenderer *renderer);
|
||||||
|
|
||||||
void gsk_renderer_clear_tree (GskRenderer *renderer,
|
GskRenderNode * gsk_renderer_get_root_node (GskRenderer *renderer);
|
||||||
GskRenderNode *old_root);
|
GdkDrawingContext * gsk_renderer_get_drawing_context (GskRenderer *renderer);
|
||||||
|
|
||||||
void gsk_renderer_maybe_resize_viewport (GskRenderer *renderer);
|
|
||||||
void gsk_renderer_maybe_update (GskRenderer *renderer);
|
|
||||||
void gsk_renderer_maybe_validate_tree (GskRenderer *renderer);
|
|
||||||
void gsk_renderer_maybe_clear (GskRenderer *renderer);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -41,8 +41,6 @@ gsk_render_node_dispose (GObject *gobject)
|
|||||||
GskRenderNode *self = GSK_RENDER_NODE (gobject);
|
GskRenderNode *self = GSK_RENDER_NODE (gobject);
|
||||||
GskRenderNodeIter iter;
|
GskRenderNodeIter iter;
|
||||||
|
|
||||||
gsk_render_node_set_invalidate_func (self, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
gsk_render_node_iter_init (&iter, self);
|
gsk_render_node_iter_init (&iter, self);
|
||||||
while (gsk_render_node_iter_next (&iter, NULL))
|
while (gsk_render_node_iter_next (&iter, NULL))
|
||||||
gsk_render_node_iter_remove (&iter);
|
gsk_render_node_iter_remove (&iter);
|
||||||
@ -50,19 +48,12 @@ gsk_render_node_dispose (GObject *gobject)
|
|||||||
G_OBJECT_CLASS (gsk_render_node_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (gsk_render_node_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gsk_render_node_real_resize (GskRenderNode *node)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_render_node_class_init (GskRenderNodeClass *klass)
|
gsk_render_node_class_init (GskRenderNodeClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
gobject_class->dispose = gsk_render_node_dispose;
|
gobject_class->dispose = gsk_render_node_dispose;
|
||||||
|
|
||||||
klass->resize = gsk_render_node_real_resize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -74,6 +65,8 @@ gsk_render_node_init (GskRenderNode *self)
|
|||||||
graphene_matrix_init_identity (&self->child_transform);
|
graphene_matrix_init_identity (&self->child_transform);
|
||||||
|
|
||||||
self->opacity = 1.0;
|
self->opacity = 1.0;
|
||||||
|
|
||||||
|
self->is_mutable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,6 +197,13 @@ gsk_render_node_insert_child_internal (GskRenderNode *node,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!node->is_mutable)
|
||||||
|
{
|
||||||
|
g_critical ("The render node of type '%s' is immutable.",
|
||||||
|
G_OBJECT_TYPE_NAME (node));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
insert_func (node, child, insert_func_data);
|
insert_func (node, child, insert_func_data);
|
||||||
|
|
||||||
g_object_ref (child);
|
g_object_ref (child);
|
||||||
@ -216,21 +216,6 @@ gsk_render_node_insert_child_internal (GskRenderNode *node,
|
|||||||
node->age += 1;
|
node->age += 1;
|
||||||
node->needs_world_matrix_update = TRUE;
|
node->needs_world_matrix_update = TRUE;
|
||||||
|
|
||||||
/* Transfer invalidated children to the current top-level */
|
|
||||||
if (child->invalidated_descendants != NULL)
|
|
||||||
{
|
|
||||||
if (node->parent == NULL)
|
|
||||||
node->invalidated_descendants = child->invalidated_descendants;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GskRenderNode *tmp = gsk_render_node_get_toplevel (node);
|
|
||||||
|
|
||||||
tmp->invalidated_descendants = child->invalidated_descendants;
|
|
||||||
}
|
|
||||||
|
|
||||||
child->invalidated_descendants = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (child->prev_sibling == NULL)
|
if (child->prev_sibling == NULL)
|
||||||
node->first_child = child;
|
node->first_child = child;
|
||||||
if (child->next_sibling == NULL)
|
if (child->next_sibling == NULL)
|
||||||
@ -296,6 +281,62 @@ insert_child_at_pos (GskRenderNode *node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_render_node_append_child:
|
||||||
|
* @node: a #GskRenderNode
|
||||||
|
* @child: a #GskRenderNode
|
||||||
|
*
|
||||||
|
* Appends @child to the list of children of @node.
|
||||||
|
*
|
||||||
|
* This function acquires a reference on @child.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): the #GskRenderNode
|
||||||
|
*
|
||||||
|
* Since: 3.22
|
||||||
|
*/
|
||||||
|
GskRenderNode *
|
||||||
|
gsk_render_node_append_child (GskRenderNode *node,
|
||||||
|
GskRenderNode *child)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
||||||
|
g_return_val_if_fail (node->is_mutable, node);
|
||||||
|
|
||||||
|
gsk_render_node_insert_child_internal (node, child,
|
||||||
|
insert_child_at_pos,
|
||||||
|
GINT_TO_POINTER (node->n_children));
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_render_node_prepend_child:
|
||||||
|
* @node: a #GskRenderNode
|
||||||
|
* @child: a #GskRenderNode
|
||||||
|
*
|
||||||
|
* Prepends @child to the list of children of @node.
|
||||||
|
*
|
||||||
|
* This function acquires a reference on @child.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): the #GskRenderNode
|
||||||
|
*
|
||||||
|
* Since: 3.22
|
||||||
|
*/
|
||||||
|
GskRenderNode *
|
||||||
|
gsk_render_node_prepend_child (GskRenderNode *node,
|
||||||
|
GskRenderNode *child)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
||||||
|
g_return_val_if_fail (node->is_mutable, node);
|
||||||
|
|
||||||
|
gsk_render_node_insert_child_internal (node, child,
|
||||||
|
insert_child_at_pos,
|
||||||
|
GINT_TO_POINTER (0));
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_render_node_insert_child_at_pos:
|
* gsk_render_node_insert_child_at_pos:
|
||||||
* @node: a #GskRenderNode
|
* @node: a #GskRenderNode
|
||||||
@ -322,6 +363,7 @@ gsk_render_node_insert_child_at_pos (GskRenderNode *node,
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
||||||
|
g_return_val_if_fail (node->is_mutable, node);
|
||||||
|
|
||||||
gsk_render_node_insert_child_internal (node, child,
|
gsk_render_node_insert_child_internal (node, child,
|
||||||
insert_child_at_pos,
|
insert_child_at_pos,
|
||||||
@ -382,6 +424,7 @@ gsk_render_node_insert_child_before (GskRenderNode *node,
|
|||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
||||||
g_return_val_if_fail (sibling == NULL || GSK_IS_RENDER_NODE (sibling), node);
|
g_return_val_if_fail (sibling == NULL || GSK_IS_RENDER_NODE (sibling), node);
|
||||||
|
g_return_val_if_fail (node->is_mutable, node);
|
||||||
|
|
||||||
gsk_render_node_insert_child_internal (node, child, insert_child_before, sibling);
|
gsk_render_node_insert_child_internal (node, child, insert_child_before, sibling);
|
||||||
|
|
||||||
@ -440,6 +483,7 @@ gsk_render_node_insert_child_after (GskRenderNode *node,
|
|||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
||||||
g_return_val_if_fail (sibling == NULL || GSK_IS_RENDER_NODE (sibling), node);
|
g_return_val_if_fail (sibling == NULL || GSK_IS_RENDER_NODE (sibling), node);
|
||||||
|
g_return_val_if_fail (node->is_mutable, node);
|
||||||
|
|
||||||
if (sibling != NULL)
|
if (sibling != NULL)
|
||||||
g_return_val_if_fail (sibling->parent == node, node);
|
g_return_val_if_fail (sibling->parent == node, node);
|
||||||
@ -500,6 +544,8 @@ gsk_render_node_replace_child (GskRenderNode *node,
|
|||||||
g_return_val_if_fail (new_child->parent == NULL, node);
|
g_return_val_if_fail (new_child->parent == NULL, node);
|
||||||
g_return_val_if_fail (old_child->parent == node, node);
|
g_return_val_if_fail (old_child->parent == node, node);
|
||||||
|
|
||||||
|
g_return_val_if_fail (node->is_mutable, node);
|
||||||
|
|
||||||
clos.prev_sibling = old_child->prev_sibling;
|
clos.prev_sibling = old_child->prev_sibling;
|
||||||
clos.next_sibling = old_child->next_sibling;
|
clos.next_sibling = old_child->next_sibling;
|
||||||
gsk_render_node_remove_child (node, old_child);
|
gsk_render_node_remove_child (node, old_child);
|
||||||
@ -529,6 +575,7 @@ gsk_render_node_remove_child (GskRenderNode *node,
|
|||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
|
||||||
|
g_return_val_if_fail (node->is_mutable, node);
|
||||||
|
|
||||||
if (child->parent != node)
|
if (child->parent != node)
|
||||||
{
|
{
|
||||||
@ -582,6 +629,7 @@ gsk_render_node_remove_all_children (GskRenderNode *node)
|
|||||||
GskRenderNodeIter iter;
|
GskRenderNodeIter iter;
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||||
|
g_return_val_if_fail (node->is_mutable, node);
|
||||||
|
|
||||||
if (node->n_children == 0)
|
if (node->n_children == 0)
|
||||||
return node;
|
return node;
|
||||||
@ -631,13 +679,12 @@ gsk_render_node_set_bounds (GskRenderNode *node,
|
|||||||
const graphene_rect_t *bounds)
|
const graphene_rect_t *bounds)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||||
|
g_return_if_fail (node->is_mutable);
|
||||||
|
|
||||||
if (bounds == NULL)
|
if (bounds == NULL)
|
||||||
graphene_rect_init_from_rect (&node->bounds, graphene_rect_zero ());
|
graphene_rect_init_from_rect (&node->bounds, graphene_rect_zero ());
|
||||||
else
|
else
|
||||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||||
|
|
||||||
gsk_render_node_queue_invalidate (node, GSK_RENDER_NODE_CHANGES_UPDATE_BOUNDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -673,6 +720,7 @@ gsk_render_node_set_transform (GskRenderNode *node,
|
|||||||
const graphene_matrix_t *transform)
|
const graphene_matrix_t *transform)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||||
|
g_return_if_fail (node->is_mutable);
|
||||||
|
|
||||||
if (transform == NULL)
|
if (transform == NULL)
|
||||||
graphene_matrix_init_identity (&node->transform);
|
graphene_matrix_init_identity (&node->transform);
|
||||||
@ -680,7 +728,6 @@ gsk_render_node_set_transform (GskRenderNode *node,
|
|||||||
graphene_matrix_init_from_matrix (&node->transform, transform);
|
graphene_matrix_init_from_matrix (&node->transform, transform);
|
||||||
|
|
||||||
node->transform_set = !graphene_matrix_is_identity (&node->transform);
|
node->transform_set = !graphene_matrix_is_identity (&node->transform);
|
||||||
gsk_render_node_queue_invalidate (node, GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -697,10 +744,8 @@ void
|
|||||||
gsk_render_node_set_child_transform (GskRenderNode *node,
|
gsk_render_node_set_child_transform (GskRenderNode *node,
|
||||||
const graphene_matrix_t *transform)
|
const graphene_matrix_t *transform)
|
||||||
{
|
{
|
||||||
GskRenderNodeIter iter;
|
|
||||||
GskRenderNode *child;
|
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||||
|
g_return_if_fail (node->is_mutable);
|
||||||
|
|
||||||
if (transform == NULL)
|
if (transform == NULL)
|
||||||
graphene_matrix_init_identity (&node->child_transform);
|
graphene_matrix_init_identity (&node->child_transform);
|
||||||
@ -708,11 +753,6 @@ gsk_render_node_set_child_transform (GskRenderNode *node,
|
|||||||
graphene_matrix_init_from_matrix (&node->child_transform, transform);
|
graphene_matrix_init_from_matrix (&node->child_transform, transform);
|
||||||
|
|
||||||
node->child_transform_set = !graphene_matrix_is_identity (&node->child_transform);
|
node->child_transform_set = !graphene_matrix_is_identity (&node->child_transform);
|
||||||
|
|
||||||
/* We need to invalidate the world matrix for our children */
|
|
||||||
gsk_render_node_iter_init (&iter, node);
|
|
||||||
while (gsk_render_node_iter_next (&iter, &child))
|
|
||||||
gsk_render_node_queue_invalidate (child, GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -730,10 +770,9 @@ gsk_render_node_set_opacity (GskRenderNode *node,
|
|||||||
double opacity)
|
double opacity)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||||
|
g_return_if_fail (node->is_mutable);
|
||||||
|
|
||||||
node->opacity = CLAMP (opacity, 0.0, 1.0);
|
node->opacity = CLAMP (opacity, 0.0, 1.0);
|
||||||
|
|
||||||
gsk_render_node_queue_invalidate (node, GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -770,10 +809,9 @@ gsk_render_node_set_hidden (GskRenderNode *node,
|
|||||||
gboolean hidden)
|
gboolean hidden)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||||
|
g_return_if_fail (node->is_mutable);
|
||||||
|
|
||||||
node->hidden = !!hidden;
|
node->hidden = !!hidden;
|
||||||
|
|
||||||
gsk_render_node_queue_invalidate (node, GSK_RENDER_NODE_CHANGES_UPDATE_VISIBILITY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -813,10 +851,9 @@ gsk_render_node_set_opaque (GskRenderNode *node,
|
|||||||
gboolean opaque)
|
gboolean opaque)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||||
|
g_return_if_fail (node->is_mutable);
|
||||||
|
|
||||||
node->opaque = !!opaque;
|
node->opaque = !!opaque;
|
||||||
|
|
||||||
gsk_render_node_queue_invalidate (node, GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -865,31 +902,6 @@ gsk_render_node_contains (GskRenderNode *node,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gsk_render_node_set_surface:
|
|
||||||
* @node: a #GskRenderNode
|
|
||||||
* @surface: (nullable): a Cairo surface
|
|
||||||
*
|
|
||||||
* Sets the contents of the #GskRenderNode.
|
|
||||||
*
|
|
||||||
* The @node will acquire a reference on the given @surface.
|
|
||||||
*
|
|
||||||
* Since: 3.22
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gsk_render_node_set_surface (GskRenderNode *node,
|
|
||||||
cairo_surface_t *surface)
|
|
||||||
{
|
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
|
||||||
|
|
||||||
g_clear_pointer (&node->surface, cairo_surface_destroy);
|
|
||||||
|
|
||||||
if (surface != NULL)
|
|
||||||
node->surface = cairo_surface_reference (surface);
|
|
||||||
|
|
||||||
gsk_render_node_queue_invalidate (node, GSK_RENDER_NODE_CHANGES_UPDATE_SURFACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
* gsk_render_node_get_toplevel:
|
* gsk_render_node_get_toplevel:
|
||||||
* @node: a #GskRenderNode
|
* @node: a #GskRenderNode
|
||||||
@ -1014,168 +1026,6 @@ gsk_render_node_get_world_matrix (GskRenderNode *node,
|
|||||||
*mv = node->world_matrix;
|
*mv = node->world_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
gsk_render_node_set_invalidate_func (GskRenderNode *node,
|
|
||||||
GskRenderNodeInvalidateFunc invalidate_func,
|
|
||||||
gpointer func_data,
|
|
||||||
GDestroyNotify destroy_func_data)
|
|
||||||
{
|
|
||||||
if (node->parent != NULL)
|
|
||||||
{
|
|
||||||
g_critical ("Render node of type '%s' is not a root node. Only root "
|
|
||||||
"nodes can have an invalidation function.",
|
|
||||||
G_OBJECT_TYPE_NAME (node));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->invalidate_func != NULL)
|
|
||||||
{
|
|
||||||
if (node->destroy_func_data != NULL)
|
|
||||||
node->destroy_func_data (node->func_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
node->invalidate_func = invalidate_func;
|
|
||||||
node->func_data = func_data;
|
|
||||||
node->destroy_func_data = destroy_func_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
GskRenderNodeChanges
|
|
||||||
gsk_render_node_get_current_state (GskRenderNode *node)
|
|
||||||
{
|
|
||||||
GskRenderNodeChanges res = 0;
|
|
||||||
|
|
||||||
if (node->needs_resize)
|
|
||||||
res |= GSK_RENDER_NODE_CHANGES_UPDATE_BOUNDS;
|
|
||||||
if (node->needs_world_matrix_update)
|
|
||||||
res |= GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM;
|
|
||||||
if (node->needs_content_update)
|
|
||||||
res |= GSK_RENDER_NODE_CHANGES_UPDATE_SURFACE;
|
|
||||||
if (node->needs_opacity_update)
|
|
||||||
res |= GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY;
|
|
||||||
if (node->needs_visibility_update)
|
|
||||||
res |= GSK_RENDER_NODE_CHANGES_UPDATE_VISIBILITY;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
GskRenderNodeChanges
|
|
||||||
gsk_render_node_get_last_state (GskRenderNode *node)
|
|
||||||
{
|
|
||||||
return node->last_state_change;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gsk_render_node_queue_invalidate (GskRenderNode *node,
|
|
||||||
GskRenderNodeChanges changes)
|
|
||||||
{
|
|
||||||
GskRenderNodeChanges cur_invalidated_bits = 0;
|
|
||||||
GskRenderNode *root;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
cur_invalidated_bits = gsk_render_node_get_current_state (node);
|
|
||||||
if ((cur_invalidated_bits & changes) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
node->needs_resize = (changes & GSK_RENDER_NODE_CHANGES_UPDATE_BOUNDS) != 0;
|
|
||||||
node->needs_world_matrix_update = (changes & GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM) != 0;
|
|
||||||
node->needs_content_update = (changes & GSK_RENDER_NODE_CHANGES_UPDATE_SURFACE) != 0;
|
|
||||||
node->needs_opacity_update = (changes & GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY) != 0;
|
|
||||||
node->needs_visibility_update = (changes & GSK_RENDER_NODE_CHANGES_UPDATE_VISIBILITY) != 0;
|
|
||||||
|
|
||||||
if (node->parent == NULL)
|
|
||||||
{
|
|
||||||
GSK_NOTE (RENDER_NODE, g_print ("Invalid node [%p] is top-level\n", node));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
root = gsk_render_node_get_toplevel (node);
|
|
||||||
|
|
||||||
if (root->invalidated_descendants == NULL)
|
|
||||||
root->invalidated_descendants = g_ptr_array_new ();
|
|
||||||
|
|
||||||
for (i = 0; i < root->invalidated_descendants->len; i++)
|
|
||||||
{
|
|
||||||
if (node == g_ptr_array_index (root->invalidated_descendants, i))
|
|
||||||
{
|
|
||||||
GSK_NOTE (RENDER_NODE, g_print ("Node [%p] already invalidated; skipping...\n", node));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GSK_NOTE (RENDER_NODE, g_print ("Adding node [%p] to list of invalid descendants of [%p]\n", node, root));
|
|
||||||
g_ptr_array_add (root->invalidated_descendants, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gsk_render_node_validate (GskRenderNode *node)
|
|
||||||
{
|
|
||||||
GPtrArray *invalidated_descendants;
|
|
||||||
gboolean call_invalidate_func;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
node->last_state_change = gsk_render_node_get_current_state (node);
|
|
||||||
|
|
||||||
/* We call the invalidation function if our state changed, or if
|
|
||||||
* the descendants state has changed
|
|
||||||
*/
|
|
||||||
call_invalidate_func = node->last_state_change != 0 ||
|
|
||||||
node->invalidated_descendants != NULL;
|
|
||||||
|
|
||||||
gsk_render_node_maybe_resize (node);
|
|
||||||
gsk_render_node_update_world_matrix (node, FALSE);
|
|
||||||
node->needs_content_update = FALSE;
|
|
||||||
node->needs_visibility_update = FALSE;
|
|
||||||
node->needs_opacity_update = FALSE;
|
|
||||||
|
|
||||||
/* Steal the array of invalidated descendants, so that changes caused by
|
|
||||||
* the validation will not cause recursions
|
|
||||||
*/
|
|
||||||
invalidated_descendants = node->invalidated_descendants;
|
|
||||||
node->invalidated_descendants = NULL;
|
|
||||||
|
|
||||||
if (invalidated_descendants != NULL)
|
|
||||||
{
|
|
||||||
for (i = 0; i < invalidated_descendants->len; i++)
|
|
||||||
{
|
|
||||||
GskRenderNode *child = g_ptr_array_index (invalidated_descendants, i);
|
|
||||||
|
|
||||||
child->last_state_change = 0;
|
|
||||||
|
|
||||||
GSK_NOTE (RENDER_NODE, g_print ("Validating descendant node [%p] (resize:%s, transform:%s)\n",
|
|
||||||
child,
|
|
||||||
child->needs_resize ? "yes" : "no",
|
|
||||||
child->needs_world_matrix_update ? "yes" : "no"));
|
|
||||||
|
|
||||||
child->last_state_change = gsk_render_node_get_current_state (child);
|
|
||||||
|
|
||||||
gsk_render_node_maybe_resize (child);
|
|
||||||
gsk_render_node_update_world_matrix (child, FALSE);
|
|
||||||
|
|
||||||
child->needs_content_update = FALSE;
|
|
||||||
child->needs_visibility_update = FALSE;
|
|
||||||
child->needs_opacity_update = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_clear_pointer (&invalidated_descendants, g_ptr_array_unref);
|
|
||||||
|
|
||||||
if (call_invalidate_func && node->invalidate_func != NULL)
|
|
||||||
node->invalidate_func (node, node->func_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gsk_render_node_maybe_resize (GskRenderNode *node)
|
|
||||||
{
|
|
||||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
|
||||||
|
|
||||||
if (!node->needs_resize)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GSK_RENDER_NODE_GET_CLASS (node)->resize (node);
|
|
||||||
|
|
||||||
node->needs_resize = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_render_node_set_name:
|
* gsk_render_node_set_name:
|
||||||
* @node: a #GskRenderNode
|
* @node: a #GskRenderNode
|
||||||
@ -1197,23 +1047,12 @@ gsk_render_node_set_name (GskRenderNode *node,
|
|||||||
node->name = g_strdup (name);
|
node->name = g_strdup (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_user_data_key_t render_node_context_key;
|
|
||||||
|
|
||||||
static void
|
|
||||||
surface_invalidate (void *data)
|
|
||||||
{
|
|
||||||
GskRenderNode *node = data;
|
|
||||||
|
|
||||||
gsk_render_node_queue_invalidate (node, GSK_RENDER_NODE_CHANGES_UPDATE_SURFACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_render_node_get_draw_context:
|
* gsk_render_node_get_draw_context:
|
||||||
* @node: a #GskRenderNode
|
* @node: a #GskRenderNode
|
||||||
*
|
*
|
||||||
* Creates a Cairo context for drawing using the surface associated
|
* Creates a Cairo context for drawing using the surface associated
|
||||||
* to the render node. If no surface has been attached to the render
|
* to the render node.
|
||||||
* node, a new surface will be created as a side effect.
|
|
||||||
*
|
*
|
||||||
* Returns: (transfer full): a Cairo context used for drawing; use
|
* Returns: (transfer full): a Cairo context used for drawing; use
|
||||||
* cairo_destroy() when done drawing
|
* cairo_destroy() when done drawing
|
||||||
@ -1226,6 +1065,7 @@ gsk_render_node_get_draw_context (GskRenderNode *node)
|
|||||||
cairo_t *res;
|
cairo_t *res;
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||||
|
g_return_val_if_fail (node->is_mutable, NULL);
|
||||||
|
|
||||||
if (node->surface == NULL)
|
if (node->surface == NULL)
|
||||||
node->surface = cairo_image_surface_create (node->opaque ? CAIRO_FORMAT_RGB24
|
node->surface = cairo_image_surface_create (node->opaque ? CAIRO_FORMAT_RGB24
|
||||||
@ -1240,7 +1080,21 @@ gsk_render_node_get_draw_context (GskRenderNode *node)
|
|||||||
node->bounds.size.width, node->bounds.size.height);
|
node->bounds.size.width, node->bounds.size.height);
|
||||||
cairo_clip (res);
|
cairo_clip (res);
|
||||||
|
|
||||||
cairo_set_user_data (res, &render_node_context_key, node, surface_invalidate);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsk_render_node_make_immutable (GskRenderNode *node)
|
||||||
|
{
|
||||||
|
GskRenderNodeIter iter;
|
||||||
|
GskRenderNode *child;
|
||||||
|
|
||||||
|
if (!node->is_mutable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node->is_mutable = FALSE;
|
||||||
|
|
||||||
|
gsk_render_node_iter_init (&iter, node);
|
||||||
|
while (gsk_render_node_iter_next (&iter, &child))
|
||||||
|
gsk_render_node_make_immutable (child);
|
||||||
|
}
|
||||||
|
@ -52,6 +52,12 @@ GskRenderNode * gsk_render_node_get_next_sibling (GskRenderNode *
|
|||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
GskRenderNode * gsk_render_node_get_previous_sibling (GskRenderNode *node);
|
GskRenderNode * gsk_render_node_get_previous_sibling (GskRenderNode *node);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_22
|
||||||
|
GskRenderNode * gsk_render_node_append_child (GskRenderNode *node,
|
||||||
|
GskRenderNode *child);
|
||||||
|
GDK_AVAILABLE_IN_3_22
|
||||||
|
GskRenderNode * gsk_render_node_prepend_child (GskRenderNode *node,
|
||||||
|
GskRenderNode *child);
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
GskRenderNode * gsk_render_node_insert_child_at_pos (GskRenderNode *node,
|
GskRenderNode * gsk_render_node_insert_child_at_pos (GskRenderNode *node,
|
||||||
GskRenderNode *child,
|
GskRenderNode *child,
|
||||||
@ -103,9 +109,6 @@ void gsk_render_node_set_opaque (GskRenderNode *
|
|||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
gboolean gsk_render_node_is_opaque (GskRenderNode *node);
|
gboolean gsk_render_node_is_opaque (GskRenderNode *node);
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
void gsk_render_node_set_surface (GskRenderNode *node,
|
|
||||||
cairo_surface_t *surface);
|
|
||||||
GDK_AVAILABLE_IN_3_22
|
|
||||||
cairo_t * gsk_render_node_get_draw_context (GskRenderNode *node);
|
cairo_t * gsk_render_node_get_draw_context (GskRenderNode *node);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_3_22
|
GDK_AVAILABLE_IN_3_22
|
||||||
|
@ -10,18 +10,6 @@ G_BEGIN_DECLS
|
|||||||
#define GSK_IS_RENDER_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_RENDER_NODE))
|
#define GSK_IS_RENDER_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_RENDER_NODE))
|
||||||
#define GSK_RENDER_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_RENDER_NODE, GskRenderNodeClass))
|
#define GSK_RENDER_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_RENDER_NODE, GskRenderNodeClass))
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GSK_RENDER_NODE_CHANGES_UPDATE_BOUNDS = 1 << 0,
|
|
||||||
GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM = 1 << 1,
|
|
||||||
GSK_RENDER_NODE_CHANGES_UPDATE_SURFACE = 1 << 2,
|
|
||||||
GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY = 1 << 3,
|
|
||||||
GSK_RENDER_NODE_CHANGES_UPDATE_VISIBILITY = 1 << 4,
|
|
||||||
GSK_RENDER_NODE_CHANEGS_UPDATE_HIERARCHY = 1 << 5
|
|
||||||
} GskRenderNodeChanges;
|
|
||||||
|
|
||||||
typedef void (* GskRenderNodeInvalidateFunc) (GskRenderNode *node,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
struct _GskRenderNode
|
struct _GskRenderNode
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
@ -59,35 +47,22 @@ struct _GskRenderNode
|
|||||||
/* Transformations applied to the children of the node */
|
/* Transformations applied to the children of the node */
|
||||||
graphene_matrix_t child_transform;
|
graphene_matrix_t child_transform;
|
||||||
|
|
||||||
/* Invalidation function for root node */
|
|
||||||
GskRenderNodeInvalidateFunc invalidate_func;
|
|
||||||
gpointer func_data;
|
|
||||||
GDestroyNotify destroy_func_data;
|
|
||||||
|
|
||||||
/* Descendants that need to be validated; only for root node */
|
|
||||||
GPtrArray *invalidated_descendants;
|
|
||||||
|
|
||||||
GskRenderNodeChanges last_state_change;
|
|
||||||
|
|
||||||
/* Bit fields; leave at the end */
|
/* Bit fields; leave at the end */
|
||||||
|
gboolean is_mutable : 1;
|
||||||
gboolean hidden : 1;
|
gboolean hidden : 1;
|
||||||
gboolean opaque : 1;
|
gboolean opaque : 1;
|
||||||
gboolean transform_set : 1;
|
gboolean transform_set : 1;
|
||||||
gboolean child_transform_set : 1;
|
gboolean child_transform_set : 1;
|
||||||
gboolean needs_resize : 1;
|
|
||||||
gboolean needs_world_matrix_update : 1;
|
gboolean needs_world_matrix_update : 1;
|
||||||
gboolean needs_content_update : 1;
|
|
||||||
gboolean needs_opacity_update : 1;
|
|
||||||
gboolean needs_visibility_update : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GskRenderNodeClass
|
struct _GskRenderNodeClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
void (* resize) (GskRenderNode *node);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void gsk_render_node_make_immutable (GskRenderNode *node);
|
||||||
|
|
||||||
void gsk_render_node_get_bounds (GskRenderNode *node,
|
void gsk_render_node_get_bounds (GskRenderNode *node,
|
||||||
graphene_rect_t *frame);
|
graphene_rect_t *frame);
|
||||||
void gsk_render_node_get_transform (GskRenderNode *node,
|
void gsk_render_node_get_transform (GskRenderNode *node,
|
||||||
@ -104,21 +79,6 @@ void gsk_render_node_update_world_matrix (GskRenderNode *node,
|
|||||||
void gsk_render_node_get_world_matrix (GskRenderNode *node,
|
void gsk_render_node_get_world_matrix (GskRenderNode *node,
|
||||||
graphene_matrix_t *mv);
|
graphene_matrix_t *mv);
|
||||||
|
|
||||||
void gsk_render_node_queue_invalidate (GskRenderNode *node,
|
|
||||||
GskRenderNodeChanges changes);
|
|
||||||
|
|
||||||
void gsk_render_node_set_invalidate_func (GskRenderNode *root,
|
|
||||||
GskRenderNodeInvalidateFunc validate_func,
|
|
||||||
gpointer data,
|
|
||||||
GDestroyNotify notify);
|
|
||||||
|
|
||||||
void gsk_render_node_validate (GskRenderNode *node);
|
|
||||||
|
|
||||||
void gsk_render_node_maybe_resize (GskRenderNode *node);
|
|
||||||
|
|
||||||
GskRenderNodeChanges gsk_render_node_get_current_state (GskRenderNode *node);
|
|
||||||
GskRenderNodeChanges gsk_render_node_get_last_state (GskRenderNode *node);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GSK_RENDER_NODE_PRIVATE_H__ */
|
#endif /* __GSK_RENDER_NODE_PRIVATE_H__ */
|
||||||
|
@ -163,7 +163,6 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
|||||||
testpopup \
|
testpopup \
|
||||||
testpopupat \
|
testpopupat \
|
||||||
testgaction \
|
testgaction \
|
||||||
testgskrenderer \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
if USE_X11
|
if USE_X11
|
||||||
@ -281,7 +280,6 @@ testtitlebar_DEPENDENCIES = $(TEST_DEPS)
|
|||||||
testwindowsize_DEPENDENCIES = $(TEST_DEPS)
|
testwindowsize_DEPENDENCIES = $(TEST_DEPS)
|
||||||
listmodel_DEPENDENCIES = $(TEST_DEPS)
|
listmodel_DEPENDENCIES = $(TEST_DEPS)
|
||||||
foreigndrawing_DEPENDENCIES = $(TEST_DEPS)
|
foreigndrawing_DEPENDENCIES = $(TEST_DEPS)
|
||||||
testgskrenderer_DEPENDENCIES = $(TEST_DEPS)
|
|
||||||
|
|
||||||
animated_resizing_SOURCES = \
|
animated_resizing_SOURCES = \
|
||||||
animated-resizing.c \
|
animated-resizing.c \
|
||||||
@ -490,8 +488,6 @@ listmodel_SOURCES = listmodel.c
|
|||||||
|
|
||||||
foreigndrawing_SOURCES = foreigndrawing.c
|
foreigndrawing_SOURCES = foreigndrawing.c
|
||||||
|
|
||||||
testgskrenderer_SOURCES = testgskrenderer.c
|
|
||||||
|
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
gradient1.png \
|
gradient1.png \
|
||||||
testgtk.1 \
|
testgtk.1 \
|
||||||
|
@ -1,229 +0,0 @@
|
|||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <graphene.h>
|
|
||||||
#include <cairo.h>
|
|
||||||
#include <gsk/gsk.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
#define BOX_SIZE 50.f
|
|
||||||
#define PADDING 10.f
|
|
||||||
#define ROOT_SIZE BOX_SIZE * 2 + PADDING * 2
|
|
||||||
|
|
||||||
static void
|
|
||||||
create_color_surface (cairo_t *cr, GdkRGBA *color, int w, int h)
|
|
||||||
{
|
|
||||||
cairo_set_source_rgba (cr, color->red, color->green, color->blue, color->alpha);
|
|
||||||
cairo_rectangle (cr, 0, 0, w, h);
|
|
||||||
cairo_fill (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GskRenderer *
|
|
||||||
get_renderer (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
GskRenderer *res;
|
|
||||||
|
|
||||||
res = g_object_get_data (G_OBJECT (widget), "-gsk-renderer");
|
|
||||||
if (res == NULL)
|
|
||||||
{
|
|
||||||
res = gsk_renderer_get_for_display (gtk_widget_get_display (widget));
|
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (widget), "-gsk-renderer",
|
|
||||||
res,
|
|
||||||
(GDestroyNotify) g_object_unref);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
create_scene (GskRenderer *renderer)
|
|
||||||
{
|
|
||||||
GskRenderNode *root, *node;
|
|
||||||
graphene_matrix_t ctm;
|
|
||||||
cairo_t *cr;
|
|
||||||
|
|
||||||
root = gsk_render_node_new ();
|
|
||||||
gsk_render_node_set_name (root, "Root node");
|
|
||||||
gsk_render_node_set_bounds (root, &(graphene_rect_t) {
|
|
||||||
.origin.x = 0.f,
|
|
||||||
.origin.y = 0.f,
|
|
||||||
.size.width = ROOT_SIZE,
|
|
||||||
.size.height = ROOT_SIZE
|
|
||||||
});
|
|
||||||
cr = gsk_render_node_get_draw_context (root);
|
|
||||||
create_color_surface (cr, &(GdkRGBA) { .red = 1, .green = 0, .blue = 0, .alpha = 1 }, ROOT_SIZE, ROOT_SIZE);
|
|
||||||
cairo_destroy (cr);
|
|
||||||
gsk_renderer_set_root_node (renderer, root);
|
|
||||||
g_object_set_data (G_OBJECT (renderer), "-gsk-renderer-root-node", root);
|
|
||||||
|
|
||||||
g_object_unref (root);
|
|
||||||
|
|
||||||
node = gsk_render_node_new ();
|
|
||||||
gsk_render_node_set_name (node, "Green node");
|
|
||||||
gsk_render_node_set_bounds (node, &(graphene_rect_t) {
|
|
||||||
.origin.x = 0.f,
|
|
||||||
.origin.y = 0.f,
|
|
||||||
.size.width = BOX_SIZE,
|
|
||||||
.size.height = BOX_SIZE
|
|
||||||
});
|
|
||||||
cr = gsk_render_node_get_draw_context (node);
|
|
||||||
create_color_surface (cr, &(GdkRGBA) { .red = 0, .green = 1, .blue = 0, .alpha = 1 }, BOX_SIZE, BOX_SIZE);
|
|
||||||
cairo_destroy (cr);
|
|
||||||
graphene_matrix_init_translate (&ctm, &(graphene_point3d_t) { .x = -0.5, .y = -0.5, .z = 0.f });
|
|
||||||
gsk_render_node_set_transform (node, &ctm);
|
|
||||||
gsk_render_node_insert_child_at_pos (root, node, 0);
|
|
||||||
g_object_unref (node);
|
|
||||||
|
|
||||||
node = gsk_render_node_new ();
|
|
||||||
gsk_render_node_set_name (node, "Blue node");
|
|
||||||
gsk_render_node_set_bounds (node, &(graphene_rect_t) {
|
|
||||||
.origin.x = 0.f,
|
|
||||||
.origin.y = 0.f,
|
|
||||||
.size.width = BOX_SIZE,
|
|
||||||
.size.height = BOX_SIZE
|
|
||||||
});
|
|
||||||
cr = gsk_render_node_get_draw_context (node);
|
|
||||||
create_color_surface (cr, &(GdkRGBA) { .red = 0, .green = 0, .blue = 1, .alpha = 1 }, BOX_SIZE, BOX_SIZE);
|
|
||||||
cairo_destroy (cr);
|
|
||||||
graphene_matrix_init_translate (&ctm, &(graphene_point3d_t) { .x = 0.5, .y = 0.5, .z = 0.f });
|
|
||||||
gsk_render_node_set_transform (node, &ctm);
|
|
||||||
gsk_render_node_insert_child_at_pos (root, node, 1);
|
|
||||||
g_object_unref (node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
realize (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
GskRenderer *renderer = get_renderer (widget);
|
|
||||||
|
|
||||||
gsk_renderer_set_window (renderer, gtk_widget_get_window (widget));
|
|
||||||
gsk_renderer_set_use_alpha (renderer, TRUE);
|
|
||||||
gsk_renderer_realize (renderer);
|
|
||||||
|
|
||||||
create_scene (renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
unrealize (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
g_object_set_data (G_OBJECT (widget), "-gsk-renderer", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
size_allocate (GtkWidget *widget, GtkAllocation *allocation)
|
|
||||||
{
|
|
||||||
GskRenderer *renderer = get_renderer (widget);
|
|
||||||
GskRenderNode *root;
|
|
||||||
graphene_matrix_t ctm;
|
|
||||||
|
|
||||||
gsk_renderer_set_viewport (renderer, &(graphene_rect_t) {
|
|
||||||
.origin.x = 0,
|
|
||||||
.origin.y = 0,
|
|
||||||
.size.width = allocation->width,
|
|
||||||
.size.height = allocation->height
|
|
||||||
});
|
|
||||||
|
|
||||||
graphene_matrix_init_translate (&ctm, &(graphene_point3d_t) {
|
|
||||||
allocation->x,
|
|
||||||
allocation->y,
|
|
||||||
0.f
|
|
||||||
});
|
|
||||||
gsk_renderer_set_modelview (renderer, &ctm);
|
|
||||||
|
|
||||||
root = g_object_get_data (G_OBJECT (renderer), "-gsk-renderer-root-node");
|
|
||||||
if (root == NULL)
|
|
||||||
{
|
|
||||||
create_scene (renderer);
|
|
||||||
root = g_object_get_data (G_OBJECT (renderer), "-gsk-renderer-root-node");
|
|
||||||
}
|
|
||||||
|
|
||||||
graphene_matrix_init_translate (&ctm, &(graphene_point3d_t) {
|
|
||||||
.x = 0,
|
|
||||||
.y = 0,
|
|
||||||
.z = 0
|
|
||||||
});
|
|
||||||
gsk_render_node_set_transform (root, &ctm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
draw (GtkWidget *widget, cairo_t *cr)
|
|
||||||
{
|
|
||||||
GskRenderer *renderer = get_renderer (widget);
|
|
||||||
|
|
||||||
gsk_renderer_set_draw_context (renderer, cr);
|
|
||||||
gsk_renderer_render (renderer);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
fade_out (GtkWidget *widget,
|
|
||||||
GdkFrameClock *frame_clock,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
static gint64 first_frame_time;
|
|
||||||
static gboolean flip = FALSE;
|
|
||||||
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
|
|
||||||
|
|
||||||
if (first_frame_time == 0)
|
|
||||||
{
|
|
||||||
first_frame_time = now;
|
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
double start = first_frame_time;
|
|
||||||
double end = first_frame_time + (double) 1000000;
|
|
||||||
double progress = (now - first_frame_time) / (end - start);
|
|
||||||
|
|
||||||
if (flip)
|
|
||||||
progress = 1 - progress;
|
|
||||||
|
|
||||||
if (progress < 0 || progress >= 1)
|
|
||||||
{
|
|
||||||
first_frame_time = now;
|
|
||||||
flip = !flip;
|
|
||||||
return G_SOURCE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GskRenderer *renderer = get_renderer (widget);
|
|
||||||
GskRenderNode *root = gsk_renderer_get_root_node (renderer);
|
|
||||||
|
|
||||||
gsk_render_node_set_opacity (root, 1.0 - progress);
|
|
||||||
|
|
||||||
gtk_widget_queue_draw (widget);
|
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
GtkWidget *window, *area;
|
|
||||||
|
|
||||||
gtk_init (NULL, NULL);
|
|
||||||
|
|
||||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
|
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "GSK Renderer");
|
|
||||||
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
|
|
||||||
|
|
||||||
area = gtk_drawing_area_new ();
|
|
||||||
gtk_widget_set_hexpand (area, TRUE);
|
|
||||||
gtk_widget_set_vexpand (area, TRUE);
|
|
||||||
gtk_widget_set_has_window (GTK_WIDGET (area), FALSE);
|
|
||||||
gtk_widget_set_app_paintable (GTK_WIDGET (area), TRUE);
|
|
||||||
gtk_container_add (GTK_CONTAINER (window), area);
|
|
||||||
|
|
||||||
g_signal_connect (area, "realize", G_CALLBACK (realize), NULL);
|
|
||||||
g_signal_connect (area, "unrealize", G_CALLBACK (unrealize), NULL);
|
|
||||||
g_signal_connect (area, "size-allocate", G_CALLBACK (size_allocate), NULL);
|
|
||||||
g_signal_connect (area, "draw", G_CALLBACK (draw), NULL);
|
|
||||||
|
|
||||||
gtk_widget_add_tick_callback (area, fade_out, NULL, NULL);
|
|
||||||
|
|
||||||
gtk_widget_show_all (window);
|
|
||||||
|
|
||||||
gtk_main ();
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user