From fd9a803159ca7e7fbe6bee1842cc78deff0da7fa Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 15 Jan 2019 12:54:32 -0500 Subject: [PATCH 3/4] st-texture-cache: purge on resume With the proprietary nvidia driver, textures get garbled on suspend, so the texture cache needs to evict all textures in that situation. --- js/ui/main.js | 6 +++++- src/st/st-texture-cache.c | 12 ++++++++++++ src/st/st-texture-cache.h | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/js/ui/main.js b/js/ui/main.js index a8779bf09..faaf07399 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -184,61 +184,65 @@ function _initializeUI() { messageTray = new MessageTray.MessageTray(); panel = new Panel.Panel(); keyboard = new Keyboard.Keyboard(); notificationDaemon = new NotificationDaemon.NotificationDaemon(); windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler(); componentManager = new Components.ComponentManager(); introspectService = new Introspect.IntrospectService(); layoutManager.init(); overview.init(); _a11ySettings = new Gio.Settings({ schema_id: A11Y_SCHEMA }); global.display.connect('overlay-key', () => { if (!_a11ySettings.get_boolean (STICKY_KEYS_ENABLE)) overview.toggle(); }); global.display.connect('show-restart-message', (display, message) => { showRestartMessage(message); return true; }); global.display.connect('restart', () => { global.reexec_self(); return true; }); - global.display.connect('gl-video-memory-purged', loadTheme); + global.display.connect('gl-video-memory-purged', () => { + let cache = St.TextureCache.get_default(); + cache.clear(); + loadTheme(); + }); // Provide the bus object for gnome-session to // initiate logouts. EndSessionDialog.init(); // We're ready for the session manager to move to the next phase Meta.register_with_session(); _startDate = new Date(); let perfModuleName = GLib.getenv("SHELL_PERF_MODULE"); if (perfModuleName) { let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT"); let module = eval('imports.perf.' + perfModuleName + ';'); Scripting.runPerfScript(module, perfOutput); } ExtensionDownloader.init(); ExtensionSystem.init(); if (sessionMode.isGreeter && screenShield) { layoutManager.connect('startup-prepared', () => { screenShield.showDialog(); }); } layoutManager.connect('startup-complete', () => { if (actionMode == Shell.ActionMode.NONE) { actionMode = Shell.ActionMode.NORMAL; } diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c index 0c794a3ab..5a3dcd81f 100644 --- a/src/st/st-texture-cache.c +++ b/src/st/st-texture-cache.c @@ -78,60 +78,72 @@ set_texture_cogl_texture (ClutterTexture *clutter_texture, CoglTexture *cogl_tex { clutter_texture_set_cogl_texture (clutter_texture, cogl_texture); g_object_set (clutter_texture, "opacity", 255, NULL); } static void st_texture_cache_class_init (StTextureCacheClass *klass) { GObjectClass *gobject_class = (GObjectClass *)klass; gobject_class->dispose = st_texture_cache_dispose; gobject_class->finalize = st_texture_cache_finalize; signals[ICON_THEME_CHANGED] = g_signal_new ("icon-theme-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, /* no default handler slot */ NULL, NULL, NULL, G_TYPE_NONE, 0); signals[TEXTURE_FILE_CHANGED] = g_signal_new ("texture-file-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, /* no default handler slot */ NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_FILE); } +/* Evicts all cached textures */ +void +st_texture_cache_clear (StTextureCache *cache) +{ + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_remove_all (cache->priv->keyed_cache); + g_signal_emit (cache, signals[ICON_THEME_CHANGED], 0); +} + /* Evicts all cached textures for named icons */ static void st_texture_cache_evict_icons (StTextureCache *cache) { GHashTableIter iter; gpointer key; gpointer value; g_hash_table_iter_init (&iter, cache->priv->keyed_cache); while (g_hash_table_iter_next (&iter, &key, &value)) { const char *cache_key = key; /* This is too conservative - it takes out all cached textures * for GIcons even when they aren't named icons, but it's not * worth the complexity of parsing the key and calling * g_icon_new_for_string(); icon theme changes aren't normal */ if (g_str_has_prefix (cache_key, CACHE_PREFIX_ICON)) g_hash_table_iter_remove (&iter); } } static void on_icon_theme_changed (GtkIconTheme *icon_theme, StTextureCache *cache) { st_texture_cache_evict_icons (cache); g_signal_emit (cache, signals[ICON_THEME_CHANGED], 0); } diff --git a/src/st/st-texture-cache.h b/src/st/st-texture-cache.h index 26f9c30ac..b87adc4d5 100644 --- a/src/st/st-texture-cache.h +++ b/src/st/st-texture-cache.h @@ -25,60 +25,61 @@ #if !defined(ST_H_INSIDE) && !defined(ST_COMPILATION) #error "Only can be included directly.h" #endif #include #include #include #include #include #define ST_TYPE_TEXTURE_CACHE (st_texture_cache_get_type ()) G_DECLARE_FINAL_TYPE (StTextureCache, st_texture_cache, ST, TEXTURE_CACHE, GObject) typedef struct _StTextureCachePrivate StTextureCachePrivate; struct _StTextureCache { GObject parent; StTextureCachePrivate *priv; }; typedef enum { ST_TEXTURE_CACHE_POLICY_NONE, ST_TEXTURE_CACHE_POLICY_FOREVER } StTextureCachePolicy; StTextureCache* st_texture_cache_get_default (void); +void st_texture_cache_clear (StTextureCache *cache); ClutterActor * st_texture_cache_load_sliced_image (StTextureCache *cache, GFile *file, gint grid_width, gint grid_height, gint scale, GFunc load_callback, gpointer user_data); ClutterActor *st_texture_cache_bind_cairo_surface_property (StTextureCache *cache, GObject *object, const char *property_name); ClutterActor *st_texture_cache_load_gicon (StTextureCache *cache, StThemeNode *theme_node, GIcon *icon, gint size, gint scale); ClutterActor *st_texture_cache_load_file_async (StTextureCache *cache, GFile *file, int available_width, int available_height, int scale); CoglTexture *st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache, GFile *file, gint scale); -- 2.18.1