mirror of
https://github.com/brl/mutter.git
synced 2024-11-09 23:46:33 -05:00
x11: stage window: reset framebuffer on foreign window unrealize
Similarly to 13dbb74c81
, we need to reset the
framebuffer in the x11 for foreign windows.
https://bugzilla.gnome.org/show_bug.cgi?id=755014
This commit is contained in:
parent
6c7f624f69
commit
ff1a5aae7a
@ -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__ */
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user