[mutter] ClutterStageCogl: Let the sub-classes handle the onscreen
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] ClutterStageCogl: Let the sub-classes handle the onscreen
- Date: Wed, 20 Jul 2016 06:27:53 +0000 (UTC)
commit 767e12125bab483c08c7f36ac6ff73614d798304
Author: Jonas Ådahl <jadahl gmail com>
Date: Wed May 25 12:44:52 2016 +0800
ClutterStageCogl: Let the sub-classes handle the onscreen
In preperation for having allowing drawing onto multiple onscreen
framebuffers, move the onscreen framebuffer handling to the
corresponding winsys dependent backends.
Currently the onscreen framebuffer is still accessed, but, as can seen
by the usage of "legacy" in the accessor name, it should be considered
the legacy method. Eventually only the X11 Compositing Manager backend
will make use of the legacy single onscreen framebuffer API.
https://bugzilla.gnome.org/show_bug.cgi?id=768976
clutter/clutter/clutter-main.c | 1 +
clutter/clutter/clutter-mutter.h | 3 +
clutter/clutter/clutter-private.h | 1 -
clutter/clutter/clutter-stage-window.c | 38 ++++++++++
clutter/clutter/clutter-stage-window.h | 18 +++++
clutter/clutter/clutter-stage.c | 1 +
clutter/clutter/cogl/clutter-stage-cogl.c | 99 +++++--------------------
clutter/clutter/cogl/clutter-stage-cogl.h | 2 -
clutter/clutter/x11/clutter-stage-x11.c | 66 +++++++++++++++--
clutter/clutter/x11/clutter-stage-x11.h | 1 +
src/backends/native/meta-stage-native.c | 114 +++++++++++++++++++++++++++++
11 files changed, 256 insertions(+), 88 deletions(-)
---
diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c
index 9e51bbb..a4f4c1f 100644
--- a/clutter/clutter/clutter-main.c
+++ b/clutter/clutter/clutter-main.c
@@ -62,6 +62,7 @@
#include "clutter-feature.h"
#include "clutter-main.h"
#include "clutter-master-clock.h"
+#include "clutter-mutter.h"
#include "clutter-private.h"
#include "clutter-settings-private.h"
#include "clutter-stage-manager.h"
diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h
index 0436631..f09a07f 100644
--- a/clutter/clutter/clutter-mutter.h
+++ b/clutter/clutter/clutter-mutter.h
@@ -33,6 +33,9 @@
CLUTTER_AVAILABLE_IN_MUTTER
void clutter_set_custom_backend_func (ClutterBackend *(* func) (void));
+CLUTTER_AVAILABLE_IN_MUTTER
+gboolean _clutter_get_sync_to_vblank (void);
+
#undef __CLUTTER_H_INSIDE__
#endif /* __CLUTTER_MUTTER_H__ */
diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h
index 67c45d0..ab2cc97 100644
--- a/clutter/clutter/clutter-private.h
+++ b/clutter/clutter/clutter-private.h
@@ -210,7 +210,6 @@ void _clutter_id_to_color (guint id,
ClutterColor *col);
void _clutter_set_sync_to_vblank (gboolean sync_to_vblank);
-gboolean _clutter_get_sync_to_vblank (void);
/* use this function as the accumulator if you have a signal with
* a G_TYPE_BOOLEAN return value; this will stop the emission as
diff --git a/clutter/clutter/clutter-stage-window.c b/clutter/clutter/clutter-stage-window.c
index 4ef082a..2efb325 100644
--- a/clutter/clutter/clutter-stage-window.c
+++ b/clutter/clutter/clutter-stage-window.c
@@ -348,3 +348,41 @@ _clutter_stage_window_get_scale_factor (ClutterStageWindow *window)
return 1;
}
+
+CoglFramebuffer *
+_clutter_stage_window_get_legacy_onscreen (ClutterStageWindow *window)
+{
+ ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
+
+ return iface->get_legacy_onscreen (window);
+}
+
+CoglFrameClosure *
+_clutter_stage_window_set_frame_callback (ClutterStageWindow *window,
+ CoglFrameCallback callback,
+ gpointer user_data)
+{
+ ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
+
+ return iface->set_frame_callback (window, callback, user_data);
+}
+
+void
+_clutter_stage_window_remove_frame_callback (ClutterStageWindow *window,
+ CoglFrameClosure *closure)
+{
+ ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
+
+ iface->remove_frame_callback (window, closure);
+}
+
+int64_t
+_clutter_stage_window_get_frame_counter (ClutterStageWindow *window)
+{
+ ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
+
+ if (iface->get_frame_counter)
+ return iface->get_frame_counter (window);
+ else
+ return 0;
+}
diff --git a/clutter/clutter/clutter-stage-window.h b/clutter/clutter/clutter-stage-window.h
index 25a68d6..863ecfc 100644
--- a/clutter/clutter/clutter-stage-window.h
+++ b/clutter/clutter/clutter-stage-window.h
@@ -86,6 +86,13 @@ struct _ClutterStageWindowIface
void (* set_scale_factor) (ClutterStageWindow *stage_window,
int factor);
int (* get_scale_factor) (ClutterStageWindow *stage_window);
+ CoglFramebuffer *(* get_legacy_onscreen) (ClutterStageWindow *stage_window);
+ CoglFrameClosure *(* set_frame_callback) (ClutterStageWindow *stage_window,
+ CoglFrameCallback callback,
+ gpointer user_data);
+ void (* remove_frame_callback) (ClutterStageWindow *stage_window,
+ CoglFrameClosure *closure);
+ int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
};
CLUTTER_AVAILABLE_IN_MUTTER
@@ -142,6 +149,17 @@ void _clutter_stage_window_set_scale_factor (ClutterStageWin
int factor);
int _clutter_stage_window_get_scale_factor (ClutterStageWindow *window);
+CoglFramebuffer *_clutter_stage_window_get_legacy_onscreen (ClutterStageWindow *stage_window);
+
+CoglFrameClosure *_clutter_stage_window_set_frame_callback (ClutterStageWindow *window,
+ CoglFrameCallback callback,
+ gpointer user_data);
+
+void _clutter_stage_window_remove_frame_callback (ClutterStageWindow *stage_winow,
+ CoglFrameClosure *closure);
+
+int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window);
+
G_END_DECLS
#endif /* __CLUTTER_STAGE_WINDOW_H__ */
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index aa34240..8f5abb4 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -69,6 +69,7 @@
#include "clutter-main.h"
#include "clutter-marshal.h"
#include "clutter-master-clock.h"
+#include "clutter-mutter.h"
#include "clutter-paint-volume-private.h"
#include "clutter-private.h"
#include "clutter-stage-manager-private.h"
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index ee9d6e9..90bc26f 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -68,14 +68,11 @@ clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
CLUTTER_NOTE (BACKEND, "Unrealizing Cogl stage [%p]", stage_cogl);
- if (stage_cogl->onscreen != NULL)
+ if (stage_cogl->frame_closure != NULL)
{
- cogl_onscreen_remove_frame_callback (stage_cogl->onscreen,
- stage_cogl->frame_closure);
+ _clutter_stage_window_remove_frame_callback (stage_window,
+ stage_cogl->frame_closure);
stage_cogl->frame_closure = NULL;
-
- cogl_object_unref (stage_cogl->onscreen);
- stage_cogl->onscreen = NULL;
}
stage_cogl->pending_swaps = 0;
@@ -126,10 +123,6 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
ClutterBackend *backend;
- CoglFramebuffer *framebuffer;
- GError *error = NULL;
- gfloat width = 800;
- gfloat height = 600;
CLUTTER_NOTE (BACKEND, "Realizing stage '%s' [%p]",
G_OBJECT_TYPE_NAME (stage_cogl),
@@ -143,34 +136,10 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
return FALSE;
}
- if (stage_cogl->onscreen == NULL)
- {
- stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
- width, height);
- }
-
- cogl_onscreen_set_swap_throttled (stage_cogl->onscreen,
- _clutter_get_sync_to_vblank ());
-
- framebuffer = COGL_FRAMEBUFFER (stage_cogl->onscreen);
- if (!cogl_framebuffer_allocate (framebuffer, &error))
- {
- g_warning ("Failed to allocate stage: %s", error->message);
- g_error_free (error);
- cogl_object_unref (stage_cogl->onscreen);
- stage_cogl->onscreen = NULL;
- return FALSE;
- }
-
- /* FIXME: for fullscreen Cogl platforms then the size we gave
- * will be ignored, so we need to make sure the stage size is
- * updated to this size. */
-
stage_cogl->frame_closure =
- cogl_onscreen_add_frame_callback (stage_cogl->onscreen,
- frame_cb,
- stage_cogl,
- NULL);
+ _clutter_stage_window_set_frame_callback (stage_window,
+ frame_cb, stage_window);
+
return TRUE;
}
@@ -263,36 +232,6 @@ clutter_stage_cogl_hide (ClutterStageWindow *stage_window)
}
static void
-clutter_stage_cogl_get_geometry (ClutterStageWindow *stage_window,
- cairo_rectangle_int_t *geometry)
-{
- ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
- int window_scale;
-
- window_scale = _clutter_stage_window_get_scale_factor (stage_window);
-
- if (geometry != NULL)
- {
- if (stage_cogl->onscreen)
- {
- CoglFramebuffer *framebuffer =
- COGL_FRAMEBUFFER (stage_cogl->onscreen);
-
- geometry->x = geometry->y = 0;
-
- geometry->width = cogl_framebuffer_get_width (framebuffer) / window_scale;
- geometry->height = cogl_framebuffer_get_height (framebuffer) / window_scale;
- }
- else
- {
- geometry->x = geometry->y = 0;
- geometry->width = 800;
- geometry->height = 600;
- }
- }
-}
-
-static void
clutter_stage_cogl_resize (ClutterStageWindow *stage_window,
gint width,
gint height)
@@ -414,6 +353,7 @@ static void
clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
+ CoglOnscreen *onscreen;
cairo_rectangle_int_t geom;
gboolean have_clip;
gboolean may_use_clipped_redraw;
@@ -428,7 +368,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
- if (!stage_cogl->onscreen)
+ onscreen = _clutter_stage_window_get_legacy_onscreen (stage_window);
+ if (!onscreen)
return;
can_blit_sub_buffer =
@@ -476,7 +417,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
if (use_clipped_redraw)
{
- int age = cogl_onscreen_get_buffer_age (stage_cogl->onscreen), i;
+ int age = cogl_onscreen_get_buffer_age (onscreen), i;
*current_damage = *clip_region;
@@ -512,7 +453,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
if (use_clipped_redraw)
{
- CoglFramebuffer *fb = COGL_FRAMEBUFFER (stage_cogl->onscreen);
+ CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
CLUTTER_NOTE (CLIPPING,
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
@@ -551,7 +492,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
if (may_use_clipped_redraw &&
G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
{
- CoglFramebuffer *fb = COGL_FRAMEBUFFER (stage_cogl->onscreen);
+ CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
CoglContext *ctx = cogl_framebuffer_get_context (fb);
static CoglPipeline *outline = NULL;
cairo_rectangle_int_t *clip = &stage_cogl->bounding_redraw_clip;
@@ -584,7 +525,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
cogl_matrix_init_identity (&modelview);
_clutter_actor_apply_modelview_transform (actor, &modelview);
cogl_framebuffer_set_modelview_matrix (fb, &modelview);
- cogl_framebuffer_draw_primitive (COGL_FRAMEBUFFER (stage_cogl->onscreen),
+ cogl_framebuffer_draw_primitive (COGL_FRAMEBUFFER (onscreen),
outline,
prim);
cogl_framebuffer_pop_matrix (fb);
@@ -619,16 +560,16 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
"cogl_onscreen_swap_region (onscreen: %p, "
"x: %d, y: %d, "
"width: %d, height: %d)",
- stage_cogl->onscreen,
+ onscreen,
damage[0], damage[1], damage[2], damage[3]);
- cogl_onscreen_swap_region (stage_cogl->onscreen,
+ cogl_onscreen_swap_region (onscreen,
damage, ndamage);
}
else
{
CLUTTER_NOTE (BACKEND, "cogl_onscreen_swap_buffers (onscreen: %p)",
- stage_cogl->onscreen);
+ onscreen);
/* If we have swap buffer events then cogl_onscreen_swap_buffers
* will return immediately and we need to track that there is a
@@ -636,7 +577,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
if (clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS))
stage_cogl->pending_swaps++;
- cogl_onscreen_swap_buffers_with_damage (stage_cogl->onscreen,
+ cogl_onscreen_swap_buffers_with_damage (onscreen,
damage, ndamage);
}
@@ -649,9 +590,10 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
static CoglFramebuffer *
clutter_stage_cogl_get_active_framebuffer (ClutterStageWindow *stage_window)
{
- ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
+ CoglOnscreen *onscreen =
+ _clutter_stage_window_get_legacy_onscreen (stage_window);
- return COGL_FRAMEBUFFER (stage_cogl->onscreen);
+ return COGL_FRAMEBUFFER (onscreen);
}
static void
@@ -683,7 +625,6 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
iface->realize = clutter_stage_cogl_realize;
iface->unrealize = clutter_stage_cogl_unrealize;
iface->get_wrapper = clutter_stage_cogl_get_wrapper;
- iface->get_geometry = clutter_stage_cogl_get_geometry;
iface->resize = clutter_stage_cogl_resize;
iface->show = clutter_stage_cogl_show;
iface->hide = clutter_stage_cogl_hide;
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.h b/clutter/clutter/cogl/clutter-stage-cogl.h
index c8abdef..690a012 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.h
+++ b/clutter/clutter/cogl/clutter-stage-cogl.h
@@ -35,8 +35,6 @@ struct _ClutterStageCogl
/* back pointer to the backend */
ClutterBackend *backend;
- CoglOnscreen *onscreen;
-
float refresh_rate;
int pending_swaps;
diff --git a/clutter/clutter/x11/clutter-stage-x11.c b/clutter/clutter/x11/clutter-stage-x11.c
index 41bd8ca..cd5c3bc 100644
--- a/clutter/clutter/x11/clutter-stage-x11.c
+++ b/clutter/clutter/x11/clutter-stage-x11.c
@@ -42,6 +42,7 @@
#include "clutter-event-private.h"
#include "clutter-feature.h"
#include "clutter-main.h"
+#include "clutter-mutter.h"
#include "clutter-paint-volume-private.h"
#include "clutter-private.h"
#include "clutter-stage-private.h"
@@ -439,10 +440,12 @@ clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
* 1x1 one if we're unrealizing the current one, so Cogl doesn't
* keep any reference to the foreign window.
*/
- if (cogl_get_draw_framebuffer () == COGL_FRAMEBUFFER (stage_cogl->onscreen))
+ if (cogl_get_draw_framebuffer () == COGL_FRAMEBUFFER (stage_x11->onscreen))
_clutter_backend_reset_cogl_framebuffer (stage_cogl->backend);
clutter_stage_window_parent_iface->unrealize (stage_window);
+
+ g_clear_pointer (&stage_x11->onscreen, cogl_object_unref);
}
static void
@@ -608,6 +611,7 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
ClutterDeviceManager *device_manager;
gfloat width, height;
+ GError *error = NULL;
clutter_actor_get_size (CLUTTER_ACTOR (stage_cogl->wrapper), &width, &height);
@@ -620,7 +624,7 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
width, height,
stage_x11->scale_factor);
- stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
+ stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
/* We just created a window of the size of the actor. No need to fix
the size of the stage, just update it. */
@@ -629,21 +633,26 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
if (stage_x11->xwin != None)
{
- cogl_x11_onscreen_set_foreign_window_xid (stage_cogl->onscreen,
+ cogl_x11_onscreen_set_foreign_window_xid (stage_x11->onscreen,
stage_x11->xwin,
_clutter_stage_x11_update_foreign_event_mask,
stage_x11);
}
- /* Chain to the parent class now. ClutterStageCogl will call cogl_framebuffer_allocate,
- which will create the X Window we need */
+ if (!cogl_framebuffer_allocate (stage_x11->onscreen, &error))
+ {
+ g_warning ("Failed to allocate stage: %s", error->message);
+ g_error_free (error);
+ cogl_object_unref (stage_x11->onscreen);
+ abort();
+ }
if (!(clutter_stage_window_parent_iface->realize (stage_window)))
return FALSE;
if (stage_x11->xwin == None)
- stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_cogl->onscreen);
+ stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_x11->onscreen);
if (clutter_stages_by_xid == NULL)
clutter_stages_by_xid = g_hash_table_new (NULL, NULL);
@@ -883,6 +892,47 @@ clutter_stage_x11_get_scale_factor (ClutterStageWindow *stage_window)
return stage_x11->scale_factor;
}
+static CoglFramebuffer *
+clutter_stage_x11_get_legacy_onscreen (ClutterStageWindow *stage_window)
+{
+ ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
+
+ return stage_x11->onscreen;
+}
+
+static CoglFrameClosure *
+clutter_stage_x11_set_frame_callback (ClutterStageWindow *stage_window,
+ CoglFrameCallback callback,
+ gpointer user_data)
+{
+ ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
+
+ cogl_onscreen_set_swap_throttled (stage_x11->onscreen,
+ _clutter_get_sync_to_vblank ());
+
+ return cogl_onscreen_add_frame_callback (stage_x11->onscreen,
+ callback,
+ user_data,
+ NULL);
+}
+
+static void
+clutter_stage_x11_remove_frame_callback (ClutterStageWindow *stage_window,
+ CoglFrameClosure *closure)
+{
+ ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
+
+ cogl_onscreen_remove_frame_callback (stage_x11->onscreen, closure);
+}
+
+static int64_t
+clutter_stage_x11_get_frame_counter (ClutterStageWindow *stage_window)
+{
+ ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
+
+ return cogl_onscreen_get_frame_counter (stage_x11->onscreen);
+}
+
static void
clutter_stage_x11_finalize (GObject *gobject)
{
@@ -957,6 +1007,10 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
iface->can_clip_redraws = clutter_stage_x11_can_clip_redraws;
iface->set_scale_factor = clutter_stage_x11_set_scale_factor;
iface->get_scale_factor = clutter_stage_x11_get_scale_factor;
+ iface->get_legacy_onscreen = clutter_stage_x11_get_legacy_onscreen;
+ iface->set_frame_callback = clutter_stage_x11_set_frame_callback;
+ iface->remove_frame_callback = clutter_stage_x11_remove_frame_callback;
+ iface->get_frame_counter = clutter_stage_x11_get_frame_counter;
}
static inline void
diff --git a/clutter/clutter/x11/clutter-stage-x11.h b/clutter/clutter/x11/clutter-stage-x11.h
index 5f577d8..f15ce9b 100644
--- a/clutter/clutter/x11/clutter-stage-x11.h
+++ b/clutter/clutter/x11/clutter-stage-x11.h
@@ -53,6 +53,7 @@ struct _ClutterStageX11
{
ClutterStageCogl parent_instance;
+ CoglOnscreen *onscreen;
Window xwin;
gint xwin_width;
gint xwin_height; /* FIXME target_width / height */
diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c
index e7cc91a..12061e5 100644
--- a/src/backends/native/meta-stage-native.c
+++ b/src/backends/native/meta-stage-native.c
@@ -26,11 +26,20 @@
#include "backends/native/meta-stage-native.h"
+#include "backends/meta-backend-private.h"
+#include "meta/meta-backend.h"
+#include "meta/meta-monitor-manager.h"
+#include "meta/util.h"
+
struct _MetaStageNative
{
ClutterStageCogl parent;
+
+ CoglOnscreen *onscreen;
};
+static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
+
static void
clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
@@ -39,12 +48,108 @@ G_DEFINE_TYPE_WITH_CODE (MetaStageNative, meta_stage_native,
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
clutter_stage_window_iface_init))
static gboolean
+meta_stage_native_realize (ClutterStageWindow *stage_window)
+{
+ MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
+ ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
+ ClutterBackend *clutter_backend = CLUTTER_BACKEND (stage_cogl->backend);
+ GError *error = NULL;
+
+ stage_native->onscreen = cogl_onscreen_new (clutter_backend->cogl_context,
+ 1, 1);
+
+ if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (stage_native->onscreen),
+ &error))
+ meta_fatal ("Failed to allocate onscreen framebuffer: %s\n",
+ error->message);
+
+ if (!(clutter_stage_window_parent_iface->realize (stage_window)))
+ meta_fatal ("Failed to realize native stage window");
+
+ return TRUE;
+}
+
+static void
+meta_stage_native_unrealize (ClutterStageWindow *stage_window)
+{
+ MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
+
+ clutter_stage_window_parent_iface->unrealize (stage_window);
+
+ g_clear_pointer (&stage_native->onscreen, cogl_object_unref);
+}
+
+static gboolean
meta_stage_native_can_clip_redraws (ClutterStageWindow *stage_window)
{
return TRUE;
}
static void
+meta_stage_native_get_geometry (ClutterStageWindow *stage_window,
+ cairo_rectangle_int_t *geometry)
+{
+ MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (stage_native->onscreen);
+
+ if (framebuffer)
+ {
+ *geometry = (cairo_rectangle_int_t) {
+ .width = cogl_framebuffer_get_width (framebuffer),
+ .height = cogl_framebuffer_get_height (framebuffer)
+ };
+ }
+ else
+ {
+ *geometry = (cairo_rectangle_int_t) {
+ .width = 1,
+ .height = 1,
+ };
+ }
+}
+
+static CoglFramebuffer *
+meta_stage_native_get_legacy_onscreen (ClutterStageWindow *stage_window)
+{
+ MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
+
+ return COGL_FRAMEBUFFER (stage_native->onscreen);
+}
+
+static CoglClosure *
+meta_stage_native_set_frame_callback (ClutterStageWindow *stage_window,
+ CoglFrameCallback callback,
+ gpointer user_data)
+{
+ MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
+
+ cogl_onscreen_set_swap_throttled (stage_native->onscreen,
+ _clutter_get_sync_to_vblank ());
+
+ return cogl_onscreen_add_frame_callback (stage_native->onscreen,
+ callback,
+ user_data,
+ NULL);
+}
+
+static void
+meta_stage_native_remove_frame_callback (ClutterStageWindow *stage_window,
+ CoglFrameClosure *closure)
+{
+ MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
+
+ cogl_onscreen_remove_frame_callback (stage_native->onscreen, closure);
+}
+
+static int64_t
+meta_stage_native_get_frame_counter (ClutterStageWindow *stage_window)
+{
+ MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
+
+ return cogl_onscreen_get_frame_counter (stage_native->onscreen);
+}
+
+static void
meta_stage_native_init (MetaStageNative *stage_native)
{
}
@@ -57,5 +162,14 @@ meta_stage_native_class_init (MetaStageNativeClass *klass)
static void
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
{
+ clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
+
+ iface->realize = meta_stage_native_realize;
+ iface->unrealize = meta_stage_native_unrealize;
iface->can_clip_redraws = meta_stage_native_can_clip_redraws;
+ iface->get_geometry = meta_stage_native_get_geometry;
+ iface->get_legacy_onscreen = meta_stage_native_get_legacy_onscreen;
+ iface->set_frame_callback = meta_stage_native_set_frame_callback;
+ iface->remove_frame_callback = meta_stage_native_remove_frame_callback;
+ iface->get_frame_counter = meta_stage_native_get_frame_counter;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]