clutter: Move redraw clip management to views

The stage window handled the redraw clip in a global manner; this would
interfere if we want to paint views individually as it'd mean
intersecting views (i.e. mirrored monitors) would loose the redraw clip
once the first view was painted. It also is awkward to have a global
state for something that is built up before redrawing, and only really
valid during paint, due to buffer damage history.

This commits removes all redraw clip management from the stage window,
moving it all into the stage views. When a redraw clip is added to the
stage, every affected view will get the same redraw clip added to it,
and eventually when painted, the stage window (ClutterStageCogl) will
retrieve the redraw clip for each view as it repaints them.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
This commit is contained in:
Jonas Ådahl 2020-02-06 10:12:54 +01:00
parent b68c630329
commit 159c83b914
9 changed files with 190 additions and 232 deletions

View File

@ -248,6 +248,9 @@ gboolean _clutter_util_rectangle_intersection (const cairo_rectangle_int_t *src1
const cairo_rectangle_int_t *src2,
cairo_rectangle_int_t *dest);
gboolean clutter_util_rectangle_equal (const cairo_rectangle_int_t *src1,
const cairo_rectangle_int_t *src2);
struct _ClutterVertex4
{

View File

@ -32,7 +32,15 @@ gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
gboolean dirty);
void clutter_stage_view_add_redraw_clip (ClutterStageView *view,
cairo_rectangle_int_t *clip);
void clutter_stage_view_add_redraw_clip (ClutterStageView *view,
const cairo_rectangle_int_t *clip);
gboolean clutter_stage_view_has_full_redraw_clip (ClutterStageView *view);
gboolean clutter_stage_view_has_redraw_clip (ClutterStageView *view);
const cairo_region_t * clutter_stage_view_peek_redraw_clip (ClutterStageView *view);
cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view);
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */

View File

@ -23,6 +23,8 @@
#include <cairo-gobject.h>
#include <math.h>
#include "clutter/clutter-private.h"
enum
{
PROP_0,
@ -50,6 +52,9 @@ typedef struct _ClutterStageViewPrivate
CoglOffscreen *shadowfb;
CoglPipeline *shadowfb_pipeline;
gboolean has_redraw_clip;
cairo_region_t *redraw_clip;
guint dirty_viewport : 1;
guint dirty_projection : 1;
} ClutterStageViewPrivate;
@ -302,6 +307,86 @@ clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view,
view_class->get_offscreen_transformation_matrix (view, matrix);
}
void
clutter_stage_view_add_redraw_clip (ClutterStageView *view,
const cairo_rectangle_int_t *clip)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
if (priv->has_redraw_clip && !priv->redraw_clip)
return;
if (!clip)
{
g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
priv->has_redraw_clip = TRUE;
return;
}
if (clip->width == 0 || clip->height == 0)
return;
if (!priv->redraw_clip)
{
if (!clutter_util_rectangle_equal (&priv->layout, clip))
priv->redraw_clip = cairo_region_create_rectangle (clip);
}
else
{
cairo_region_union_rectangle (priv->redraw_clip, clip);
if (cairo_region_num_rectangles (priv->redraw_clip) == 1)
{
cairo_rectangle_int_t redraw_clip_extents;
cairo_region_get_extents (priv->redraw_clip, &redraw_clip_extents);
if (clutter_util_rectangle_equal (&priv->layout, &redraw_clip_extents))
g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
}
}
priv->has_redraw_clip = TRUE;
}
gboolean
clutter_stage_view_has_redraw_clip (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
return priv->has_redraw_clip;
}
gboolean
clutter_stage_view_has_full_redraw_clip (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
return priv->has_redraw_clip && !priv->redraw_clip;
}
const cairo_region_t *
clutter_stage_view_peek_redraw_clip (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
return priv->redraw_clip;
}
cairo_region_t *
clutter_stage_view_take_redraw_clip (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
priv->has_redraw_clip = FALSE;
return g_steal_pointer (&priv->redraw_clip);
}
void
clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
gfloat *x,
@ -414,6 +499,7 @@ clutter_stage_view_dispose (GObject *object)
g_clear_pointer (&priv->offscreen, cogl_object_unref);
g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
g_clear_pointer (&priv->shadowfb_pipeline, cogl_object_unref);
g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object);
}

View File

@ -178,77 +178,6 @@ _clutter_stage_window_clear_update_time (ClutterStageWindow *window)
iface->clear_update_time (window);
}
void
_clutter_stage_window_add_redraw_clip (ClutterStageWindow *window,
cairo_rectangle_int_t *stage_clip)
{
ClutterStageWindowInterface *iface;
g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->add_redraw_clip != NULL)
iface->add_redraw_clip (window, stage_clip);
}
/* Determines if the backend will clip the rendering of the next
* frame.
*
* Note: at the start of each new frame there is an implied clip that
* clips everything (i.e. nothing would be drawn) so this function
* will return True at the start of a new frame if the backend
* supports clipped redraws.
*/
gboolean
_clutter_stage_window_has_redraw_clips (ClutterStageWindow *window)
{
ClutterStageWindowInterface *iface;
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->has_redraw_clips != NULL)
return iface->has_redraw_clips (window);
return FALSE;
}
/* Determines if the backend will discard any additional redraw clips
* and instead promote them to a full stage redraw.
*
* The ideas is that backend may have some heuristics that cause it to
* give up tracking redraw clips so this can be used to avoid the cost
* of calculating a redraw clip when we know it's going to be ignored
* anyway.
*/
gboolean
_clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window)
{
ClutterStageWindowInterface *iface;
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->ignoring_redraw_clips != NULL)
return iface->ignoring_redraw_clips (window);
return TRUE;
}
cairo_region_t *
_clutter_stage_window_get_redraw_clip (ClutterStageWindow *window)
{
ClutterStageWindowInterface *iface;
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->get_redraw_clip != NULL)
return iface->get_redraw_clip (window);
return NULL;
}
void
_clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
gboolean accept_focus)

View File

@ -51,12 +51,6 @@ struct _ClutterStageWindowInterface
gint64 (* get_update_time) (ClutterStageWindow *stage_window);
void (* clear_update_time) (ClutterStageWindow *stage_window);
void (* add_redraw_clip) (ClutterStageWindow *stage_window,
cairo_rectangle_int_t *stage_rectangle);
gboolean (* has_redraw_clips) (ClutterStageWindow *stage_window);
gboolean (* ignoring_redraw_clips) (ClutterStageWindow *stage_window);
cairo_region_t * (* get_redraw_clip) (ClutterStageWindow *stage_window);
void (* set_accept_focus) (ClutterStageWindow *stage_window,
gboolean accept_focus);
@ -94,12 +88,6 @@ void _clutter_stage_window_schedule_update (ClutterStageWin
gint64 _clutter_stage_window_get_update_time (ClutterStageWindow *window);
void _clutter_stage_window_clear_update_time (ClutterStageWindow *window);
void _clutter_stage_window_add_redraw_clip (ClutterStageWindow *window,
cairo_rectangle_int_t *stage_clip);
gboolean _clutter_stage_window_has_redraw_clips (ClutterStageWindow *window);
gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window);
cairo_region_t * _clutter_stage_window_get_redraw_clip (ClutterStageWindow *window);
void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
gboolean accept_focus);

View File

@ -557,6 +557,33 @@ pick_record_contains_point (ClutterStage *stage,
return TRUE;
}
static void
clutter_stage_add_redraw_clip (ClutterStage *stage,
cairo_rectangle_int_t *clip)
{
GList *l;
for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
{
ClutterStageView *view = l->data;
if (!clip)
{
clutter_stage_view_add_redraw_clip (view, NULL);
}
else
{
cairo_rectangle_int_t view_layout;
cairo_rectangle_int_t intersection;
clutter_stage_view_get_layout (view, &view_layout);
if (_clutter_util_rectangle_intersection (&view_layout, clip,
&intersection))
clutter_stage_view_add_redraw_clip (view, &intersection);
}
}
}
static inline void
queue_full_redraw (ClutterStage *stage)
{
@ -575,7 +602,7 @@ queue_full_redraw (ClutterStage *stage)
if (stage_window == NULL)
return;
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
clutter_stage_add_redraw_clip (stage, NULL);
}
static gboolean
@ -1413,16 +1440,12 @@ clutter_stage_do_redraw (ClutterStage *stage)
static GSList *
_clutter_stage_check_updated_pointers (ClutterStage *stage)
{
ClutterStagePrivate *priv = stage->priv;
ClutterBackend *backend;
ClutterSeat *seat;
GSList *updating = NULL;
GList *l, *devices;
cairo_region_t *clip;
graphene_point_t point;
clip = _clutter_stage_window_get_redraw_clip (priv->impl);
backend = clutter_get_default_backend ();
seat = clutter_backend_get_default_seat (backend);
devices = clutter_seat_list_devices (seat);
@ -1430,6 +1453,8 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage)
for (l = devices; l; l = l->next)
{
ClutterInputDevice *dev = l->data;
ClutterStageView *view;
const cairo_region_t *clip;
if (clutter_input_device_get_device_mode (dev) !=
CLUTTER_INPUT_MODE_MASTER)
@ -1445,6 +1470,11 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage)
if (!clutter_input_device_get_coords (dev, NULL, &point))
continue;
view = clutter_stage_get_view_at (stage, point.x, point.y);
if (!view)
continue;
clip = clutter_stage_view_peek_redraw_clip (view);
if (!clip || cairo_region_contains_point (clip, point.x, point.y))
updating = g_slist_prepend (updating, dev);
break;
@ -1554,6 +1584,22 @@ clutter_stage_real_queue_relayout (ClutterActor *self)
parent_class->queue_relayout (self);
}
static gboolean
is_full_stage_redraw_queued (ClutterStage *stage)
{
GList *l;
for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
{
ClutterStageView *view = l->data;
if (!clutter_stage_view_has_full_redraw_clip (view))
return FALSE;
}
return TRUE;
}
static gboolean
clutter_stage_real_queue_redraw (ClutterActor *actor,
ClutterActor *leaf,
@ -1575,12 +1621,12 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
if (stage_window == NULL)
return TRUE;
if (_clutter_stage_window_ignoring_redraw_clips (stage_window))
if (is_full_stage_redraw_queued (stage))
return FALSE;
if (redraw_clip == NULL)
{
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
clutter_stage_add_redraw_clip (stage, NULL);
return FALSE;
}
@ -1612,23 +1658,20 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
stage_clip.width = intersection_box.x2 - stage_clip.x;
stage_clip.height = intersection_box.y2 - stage_clip.y;
_clutter_stage_window_add_redraw_clip (stage_window, &stage_clip);
clutter_stage_add_redraw_clip (stage, &stage_clip);
return FALSE;
}
gboolean
_clutter_stage_has_full_redraw_queued (ClutterStage *stage)
{
ClutterStageWindow *stage_window = _clutter_stage_get_window (stage);
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage) || stage_window == NULL)
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return FALSE;
if (stage->priv->redraw_pending &&
!_clutter_stage_window_has_redraw_clips (stage_window))
return TRUE;
else
if (!stage->priv->redraw_pending)
return FALSE;
return is_full_stage_redraw_queued (stage);
}
static ClutterActor *

View File

@ -214,6 +214,16 @@ _clutter_util_rectangle_intersection (const cairo_rectangle_int_t *src1,
}
}
gboolean
clutter_util_rectangle_equal (const cairo_rectangle_int_t *src1,
const cairo_rectangle_int_t *src2)
{
return ((src1->x == src2->x) &&
(src1->y == src2->y) &&
(src1->width == src2->width) &&
(src1->height == src2->height));
}
float
_clutter_util_matrix_determinant (const ClutterMatrix *matrix)
{

View File

@ -290,97 +290,6 @@ clutter_stage_cogl_resize (ClutterStageWindow *stage_window,
{
}
static gboolean
clutter_stage_cogl_has_redraw_clips (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
/* NB: at the start of each new frame there is an implied clip that
* clips everything (i.e. nothing would be drawn) so we need to make
* sure we return True in the un-initialized case here.
*/
if (!stage_cogl->initialized_redraw_clip ||
(stage_cogl->initialized_redraw_clip &&
stage_cogl->redraw_clip))
return TRUE;
else
return FALSE;
}
static gboolean
clutter_stage_cogl_ignoring_redraw_clips (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
/* NB: a NULL clip means a full stage redraw is required */
if (stage_cogl->initialized_redraw_clip &&
!stage_cogl->redraw_clip)
return TRUE;
else
return FALSE;
}
/* A redraw clip represents (in stage coordinates) the bounding box of
* something that needs to be redrawn. Typically they are added to the
* StageWindow as a result of clutter_actor_queue_clipped_redraw() by
* actors such as ClutterGLXTexturePixmap. All redraw clips are
* discarded after the next paint.
*
* A NULL stage_clip means the whole stage needs to be redrawn.
*
* What we do with this information:
* - we keep track of the bounding box for all redraw clips
* - when we come to redraw; we scissor the redraw to that box and use
* glBlitFramebuffer to present the redraw to the front
* buffer.
*/
static void
clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window,
cairo_rectangle_int_t *stage_clip)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
/* If we are already forced to do a full stage redraw then bail early */
if (clutter_stage_cogl_ignoring_redraw_clips (stage_window))
return;
/* A NULL stage clip means a full stage redraw has been queued and
* we keep track of this by setting a NULL redraw_clip.
*/
if (stage_clip == NULL)
{
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
stage_cogl->initialized_redraw_clip = TRUE;
return;
}
/* Ignore requests to add degenerate/empty clip rectangles */
if (stage_clip->width == 0 || stage_clip->height == 0)
return;
if (!stage_cogl->redraw_clip)
{
stage_cogl->redraw_clip = cairo_region_create_rectangle (stage_clip);
}
else
{
cairo_region_union_rectangle (stage_cogl->redraw_clip, stage_clip);
}
stage_cogl->initialized_redraw_clip = TRUE;
}
static cairo_region_t *
clutter_stage_cogl_get_redraw_clip (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
if (stage_cogl->using_clipped_redraw && stage_cogl->redraw_clip)
return cairo_region_copy (stage_cogl->redraw_clip);
return NULL;
}
static inline gboolean
valid_buffer_age (ClutterStageViewCogl *view_cogl,
int age)
@ -397,7 +306,8 @@ valid_buffer_age (ClutterStageViewCogl *view_cogl,
static void
paint_damage_region (ClutterStageWindow *stage_window,
ClutterStageView *view,
cairo_region_t *swap_region)
cairo_region_t *swap_region,
cairo_region_t *queued_redraw_clip)
{
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
@ -434,8 +344,7 @@ paint_damage_region (ClutterStageWindow *stage_window,
}
/* Red for the clip */
if (stage_cogl->initialized_redraw_clip &&
stage_cogl->redraw_clip)
if (queued_redraw_clip)
{
static CoglPipeline *overlay_red = NULL;
@ -445,13 +354,13 @@ paint_damage_region (ClutterStageWindow *stage_window,
cogl_pipeline_set_color4ub (overlay_red, 0x33, 0x00, 0x00, 0x33);
}
n_rects = cairo_region_num_rectangles (stage_cogl->redraw_clip);
n_rects = cairo_region_num_rectangles (queued_redraw_clip);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
float x_1, x_2, y_1, y_2;
cairo_region_get_rectangle (stage_cogl->redraw_clip, i, &rect);
cairo_region_get_rectangle (queued_redraw_clip, i, &rect);
x_1 = rect.x;
x_2 = rect.x + rect.width;
y_1 = rect.y;
@ -468,13 +377,14 @@ static gboolean
swap_framebuffer (ClutterStageWindow *stage_window,
ClutterStageView *view,
cairo_region_t *swap_region,
gboolean swap_with_damage)
gboolean swap_with_damage,
cairo_region_t *queued_redraw_clip)
{
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
int *damage, n_rects, i;
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)))
paint_damage_region (stage_window, view, swap_region);
paint_damage_region (stage_window, view, swap_region, queued_redraw_clip);
n_rects = cairo_region_num_rectangles (swap_region);
damage = g_newa (int, n_rects * 4);
@ -711,7 +621,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
gboolean do_swap_buffer;
gboolean swap_with_damage;
ClutterActor *wrapper;
cairo_region_t *redraw_clip = NULL;
cairo_region_t *redraw_clip;
cairo_region_t *queued_redraw_clip;
cairo_region_t *fb_clip_region;
cairo_region_t *swap_region;
cairo_rectangle_int_t redraw_rect;
@ -733,20 +644,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled ();
redraw_clip = clutter_stage_view_take_redraw_clip (view);
/* NB: a NULL redraw clip == full stage redraw */
if (!stage_cogl->redraw_clip)
if (!redraw_clip)
is_full_redraw = TRUE;
else
{
cairo_region_t *view_region;
redraw_clip = cairo_region_copy (stage_cogl->redraw_clip);
view_region = cairo_region_create_rectangle (&view_rect);
cairo_region_intersect (redraw_clip, view_region);
is_full_redraw = cairo_region_equal (redraw_clip, view_region);
cairo_region_destroy (view_region);
}
is_full_redraw = FALSE;
may_use_clipped_redraw = FALSE;
if (_clutter_stage_window_can_clip_redraws (stage_window) &&
@ -798,6 +702,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
redraw_clip = cairo_region_create_rectangle (&view_rect);
}
queued_redraw_clip = cairo_region_copy (redraw_clip);
if (may_use_clipped_redraw &&
G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)))
use_clipped_redraw = TRUE;
@ -845,7 +751,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
cairo_region_intersect_rectangle (view_damage, &view_rect);
/* Update the redraw clip region with the extra damage. */
cairo_region_union (stage_cogl->redraw_clip, view_damage);
cairo_region_union (redraw_clip, view_damage);
cairo_region_union (redraw_clip, view_damage);
cairo_region_destroy (view_damage);
@ -894,8 +800,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
cairo_rectangle_int_t clip_rect;
cairo_rectangle_int_t scissor_rect;
stage_cogl->using_clipped_redraw = TRUE;
if (cairo_region_num_rectangles (fb_clip_region) == 1)
{
cairo_region_get_extents (fb_clip_region, &clip_rect);
@ -926,8 +830,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
paint_stage (stage_cogl, view, redraw_clip);
cogl_framebuffer_pop_clip (fb);
stage_cogl->using_clipped_redraw = FALSE;
}
else
{
@ -1033,6 +935,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
}
g_clear_pointer (&redraw_clip, cairo_region_destroy);
g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
g_clear_pointer (&fb_clip_region, cairo_region_destroy);
if (do_swap_buffer)
@ -1056,7 +959,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
res = swap_framebuffer (stage_window,
view,
swap_region,
swap_with_damage);
swap_with_damage,
queued_redraw_clip);
cairo_region_destroy (swap_region);
@ -1081,6 +985,9 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
{
ClutterStageView *view = l->data;
if (!clutter_stage_view_has_redraw_clip (view))
continue;
swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
}
@ -1097,10 +1004,6 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
stage_cogl->pending_swaps++;
}
/* reset the redraw clipping for the next paint... */
stage_cogl->initialized_redraw_clip = FALSE;
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
stage_cogl->frame_count++;
COGL_TRACE_END (ClutterStageCoglRedraw);
@ -1118,10 +1021,6 @@ clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
iface->schedule_update = clutter_stage_cogl_schedule_update;
iface->get_update_time = clutter_stage_cogl_get_update_time;
iface->clear_update_time = clutter_stage_cogl_clear_update_time;
iface->add_redraw_clip = clutter_stage_cogl_add_redraw_clip;
iface->has_redraw_clips = clutter_stage_cogl_has_redraw_clips;
iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips;
iface->get_redraw_clip = clutter_stage_cogl_get_redraw_clip;
iface->redraw = clutter_stage_cogl_redraw;
}

View File

@ -55,14 +55,6 @@ struct _ClutterStageCogl
unsigned int frame_count;
gint last_sync_delay;
cairo_region_t *redraw_clip;
guint initialized_redraw_clip : 1;
/* TRUE if the current paint cycle has a clipped redraw. In that
case bounding_redraw_clip specifies the the bounds. */
guint using_clipped_redraw : 1;
};
struct _ClutterStageCoglClass