forked from AuroraMiddleware/gtk
widget: Cache clip from creating render node
When the clip changes that is passed to a snapshot function, we need to create eventual cached render nodes because they might not have drawn their whole area before. Fixes issues with redrawing when scrolling.
This commit is contained in:
parent
278ab3c4de
commit
4bf90633ea
@ -1594,6 +1594,23 @@ gtk_snapshot_append_color (GtkSnapshot *snapshot,
|
||||
gsk_render_node_unref (node);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_snapshot_get_clip (GtkSnapshot *snapshot,
|
||||
graphene_rect_t *out_clip)
|
||||
{
|
||||
const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
|
||||
|
||||
if (!current_state->has_clip)
|
||||
return FALSE;
|
||||
|
||||
graphene_rect_offset_r (¤t_state->clip,
|
||||
- current_state->translate_x,
|
||||
- current_state->translate_y,
|
||||
out_clip);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_clips_rect:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
|
@ -99,11 +99,13 @@ struct _GtkSnapshotClass {
|
||||
GObjectClass parent_class; /* it's really GdkSnapshotClass, but don't tell anyone! */
|
||||
};
|
||||
|
||||
GtkSnapshot * gtk_snapshot_new_child (GtkSnapshot *parent,
|
||||
const char *name,
|
||||
...) G_GNUC_PRINTF (2, 3);
|
||||
void gtk_snapshot_append_node_internal (GtkSnapshot *snapshot,
|
||||
GskRenderNode *node);
|
||||
GtkSnapshot * gtk_snapshot_new_child (GtkSnapshot *parent,
|
||||
const char *name,
|
||||
...) G_GNUC_PRINTF (2, 3);
|
||||
void gtk_snapshot_append_node_internal (GtkSnapshot *snapshot,
|
||||
GskRenderNode *node);
|
||||
gboolean gtk_snapshot_get_clip (GtkSnapshot *snapshot,
|
||||
graphene_rect_t *out_clip);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -4021,6 +4021,7 @@ gtk_widget_queue_draw (GtkWidget *widget)
|
||||
|
||||
priv->draw_needed = TRUE;
|
||||
g_clear_pointer (&priv->render_node, gsk_render_node_unref);
|
||||
priv->render_node_has_clip = FALSE;
|
||||
gtk_widget_invalidate_paintable_contents (widget);
|
||||
if (_gtk_widget_get_has_surface (widget) &&
|
||||
_gtk_widget_get_realized (widget))
|
||||
@ -13816,6 +13817,8 @@ gtk_widget_snapshot (GtkWidget *widget,
|
||||
{
|
||||
GtkWidgetPrivate *priv = widget->priv;
|
||||
graphene_rect_t offset_clip;
|
||||
graphene_rect_t clip;
|
||||
gboolean has_clip;
|
||||
double opacity;
|
||||
|
||||
if (!_gtk_widget_is_drawable (widget))
|
||||
@ -13841,13 +13844,28 @@ gtk_widget_snapshot (GtkWidget *widget,
|
||||
if (opacity <= 0.0)
|
||||
return;
|
||||
|
||||
if (priv->draw_needed)
|
||||
has_clip = gtk_snapshot_get_clip (snapshot, &clip);
|
||||
|
||||
if (priv->draw_needed ||
|
||||
(priv->render_node_has_clip && (!has_clip || !graphene_rect_contains_rect (&priv->render_node_clip, &clip))))
|
||||
{
|
||||
GskRenderNode *render_node;
|
||||
|
||||
render_node = gtk_widget_create_render_node (widget, snapshot);
|
||||
/* This can happen when nested drawing happens and a widget contains itself */
|
||||
/* This can happen when nested drawing happens and a widget contains itself
|
||||
* or when we replace a clipped area */
|
||||
g_clear_pointer (&priv->render_node, gsk_render_node_unref);
|
||||
priv->render_node = render_node;
|
||||
if (has_clip)
|
||||
{
|
||||
priv->render_node_clip = clip;
|
||||
priv->render_node_has_clip = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->render_node_has_clip = FALSE;
|
||||
}
|
||||
|
||||
priv->draw_needed = FALSE;
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,7 @@ struct _GtkWidgetPrivate
|
||||
|
||||
/* Queue-draw related flags */
|
||||
guint draw_needed : 1;
|
||||
guint render_node_has_clip : 1;
|
||||
|
||||
/* Expand-related flags */
|
||||
guint need_compute_expand : 1; /* Need to recompute computed_[hv]_expand */
|
||||
@ -145,8 +146,11 @@ struct _GtkWidgetPrivate
|
||||
/* The widget's requested sizes */
|
||||
SizeRequestCache requests;
|
||||
|
||||
/* The render node we draw or %NULL if not yet created. */
|
||||
/* The render node we draw or %NULL if not yet created.*/
|
||||
GskRenderNode *render_node;
|
||||
/* The clip that existed when the render node was drawn
|
||||
* Ignored when render_node_has_clip == FALSE */
|
||||
graphene_rect_t render_node_clip;
|
||||
|
||||
GSList *paintables;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user