[clutter] clutter-stage: Add clutter_stage_get_redraw_clip_bounds



commit a72237b8761d3c760922703e981a1234abf4a6fe
Author: Neil Roberts <neil linux intel com>
Date:   Tue Jul 12 17:16:43 2011 +0100

    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

 clutter/clutter-stage-window.c             |   15 ++++++++++
 clutter/clutter-stage-window.h             |    6 ++++
 clutter/clutter-stage.c                    |   41 ++++++++++++++++++++++++++++
 clutter/clutter-stage.h                    |    4 +++
 clutter/cogl/clutter-stage-cogl.c          |   25 +++++++++++++++++
 clutter/cogl/clutter-stage-cogl.h          |    4 +++
 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 93d522a..04cf786 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 9666b89..de84e31 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 ac0e65f..991becf 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 855fe36..cdd7797 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 111605e..3f3704d 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 e718d27..891eeb8 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 98a34dc..752388e 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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]