From d19e78af2459b1b5165848b643525df29ee20265 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 19 Mar 2015 15:46:08 +0100 Subject: [PATCH] Refresh all background instances after suspend if needed NVIDIA drivers don't preserve FBO contents across suspend / resume cycles which results in broken backgrounds. We can work around that by forcing a refresh when coming out of suspend. https://bugzilla.gnome.org/show_bug.cgi?id=739178 --- js/ui/layout.js | 13 +++++++++++++ src/shell-util.c | 33 +++++++++++++++++++++++++++++++++ src/shell-util.h | 2 ++ 3 files changed, 48 insertions(+) diff --git a/js/ui/layout.js b/js/ui/layout.js index 9228bd125..e9aab1300 100644 --- a/js/ui/layout.js +++ b/js/ui/layout.js @@ -11,6 +11,7 @@ const St = imports.gi.St; const Background = imports.ui.background; const BackgroundMenu = imports.ui.backgroundMenu; +const LoginManager = imports.misc.loginManager; const DND = imports.ui.dnd; const Main = imports.ui.main; @@ -248,6 +249,18 @@ const LayoutManager = new Lang.Class({ global.screen.connect('in-fullscreen-changed', Lang.bind(this, this._updateFullscreen)); this._monitorsChanged(); + + // NVIDIA drivers don't preserve FBO contents across + // suspend/resume, see + // https://bugzilla.gnome.org/show_bug.cgi?id=739178 + if (Shell.util_need_background_refresh()) { + LoginManager.getLoginManager().connect('prepare-for-sleep', + function(lm, suspending) { + if (suspending) + return; + Meta.Background.refresh_all(); + }); + } }, // This is called by Main after everything else is constructed diff --git a/src/shell-util.c b/src/shell-util.c index 5ae4fdb3c..87924038a 100644 --- a/src/shell-util.c +++ b/src/shell-util.c @@ -5,6 +5,9 @@ #include #include +#include +#include + #include "shell-util.h" #include #include @@ -330,3 +333,33 @@ shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker, clutter_actor_hide (CLUTTER_ACTOR (texture)); } } + +typedef const gchar *(*ShellGLGetString) (GLenum); + +static const gchar * +get_gl_vendor (void) +{ + static const gchar *vendor = NULL; + + if (!vendor) + { + ShellGLGetString gl_get_string; + gl_get_string = (ShellGLGetString) cogl_get_proc_address ("glGetString"); + if (gl_get_string) + vendor = gl_get_string (GL_VENDOR); + } + + return vendor; +} + +gboolean +shell_util_need_background_refresh (void) +{ + if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) + return FALSE; + + if (g_strcmp0 (get_gl_vendor (), "NVIDIA Corporation") == 0) + return TRUE; + + return FALSE; +} diff --git a/src/shell-util.h b/src/shell-util.h index d7ab4fdcf..be20083d4 100644 --- a/src/shell-util.h +++ b/src/shell-util.h @@ -44,6 +44,8 @@ GdkPixbuf *shell_util_create_pixbuf_from_data (const guchar *data, void shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker, ClutterTexture *texture); +gboolean shell_util_need_background_refresh (void); + G_END_DECLS #endif /* __SHELL_UTIL_H__ */