summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bragg <robert@linux.intel.com>2011-03-10 22:05:03 +0000
committerRobert Bragg <robert@linux.intel.com>2011-04-11 15:28:53 +0100
commitc739cb2809c5b29c33d504142ce10b42c238e7d4 (patch)
treee68f5fcd0f184ad58b7402c4032d3e4935063e2f
parent997ea0fdee2f72b26c4805ccc40079becc9fc1f2 (diff)
downloadclutter-c739cb2809c5b29c33d504142ce10b42c238e7d4.tar.gz
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.
-rw-r--r--clutter/clutter-actor.c17
-rw-r--r--clutter/clutter-stage-private.h4
-rw-r--r--clutter/clutter-stage-window.c20
-rw-r--r--clutter/clutter-stage-window.h123
-rw-r--r--clutter/clutter-stage.c32
5 files changed, 129 insertions, 67 deletions
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 6316a15ef..b6e18338e 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 79a22f3d3..7e7b395d4 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 a438d5098..d4e2bb54e 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 d616d2b11..9666b89c5 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 bb2b3456a..54717a058 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;
+}