[gtk+] gsk: Add gsk_renderer_new_for_window()



commit 5563841603eab5ec4ec7516114bc60b647b0664d
Author: Benjamin Otte <otte redhat com>
Date:   Tue Nov 29 04:27:21 2016 +0100

    gsk: Add gsk_renderer_new_for_window()
    
    and remove gsk_renderer_get_for_display().
    
    This new function returns a realized renderer. Because of that, GSK can
    catch failures to realize, destroy the renderer and try another one.
    
    Or in short: I can finally use GTK on Weston with the nvidia binary
    drivers again.
    
    Signed-off-by: Emmanuele Bassi <ebassi gnome org>

 docs/reference/gsk/gsk4-sections.txt |    2 +-
 gsk/gskrenderer.c                    |  102 +++++++++++++++++++++++++---------
 gsk/gskrenderer.h                    |    2 +-
 gtk/gtkwindow.c                      |   18 +++---
 4 files changed, 85 insertions(+), 39 deletions(-)
---
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt
index 1a1a18d..bc757b5 100644
--- a/docs/reference/gsk/gsk4-sections.txt
+++ b/docs/reference/gsk/gsk4-sections.txt
@@ -1,6 +1,6 @@
 <SECTION>
 <FILE>GskRenderer</FILE>
-gsk_renderer_get_for_display
+gsk_renderer_new_for_window
 gsk_renderer_set_viewport
 gsk_renderer_get_viewport
 gsk_renderer_set_scale_factor
diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c
index 7d0d842..629551c 100644
--- a/gsk/gskrenderer.c
+++ b/gsk/gskrenderer.c
@@ -686,23 +686,11 @@ gsk_renderer_get_profiler (GskRenderer *renderer)
   return priv->profiler;
 }
 
-/**
- * gsk_renderer_get_for_display:
- * @display: a #GdkDisplay
- *
- * Creates an appropriate #GskRenderer instance for the given @display.
- *
- * Returns: (transfer full) (nullable): a #GskRenderer
- *
- * Since: 3.90
- */
-GskRenderer *
-gsk_renderer_get_for_display (GdkDisplay *display)
+static GType
+get_renderer_for_env_var (GdkWindow *window)
 {
   static const char *use_software;
 
-  GType renderer_type = G_TYPE_INVALID;
-
   if (use_software == NULL)
     {
       use_software = g_getenv ("GSK_USE_SOFTWARE");
@@ -711,27 +699,87 @@ gsk_renderer_get_for_display (GdkDisplay *display)
     }
 
   if (use_software[0] != '0')
-    return g_object_new (GSK_TYPE_CAIRO_RENDERER, "display", display, NULL);
+    return GSK_TYPE_CAIRO_RENDERER;
 
+  return G_TYPE_INVALID;
+}
+
+static GType
+get_renderer_for_backend (GdkWindow *window)
+{
 #ifdef GDK_WINDOWING_X11
-  if (GDK_IS_X11_DISPLAY (display))
-    renderer_type = GSK_TYPE_GL_RENDERER; 
-  else
+  if (GDK_IS_X11_WINDOW (window))
+    return GSK_TYPE_GL_RENDERER; 
 #endif
 #ifdef GDK_WINDOWING_WAYLAND
-  if (GDK_IS_WAYLAND_DISPLAY (display))
-    renderer_type = GSK_TYPE_GL_RENDERER;
-  else
+  if (GDK_IS_WAYLAND_WINDOW (window))
+    return GSK_TYPE_GL_RENDERER;
 #endif
-    renderer_type = GSK_TYPE_CAIRO_RENDERER;
 
-  GSK_NOTE (RENDERER, g_print ("Creating renderer of type '%s' for display '%s'\n",
-                               g_type_name (renderer_type),
-                               G_OBJECT_TYPE_NAME (display)));
+  return G_TYPE_INVALID;
+}
+
+static GType
+get_renderer_fallback (GdkWindow *window)
+{
+  return GSK_TYPE_CAIRO_RENDERER;
+}
+
+static struct {
+  GType (* get_renderer) (GdkWindow *window);
+} renderer_possibilities[] = {
+  { get_renderer_for_env_var },
+  { get_renderer_for_backend },
+  { get_renderer_fallback },
+};
 
-  g_assert (renderer_type != G_TYPE_INVALID);
+/**
+ * gsk_renderer_new_for_window:
+ * @display: a #GdkDisplay
+ *
+ * Creates an appropriate #GskRenderer instance for the given @window.
+ *
+ * The renderer will be realized when it is returned.
+ *
+ * Returns: (transfer full) (nullable): a #GskRenderer
+ *
+ * Since: 3.90
+ */
+GskRenderer *
+gsk_renderer_new_for_window (GdkWindow *window)
+{
+  GType renderer_type;
+  GskRenderer *renderer;
+  guint i;
+
+  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+
+  for (i = 0; i < G_N_ELEMENTS (renderer_possibilities); i++)
+    {
+      renderer_type = renderer_possibilities[i].get_renderer (window);
+      if (renderer_type == G_TYPE_INVALID)
+        continue;
+
+      renderer = g_object_new (renderer_type,
+                               "display", gdk_window_get_display (window),
+                               NULL);
+
+      if (gsk_renderer_realize (renderer, window))
+        {
+          GSK_NOTE (RENDERER, g_print ("Using renderer of type '%s' for display '%s'\n",
+                                       G_OBJECT_TYPE_NAME (renderer),
+                                       G_OBJECT_TYPE_NAME (window)));
+          return renderer;
+        }
+
+      GSK_NOTE (RENDERER, g_print ("Failed to realize renderer of type '%s' for window '%s'\n",
+                                   G_OBJECT_TYPE_NAME (renderer),
+                                   G_OBJECT_TYPE_NAME (window)));
+      g_object_unref (renderer);
+    }
 
-  return g_object_new (renderer_type, "display", display, NULL);
+  g_assert_not_reached ();
+  return NULL;
 }
 
 cairo_surface_t *
diff --git a/gsk/gskrenderer.h b/gsk/gskrenderer.h
index 031de8e..646ba6d 100644
--- a/gsk/gskrenderer.h
+++ b/gsk/gskrenderer.h
@@ -39,7 +39,7 @@ GDK_AVAILABLE_IN_3_90
 GType gsk_renderer_get_type (void) G_GNUC_CONST;
 
 GDK_AVAILABLE_IN_3_90
-GskRenderer *           gsk_renderer_get_for_display            (GdkDisplay              *display);
+GskRenderer *           gsk_renderer_new_for_window             (GdkWindow               *window);
 
 GDK_AVAILABLE_IN_3_90
 void                    gsk_renderer_set_viewport               (GskRenderer             *renderer,
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 89a43e8..0e9678e 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -6886,12 +6886,6 @@ gtk_window_realize (GtkWidget *widget)
 
   _gtk_widget_get_allocation (widget, &allocation);
 
-  if (priv->renderer == NULL)
-    {
-      priv->renderer = gsk_renderer_get_for_display (gtk_widget_get_display (widget));
-      gsk_renderer_set_scale_factor (priv->renderer, gtk_widget_get_scale_factor (widget));
-    }
-
   if (gtk_widget_get_parent_window (widget))
     {
       gdk_window = gdk_window_new_child (gtk_widget_get_parent_window (widget),
@@ -6910,7 +6904,8 @@ gtk_window_realize (GtkWidget *widget)
           popover_realize (popover->widget, popover, window);
         }
 
-      gsk_renderer_realize (priv->renderer, gdk_window);
+      priv->renderer = gsk_renderer_new_for_window (gdk_window);
+      gsk_renderer_set_scale_factor (priv->renderer, gtk_widget_get_scale_factor (widget));
 
       return;
     }
@@ -6994,6 +6989,12 @@ gtk_window_realize (GtkWidget *widget)
   gtk_widget_register_window (widget, gdk_window);
   gtk_widget_set_realized (widget, TRUE);
 
+  if (priv->renderer == NULL)
+    {
+      priv->renderer = gsk_renderer_new_for_window (gdk_window);
+      gsk_renderer_set_scale_factor (priv->renderer, gtk_widget_get_scale_factor (widget));
+    }
+
   if (priv->client_decorated && priv->type == GTK_WINDOW_TOPLEVEL)
     {
       const gchar *cursor_names[8] = {
@@ -7106,9 +7107,6 @@ gtk_window_realize (GtkWidget *widget)
     }
 
   check_scale_changed (window);
-
-  /* Renderer */
-  gsk_renderer_realize (priv->renderer, gdk_window);
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]