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
This commit is contained in:
parent
cb4e88884b
commit
13dbb74c81
@ -23,6 +23,8 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||||
|
|
||||||
#include <glib/gi18n-lib.h>
|
#include <glib/gi18n-lib.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -83,6 +85,29 @@ static GdkDisplay *_foreign_dpy = NULL;
|
|||||||
|
|
||||||
static gboolean disable_event_retrieval = FALSE;
|
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
|
static void
|
||||||
clutter_backend_gdk_init_settings (ClutterBackendGdk *backend_gdk)
|
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);
|
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);
|
gdk_window_remove_filter (NULL, cogl_gdk_filter, backend_gdk);
|
||||||
g_object_unref (backend_gdk->display);
|
g_object_unref (backend_gdk->display);
|
||||||
|
|
||||||
@ -413,7 +440,7 @@ clutter_backend_gdk_class_init (ClutterBackendGdkClass *klass)
|
|||||||
static void
|
static void
|
||||||
clutter_backend_gdk_init (ClutterBackendGdk *backend_gdk)
|
clutter_backend_gdk_init (ClutterBackendGdk *backend_gdk)
|
||||||
{
|
{
|
||||||
/* nothing to do here */
|
backend_gdk->dummy_onscreen = COGL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,6 +50,8 @@ struct _ClutterBackendGdk
|
|||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
GdkScreen *screen;
|
GdkScreen *screen;
|
||||||
|
|
||||||
|
CoglOnscreen *dummy_onscreen;
|
||||||
|
|
||||||
ClutterDeviceManager *device_manager;
|
ClutterDeviceManager *device_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,6 +69,8 @@ void _clutter_backend_gdk_events_init (ClutterBackend *backend);
|
|||||||
void _clutter_backend_gdk_update_setting (ClutterBackendGdk *backend,
|
void _clutter_backend_gdk_update_setting (ClutterBackendGdk *backend,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
|
|
||||||
|
void _clutter_backend_gdk_reset_framebuffer (ClutterBackendGdk *backend);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_BACKEND_GDK_H__ */
|
#endif /* __CLUTTER_BACKEND_GDK_H__ */
|
||||||
|
@ -182,7 +182,26 @@ clutter_stage_gdk_unrealize (ClutterStageWindow *stage_window)
|
|||||||
"clutter-stage-window", NULL);
|
"clutter-stage-window", NULL);
|
||||||
|
|
||||||
if (stage_gdk->foreign_window)
|
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
|
else
|
||||||
gdk_window_destroy (stage_gdk->window);
|
gdk_window_destroy (stage_gdk->window);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user