Addl fix #397: GPU acceleration
authorColin Clark <colin.clark@cclark.uk>
Tue, 7 Jul 2020 10:46:52 +0000 (11:46 +0100)
committerColin Clark <colin.clark@cclark.uk>
Tue, 7 Jul 2020 10:46:52 +0000 (11:46 +0100)
https://github.com/BestImageViewer/geeqie/issues/397

If two windows are open, switching between the two windows may cause a
crash with the message:
The error was 'GLXBadDrawable'

The bug happens with Nouveau drivers and Radeon drivers, but not with
Nvidia drivers.

This patch disables Clutter if the system is liable to this bug. The
user is given the possibility to override this with an option in
Preferences/Behavior.

src/main.c
src/options.c
src/options.h
src/pixbuf-renderer.c
src/preferences.c
src/rcfile.c

index e6d3e5b..a1ae5d3 100644 (file)
 #include <clutter-gtk/clutter-gtk.h>
 #endif
 
+#ifdef HAVE_GTHREAD
+/* FIXME: see below */
+#include <X11/Xlib.h>
+#endif
 
 gboolean thumb_format_changed = FALSE;
 static RemoteConnection *remote_connection = NULL;
@@ -852,6 +856,11 @@ gint main(gint argc, gchar *argv[])
 #ifdef HAVE_GTHREAD
 #if !GLIB_CHECK_VERSION(2,32,0)
        g_thread_init(NULL);
+#endif
+#ifdef HAVE_CLUTTER
+/* FIXME: see below */
+       putenv("LIBGL_ALWAYS_INDIRECT=1");
+       XInitThreads();
 #endif
        gdk_threads_init();
        gdk_threads_enter();
@@ -947,6 +956,23 @@ gint main(gint argc, gchar *argv[])
                filter_rebuild();
                }
 
+#ifdef HAVE_CLUTTER
+/* FIXME: For the background of this see:
+ * https://github.com/BestImageViewer/geeqie/issues/397
+ * The feature CLUTTER_FEATURE_SWAP_EVENTS indictates if the
+ * system is liable to exhibit this problem.
+ * The user is provided with an override in Preferences/Behavior
+ */
+       if (!options->override_disable_gpu)
+               {
+               DEBUG_1("CLUTTER_FEATURE_SWAP_EVENTS %d",clutter_feature_available(CLUTTER_FEATURE_SWAP_EVENTS));
+               if (clutter_feature_available(CLUTTER_FEATURE_SWAP_EVENTS) != 0)
+                       {
+                       options->disable_gpu = TRUE;
+                       }
+               }
+#endif
+
        /* handle missing config file and commandline additions*/
        if (!layout_window_list)
                {
index f5441fc..2ea1f99 100644 (file)
@@ -215,6 +215,9 @@ ConfOptions *init_options(ConfOptions *options)
        options->mouse_button_8 = g_strdup("Back");
        options->mouse_button_9 = g_strdup("Forward");
 
+       options->disable_gpu = FALSE;
+       options->override_disable_gpu = FALSE;
+
        for (i = 0; i < FILE_FORMAT_CLASSES; i++)
                {
                options->class_filter[i] = TRUE;
index e677dba..9de4ace 100644 (file)
@@ -328,6 +328,10 @@ struct _ConfOptions
 
        gboolean read_metadata_in_idle;
 
+       /* GPU - see main.c */
+       gboolean disable_gpu;
+       gboolean override_disable_gpu;
+
        GList *disabled_plugins;
 };
 
index b960cb9..4693943 100644 (file)
@@ -401,7 +401,7 @@ static void pixbuf_renderer_class_init(PixbufRendererClass *class)
 
 static RendererFuncs *pr_backend_renderer_new(PixbufRenderer *pr)
 {
-       if (options->image.use_clutter_renderer)
+       if (options->image.use_clutter_renderer && !options->disable_gpu)
                {
 #ifdef HAVE_CLUTTER
                return renderer_clutter_new(pr);
index e8c2743..dee0b47 100644 (file)
@@ -454,6 +454,8 @@ static void config_window_apply(void)
        options->mouse_button_8 = c_options->mouse_button_8;
        options->mouse_button_9 = c_options->mouse_button_9;
 
+       options->override_disable_gpu = c_options->override_disable_gpu;
+
        config_tab_keywords_save();
 
        image_options_sync();
@@ -2186,6 +2188,7 @@ static void config_tab_image(GtkWidget *notebook)
        GtkWidget *table;
        GtkWidget *spin;
        GtkWidget *two_pass;
+       GtkWidget *gpu_accel;
 
        vbox = scrolled_notebook_page(notebook, _("Image"));
 
@@ -2199,8 +2202,12 @@ static void config_tab_image(GtkWidget *notebook)
                }
 
 #ifdef HAVE_CLUTTER
-       pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library (Requires restart)"),
+       gpu_accel = pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library (Requires restart)"),
                              options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer);
+       if (options->disable_gpu && !options->override_disable_gpu)
+               {
+               gtk_widget_set_sensitive(gpu_accel, FALSE);
+               }
 #endif
 
        two_pass = pref_checkbox_new_int(group, _("Two pass rendering (apply HQ zoom and color correction in second pass)"),
@@ -3253,6 +3260,7 @@ static void config_tab_behavior(GtkWidget *notebook)
        GtkWidget *marks;
        GtkWidget *with_rename;
        GtkWidget *collections_on_top;
+       GtkWidget *checkbox;
 
        vbox = scrolled_notebook_page(notebook, _("Behavior"));
 
@@ -3363,6 +3371,14 @@ static void config_tab_behavior(GtkWidget *notebook)
        table = pref_table_new(group, 2, 1, FALSE, FALSE);
        add_mouse_selection_menu(table, 0, 0, _("Mouse button Forward:"), options->mouse_button_9, &c_options->mouse_button_9);
 
+       pref_spacer(group, PREF_PAD_GROUP);
+
+       group = pref_group_new(vbox, FALSE, _("GPU"), GTK_ORIENTATION_VERTICAL);
+
+       checkbox = pref_checkbox_new_int(group, _("Override disable GPU"),
+                               options->override_disable_gpu, &c_options->override_disable_gpu);
+       gtk_widget_set_tooltip_text(checkbox, "Contact the developers for usage");
+
 #ifdef DEBUG
        pref_spacer(group, PREF_PAD_GROUP);
 
index ba2f0fd..4a7497d 100644 (file)
@@ -517,6 +517,10 @@ static void write_global_attributes(GString *outstr, gint indent)
        WRITE_NL(); WRITE_CHAR(*options, mouse_button_8);
        WRITE_NL(); WRITE_CHAR(*options, mouse_button_9);
        WRITE_SEPARATOR();
+
+       /* GPU - see main.c */
+       WRITE_NL(); WRITE_BOOL(*options, override_disable_gpu);
+       WRITE_SEPARATOR();
 }
 
 static void write_color_profile(GString *outstr, gint indent)
@@ -935,6 +939,9 @@ static gboolean load_global_params(const gchar **attribute_names, const gchar **
                if (READ_CHAR(*options, mouse_button_8)) continue;
                if (READ_CHAR(*options, mouse_button_9)) continue;
 
+               /* GPU - see main.c */
+               if (READ_BOOL(*options, override_disable_gpu)) continue;
+
                /* Dummy options */
                if (READ_DUMMY(*options, image.dither_quality, "deprecated since 2012-08-13")) continue;