stage-window: tweak has_redraw_clips semantics

This tweaks the semantics of the has_redraw_clips vfunc so we can assume
that at the start of a new frame there is an implied, initial,
redraw_clip that clips everything (i.e. nothing would be redrawn) so in
that case we would expect the has_redraw_clips vfunc to return True at
the start of a new frame for backends that support clipping.

Previously there was an ambiguity when this function returned False
since it could either mean a full screen redraw had been queued or it
could mean that the clip state wasn't yet initialized for that frame.
This would result in _clutter_stage_has_full_redraw_queued() returning
True at the start of a new frame even before any actors have been
updated, which in turn meant we would incorrectly ignore queue_redraw
requests for actors, believing them to be redundant.
This commit is contained in:
Robert Bragg 2010-11-23 16:05:44 +00:00
parent 446107f19d
commit 5f181f7265
3 changed files with 43 additions and 13 deletions

View File

@ -124,6 +124,14 @@ _clutter_stage_window_add_redraw_clip (ClutterStageWindow *window,
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)
{
@ -138,6 +146,14 @@ _clutter_stage_window_has_redraw_clips (ClutterStageWindow *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)
{

View File

@ -278,9 +278,16 @@ clutter_stage_egl_has_redraw_clips (ClutterStageWindow *stage_window)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
/* NB: a degenerate clip means a full stage redraw is required */
if (stage_egl->initialized_redraw_clip &&
stage_egl->bounding_redraw_clip.width != 0)
/* 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.
*
* 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_egl->initialized_redraw_clip ||
(stage_egl->initialized_redraw_clip &&
stage_egl->bounding_redraw_clip.width != 0))
return TRUE;
else
return FALSE;
@ -291,7 +298,7 @@ clutter_stage_egl_ignoring_redraw_clips (ClutterStageWindow *stage_window)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
/* NB: a degenerate clip means a full stage redraw is required */
/* NB: a clip width of 0 means a full stage redraw is required */
if (stage_egl->initialized_redraw_clip &&
stage_egl->bounding_redraw_clip.width == 0)
return TRUE;
@ -324,7 +331,7 @@ clutter_stage_egl_add_redraw_clip (ClutterStageWindow *stage_window,
return;
/* A NULL stage clip means a full stage redraw has been queued and
* we keep track of this by setting a degenerate
* we keep track of this by setting a zero width
* stage_egl->bounding_redraw_clip */
if (stage_clip == NULL)
{
@ -444,7 +451,7 @@ _clutter_stage_egl_redraw (ClutterStageEGL *stage_egl,
#endif
if (G_LIKELY (backend_egl->can_blit_sub_buffer) &&
/* NB: a degenerate redraw clip width == full stage redraw */
/* NB: a zero width clip == full stage redraw */
stage_egl->bounding_redraw_clip.width != 0 &&
/* some drivers struggle to get going and produce some junk
* frames when starting up... */

View File

@ -291,9 +291,16 @@ clutter_stage_glx_has_redraw_clips (ClutterStageWindow *stage_window)
{
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window);
/* NB: a degenerate clip means a full stage redraw is required */
if (stage_glx->initialized_redraw_clip &&
stage_glx->bounding_redraw_clip.width != 0)
/* 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.
*
* 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_glx->initialized_redraw_clip ||
(stage_glx->initialized_redraw_clip &&
stage_glx->bounding_redraw_clip.width != 0))
return TRUE;
else
return FALSE;
@ -304,7 +311,7 @@ clutter_stage_glx_ignoring_redraw_clips (ClutterStageWindow *stage_window)
{
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window);
/* NB: a degenerate clip means a full stage redraw is required */
/* NB: a clip width of 0 means a full stage redraw is required */
if (stage_glx->initialized_redraw_clip &&
stage_glx->bounding_redraw_clip.width == 0)
return TRUE;
@ -369,7 +376,7 @@ clutter_stage_glx_add_redraw_clip (ClutterStageWindow *stage_window,
return;
/* A NULL stage clip means a full stage redraw has been queued and
* we keep track of this by setting a degenerate
* we keep track of this by setting a zero width
* stage_glx->bounding_redraw_clip */
if (stage_clip == NULL)
{
@ -408,7 +415,7 @@ clutter_stage_glx_add_redraw_clip (ClutterStageWindow *stage_window,
if (redraw_area > (stage_area * 0.7f))
{
g_print ("DEBUG: clipped redraw too big, forcing full redraw\n");
/* Set a degenerate clip to force a full redraw */
/* Set a zero width clip to force a full redraw */
stage_glx->bounding_redraw_clip.width = 0;
}
#endif
@ -519,7 +526,7 @@ _clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer);
if (G_LIKELY (backend_glx->can_blit_sub_buffer) &&
/* NB: a degenerate redraw clip width == full stage redraw */
/* NB: a zero width redraw clip == full stage redraw */
stage_glx->bounding_redraw_clip.width != 0 &&
/* some drivers struggle to get going and produce some junk
* frames when starting up... */