[gtk/wip/otte/gleanup: 2/2] gdk: Add a GL workaround for nvidia




commit 958e3e35b138d8a660a74e5f24b51891a34a7525
Author: Benjamin Otte <otte redhat com>
Date:   Wed Jul 7 05:07:28 2021 +0200

    gdk: Add a GL workaround for nvidia
    
    nvidia's driver apparently insists on the first eglMakeCurrent()
    to happen on a surface for all GL contexts meant to draw to surfaces.
    
    So do that in the renderers.

 gdk/gdkglcontext.c        | 28 +++++++++++++++++-----------
 gdk/gdkglcontextprivate.h |  2 ++
 gsk/gl/gskglrenderer.c    |  5 ++++-
 gsk/ngl/gsknglrenderer.c  |  7 +++++++
 4 files changed, 30 insertions(+), 12 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 27e19a0030..e55331388e 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -1135,22 +1135,13 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
   priv->extensions_checked = TRUE;
 }
 
-/**
- * gdk_gl_context_make_current:
- * @context: a `GdkGLContext`
- *
- * Makes the @context the current one.
- */
 void
-gdk_gl_context_make_current (GdkGLContext *context)
+gdk_gl_context_make_current_full (GdkGLContext *context,
+                                  gboolean      surfaceless)
 {
   GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
   MaskedContext *current, *masked_context;
-  gboolean surfaceless;
-
-  g_return_if_fail (GDK_IS_GL_CONTEXT (context));
 
-  surfaceless = !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context));
   masked_context = mask_context (context, surfaceless);
 
   current = g_private_get (&thread_current_context);
@@ -1182,6 +1173,21 @@ gdk_gl_context_make_current (GdkGLContext *context)
   gdk_gl_context_check_extensions (context);
 }
 
+/**
+ * gdk_gl_context_make_current:
+ * @context: a `GdkGLContext`
+ *
+ * Makes the @context the current one.
+ */
+void
+gdk_gl_context_make_current (GdkGLContext *context)
+{
+  g_return_if_fail (GDK_IS_GL_CONTEXT (context));
+
+  gdk_gl_context_make_current_full (context,
+                                    !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)));
+};
+
 /**
  * gdk_gl_context_get_display:
  * @context: a `GdkGLContext`
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index bbc7397d0a..8dcfd975a5 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -97,6 +97,8 @@ void                    gdk_gl_context_upload_texture           (GdkGLContext
                                                                  int              stride,
                                                                  GdkMemoryFormat  data_format,
                                                                  guint            texture_target);
+void                    gdk_gl_context_make_current_full        (GdkGLContext    *context,
+                                                                 gboolean         surfaceless);
 GdkGLContextPaintData * gdk_gl_context_get_paint_data           (GdkGLContext    *context);
 gboolean                gdk_gl_context_use_texture_rectangle    (GdkGLContext    *context);
 gboolean                gdk_gl_context_has_unpack_subimage      (GdkGLContext    *context);
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index a801f55ab3..4439594028 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -3557,7 +3557,10 @@ gsk_gl_renderer_realize (GskRenderer  *renderer,
   if (!gdk_gl_context_realize (self->gl_context, error))
     return FALSE;
 
-  gdk_gl_context_make_current (self->gl_context);
+  /* Use make_current_full() to work around nvidia bug where the first
+   * make_current() must not happen surfaceless or the GL context
+   * will never be able to render to the surface directly */
+  gdk_gl_context_make_current_full (self->gl_context, FALSE);
 
   g_assert (self->gl_driver == NULL);
   self->gl_profiler = gsk_gl_profiler_new (self->gl_context);
diff --git a/gsk/ngl/gsknglrenderer.c b/gsk/ngl/gsknglrenderer.c
index fa393c11cf..f5e8f6375b 100644
--- a/gsk/ngl/gsknglrenderer.c
+++ b/gsk/ngl/gsknglrenderer.c
@@ -31,6 +31,8 @@
 #include "gsknglrenderjobprivate.h"
 #include "gsknglrendererprivate.h"
 
+#include "gdk/gdkglcontextprivate.h"
+
 struct _GskNglRendererClass
 {
   GskRendererClass parent_class;
@@ -104,6 +106,11 @@ gsk_ngl_renderer_realize (GskRenderer  *renderer,
       !gdk_gl_context_realize (context, error))
     goto failure;
 
+  /* Use make_current_full() to work around nvidia bug where the first
+   * make_current() must not happen surfaceless or the GL context
+   * will never be able to render to the surface directly */
+  gdk_gl_context_make_current_full (context, FALSE);
+
 #ifdef G_ENABLE_DEBUG
   if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), SHADERS))
     debug_shaders = TRUE;


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