diff options
-rw-r--r-- | clutter/gdk/clutter-backend-gdk.c | 29 | ||||
-rw-r--r-- | clutter/gdk/clutter-backend-gdk.h | 4 | ||||
-rw-r--r-- | clutter/gdk/clutter-stage-gdk.c | 21 |
3 files changed, 52 insertions, 2 deletions
diff --git a/clutter/gdk/clutter-backend-gdk.c b/clutter/gdk/clutter-backend-gdk.c index a464e684b..fab7bf0c5 100644 --- a/clutter/gdk/clutter-backend-gdk.c +++ b/clutter/gdk/clutter-backend-gdk.c @@ -23,6 +23,8 @@ #include "config.h" #endif +#define CLUTTER_ENABLE_EXPERIMENTAL_API + #include <glib/gi18n-lib.h> #include <string.h> @@ -83,6 +85,29 @@ static GdkDisplay *_foreign_dpy = NULL; static gboolean disable_event_retrieval = FALSE; +void +_clutter_backend_gdk_reset_framebuffer (ClutterBackendGdk *backend_gdk) +{ + if (backend_gdk->dummy_onscreen == COGL_INVALID_HANDLE) + { + CoglContext *context = + clutter_backend_get_cogl_context (CLUTTER_BACKEND (backend_gdk)); + CoglError *internal_error = NULL; + + backend_gdk->dummy_onscreen = cogl_onscreen_new (context, 1, 1); + + if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (backend_gdk->dummy_onscreen), + &internal_error)) + { + g_error ("Unable to create dummy onscreen: %s", internal_error->message); + cogl_error_free (internal_error); + return; + } + } + + cogl_set_framebuffer (COGL_FRAMEBUFFER (backend_gdk->dummy_onscreen)); +} + static void clutter_backend_gdk_init_settings (ClutterBackendGdk *backend_gdk) { @@ -226,6 +251,8 @@ clutter_backend_gdk_finalize (GObject *gobject) { ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (gobject); + g_clear_pointer (&backend_gdk->dummy_onscreen, cogl_object_unref); + gdk_window_remove_filter (NULL, cogl_gdk_filter, backend_gdk); g_object_unref (backend_gdk->display); @@ -413,7 +440,7 @@ clutter_backend_gdk_class_init (ClutterBackendGdkClass *klass) static void clutter_backend_gdk_init (ClutterBackendGdk *backend_gdk) { - /* nothing to do here */ + backend_gdk->dummy_onscreen = COGL_INVALID_HANDLE; } /** diff --git a/clutter/gdk/clutter-backend-gdk.h b/clutter/gdk/clutter-backend-gdk.h index fb5411315..7f234590c 100644 --- a/clutter/gdk/clutter-backend-gdk.h +++ b/clutter/gdk/clutter-backend-gdk.h @@ -50,6 +50,8 @@ struct _ClutterBackendGdk GdkDisplay *display; GdkScreen *screen; + CoglOnscreen *dummy_onscreen; + ClutterDeviceManager *device_manager; }; @@ -67,6 +69,8 @@ void _clutter_backend_gdk_events_init (ClutterBackend *backend); void _clutter_backend_gdk_update_setting (ClutterBackendGdk *backend, const gchar *name); +void _clutter_backend_gdk_reset_framebuffer (ClutterBackendGdk *backend); + G_END_DECLS #endif /* __CLUTTER_BACKEND_GDK_H__ */ diff --git a/clutter/gdk/clutter-stage-gdk.c b/clutter/gdk/clutter-stage-gdk.c index 5cf394797..7152b11fb 100644 --- a/clutter/gdk/clutter-stage-gdk.c +++ b/clutter/gdk/clutter-stage-gdk.c @@ -182,7 +182,26 @@ clutter_stage_gdk_unrealize (ClutterStageWindow *stage_window) "clutter-stage-window", NULL); if (stage_gdk->foreign_window) - g_object_unref (stage_gdk->window); + { + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (stage_cogl->backend); + + g_object_unref (stage_gdk->window); + + /* Clutter still uses part of the deprecated stateful API of + * Cogl (in particulart cogl_set_framebuffer). It means Cogl + * can keep an internal reference to the onscreen object we + * rendered to. In the case of foreign window, we want to + * avoid this, as we don't know what's going to happen to + * that window. + * + * The following call sets the current Cogl framebuffer to a + * dummy 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)) + _clutter_backend_gdk_reset_framebuffer (backend_gdk); + } else gdk_window_destroy (stage_gdk->window); |