summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2011-07-12 17:16:43 +0100
committerNeil Roberts <neil@linux.intel.com>2011-07-13 13:54:50 +0100
commita72237b8761d3c760922703e981a1234abf4a6fe (patch)
tree6cbff01e9c6e1c61d804f6461dfc9fb5889c630c
parent25a7435a866385aa19a4417957d5b9cdc3bd69ac (diff)
downloadclutter-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.c15
-rw-r--r--clutter/clutter-stage-window.h6
-rw-r--r--clutter/clutter-stage.c41
-rw-r--r--clutter/clutter-stage.h4
-rw-r--r--clutter/cogl/clutter-stage-cogl.c25
-rw-r--r--clutter/cogl/clutter-stage-cogl.h4
-rw-r--r--doc/reference/clutter/clutter-sections.txt1
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