[gtk/wip.win32.fixes: 36/37] media/gstreamer: Attempt to use GL for video for Windows




commit 12895d633ba457701d4d598c9068923516bb6df6
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Sat Feb 13 18:40:56 2021 +0800

    media/gstreamer: Attempt to use GL for video for Windows
    
    Add a stab to support sharing the WGL context in GDK with the WGL
    context in GStreamer, so that we can also use OpenGL in the gstreamer
    media backend to playback videos.

 modules/media/gtkgstpaintable.c | 13 -----------
 modules/media/gtkgstsink.c      | 52 +++++++++++++++++++++++++++++++++++------
 2 files changed, 45 insertions(+), 20 deletions(-)
---
diff --git a/modules/media/gtkgstpaintable.c b/modules/media/gtkgstpaintable.c
index ab837382b8..ba5aefca4b 100644
--- a/modules/media/gtkgstpaintable.c
+++ b/modules/media/gtkgstpaintable.c
@@ -118,18 +118,6 @@ gtk_gst_paintable_video_renderer_create_video_sink (GstPlayerVideoRenderer *rend
   GtkGstPaintable *self = GTK_GST_PAINTABLE (renderer);
   GstElement *sink, *glsinkbin;
 
-#if GST_GL_HAVE_WINDOW_WIN32 && GST_GL_HAVE_PLATFORM_WGL && defined (GDK_WINDOWING_WIN32)
-  /*
-   * Unfortunately, we can't connect the GstGLContext with our GDKGLContext,
-   * since gdk_gl_context_make_current(), which calls wglMakeCurrent(), does not
-   * allow us to share WGL contexts across threads, which will cause a crash.
-   * See MR !3034, so no WGL in the gstreamer media backend :(
-   */
-  sink = g_object_new (GTK_TYPE_GST_SINK,
-                       "paintable", self,
-                       NULL);
-  return sink;
-#else
   sink = g_object_new (GTK_TYPE_GST_SINK,
                        "paintable", self,
                        "gl-context", self->context,
@@ -143,7 +131,6 @@ gtk_gst_paintable_video_renderer_create_video_sink (GstPlayerVideoRenderer *rend
   g_object_set (glsinkbin, "sink", sink, NULL);
 
   return glsinkbin;
-#endif
 }
 
 static void
diff --git a/modules/media/gtkgstsink.c b/modules/media/gtkgstsink.c
index 8a0a124e3b..b5373de4b8 100644
--- a/modules/media/gtkgstsink.c
+++ b/modules/media/gtkgstsink.c
@@ -35,6 +35,11 @@
 #include <gst/gl/wayland/gstgldisplay_wayland.h>
 #endif
 
+#if GST_GL_HAVE_WINDOW_WIN32 && GST_GL_HAVE_PLATFORM_WGL && defined (GDK_WINDOWING_WIN32)
+#include <gdk/win32/gdkwin32.h>
+#include <epoxy/wgl.h>
+#endif
+
 #include <gst/gl/gstglfuncs.h>
 
 enum {
@@ -341,27 +346,36 @@ gtk_gst_sink_show_frame (GstVideoSink *vsink,
   return GST_FLOW_OK;
 }
 
+#if GST_GL_HAVE_WINDOW_WIN32 && GST_GL_HAVE_PLATFORM_WGL && defined (GDK_WINDOWING_WIN32)
+#define HANDLE_EXTERNAL_WGL_MAKE_CURRENT epoxy_handle_external_wglMakeCurrent ()
+#else
+#define HANDLE_EXTERNAL_WGL_MAKE_CURRENT
+#endif
+
 static void
 gtk_gst_sink_initialize_gl (GtkGstSink *self)
 {
   GdkDisplay *display;
   GError *error = NULL;
+  GstGLPlatform platform = GST_GL_PLATFORM_NONE;
+  GstGLAPI gl_api = GST_GL_API_NONE;
+  guintptr gl_handle = 0;
 
   display = gdk_gl_context_get_display (self->gdk_context);
 
+  HANDLE_EXTERNAL_WGL_MAKE_CURRENT;
   gdk_gl_context_make_current (self->gdk_context);
 
 #if GST_GL_HAVE_WINDOW_X11 && GST_GL_HAVE_PLATFORM_GLX && defined (GDK_WINDOWING_X11)
   if (GDK_IS_X11_DISPLAY (display))
     {
-      GstGLPlatform platform = GST_GL_PLATFORM_GLX;
-      GstGLAPI gl_api;
-      guintptr gl_handle;
+      platform = GST_GL_PLATFORM_GLX;
 
       GST_DEBUG_OBJECT (self, "got GLX on X11!");
 
       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)
         {
           self->gst_display = GST_GL_DISPLAY (gst_gl_display_x11_new_with_display 
(gdk_x11_display_get_xdisplay (display)));
@@ -378,13 +392,10 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
 #if GST_GL_HAVE_WINDOW_WAYLAND && GST_GL_HAVE_PLATFORM_EGL && defined (GDK_WINDOWING_WAYLAND)
   if (GDK_IS_WAYLAND_DISPLAY (display))
     {
-      GstGLPlatform platform = GST_GL_PLATFORM_GLX;
-      GstGLAPI gl_api;
-      guintptr gl_handle;
+      platform = GST_GL_PLATFORM_EGL;
 
       GST_DEBUG_OBJECT (self, "got EGL on Wayland!");
 
-      platform = GST_GL_PLATFORM_EGL;
       gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL);
       gl_handle = gst_gl_context_get_current_gl_context (platform);
 
@@ -403,6 +414,30 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
         }
     }
   else
+#endif
+#if GST_GL_HAVE_WINDOW_WIN32 && GST_GL_HAVE_PLATFORM_WGL && defined (GDK_WINDOWING_WIN32)
+  if (GDK_IS_WIN32_DISPLAY (display) &&
+      !gdk_gl_context_get_use_es (self->gdk_context))
+    {
+      platform = GST_GL_PLATFORM_WGL;
+
+      GST_DEBUG_OBJECT (self, "got WGL on Win32!");
+
+      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)
+        {
+          self->gst_display = gst_gl_display_new ();
+          self->gst_app_context = gst_gl_context_new_wrapped (self->gst_display, gl_handle, platform, 
gl_api);
+        }
+      else
+        {
+          GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext, not using WGL");
+             return;
+        }
+    }
+  else
 #endif
     {
       GST_INFO_OBJECT (self, "Unsupported GDK display %s for GL", G_OBJECT_TYPE_NAME (display));
@@ -412,6 +447,8 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
   g_assert (self->gst_app_context != NULL);
 
   gst_gl_context_activate (self->gst_app_context, TRUE);
+  HANDLE_EXTERNAL_WGL_MAKE_CURRENT;
+
   if (!gst_gl_context_fill_info (self->gst_app_context, &error))
     {
       GST_ERROR_OBJECT (self, "failed to retrieve GDK context info: %s", error->message);
@@ -423,6 +460,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
   else
     {
       gst_gl_context_activate (self->gst_app_context, FALSE);
+      HANDLE_EXTERNAL_WGL_MAKE_CURRENT;
     }
 
   if (!gst_gl_display_create_context (self->gst_display, self->gst_app_context, &self->gst_context, &error))


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