summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <llandwerlin@gmail.com>2015-09-15 00:30:05 +0100
committerLionel Landwerlin <llandwerlin@gmail.com>2015-09-15 12:29:04 +0100
commitff1a5aae7ac374592f1a9f7ff7be6d0a4bd576c2 (patch)
tree6df8e374a95e8388c537f0010556b1cb2c306e00
parent6c7f624f691415ca9ae8c1a95d41b359704d6f1b (diff)
downloadclutter-ff1a5aae7ac374592f1a9f7ff7be6d0a4bd576c2.tar.gz
x11: stage window: reset framebuffer on foreign window unrealize
Similarly to 13dbb74c81bec861d3a135fb53966ae5562831a7, we need to reset the framebuffer in the x11 for foreign windows. https://bugzilla.gnome.org/show_bug.cgi?id=755014
-rw-r--r--clutter/clutter-backend-private.h5
-rw-r--r--clutter/clutter-backend.c25
-rw-r--r--clutter/gdk/clutter-backend-gdk.c27
-rw-r--r--clutter/gdk/clutter-backend-gdk.h4
-rw-r--r--clutter/gdk/clutter-stage-gdk.c3
-rw-r--r--clutter/x11/clutter-stage-x11.c14
6 files changed, 45 insertions, 33 deletions
diff --git a/clutter/clutter-backend-private.h b/clutter/clutter-backend-private.h
index 7502eced3..6e1e7ec69 100644
--- a/clutter/clutter-backend-private.h
+++ b/clutter/clutter-backend-private.h
@@ -46,6 +46,8 @@ struct _ClutterBackend
CoglContext *cogl_context;
GSource *cogl_source;
+ CoglOnscreen *dummy_onscreen;
+
ClutterDeviceManager *device_manager;
cairo_font_options_t *font_options;
@@ -149,6 +151,9 @@ gint32 _clutter_backend_get_units_serial (Clutter
PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend);
+void _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend);
+
+
G_END_DECLS
#endif /* __CLUTTER_BACKEND_PRIVATE_H__ */
diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c
index e1d2336c2..91bda8315 100644
--- a/clutter/clutter-backend.c
+++ b/clutter/clutter-backend.c
@@ -135,6 +135,8 @@ clutter_backend_dispose (GObject *gobject)
/* remove all event translators */
g_clear_pointer (&backend->event_translators, g_list_free);
+ g_clear_pointer (&backend->dummy_onscreen, cogl_object_unref);
+
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
}
@@ -762,6 +764,8 @@ clutter_backend_init (ClutterBackend *self)
{
self->units_per_em = -1.0;
self->units_serial = 1;
+
+ self->dummy_onscreen = COGL_INVALID_HANDLE;
}
void
@@ -1435,3 +1439,24 @@ _clutter_backend_get_keymap_direction (ClutterBackend *backend)
return PANGO_DIRECTION_NEUTRAL;
}
+
+void
+_clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend)
+{
+ if (backend->dummy_onscreen == COGL_INVALID_HANDLE)
+ {
+ CoglError *internal_error = NULL;
+
+ backend->dummy_onscreen = cogl_onscreen_new (backend->cogl_context, 1, 1);
+
+ if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (backend->dummy_onscreen),
+ &internal_error))
+ {
+ g_critical ("Unable to create dummy onscreen: %s", internal_error->message);
+ cogl_error_free (internal_error);
+ return;
+ }
+ }
+
+ cogl_set_framebuffer (COGL_FRAMEBUFFER (backend->dummy_onscreen));
+}
diff --git a/clutter/gdk/clutter-backend-gdk.c b/clutter/gdk/clutter-backend-gdk.c
index 11eeb9cd4..ce5349ddb 100644
--- a/clutter/gdk/clutter-backend-gdk.c
+++ b/clutter/gdk/clutter-backend-gdk.c
@@ -85,29 +85,6 @@ 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)
{
@@ -251,8 +228,6 @@ 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);
@@ -440,8 +415,6 @@ clutter_backend_gdk_class_init (ClutterBackendGdkClass *klass)
static void
clutter_backend_gdk_init (ClutterBackendGdk *backend_gdk)
{
- backend_gdk->dummy_onscreen = COGL_INVALID_HANDLE;
-
/* Deactivate sync to vblank since we have the GdkFrameClock to
* drive us from the compositor.
*/
diff --git a/clutter/gdk/clutter-backend-gdk.h b/clutter/gdk/clutter-backend-gdk.h
index 7f234590c..fb5411315 100644
--- a/clutter/gdk/clutter-backend-gdk.h
+++ b/clutter/gdk/clutter-backend-gdk.h
@@ -50,8 +50,6 @@ struct _ClutterBackendGdk
GdkDisplay *display;
GdkScreen *screen;
- CoglOnscreen *dummy_onscreen;
-
ClutterDeviceManager *device_manager;
};
@@ -69,8 +67,6 @@ 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 2f2939b27..0620e4c13 100644
--- a/clutter/gdk/clutter-stage-gdk.c
+++ b/clutter/gdk/clutter-stage-gdk.c
@@ -184,7 +184,6 @@ clutter_stage_gdk_unrealize (ClutterStageWindow *stage_window)
if (stage_gdk->foreign_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
- ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (stage_cogl->backend);
g_object_unref (stage_gdk->window);
@@ -200,7 +199,7 @@ clutter_stage_gdk_unrealize (ClutterStageWindow *stage_window)
* 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);
+ _clutter_backend_reset_cogl_framebuffer (stage_cogl->backend);
}
else
gdk_window_destroy (stage_gdk->window);
diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c
index aecd978a7..84a6ab7dc 100644
--- a/clutter/x11/clutter-stage-x11.c
+++ b/clutter/x11/clutter-stage-x11.c
@@ -403,6 +403,7 @@ on_window_scaling_factor_notify (GObject *settings,
static void
clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
{
+ ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
if (clutter_stages_by_xid != NULL)
@@ -415,6 +416,19 @@ clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
GINT_TO_POINTER (stage_x11->xwin));
}
+ /* 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_reset_cogl_framebuffer (stage_cogl->backend);
+
clutter_stage_window_parent_iface->unrealize (stage_window);
}