diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 9e51bbb42..a4f4c1fef 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 0436631fd..f09a07fcc 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 67c45d0ed..ab2cc97c2 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 4ef082a99..2efb325c4 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 25a68d60f..863ecfc2d 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 aa34240b9..8f5abb4a1 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 ee9d6e9a6..90bc26f52 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; } @@ -262,36 +231,6 @@ clutter_stage_cogl_hide (ClutterStageWindow *stage_window) clutter_actor_unmap (CLUTTER_ACTOR (stage_cogl->wrapper)); } -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, @@ -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 c8abdef4c..690a01246 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 41bd8ca75..cd5c3bc8f 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 5f577d8af..f15ce9b82 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 e7cc91a0d..12061e5e1 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); @@ -38,12 +47,108 @@ G_DEFINE_TYPE_WITH_CODE (MetaStageNative, meta_stage_native, CLUTTER_TYPE_STAGE_COGL, 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; }