From bf6c9bea02c9800a53e3db65966ffdc4ab506cb0 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 9 Jun 2016 19:07:15 +0200 Subject: [PATCH 1/4] restart: Make meta_restart() work without a message In some cases there's no meaningful message to show. https://bugzilla.gnome.org/show_bug.cgi?id=739178 --- src/core/restart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/restart.c b/src/core/restart.c index f01464c..1fa1c88 100644 --- a/src/core/restart.c +++ b/src/core/restart.c @@ -103,7 +103,7 @@ restart_message_painted (gpointer data) /** * meta_restart: - * @message: message to display to the user. + * @message: (allow-none): message to display to the user, or %NULL * * Starts the process of restarting the compositor. Note that Mutter's * involvement here is to make the restart visually smooth for the @@ -126,7 +126,7 @@ meta_restart (const char *message) MUTTER_LIBEXECDIR "/mutter-restart-helper", NULL }; - if (meta_display_show_restart_message (display, message)) + if (message && meta_display_show_restart_message (display, message)) { /* Wait until the stage was painted */ clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT, -- 2.7.4 From 384709b7304adedc730b605953cb8393c4708dbc Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Fri, 20 May 2016 19:22:23 +0200 Subject: [PATCH 2/4] compositor: Handle GL context reset errors Emit a signal so that interested parties can recreate their FBOs and queue a full scene graph redraw to ensure we don't end up showing graphical artifacts. This relies on the GL driver supporting the ARB_robustness extension and cogl creating a suitable GL context. For now we only make use of it with the X backend since the only driver with which this is useful is NVIDIA. https://bugzilla.gnome.org/show_bug.cgi?id=739178 --- src/backends/x11/meta-backend-x11.c | 2 ++ src/compositor/compositor-private.h | 1 + src/compositor/compositor.c | 28 ++++++++++++++++++++++++++-- src/core/display.c | 9 +++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index 586f991..4a041ff 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -696,6 +696,8 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass) static void meta_backend_x11_init (MetaBackendX11 *x11) { + clutter_x11_request_reset_on_video_memory_purge (); + /* We do X11 event retrieval ourselves */ clutter_x11_disable_event_retrieval (); } diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index e9b7463..9d99f6f 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -35,6 +35,7 @@ struct _MetaCompositor CoglOnscreen *onscreen; CoglFrameClosure *frame_closure; + CoglContext *context; /* Used for unredirecting fullscreen windows */ guint disable_unredirect_count; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 11b7c2c..75272ef 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -1152,8 +1152,7 @@ frame_callback (CoglOnscreen *onscreen, * is fairly fast, so calling it twice and subtracting to get a * nearly-zero number is acceptable, if a litle ugly. */ - CoglContext *context = cogl_framebuffer_get_context (COGL_FRAMEBUFFER (onscreen)); - gint64 current_cogl_time = cogl_get_clock_time (context); + gint64 current_cogl_time = cogl_get_clock_time (compositor->context); gint64 current_monotonic_time = g_get_monotonic_time (); presentation_time = @@ -1183,6 +1182,7 @@ meta_pre_paint_func (gpointer data) frame_callback, compositor, NULL); + compositor->context = cogl_framebuffer_get_context (COGL_FRAMEBUFFER (compositor->onscreen)); } if (compositor->windows == NULL) @@ -1236,6 +1236,7 @@ static gboolean meta_post_paint_func (gpointer data) { MetaCompositor *compositor = data; + CoglGraphicsResetStatus status; if (compositor->frame_has_updated_xsurfaces) { @@ -1245,6 +1246,29 @@ meta_post_paint_func (gpointer data) compositor->frame_has_updated_xsurfaces = FALSE; } + status = cogl_get_graphics_reset_status (compositor->context); + switch (status) + { + case COGL_GRAPHICS_RESET_STATUS_NO_ERROR: + break; + + case COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET: + g_signal_emit_by_name (compositor->display, "gl-video-memory-purged"); + clutter_actor_queue_redraw (CLUTTER_ACTOR (compositor->stage)); + break; + + default: + /* The ARB_robustness spec says that, on error, the application + should destroy the old context and create a new one. Since we + don't have the necessary plumbing to do this we'll simply + restart the process. Obviously we can't do this when we are + a wayland compositor but in that case we shouldn't get here + since we don't enable robustness in that case. */ + g_assert (!meta_is_wayland_compositor ()); + meta_restart (NULL); + break; + } + return TRUE; } diff --git a/src/core/display.c b/src/core/display.c index 29242fa..8b9dd04 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -122,6 +122,7 @@ enum GRAB_OP_END, SHOW_RESTART_MESSAGE, RESTART, + GL_VIDEO_MEMORY_PURGED, LAST_SIGNAL }; @@ -329,6 +330,14 @@ meta_display_class_init (MetaDisplayClass *klass) NULL, NULL, G_TYPE_BOOLEAN, 0); + display_signals[GL_VIDEO_MEMORY_PURGED] = + g_signal_new ("gl-video-memory-purged", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + g_object_class_install_property (object_class, PROP_FOCUS_WINDOW, g_param_spec_object ("focus-window", -- 2.7.4 From 2cbaf5d5a5ee256b2623b6d52d4fa9e891a1abd0 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Sun, 29 May 2016 19:58:25 +0200 Subject: [PATCH 3/4] MetaBackground: invalidate contents on loss of graphics context We use FBOs so we need to cause them to be recreated if we get a GL context lost error. https://bugzilla.gnome.org/show_bug.cgi?id=739178 --- src/compositor/meta-background.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c index de0407b..8195814 100644 --- a/src/compositor/meta-background.c +++ b/src/compositor/meta-background.c @@ -300,6 +300,18 @@ meta_background_finalize (GObject *object) } static void +meta_background_constructed (GObject *object) +{ + MetaBackground *self = META_BACKGROUND (object); + MetaBackgroundPrivate *priv = self->priv; + + G_OBJECT_CLASS (meta_background_parent_class)->constructed (object); + + g_signal_connect_object (meta_screen_get_display (priv->screen), "gl-video-memory-purged", + G_CALLBACK (mark_changed), object, G_CONNECT_SWAPPED); +} + +static void meta_background_class_init (MetaBackgroundClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -309,6 +321,7 @@ meta_background_class_init (MetaBackgroundClass *klass) object_class->dispose = meta_background_dispose; object_class->finalize = meta_background_finalize; + object_class->constructed = meta_background_constructed; object_class->set_property = meta_background_set_property; object_class->get_property = meta_background_get_property; -- 2.7.4 From bf0837c9b0b2f25344d92c4f7bbcd83e089c2f38 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Sun, 29 May 2016 20:00:45 +0200 Subject: [PATCH 4/4] MetaSurfaceActorX11: invalidate the stex on loss of graphics context MetaShapedTexture uses FBOs when mipmapping so we need to cause them to be recreated if we get a GL context lost error. https://bugzilla.gnome.org/show_bug.cgi?id=739178 --- src/compositor/meta-surface-actor-x11.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c index c837b5e..f10ec86 100644 --- a/src/compositor/meta-surface-actor-x11.c +++ b/src/compositor/meta-surface-actor-x11.c @@ -44,6 +44,7 @@ struct _MetaSurfaceActorX11Private MetaDisplay *display; CoglTexture *texture; + CoglTexture *texture_right; Pixmap pixmap; Damage damage; @@ -106,6 +107,7 @@ detach_pixmap (MetaSurfaceActorX11 *self) meta_error_trap_pop (display); g_clear_pointer (&priv->texture, cogl_object_unref); + g_clear_pointer (&priv->texture_right, cogl_object_unref); } static void @@ -145,7 +147,7 @@ set_pixmap (MetaSurfaceActorX11 *self, meta_shaped_texture_set_textures (stex, COGL_TEXTURE (texture), COGL_TEXTURE (texture_right)); if (priv->stereo) - cogl_object_unref (texture_right); + priv->texture_right = COGL_TEXTURE (texture_right); } static void @@ -408,6 +410,22 @@ window_decorated_notify (MetaWindow *window, create_damage (self); } +static void +reset_texture (MetaSurfaceActorX11 *self) +{ + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + + if (!priv->texture) + return; + + /* Setting the texture to NULL will cause all the FBO's cached by the + * shaped texture's MetaTextureTower to be discarded and recreated. + */ + meta_shaped_texture_set_textures (stex, NULL, NULL); + meta_shaped_texture_set_textures (stex, priv->texture, priv->texture_right); +} + MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window) { @@ -421,6 +439,9 @@ meta_surface_actor_x11_new (MetaWindow *window) priv->window = window; priv->display = display; + g_signal_connect_object (priv->display, "gl-video-memory-purged", + G_CALLBACK (reset_texture), self, G_CONNECT_SWAPPED); + xwindow = meta_window_x11_get_toplevel_xwindow (window); priv->stereo = meta_compositor_window_is_stereo (display->screen, xwindow); meta_compositor_select_stereo_notify (display->screen, xwindow); -- 2.7.4