[clutter/wip/cogl-winsys-glx: 10/20] stage: adds internal_get_active_framebuffer API



commit c739cb2809c5b29c33d504142ce10b42c238e7d4
Author: Robert Bragg <robert linux intel com>
Date:   Thu Mar 10 22:05:03 2011 +0000

    stage: adds internal_get_active_framebuffer API
    
    This adds an internal _clutter_stage_get_active_framebuffer function
    that can be used to get a pointer to the current CoglFramebuffer pointer
    that is in use, in association with a given stage.
    
    The "active" infix in the function name is there because we shouldn't
    assume that a stage will always correspond to only a single framebuffer
    so we aren't getting a pointer to a sole framebuffer, we are getting
    a pointer to the framebuffer that is currently in use/being painted.
    
    This API is now used for culling purposes where we need to check if we
    are currently painting an actor to a framebuffer that is offscreen, that
    doesn't correspond to the stage.

 clutter/clutter-actor.c         |   17 +++---
 clutter/clutter-stage-private.h |    4 +
 clutter/clutter-stage-window.c  |   20 ++++++
 clutter/clutter-stage-window.h  |  123 ++++++++++++++++++++-------------------
 clutter/clutter-stage.c         |   32 ++++++++++
 5 files changed, 129 insertions(+), 67 deletions(-)
---
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 6316a15..b6e1833 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -2524,14 +2524,6 @@ cull_actor (ClutterActor *self)
   const ClutterPlane *stage_clip;
   ClutterCullResult result;
 
-  if (cogl_get_draw_framebuffer () != NULL)
-    {
-      CLUTTER_NOTE (CLIPPING, "Bail from cull_actor without culling (%s): "
-                    "Current framebuffer doesn't correspond to stage",
-                    G_OBJECT_TYPE_NAME (self));
-      return FALSE;
-    }
-
   if (!priv->last_paint_volume_valid)
     {
       CLUTTER_NOTE (CLIPPING, "Bail from cull_actor without culling (%s): "
@@ -2553,6 +2545,15 @@ cull_actor (ClutterActor *self)
       return FALSE;
     }
 
+  if (cogl_get_draw_framebuffer () !=
+      _clutter_stage_get_active_framebuffer (CLUTTER_STAGE (stage)))
+    {
+      CLUTTER_NOTE (CLIPPING, "Bail from cull_actor without culling (%s): "
+                    "Current framebuffer doesn't correspond to stage",
+                    G_OBJECT_TYPE_NAME (self));
+      return FALSE;
+    }
+
   result = _clutter_paint_volume_cull (&priv->last_paint_volume, stage_clip);
   if (result == CLUTTER_CULL_RESULT_IN ||
       result == CLUTTER_CULL_RESULT_PARTIAL)
diff --git a/clutter/clutter-stage-private.h b/clutter/clutter-stage-private.h
index 79a22f3..7e7b395 100644
--- a/clutter/clutter-stage-private.h
+++ b/clutter/clutter-stage-private.h
@@ -27,6 +27,8 @@
 #include <clutter/clutter-input-device.h>
 #include <clutter/clutter-private.h>
 
+#include <cogl/cogl.h>
+
 G_BEGIN_DECLS
 
 typedef struct _ClutterStageQueueRedrawEntry ClutterStageQueueRedrawEntry;
@@ -92,6 +94,8 @@ void     _clutter_stage_set_motion_events_enabled (ClutterStage *stage,
                                                    gboolean      enabled);
 gboolean _clutter_stage_get_motion_events_enabled (ClutterStage *stage);
 
+CoglFramebuffer *_clutter_stage_get_active_framebuffer (ClutterStage *stage);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_STAGE_PRIVATE_H__ */
diff --git a/clutter/clutter-stage-window.c b/clutter/clutter-stage-window.c
index a438d50..d4e2bb5 100644
--- a/clutter/clutter-stage-window.c
+++ b/clutter/clutter-stage-window.c
@@ -192,3 +192,23 @@ _clutter_stage_window_redraw (ClutterStageWindow *window)
   if (iface->redraw)
     iface->redraw (window);
 }
+
+/* NB: The presumption shouldn't be that a stage can't be comprised of
+ * multiple internal framebuffers, so instead of simply naming this
+ * function _clutter_stage_window_get_framebuffer(), the "active"
+ * infix is intended to clarify that it gets the framebuffer that is
+ * currently in use/being painted.
+ */
+CoglFramebuffer *
+_clutter_stage_window_get_active_framebuffer (ClutterStageWindow *window)
+{
+  ClutterStageWindowIface *iface;
+
+  g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), NULL);
+
+  iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
+  if (iface->get_active_framebuffer)
+    return iface->get_active_framebuffer (window);
+  else
+    return NULL;
+}
diff --git a/clutter/clutter-stage-window.h b/clutter/clutter-stage-window.h
index d616d2b..9666b89 100644
--- a/clutter/clutter-stage-window.h
+++ b/clutter/clutter-stage-window.h
@@ -2,6 +2,7 @@
 #define __CLUTTER_STAGE_WINDOW_H__
 
 #include <clutter/clutter-actor.h>
+#include <cogl/cogl.h>
 
 G_BEGIN_DECLS
 
@@ -33,79 +34,83 @@ struct _ClutterStageWindowIface
   /*< private >*/
   GTypeInterface parent_iface;
 
-  ClutterActor *(* get_wrapper)           (ClutterStageWindow *stage_window);
+  ClutterActor     *(* get_wrapper)             (ClutterStageWindow *stage_window);
 
-  void          (* set_title)             (ClutterStageWindow *stage_window,
-                                           const gchar        *title);
-  void          (* set_fullscreen)        (ClutterStageWindow *stage_window,
-                                           gboolean            is_fullscreen);
-  void          (* set_cursor_visible)    (ClutterStageWindow *stage_window,
-                                           gboolean            cursor_visible);
-  void          (* set_user_resizable)    (ClutterStageWindow *stage_window,
-                                           gboolean            is_resizable);
+  void              (* set_title)               (ClutterStageWindow *stage_window,
+                                                 const gchar        *title);
+  void              (* set_fullscreen)          (ClutterStageWindow *stage_window,
+                                                 gboolean            is_fullscreen);
+  void              (* set_cursor_visible)      (ClutterStageWindow *stage_window,
+                                                 gboolean            cursor_visible);
+  void              (* set_user_resizable)      (ClutterStageWindow *stage_window,
+                                                 gboolean            is_resizable);
 
-  gboolean      (* realize)               (ClutterStageWindow *stage_window);
-  void          (* unrealize)             (ClutterStageWindow *stage_window);
+  gboolean          (* realize)                 (ClutterStageWindow *stage_window);
+  void              (* unrealize)               (ClutterStageWindow *stage_window);
 
-  void          (* show)                  (ClutterStageWindow *stage_window,
-                                           gboolean            do_raise);
-  void          (* hide)                  (ClutterStageWindow *stage_window);
+  void              (* show)                    (ClutterStageWindow *stage_window,
+                                                 gboolean            do_raise);
+  void              (* hide)                    (ClutterStageWindow *stage_window);
 
-  void          (* resize)                (ClutterStageWindow *stage_window,
-                                           gint                width,
-                                           gint                height);
-  void          (* get_geometry)          (ClutterStageWindow *stage_window,
-                                           ClutterGeometry    *geometry);
+  void              (* resize)                  (ClutterStageWindow *stage_window,
+                                                 gint                width,
+                                                 gint                height);
+  void              (* get_geometry)            (ClutterStageWindow *stage_window,
+                                                 ClutterGeometry    *geometry);
 
-  int           (* get_pending_swaps)     (ClutterStageWindow *stage_window);
+  int               (* get_pending_swaps)       (ClutterStageWindow *stage_window);
 
-  void          (* add_redraw_clip)       (ClutterStageWindow *stage_window,
-                                           ClutterGeometry    *stage_rectangle);
-  gboolean      (* has_redraw_clips)      (ClutterStageWindow *stage_window);
-  gboolean      (* ignoring_redraw_clips) (ClutterStageWindow *stage_window);
+  void              (* add_redraw_clip)         (ClutterStageWindow *stage_window,
+                                                 ClutterGeometry    *stage_rectangle);
+  gboolean          (* has_redraw_clips)        (ClutterStageWindow *stage_window);
+  gboolean          (* ignoring_redraw_clips)   (ClutterStageWindow *stage_window);
 
-  void          (* set_accept_focus)      (ClutterStageWindow *stage_window,
-                                           gboolean            accept_focus);
+  void              (* set_accept_focus)        (ClutterStageWindow *stage_window,
+                                                 gboolean            accept_focus);
 
-  void          (* redraw)                (ClutterStageWindow *stage_window);
+  void              (* redraw)                  (ClutterStageWindow *stage_window);
+
+  CoglFramebuffer  *(* get_active_framebuffer)  (ClutterStageWindow *stage_window);
 };
 
 GType clutter_stage_window_get_type (void) G_GNUC_CONST;
 
-ClutterActor *_clutter_stage_window_get_wrapper        (ClutterStageWindow *window);
-
-void          _clutter_stage_window_set_title          (ClutterStageWindow *window,
-                                                        const gchar        *title);
-void          _clutter_stage_window_set_fullscreen     (ClutterStageWindow *window,
-                                                        gboolean            is_fullscreen);
-void          _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
-                                                        gboolean            is_visible);
-void          _clutter_stage_window_set_user_resizable (ClutterStageWindow *window,
-                                                        gboolean            is_resizable);
-
-gboolean      _clutter_stage_window_realize               (ClutterStageWindow *window);
-void          _clutter_stage_window_unrealize             (ClutterStageWindow *window);
-
-void          _clutter_stage_window_show                  (ClutterStageWindow *window,
-                                                           gboolean            do_raise);
-void          _clutter_stage_window_hide                  (ClutterStageWindow *window);
-
-void          _clutter_stage_window_resize                (ClutterStageWindow *window,
-                                                           gint                width,
-                                                           gint                height);
-void          _clutter_stage_window_get_geometry          (ClutterStageWindow *window,
-                                                           ClutterGeometry    *geometry);
-int           _clutter_stage_window_get_pending_swaps     (ClutterStageWindow *window);
-
-void          _clutter_stage_window_add_redraw_clip       (ClutterStageWindow *window,
-                                                           ClutterGeometry    *stage_clip);
-gboolean      _clutter_stage_window_has_redraw_clips      (ClutterStageWindow *window);
-gboolean      _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window);
-
-void          _clutter_stage_window_set_accept_focus      (ClutterStageWindow *window,
+ClutterActor *    _clutter_stage_window_get_wrapper        (ClutterStageWindow *window);
+
+void              _clutter_stage_window_set_title          (ClutterStageWindow *window,
+                                                            const gchar        *title);
+void              _clutter_stage_window_set_fullscreen     (ClutterStageWindow *window,
+                                                            gboolean            is_fullscreen);
+void              _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
+                                                            gboolean            is_visible);
+void              _clutter_stage_window_set_user_resizable (ClutterStageWindow *window,
+                                                            gboolean            is_resizable);
+
+gboolean          _clutter_stage_window_realize                 (ClutterStageWindow *window);
+void              _clutter_stage_window_unrealize               (ClutterStageWindow *window);
+
+void              _clutter_stage_window_show                    (ClutterStageWindow *window,
+                                                                 gboolean            do_raise);
+void              _clutter_stage_window_hide                    (ClutterStageWindow *window);
+
+void              _clutter_stage_window_resize                  (ClutterStageWindow *window,
+                                                                 gint                width,
+                                                                 gint                height);
+void              _clutter_stage_window_get_geometry            (ClutterStageWindow *window,
+                                                                 ClutterGeometry    *geometry);
+int               _clutter_stage_window_get_pending_swaps       (ClutterStageWindow *window);
+
+void              _clutter_stage_window_add_redraw_clip         (ClutterStageWindow *window,
+                                                                 ClutterGeometry    *stage_clip);
+gboolean          _clutter_stage_window_has_redraw_clips        (ClutterStageWindow *window);
+gboolean          _clutter_stage_window_ignoring_redraw_clips   (ClutterStageWindow *window);
+
+void              _clutter_stage_window_set_accept_focus        (ClutterStageWindow *window,
                                                            gboolean            accept_focus);
 
-void          _clutter_stage_window_redraw                (ClutterStageWindow *window);
+void              _clutter_stage_window_redraw                  (ClutterStageWindow *window);
+
+CoglFramebuffer  *_clutter_stage_window_get_active_framebuffer  (ClutterStageWindow *window);
 
 G_END_DECLS
 
diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c
index bb2b345..54717a0 100644
--- a/clutter/clutter-stage.c
+++ b/clutter/clutter-stage.c
@@ -145,6 +145,8 @@ struct _ClutterStagePrivate
 
   ClutterPickMode     pick_buffer_mode;
 
+  CoglFramebuffer    *active_framebuffer;
+
   GHashTable *devices;
 
   GTimer *fps_timer;
@@ -490,6 +492,23 @@ _cogl_util_get_eye_planes_for_screen_poly (float *polygon,
   cogl_vector3_normalize (&plane->n);
 }
 
+static void
+_clutter_stage_update_active_framebuffer (ClutterStage *stage)
+{
+  ClutterStagePrivate *priv = stage->priv;
+
+  /* We track the CoglFramebuffer that corresponds to the stage itself
+   * so, for example, we can disable culling when rendering to an
+   * offscreen framebuffer.
+   */
+
+  priv->active_framebuffer =
+    _clutter_stage_window_get_active_framebuffer (priv->impl);
+
+  if (!priv->active_framebuffer)
+    priv->active_framebuffer = cogl_get_draw_framebuffer ();
+}
+
 /* This provides a common point of entry for painting the scenegraph
  * for picking or painting...
  *
@@ -545,6 +564,7 @@ _clutter_stage_do_paint (ClutterStage *stage, const ClutterGeometry *clip)
                                              priv->current_clip_planes);
 
   _clutter_stage_paint_volume_stack_free_all (stage);
+  _clutter_stage_update_active_framebuffer (stage);
   clutter_actor_paint (CLUTTER_ACTOR (stage));
 }
 
@@ -3838,3 +3858,15 @@ _clutter_stage_get_motion_events_enabled (ClutterStage *stage)
 {
   return stage->priv->motion_events_enabled;
 }
+
+/* NB: The presumption shouldn't be that a stage can't be comprised
+ * of multiple internal framebuffers, so instead of simply naming
+ * this function _clutter_stage_get_framebuffer(), the "active"
+ * infix is intended to clarify that it gets the framebuffer that
+ * is currently in use/being painted.
+ */
+CoglFramebuffer *
+_clutter_stage_get_active_framebuffer (ClutterStage *stage)
+{
+  return stage->priv->active_framebuffer;
+}



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