diff options
author | Neil Roberts <neil@linux.intel.com> | 2011-07-12 17:16:43 +0100 |
---|---|---|
committer | Neil Roberts <neil@linux.intel.com> | 2011-07-13 13:54:50 +0100 |
commit | a72237b8761d3c760922703e981a1234abf4a6fe (patch) | |
tree | 6cbff01e9c6e1c61d804f6461dfc9fb5889c630c | |
parent | 25a7435a866385aa19a4417957d5b9cdc3bd69ac (diff) | |
download | clutter-a72237b8761d3c760922703e981a1234abf4a6fe.tar.gz |
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
-rw-r--r-- | clutter/clutter-stage-window.c | 15 | ||||
-rw-r--r-- | clutter/clutter-stage-window.h | 6 | ||||
-rw-r--r-- | clutter/clutter-stage.c | 41 | ||||
-rw-r--r-- | clutter/clutter-stage.h | 4 | ||||
-rw-r--r-- | clutter/cogl/clutter-stage-cogl.c | 25 | ||||
-rw-r--r-- | clutter/cogl/clutter-stage-cogl.h | 4 | ||||
-rw-r--r-- | doc/reference/clutter/clutter-sections.txt | 1 |
7 files changed, 96 insertions, 0 deletions
diff --git a/clutter/clutter-stage-window.c b/clutter/clutter-stage-window.c index 93d522ad6..04cf7865f 100644 --- a/clutter/clutter-stage-window.c +++ b/clutter/clutter-stage-window.c @@ -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) diff --git a/clutter/clutter-stage-window.h b/clutter/clutter-stage-window.h index 9666b89c5..de84e3174 100644 --- a/clutter/clutter-stage-window.h +++ b/clutter/clutter-stage-window.h @@ -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); diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index ac0e65f31..991becfde 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -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, diff --git a/clutter/clutter-stage.h b/clutter/clutter-stage.h index 855fe36f3..cdd779735 100644 --- a/clutter/clutter-stage.h +++ b/clutter/clutter-stage.h @@ -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); diff --git a/clutter/cogl/clutter-stage-cogl.c b/clutter/cogl/clutter-stage-cogl.c index 111605ec7..3f3704d86 100644 --- a/clutter/cogl/clutter-stage-cogl.c +++ b/clutter/cogl/clutter-stage-cogl.c @@ -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; } diff --git a/clutter/cogl/clutter-stage-cogl.h b/clutter/cogl/clutter-stage-cogl.h index e718d2767..891eeb824 100644 --- a/clutter/cogl/clutter-stage-cogl.h +++ b/clutter/cogl/clutter-stage-cogl.h @@ -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 diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt index 98a34dcfa..752388e26 100644 --- a/doc/reference/clutter/clutter-sections.txt +++ b/doc/reference/clutter/clutter-sections.txt @@ -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 |