clutter-stage: Add clutter_stage_get_redraw_clip_bounds
This adds a public function to get the bounds of the current clipped redraw on a stage. This should only be called while the stage is being painted. The function diverts to a virtual function on the ClutterStageWindow implementation. If the function isn't implemented or it returns FALSE then the entire stage is reported. The clip bounds are in integer pixel coordinates in the stage's coordinate space. http://bugzilla.clutter-project.org/show_bug.cgi?id=2421
This commit is contained in:
parent
25a7435a86
commit
a72237b876
@ -175,6 +175,21 @@ _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
||||
cairo_rectangle_int_t *stage_clip)
|
||||
{
|
||||
ClutterStageWindowIface *iface;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
|
||||
|
||||
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
if (iface->get_redraw_clip_bounds)
|
||||
return iface->get_redraw_clip_bounds (window, stage_clip);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
|
||||
gboolean accept_focus)
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <clutter/clutter-actor.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <cairo.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -64,6 +65,9 @@ struct _ClutterStageWindowIface
|
||||
ClutterGeometry *stage_rectangle);
|
||||
gboolean (* has_redraw_clips) (ClutterStageWindow *stage_window);
|
||||
gboolean (* ignoring_redraw_clips) (ClutterStageWindow *stage_window);
|
||||
gboolean (* get_redraw_clip_bounds) (ClutterStageWindow *stage_window,
|
||||
cairo_rectangle_int_t *clip);
|
||||
|
||||
|
||||
void (* set_accept_focus) (ClutterStageWindow *stage_window,
|
||||
gboolean accept_focus);
|
||||
@ -104,6 +108,8 @@ void _clutter_stage_window_add_redraw_clip (ClutterStageWin
|
||||
ClutterGeometry *stage_clip);
|
||||
gboolean _clutter_stage_window_has_redraw_clips (ClutterStageWindow *window);
|
||||
gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window);
|
||||
gboolean _clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
||||
cairo_rectangle_int_t *clip);
|
||||
|
||||
void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
|
||||
gboolean accept_focus);
|
||||
|
@ -1176,6 +1176,47 @@ _clutter_stage_has_full_redraw_queued (ClutterStage *stage)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_get_redraw_clip_bounds:
|
||||
* @stage: A #ClutterStage
|
||||
* @clip: (out caller-allocates): Return location for the clip bounds
|
||||
*
|
||||
* Gets the bounds of the current redraw for @stage in stage pixel
|
||||
* coordinates. E.g., if only a single actor has queued a redraw then
|
||||
* Clutter may redraw the stage with a clip so that it doesn't have to
|
||||
* paint every pixel in the stage. This function would then return the
|
||||
* bounds of that clip. An application can use this information to
|
||||
* avoid some extra work if it knows that some regions of the stage
|
||||
* aren't going to be painted. This should only be called while the
|
||||
* stage is being painted. If there is no current redraw clip then
|
||||
* this function will set @clip to the full extents of the stage.
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
void
|
||||
clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
|
||||
cairo_rectangle_int_t *clip)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
g_return_if_fail (clip != NULL);
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
if (!_clutter_stage_window_get_redraw_clip_bounds (priv->impl, clip))
|
||||
{
|
||||
ClutterGeometry geometry;
|
||||
|
||||
/* Set clip to the full extents of the stage */
|
||||
_clutter_stage_window_get_geometry (priv->impl, &geometry);
|
||||
clip->x = 0;
|
||||
clip->y = 0;
|
||||
clip->width = geometry.width;
|
||||
clip->height = geometry.height;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
read_pixels_to_file (char *filename_stem,
|
||||
int x,
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <clutter/clutter-group.h>
|
||||
#include <clutter/clutter-color.h>
|
||||
#include <clutter/clutter-event.h>
|
||||
#include <cairo.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -263,6 +264,9 @@ void clutter_stage_set_accept_focus (ClutterStage *stage,
|
||||
gboolean clutter_stage_get_accept_focus (ClutterStage *stage);
|
||||
|
||||
|
||||
void clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
|
||||
cairo_rectangle_int_t *clip);
|
||||
|
||||
void clutter_stage_set_motion_events_enabled (ClutterStage *stage,
|
||||
gboolean enabled);
|
||||
gboolean clutter_stage_get_motion_events_enabled (ClutterStage *stage);
|
||||
|
@ -324,6 +324,25 @@ clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window,
|
||||
stage_cogl->initialized_redraw_clip = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_stage_cogl_get_redraw_clip_bounds (ClutterStageWindow *stage_window,
|
||||
cairo_rectangle_int_t *stage_clip)
|
||||
{
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
|
||||
if (stage_cogl->using_clipped_redraw)
|
||||
{
|
||||
stage_clip->x = stage_cogl->bounding_redraw_clip.x;
|
||||
stage_clip->y = stage_cogl->bounding_redraw_clip.y;
|
||||
stage_clip->width = stage_cogl->bounding_redraw_clip.width;
|
||||
stage_clip->height = stage_cogl->bounding_redraw_clip.height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* XXX: This is basically identical to clutter_stage_glx_redraw */
|
||||
static void
|
||||
clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
@ -401,6 +420,9 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
stage_cogl->bounding_redraw_clip.y,
|
||||
stage_cogl->bounding_redraw_clip.width,
|
||||
stage_cogl->bounding_redraw_clip.height);
|
||||
|
||||
stage_cogl->using_clipped_redraw = TRUE;
|
||||
|
||||
cogl_clip_push_window_rectangle (stage_cogl->bounding_redraw_clip.x,
|
||||
stage_cogl->bounding_redraw_clip.y,
|
||||
stage_cogl->bounding_redraw_clip.width,
|
||||
@ -408,6 +430,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
_clutter_stage_do_paint (CLUTTER_STAGE (wrapper),
|
||||
&stage_cogl->bounding_redraw_clip);
|
||||
cogl_clip_pop ();
|
||||
|
||||
stage_cogl->using_clipped_redraw = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -568,6 +592,7 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||
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_bounds = clutter_stage_cogl_get_redraw_clip_bounds;
|
||||
iface->redraw = clutter_stage_cogl_redraw;
|
||||
iface->get_active_framebuffer = clutter_stage_cogl_get_active_framebuffer;
|
||||
}
|
||||
|
@ -60,6 +60,10 @@ struct _ClutterStageCogl
|
||||
ClutterGeometry bounding_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
|
||||
|
@ -610,6 +610,7 @@ clutter_stage_set_minimum_size
|
||||
clutter_stage_get_minimum_size
|
||||
clutter_stage_set_no_clear_hint
|
||||
clutter_stage_get_no_clear_hint
|
||||
clutter_stage_get_redraw_clip_bounds
|
||||
clutter_stage_set_accept_focus
|
||||
clutter_stage_get_accept_focus
|
||||
clutter_stage_get_motion_events_enabled
|
||||
|
Loading…
Reference in New Issue
Block a user