[clutter] gdk: stage window: reset framebuffer on foreign window unrealize
- From: Lionel Landwerlin <llandwerlin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter] gdk: stage window: reset framebuffer on foreign window unrealize
- Date: Fri, 11 Sep 2015 22:41:25 +0000 (UTC)
commit 13dbb74c81bec861d3a135fb53966ae5562831a7
Author: Lionel Landwerlin <llandwerlin gmail com>
Date: Fri Sep 11 17:24:05 2015 +0200
gdk: stage window: reset framebuffer on foreign window unrealize
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.
This change sets the current Cogl framebuffer to a dummy 1x1
framebuffer if the current Cogl framebuffer is the one we're
unrealizing.
https://bugzilla.gnome.org/show_bug.cgi?id=754890
clutter/gdk/clutter-backend-gdk.c | 29 ++++++++++++++++++++++++++++-
clutter/gdk/clutter-backend-gdk.h | 4 ++++
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 a464e68..fab7bf0 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 fb54113..7f23459 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 5cf3947..7152b11 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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]