[gtk/gst.gl.win32: 43/44] gtkgstsink.c: Determine GstGLAPI using GDK if needed




commit bde0f481cbb51ad2ade8c93f72ea3b08f73e9ff2
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Fri May 21 12:44:37 2021 +0800

    gtkgstsink.c: Determine GstGLAPI using GDK if needed
    
    We need to juggle things between our GstGLContext and GdkGLContext,
    which involved going through libepoxy.  libepoxy provided
    epoxy_handle_external_wglMakeCurrent(), which is required after we call
    wglMakeCurrent() from within GstGL, so that it has the correct GL
    function pointers to perform gdk_gl_context_make_current() for
    WGL (desktop OpenGL) contexts, but neither libepoxy nor GstGL provide
    functionality to go the other way round, meaning
    gst_gl_context_get_current_gl_api() will crash as the function pointers
    to call GL functions from within it is wrong.
    
    In order to remedy that, we just use the GDK APIs to check whether our
    WGL context is a legacy context and from that we determine what GstGLAPI
    we will use for our GstGLContext.  For EGL contexts, we continue to use
    gst_gl_context_get_current_gl_api().

 modules/media/gtkgstsink.c | 36 +++++++++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 5 deletions(-)
---
diff --git a/modules/media/gtkgstsink.c b/modules/media/gtkgstsink.c
index 746f02b327..8775ec54f4 100644
--- a/modules/media/gtkgstsink.c
+++ b/modules/media/gtkgstsink.c
@@ -382,6 +382,35 @@ reactivate_gdk_wgl_context (GdkGLContext *ctx)
   if (!gdk_gl_context_get_use_es (ctx))
     gdk_gl_context_make_current (ctx);
 }
+
+/*
+ * Unfortunately, libepoxy does not offer a way to allow us to safely call
+ * gst_gl_context_get_current_gl_api() on a WGL context that underlies a
+ * GdkGLContext after we notify libepoxy an external wglMakeCurrent() has
+ * been called (which is required for the first gdk_gl_context_make_current()
+ * call in gtk_gst_sink_initialize_gl(), for instance), so we can't do
+ * gst_gl_context_get_current_gl_api() directly on WGL contexts that underlies
+ * GdkGLContext's.  So, we just ask GDK about our WGL context, since it already
+ * knows what kind of WGL context we have there...
+ */
+static gboolean
+check_win32_gst_gl_api (GdkGLContext  *ctx,
+                        GstGLPlatform *platform,
+                        GstGLAPI      *gl_api)
+{
+  gboolean is_gles = gdk_gl_context_get_use_es (ctx);
+
+  g_return_val_if_fail (*gl_api == GST_GL_API_NONE, FALSE);
+
+  *platform = is_gles ? GST_GL_PLATFORM_EGL : GST_GL_PLATFORM_WGL;
+
+  if (is_gles)
+    *gl_api = gst_gl_context_get_current_gl_api (*platform, NULL, NULL);
+  else
+    *gl_api = gdk_gl_context_is_legacy (ctx) ? GST_GL_API_OPENGL : GST_GL_API_OPENGL3;
+
+  return is_gles;
+}
 #else
 #define HANDLE_EXTERNAL_WGL_MAKE_CURRENT(ctx)
 #define DEACTIVATE_WGL_CONTEXT(ctx)
@@ -470,14 +499,11 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
 #if GST_GL_HAVE_WINDOW_WIN32 && (GST_GL_HAVE_PLATFORM_WGL || GST_GL_HAVE_PLATFORM_EGL) && defined 
(GDK_WINDOWING_WIN32)
   if (GDK_IS_WIN32_DISPLAY (display))
     {
-      gboolean is_gles = gdk_gl_context_get_use_es (self->gdk_context);
+      gboolean is_gles = check_win32_gst_gl_api (self->gdk_context, &platform, &gl_api);
       const gchar *gl_type = is_gles ? "EGL" : "WGL";
 
-      platform = is_gles ? GST_GL_PLATFORM_EGL : GST_GL_PLATFORM_WGL;
-
       GST_DEBUG_OBJECT (self, "got %s on Win32!", gl_type);
 
-      gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL);
       gl_handle = gst_gl_context_get_current_gl_context (platform);
 
       if (gl_handle)
@@ -491,7 +517,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
            * otherwise gst_gl_display_new() will assume an EGL display, which won't work for us
            */
 
-          if (gl_api == GST_GL_API_OPENGL3 || gl_api == GST_GL_API_OPENGL)
+          if (gl_api & (GST_GL_API_OPENGL3 | GST_GL_API_OPENGL))
             {
 #ifdef HAVE_GST_GL_DISPLAY_NEW_WITH_TYPE
               self->gst_display = gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_WIN32);


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