mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 19:10:43 -05:00
ClutterStage: Store clip area as a region
This will allow drawing optimizations as a region is more concrete than the bounding rectangle. https://bugzilla.gnome.org/show_bug.cgi?id=782344
This commit is contained in:
parent
77fd682c8b
commit
af3475f65f
@ -231,19 +231,35 @@ _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
cairo_region_t *
|
||||||
_clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
_clutter_stage_window_get_redraw_clip (ClutterStageWindow *window)
|
||||||
cairo_rectangle_int_t *stage_clip)
|
|
||||||
{
|
{
|
||||||
ClutterStageWindowIface *iface;
|
ClutterStageWindowIface *iface;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
|
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
|
||||||
|
|
||||||
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||||
if (iface->get_redraw_clip_bounds != NULL)
|
if (iface->get_redraw_clip != NULL)
|
||||||
return iface->get_redraw_clip_bounds (window, stage_clip);
|
return iface->get_redraw_clip (window);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
||||||
|
cairo_rectangle_int_t *stage_clip)
|
||||||
|
{
|
||||||
|
cairo_region_t *redraw_clip;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
|
||||||
|
|
||||||
|
redraw_clip = _clutter_stage_window_get_redraw_clip (window);
|
||||||
|
if (!redraw_clip)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
cairo_region_get_extents (redraw_clip, stage_clip);
|
||||||
|
cairo_region_destroy (redraw_clip);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -68,9 +68,7 @@ struct _ClutterStageWindowIface
|
|||||||
cairo_rectangle_int_t *stage_rectangle);
|
cairo_rectangle_int_t *stage_rectangle);
|
||||||
gboolean (* has_redraw_clips) (ClutterStageWindow *stage_window);
|
gboolean (* has_redraw_clips) (ClutterStageWindow *stage_window);
|
||||||
gboolean (* ignoring_redraw_clips) (ClutterStageWindow *stage_window);
|
gboolean (* ignoring_redraw_clips) (ClutterStageWindow *stage_window);
|
||||||
gboolean (* get_redraw_clip_bounds) (ClutterStageWindow *stage_window,
|
cairo_region_t * (* get_redraw_clip) (ClutterStageWindow *stage_window);
|
||||||
cairo_rectangle_int_t *clip);
|
|
||||||
|
|
||||||
|
|
||||||
void (* set_accept_focus) (ClutterStageWindow *stage_window,
|
void (* set_accept_focus) (ClutterStageWindow *stage_window,
|
||||||
gboolean accept_focus);
|
gboolean accept_focus);
|
||||||
@ -125,6 +123,7 @@ gboolean _clutter_stage_window_has_redraw_clips (ClutterStageWin
|
|||||||
gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window);
|
gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window);
|
||||||
gboolean _clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
gboolean _clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
||||||
cairo_rectangle_int_t *clip);
|
cairo_rectangle_int_t *clip);
|
||||||
|
cairo_region_t * _clutter_stage_window_get_redraw_clip (ClutterStageWindow *window);
|
||||||
|
|
||||||
void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
|
void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
|
||||||
gboolean accept_focus);
|
gboolean accept_focus);
|
||||||
|
@ -1315,6 +1315,31 @@ clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_region_t *
|
||||||
|
clutter_stage_get_redraw_clip (ClutterStage *stage)
|
||||||
|
{
|
||||||
|
ClutterStagePrivate *priv;
|
||||||
|
cairo_rectangle_int_t clip;
|
||||||
|
cairo_region_t *region;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||||
|
|
||||||
|
priv = stage->priv;
|
||||||
|
|
||||||
|
region = _clutter_stage_window_get_redraw_clip (priv->impl);
|
||||||
|
if (region)
|
||||||
|
return region;
|
||||||
|
|
||||||
|
if (!region)
|
||||||
|
{
|
||||||
|
/* Set clip to the full extents of the stage */
|
||||||
|
_clutter_stage_window_get_geometry (priv->impl, &clip);
|
||||||
|
region = cairo_region_create_rectangle (&clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_pixels_to_file (char *filename_stem,
|
read_pixels_to_file (char *filename_stem,
|
||||||
int x,
|
int x,
|
||||||
|
@ -245,6 +245,9 @@ guchar * clutter_stage_read_pixels (ClutterStage
|
|||||||
CLUTTER_AVAILABLE_IN_ALL
|
CLUTTER_AVAILABLE_IN_ALL
|
||||||
void clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
|
void clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
|
||||||
cairo_rectangle_int_t *clip);
|
cairo_rectangle_int_t *clip);
|
||||||
|
CLUTTER_AVAILABLE_IN_MUTTER
|
||||||
|
cairo_region_t * clutter_stage_get_redraw_clip (ClutterStage *stage);
|
||||||
|
|
||||||
CLUTTER_AVAILABLE_IN_ALL
|
CLUTTER_AVAILABLE_IN_ALL
|
||||||
void clutter_stage_ensure_viewport (ClutterStage *stage);
|
void clutter_stage_ensure_viewport (ClutterStage *stage);
|
||||||
CLUTTER_AVAILABLE_IN_ALL
|
CLUTTER_AVAILABLE_IN_ALL
|
||||||
|
@ -54,7 +54,7 @@ typedef struct _ClutterStageViewCoglPrivate
|
|||||||
/* Stores a list of previous damaged areas in the stage coordinate space */
|
/* Stores a list of previous damaged areas in the stage coordinate space */
|
||||||
#define DAMAGE_HISTORY_MAX 16
|
#define DAMAGE_HISTORY_MAX 16
|
||||||
#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
|
#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
|
||||||
cairo_rectangle_int_t damage_history[DAMAGE_HISTORY_MAX];
|
cairo_region_t * damage_history[DAMAGE_HISTORY_MAX];
|
||||||
unsigned int damage_index;
|
unsigned int damage_index;
|
||||||
} ClutterStageViewCoglPrivate;
|
} ClutterStageViewCoglPrivate;
|
||||||
|
|
||||||
@ -246,13 +246,10 @@ clutter_stage_cogl_has_redraw_clips (ClutterStageWindow *stage_window)
|
|||||||
/* NB: at the start of each new frame there is an implied clip that
|
/* 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
|
* clips everything (i.e. nothing would be drawn) so we need to make
|
||||||
* sure we return True in the un-initialized case here.
|
* sure we return True in the un-initialized case here.
|
||||||
*
|
|
||||||
* NB: a clip width of 0 means a full stage redraw has been queued
|
|
||||||
* so we effectively don't have any redraw clips in that case.
|
|
||||||
*/
|
*/
|
||||||
if (!stage_cogl->initialized_redraw_clip ||
|
if (!stage_cogl->initialized_redraw_clip ||
|
||||||
(stage_cogl->initialized_redraw_clip &&
|
(stage_cogl->initialized_redraw_clip &&
|
||||||
stage_cogl->bounding_redraw_clip.width != 0))
|
stage_cogl->redraw_clip))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -263,9 +260,9 @@ clutter_stage_cogl_ignoring_redraw_clips (ClutterStageWindow *stage_window)
|
|||||||
{
|
{
|
||||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||||
|
|
||||||
/* NB: a clip width of 0 means a full stage redraw is required */
|
/* NB: a NULL clip means a full stage redraw is required */
|
||||||
if (stage_cogl->initialized_redraw_clip &&
|
if (stage_cogl->initialized_redraw_clip &&
|
||||||
stage_cogl->bounding_redraw_clip.width == 0)
|
!stage_cogl->redraw_clip)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -296,11 +293,11 @@ clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* A NULL stage clip means a full stage redraw has been queued and
|
/* A NULL stage clip means a full stage redraw has been queued and
|
||||||
* we keep track of this by setting a zero width
|
* we keep track of this by setting a NULL redraw_clip.
|
||||||
* stage_cogl->bounding_redraw_clip */
|
*/
|
||||||
if (stage_clip == NULL)
|
if (stage_clip == NULL)
|
||||||
{
|
{
|
||||||
stage_cogl->bounding_redraw_clip.width = 0;
|
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
|
||||||
stage_cogl->initialized_redraw_clip = TRUE;
|
stage_cogl->initialized_redraw_clip = TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -309,34 +306,27 @@ clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window,
|
|||||||
if (stage_clip->width == 0 || stage_clip->height == 0)
|
if (stage_clip->width == 0 || stage_clip->height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!stage_cogl->initialized_redraw_clip)
|
if (!stage_cogl->redraw_clip)
|
||||||
{
|
{
|
||||||
stage_cogl->bounding_redraw_clip = *stage_clip;
|
stage_cogl->redraw_clip = cairo_region_create_rectangle (stage_clip);
|
||||||
}
|
}
|
||||||
else if (stage_cogl->bounding_redraw_clip.width > 0)
|
else
|
||||||
{
|
{
|
||||||
_clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip,
|
cairo_region_union_rectangle (stage_cogl->redraw_clip, stage_clip);
|
||||||
stage_clip,
|
|
||||||
&stage_cogl->bounding_redraw_clip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stage_cogl->initialized_redraw_clip = TRUE;
|
stage_cogl->initialized_redraw_clip = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static cairo_region_t *
|
||||||
clutter_stage_cogl_get_redraw_clip_bounds (ClutterStageWindow *stage_window,
|
clutter_stage_cogl_get_redraw_clip (ClutterStageWindow *stage_window)
|
||||||
cairo_rectangle_int_t *stage_clip)
|
|
||||||
{
|
{
|
||||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||||
|
|
||||||
if (stage_cogl->using_clipped_redraw)
|
if (stage_cogl->using_clipped_redraw && stage_cogl->redraw_clip)
|
||||||
{
|
return cairo_region_copy (stage_cogl->redraw_clip);
|
||||||
*stage_clip = stage_cogl->bounding_redraw_clip;
|
|
||||||
|
|
||||||
return TRUE;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
@ -414,37 +404,51 @@ swap_framebuffer (ClutterStageWindow *stage_window,
|
|||||||
static void
|
static void
|
||||||
paint_stage (ClutterStageCogl *stage_cogl,
|
paint_stage (ClutterStageCogl *stage_cogl,
|
||||||
ClutterStageView *view,
|
ClutterStageView *view,
|
||||||
const cairo_rectangle_int_t *clip)
|
cairo_region_t *clip)
|
||||||
{
|
{
|
||||||
ClutterStage *stage = stage_cogl->wrapper;
|
ClutterStage *stage = stage_cogl->wrapper;
|
||||||
|
cairo_rectangle_int_t clip_rect;
|
||||||
|
|
||||||
|
cairo_region_get_extents (clip, &clip_rect);
|
||||||
|
|
||||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||||
_clutter_stage_paint_view (stage, view, clip);
|
_clutter_stage_paint_view (stage, view, &clip_rect);
|
||||||
|
|
||||||
if (clutter_stage_view_get_onscreen (view) !=
|
if (clutter_stage_view_get_onscreen (view) !=
|
||||||
clutter_stage_view_get_framebuffer (view))
|
clutter_stage_view_get_framebuffer (view))
|
||||||
{
|
{
|
||||||
clutter_stage_view_blit_offscreen (view, clip);
|
clutter_stage_view_blit_offscreen (view, &clip_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_current_damage_history_and_step (ClutterStageView *view)
|
fill_current_damage_history (ClutterStageView *view,
|
||||||
|
cairo_region_t *damage)
|
||||||
{
|
{
|
||||||
ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
|
ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
|
||||||
ClutterStageViewCoglPrivate *view_priv =
|
ClutterStageViewCoglPrivate *view_priv =
|
||||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||||
cairo_rectangle_int_t view_rect;
|
cairo_region_t **current_damage;
|
||||||
cairo_rectangle_int_t *current_damage;
|
|
||||||
|
|
||||||
current_damage =
|
current_damage =
|
||||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
|
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
|
||||||
clutter_stage_view_get_layout (view, &view_rect);
|
|
||||||
|
|
||||||
*current_damage = view_rect;
|
g_clear_pointer (current_damage, cairo_region_destroy);
|
||||||
|
*current_damage = cairo_region_copy (damage);
|
||||||
view_priv->damage_index++;
|
view_priv->damage_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_current_damage_history_rectangle (ClutterStageView *view,
|
||||||
|
const cairo_rectangle_int_t *rect)
|
||||||
|
{
|
||||||
|
cairo_region_t *damage;
|
||||||
|
|
||||||
|
damage = cairo_region_create_rectangle (rect);
|
||||||
|
fill_current_damage_history (view, damage);
|
||||||
|
cairo_region_destroy (damage);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
transform_swap_region_to_onscreen (ClutterStageView *view,
|
transform_swap_region_to_onscreen (ClutterStageView *view,
|
||||||
cairo_rectangle_int_t *swap_region)
|
cairo_rectangle_int_t *swap_region)
|
||||||
@ -499,9 +503,11 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
gboolean do_swap_buffer;
|
gboolean do_swap_buffer;
|
||||||
gboolean swap_with_damage;
|
gboolean swap_with_damage;
|
||||||
ClutterActor *wrapper;
|
ClutterActor *wrapper;
|
||||||
cairo_rectangle_int_t redraw_clip;
|
cairo_region_t *redraw_clip;
|
||||||
|
cairo_region_t *clip_region;
|
||||||
cairo_rectangle_int_t swap_region;
|
cairo_rectangle_int_t swap_region;
|
||||||
cairo_rectangle_int_t clip_region;
|
cairo_rectangle_int_t clip_rect;
|
||||||
|
cairo_rectangle_int_t redraw_rect;
|
||||||
gboolean clip_region_empty;
|
gboolean clip_region_empty;
|
||||||
int fb_scale;
|
int fb_scale;
|
||||||
|
|
||||||
@ -517,20 +523,19 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
cogl_is_onscreen (fb) &&
|
cogl_is_onscreen (fb) &&
|
||||||
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
||||||
|
|
||||||
/* NB: a zero width redraw clip == full stage redraw */
|
/* NB: a NULL redraw clip == full stage redraw */
|
||||||
if (stage_cogl->bounding_redraw_clip.width == 0)
|
if (!stage_cogl->redraw_clip)
|
||||||
have_clip = FALSE;
|
have_clip = FALSE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
redraw_clip = stage_cogl->bounding_redraw_clip;
|
cairo_region_t *view_region;
|
||||||
_clutter_util_rectangle_intersection (&redraw_clip,
|
redraw_clip = cairo_region_copy (stage_cogl->redraw_clip);
|
||||||
&view_rect,
|
|
||||||
&redraw_clip);
|
|
||||||
|
|
||||||
have_clip = !(redraw_clip.x == view_rect.x &&
|
view_region = cairo_region_create_rectangle (&view_rect);
|
||||||
redraw_clip.y == view_rect.y &&
|
cairo_region_intersect (redraw_clip, view_region);
|
||||||
redraw_clip.width == view_rect.width &&
|
|
||||||
redraw_clip.height == view_rect.height);
|
have_clip = !cairo_region_equal (redraw_clip, view_region);
|
||||||
|
cairo_region_destroy (view_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
may_use_clipped_redraw = FALSE;
|
may_use_clipped_redraw = FALSE;
|
||||||
@ -542,11 +547,12 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
|
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
|
||||||
{
|
{
|
||||||
may_use_clipped_redraw = TRUE;
|
may_use_clipped_redraw = TRUE;
|
||||||
clip_region = redraw_clip;
|
clip_region = cairo_region_reference (redraw_clip);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clip_region = (cairo_rectangle_int_t){ 0 };
|
clip_region = cairo_region_create ();
|
||||||
|
redraw_clip = cairo_region_reference (clip_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (may_use_clipped_redraw &&
|
if (may_use_clipped_redraw &&
|
||||||
@ -555,7 +561,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
else
|
else
|
||||||
use_clipped_redraw = FALSE;
|
use_clipped_redraw = FALSE;
|
||||||
|
|
||||||
clip_region_empty = may_use_clipped_redraw && clip_region.width == 0;
|
clip_region_empty = may_use_clipped_redraw && cairo_region_is_empty (clip_region);
|
||||||
|
|
||||||
fb_scale = clutter_stage_view_get_scale (view);
|
fb_scale = clutter_stage_view_get_scale (view);
|
||||||
|
|
||||||
@ -565,34 +571,26 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
if (use_clipped_redraw && !clip_region_empty)
|
if (use_clipped_redraw && !clip_region_empty)
|
||||||
{
|
{
|
||||||
int age, i;
|
int age, i;
|
||||||
cairo_rectangle_int_t *current_damage =
|
|
||||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index++)];
|
|
||||||
|
|
||||||
age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
|
age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
|
||||||
|
|
||||||
if (valid_buffer_age (view_cogl, age))
|
if (valid_buffer_age (view_cogl, age))
|
||||||
{
|
{
|
||||||
*current_damage = clip_region;
|
fill_current_damage_history (view, clip_region);
|
||||||
|
|
||||||
for (i = 1; i <= age; i++)
|
for (i = 1; i <= age; i++)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t *damage =
|
cairo_region_t *damage =
|
||||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)];
|
view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)];
|
||||||
|
cairo_region_union (clip_region, damage);
|
||||||
_clutter_util_rectangle_union (&clip_region, damage, &clip_region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the bounding redraw clip state with the extra damage. */
|
/* Update the redraw clip state with the extra damage. */
|
||||||
_clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip,
|
cairo_region_union (stage_cogl->redraw_clip, clip_region);
|
||||||
&clip_region,
|
|
||||||
&stage_cogl->bounding_redraw_clip);
|
|
||||||
|
|
||||||
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: x=%d, y=%d, width=%d, height=%d\n",
|
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
|
||||||
age,
|
age,
|
||||||
clip_region.x,
|
cairo_region_num_rectangles (clip_region));
|
||||||
clip_region.y,
|
|
||||||
clip_region.width,
|
|
||||||
clip_region.height);
|
|
||||||
|
|
||||||
swap_with_damage = TRUE;
|
swap_with_damage = TRUE;
|
||||||
}
|
}
|
||||||
@ -600,15 +598,17 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
{
|
{
|
||||||
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
|
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
|
||||||
use_clipped_redraw = FALSE;
|
use_clipped_redraw = FALSE;
|
||||||
*current_damage = view_rect;
|
fill_current_damage_history_rectangle (view, &view_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!use_clipped_redraw)
|
else if (!use_clipped_redraw)
|
||||||
{
|
{
|
||||||
fill_current_damage_history_and_step (view);
|
fill_current_damage_history_rectangle (view, &view_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_region_get_extents (clip_region, &clip_rect);
|
||||||
|
|
||||||
cogl_push_framebuffer (fb);
|
cogl_push_framebuffer (fb);
|
||||||
if (use_clipped_redraw && clip_region_empty)
|
if (use_clipped_redraw && clip_region_empty)
|
||||||
{
|
{
|
||||||
@ -621,21 +621,21 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
|
|
||||||
CLUTTER_NOTE (CLIPPING,
|
CLUTTER_NOTE (CLIPPING,
|
||||||
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
|
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
|
||||||
clip_region.x,
|
clip_rect.x,
|
||||||
clip_region.y,
|
clip_rect.y,
|
||||||
clip_region.width,
|
clip_rect.width,
|
||||||
clip_region.height);
|
clip_rect.height);
|
||||||
|
|
||||||
stage_cogl->using_clipped_redraw = TRUE;
|
stage_cogl->using_clipped_redraw = TRUE;
|
||||||
|
|
||||||
scissor_x = (clip_region.x - view_rect.x) * fb_scale;
|
scissor_x = (clip_rect.x - view_rect.x) * fb_scale;
|
||||||
scissor_y = (clip_region.y - view_rect.y) * fb_scale;
|
scissor_y = (clip_rect.y - view_rect.y) * fb_scale;
|
||||||
cogl_framebuffer_push_scissor_clip (fb,
|
cogl_framebuffer_push_scissor_clip (fb,
|
||||||
scissor_x,
|
scissor_x,
|
||||||
scissor_y,
|
scissor_y,
|
||||||
clip_region.width * fb_scale,
|
clip_rect.width * fb_scale,
|
||||||
clip_region.height * fb_scale);
|
clip_rect.height * fb_scale);
|
||||||
paint_stage (stage_cogl, view, &clip_region);
|
paint_stage (stage_cogl, view, clip_region);
|
||||||
cogl_framebuffer_pop_clip (fb);
|
cogl_framebuffer_pop_clip (fb);
|
||||||
|
|
||||||
stage_cogl->using_clipped_redraw = FALSE;
|
stage_cogl->using_clipped_redraw = FALSE;
|
||||||
@ -645,7 +645,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
CLUTTER_NOTE (CLIPPING, "Unclipped stage paint\n");
|
CLUTTER_NOTE (CLIPPING, "Unclipped stage paint\n");
|
||||||
|
|
||||||
/* If we are trying to debug redraw issues then we want to pass
|
/* If we are trying to debug redraw issues then we want to pass
|
||||||
* the bounding_redraw_clip so it can be visualized */
|
* the redraw_clip so it can be visualized */
|
||||||
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
|
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
|
||||||
may_use_clipped_redraw &&
|
may_use_clipped_redraw &&
|
||||||
!clip_region_empty)
|
!clip_region_empty)
|
||||||
@ -653,31 +653,39 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
int scissor_x;
|
int scissor_x;
|
||||||
int scissor_y;
|
int scissor_y;
|
||||||
|
|
||||||
scissor_x = (clip_region.x - view_rect.x) * fb_scale;;
|
scissor_x = (clip_rect.x - view_rect.x) * fb_scale;;
|
||||||
scissor_y = (clip_region.y - view_rect.y) * fb_scale;
|
scissor_y = (clip_rect.y - view_rect.y) * fb_scale;
|
||||||
cogl_framebuffer_push_scissor_clip (fb,
|
cogl_framebuffer_push_scissor_clip (fb,
|
||||||
scissor_x,
|
scissor_x,
|
||||||
scissor_y,
|
scissor_y,
|
||||||
clip_region.width * fb_scale,
|
clip_rect.width * fb_scale,
|
||||||
clip_region.height * fb_scale);
|
clip_rect.height * fb_scale);
|
||||||
paint_stage (stage_cogl, view, &clip_region);
|
paint_stage (stage_cogl, view, clip_region);
|
||||||
cogl_framebuffer_pop_clip (fb);
|
cogl_framebuffer_pop_clip (fb);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
paint_stage (stage_cogl, view, &view_rect);
|
{
|
||||||
|
cairo_region_t *view_region;
|
||||||
|
|
||||||
|
view_region = cairo_region_create_rectangle (&view_rect);
|
||||||
|
paint_stage (stage_cogl, view, view_region);
|
||||||
|
cairo_region_destroy (view_region);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cogl_pop_framebuffer ();
|
cogl_pop_framebuffer ();
|
||||||
|
|
||||||
|
cairo_region_get_extents (redraw_clip, &redraw_rect);
|
||||||
|
|
||||||
if (may_use_clipped_redraw &&
|
if (may_use_clipped_redraw &&
|
||||||
G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
|
G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
|
||||||
{
|
{
|
||||||
CoglContext *ctx = cogl_framebuffer_get_context (fb);
|
CoglContext *ctx = cogl_framebuffer_get_context (fb);
|
||||||
static CoglPipeline *outline = NULL;
|
static CoglPipeline *outline = NULL;
|
||||||
ClutterActor *actor = CLUTTER_ACTOR (wrapper);
|
ClutterActor *actor = CLUTTER_ACTOR (wrapper);
|
||||||
float x_1 = redraw_clip.x;
|
float x_1 = redraw_rect.x;
|
||||||
float x_2 = redraw_clip.x + redraw_clip.width;
|
float x_2 = redraw_rect.x + redraw_rect.width;
|
||||||
float y_1 = redraw_clip.y;
|
float y_1 = redraw_rect.y;
|
||||||
float y_2 = redraw_clip.y + redraw_clip.height;
|
float y_2 = redraw_rect.y + redraw_rect.height;
|
||||||
CoglVertexP2 quad[4] = {
|
CoglVertexP2 quad[4] = {
|
||||||
{ x_1, y_1 },
|
{ x_1, y_1 },
|
||||||
{ x_2, y_1 },
|
{ x_2, y_1 },
|
||||||
@ -724,10 +732,10 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
else if (use_clipped_redraw)
|
else if (use_clipped_redraw)
|
||||||
{
|
{
|
||||||
swap_region = (cairo_rectangle_int_t) {
|
swap_region = (cairo_rectangle_int_t) {
|
||||||
.x = (clip_region.x - view_rect.x) * fb_scale,
|
.x = (clip_rect.x - view_rect.x) * fb_scale,
|
||||||
.y = (clip_region.y - view_rect.y) * fb_scale,
|
.y = (clip_rect.y - view_rect.y) * fb_scale,
|
||||||
.width = clip_region.width * fb_scale,
|
.width = clip_rect.width * fb_scale,
|
||||||
.height = clip_region.height * fb_scale,
|
.height = clip_rect.height * fb_scale,
|
||||||
};
|
};
|
||||||
g_assert (swap_region.width > 0);
|
g_assert (swap_region.width > 0);
|
||||||
do_swap_buffer = TRUE;
|
do_swap_buffer = TRUE;
|
||||||
@ -749,6 +757,11 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
do_swap_buffer = TRUE;
|
do_swap_buffer = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (redraw_clip)
|
||||||
|
cairo_region_destroy (redraw_clip);
|
||||||
|
if (clip_region)
|
||||||
|
cairo_region_destroy (clip_region);
|
||||||
|
|
||||||
if (do_swap_buffer)
|
if (do_swap_buffer)
|
||||||
{
|
{
|
||||||
if (clutter_stage_view_get_onscreen (view) !=
|
if (clutter_stage_view_get_onscreen (view) !=
|
||||||
@ -796,6 +809,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
|||||||
|
|
||||||
/* reset the redraw clipping for the next paint... */
|
/* reset the redraw clipping for the next paint... */
|
||||||
stage_cogl->initialized_redraw_clip = FALSE;
|
stage_cogl->initialized_redraw_clip = FALSE;
|
||||||
|
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
|
||||||
|
|
||||||
stage_cogl->frame_count++;
|
stage_cogl->frame_count++;
|
||||||
}
|
}
|
||||||
@ -810,7 +824,7 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
|
|||||||
gboolean has_buffer_age =
|
gboolean has_buffer_age =
|
||||||
cogl_is_onscreen (framebuffer) &&
|
cogl_is_onscreen (framebuffer) &&
|
||||||
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
||||||
cairo_rectangle_int_t *rect;
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
if (!has_buffer_age)
|
if (!has_buffer_age)
|
||||||
{
|
{
|
||||||
@ -823,12 +837,18 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
|
|||||||
ClutterStageViewCoglPrivate *view_priv =
|
ClutterStageViewCoglPrivate *view_priv =
|
||||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||||
cairo_rectangle_int_t view_layout;
|
cairo_rectangle_int_t view_layout;
|
||||||
|
cairo_region_t *damage;
|
||||||
|
|
||||||
clutter_stage_view_get_layout (view, &view_layout);
|
clutter_stage_view_get_layout (view, &view_layout);
|
||||||
|
|
||||||
rect = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
|
damage = view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
|
||||||
*x = rect->x - view_layout.x;
|
if (damage)
|
||||||
*y = rect->y - view_layout.y;
|
cairo_region_get_rectangle (damage, 0, &rect);
|
||||||
|
else
|
||||||
|
rect.x = rect.y = 0;
|
||||||
|
|
||||||
|
*x = rect.x - view_layout.x;
|
||||||
|
*y = rect.y - view_layout.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,7 +867,7 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
|||||||
iface->add_redraw_clip = clutter_stage_cogl_add_redraw_clip;
|
iface->add_redraw_clip = clutter_stage_cogl_add_redraw_clip;
|
||||||
iface->has_redraw_clips = clutter_stage_cogl_has_redraw_clips;
|
iface->has_redraw_clips = clutter_stage_cogl_has_redraw_clips;
|
||||||
iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips;
|
iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips;
|
||||||
iface->get_redraw_clip_bounds = clutter_stage_cogl_get_redraw_clip_bounds;
|
iface->get_redraw_clip = clutter_stage_cogl_get_redraw_clip;
|
||||||
iface->redraw = clutter_stage_cogl_redraw;
|
iface->redraw = clutter_stage_cogl_redraw;
|
||||||
iface->get_dirty_pixel = clutter_stage_cogl_get_dirty_pixel;
|
iface->get_dirty_pixel = clutter_stage_cogl_get_dirty_pixel;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ struct _ClutterStageCogl
|
|||||||
* junk frames to start with. */
|
* junk frames to start with. */
|
||||||
unsigned int frame_count;
|
unsigned int frame_count;
|
||||||
|
|
||||||
cairo_rectangle_int_t bounding_redraw_clip;
|
cairo_region_t *redraw_clip;
|
||||||
|
|
||||||
guint initialized_redraw_clip : 1;
|
guint initialized_redraw_clip : 1;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user