summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdk/win32/gdkglcontext-win32-wgl-private.c56
-rw-r--r--gdk/win32/gdkglcontext-win32-wgl.c12
-rw-r--r--gdk/win32/gdkglcontext-win32.h17
-rw-r--r--gdk/win32/meson.build2
-rw-r--r--modules/media/gtkgstsink.c78
5 files changed, 88 insertions, 77 deletions
diff --git a/gdk/win32/gdkglcontext-win32-wgl-private.c b/gdk/win32/gdkglcontext-win32-wgl-private.c
new file mode 100644
index 0000000000..7da5016f05
--- /dev/null
+++ b/gdk/win32/gdkglcontext-win32-wgl-private.c
@@ -0,0 +1,56 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * gdkglcontext-win32-wgl-private.c: Win32 specific OpenGL wrappers
+ *
+ * Copyright © 2023 Chun-wei Fan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * These wrapper functions are used when we don't want to use the wgl*() core functions
+ * that we acquire via libepoxy (such as when we are disposing the Gdk(W)GLContext from,
+ * different threads, so for these calls, we are actually linking to the system's/ICD
+ * opengl32.dll directly, so that we are guaranteed that the "right" versions of these
+ * WGL calls are carried out. This must be a separate source file because we can't include
+ * the system's GL/gl.h with epoxy/(w)gl.h together in a single source file. We should not
+ * need to use these when we are creating/initializing a WGL context in GDK, since we should
+ * be in the same thread at this point.
+ */
+
+#define DONT_INCLUDE_LIBEPOXY
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <GL/gl.h>
+
+#include "gdkglcontext-win32.h"
+
+void
+gdk_win32_private_wglDeleteContext (HGLRC hglrc)
+{
+ wglDeleteContext (hglrc);
+}
+
+HGLRC
+gdk_win32_private_wglGetCurrentContext (void)
+{
+ return wglGetCurrentContext ();
+}
+
+BOOL
+gdk_win32_private_wglMakeCurrent (HDC hdc,
+ HGLRC hglrc)
+{
+ return wglMakeCurrent (hdc, hglrc);
+}
diff --git a/gdk/win32/gdkglcontext-win32-wgl.c b/gdk/win32/gdkglcontext-win32-wgl.c
index 4c32a74f88..572c2f37b7 100644
--- a/gdk/win32/gdkglcontext-win32-wgl.c
+++ b/gdk/win32/gdkglcontext-win32-wgl.c
@@ -60,12 +60,12 @@ gdk_win32_gl_context_wgl_dispose (GObject *gobject)
if (context_wgl->wgl_context != NULL)
{
- if (wglGetCurrentContext () == context_wgl->wgl_context)
- wglMakeCurrent (NULL, NULL);
+ if (gdk_win32_private_wglGetCurrentContext () == context_wgl->wgl_context)
+ gdk_win32_private_wglMakeCurrent (NULL, NULL);
GDK_NOTE (OPENGL, g_print ("Destroying WGL context\n"));
- wglDeleteContext (context_wgl->wgl_context);
+ gdk_win32_private_wglDeleteContext (context_wgl->wgl_context);
context_wgl->wgl_context = NULL;
}
@@ -628,7 +628,7 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
static gboolean
gdk_win32_gl_context_wgl_clear_current (GdkGLContext *context)
{
- return wglMakeCurrent (NULL, NULL);
+ return gdk_win32_private_wglMakeCurrent (NULL, NULL);
}
static gboolean
@@ -636,7 +636,7 @@ gdk_win32_gl_context_wgl_is_current (GdkGLContext *context)
{
GdkWin32GLContextWGL *self = GDK_WIN32_GL_CONTEXT_WGL (context);
- return self->wgl_context == wglGetCurrentContext ();
+ return self->wgl_context == gdk_win32_private_wglGetCurrentContext ();
}
static gboolean
@@ -654,7 +654,7 @@ gdk_win32_gl_context_wgl_make_current (GdkGLContext *context,
else
hdc = GDK_WIN32_SURFACE (surface)->hdc;
- if (!wglMakeCurrent (hdc, context_wgl->wgl_context))
+ if (!gdk_win32_private_wglMakeCurrent (hdc, context_wgl->wgl_context))
return FALSE;
if (!surfaceless && display_win32->hasWglEXTSwapControl)
diff --git a/gdk/win32/gdkglcontext-win32.h b/gdk/win32/gdkglcontext-win32.h
index 77995671ce..787c8b1a09 100644
--- a/gdk/win32/gdkglcontext-win32.h
+++ b/gdk/win32/gdkglcontext-win32.h
@@ -21,6 +21,7 @@
#ifndef __GDK_WIN32_GL_CONTEXT__
#define __GDK_WIN32_GL_CONTEXT__
+#ifndef DONT_INCLUDE_LIBEPOXY
#include <epoxy/gl.h>
#include <epoxy/wgl.h>
@@ -31,9 +32,18 @@
#include "gdkglcontextprivate.h"
#include "gdkdisplayprivate.h"
#include "gdksurface.h"
+#else
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <GL/gl.h>
+
+# include <glib.h>
+#endif
G_BEGIN_DECLS
+#ifndef DONT_INCLUDE_LIBEPOXY
+
#define GDK_WIN32_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WIN32_GL_CONTEXT, GdkWin32GLContextClass))
#define GDK_WIN32_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WIN32_GL_CONTEXT, GdkWin32GLContextClass))
#define GDK_WIN32_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WIN32_GL_CONTEXT))
@@ -78,6 +88,13 @@ GType gdk_win32_gl_context_egl_get_type (void) G_GNUC_CONST;
void
_gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface);
+#endif /* !DONT_INCLUDE_LIBEPOXY */
+
+HGLRC gdk_win32_private_wglGetCurrentContext (void);
+BOOL gdk_win32_private_wglMakeCurrent (HDC hdc,
+ HGLRC hglrc);
+void gdk_win32_private_wglDeleteContext (HGLRC hglrc);
+
G_END_DECLS
#endif /* __GDK_WIN32_GL_CONTEXT__ */
diff --git a/gdk/win32/meson.build b/gdk/win32/meson.build
index bcf7d7c78f..3dc16aabb6 100644
--- a/gdk/win32/meson.build
+++ b/gdk/win32/meson.build
@@ -23,6 +23,7 @@ gdk_win32_sources = gdk_win32_public_sources + files([
'gdkdevice-wintab.c',
'gdkdrop-win32.c',
'gdkglobals-win32.c',
+ 'gdkglcontext-win32-wgl-private.c',
'gdkhdataoutputstream-win32.c',
'gdkinput-dmanipulation.c',
'gdkinput-winpointer.c',
@@ -59,6 +60,7 @@ endif
gdk_win32_deps = [
pangowin32_dep, # FIXME
cc.find_library('hid'),
+ cc.find_library('opengl32'),
]
libgdk_win32 = static_library('gdk-win32',
diff --git a/modules/media/gtkgstsink.c b/modules/media/gtkgstsink.c
index 0e3e29b9f7..552c23c23d 100644
--- a/modules/media/gtkgstsink.c
+++ b/modules/media/gtkgstsink.c
@@ -40,7 +40,6 @@
#if GST_GL_HAVE_WINDOW_WIN32 && (GST_GL_HAVE_PLATFORM_WGL || GST_GL_HAVE_PLATFORM_EGL) && defined (GDK_WINDOWING_WIN32)
#include <gdk/win32/gdkwin32.h>
-#include <epoxy/wgl.h>
#endif
#if GST_GL_HAVE_PLATFORM_EGL && (GST_GL_HAVE_WINDOW_WIN32 || GST_GL_HAVE_WINDOW_X11)
@@ -359,69 +358,6 @@ gtk_gst_sink_show_frame (GstVideoSink *vsink,
return GST_FLOW_OK;
}
-#if GST_GL_HAVE_WINDOW_WIN32 && (GST_GL_HAVE_PLATFORM_WGL || GST_GL_HAVE_PLATFORM_EGL) && defined (GDK_WINDOWING_WIN32)
-#define HANDLE_EXTERNAL_WGL_MAKE_CURRENT(ctx) handle_wgl_makecurrent(ctx)
-#define DEACTIVATE_WGL_CONTEXT(ctx) deactivate_gdk_wgl_context(ctx)
-#define REACTIVATE_WGL_CONTEXT(ctx) reactivate_gdk_wgl_context(ctx)
-
-static void
-handle_wgl_makecurrent (GdkGLContext *ctx)
-{
- if (!gdk_gl_context_get_use_es (ctx))
- epoxy_handle_external_wglMakeCurrent();
-}
-
-static void
-deactivate_gdk_wgl_context (GdkGLContext *ctx)
-{
- if (!gdk_gl_context_get_use_es (ctx))
- {
- HDC hdc = GetDC (GDK_SURFACE_HWND (gdk_gl_context_get_surface (ctx)));
- wglMakeCurrent (hdc, NULL);
- }
-}
-
-static void
-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)
-#define REACTIVATE_WGL_CONTEXT(ctx)
-#endif
-
static gboolean
gtk_gst_sink_initialize_gl (GtkGstSink *self)
{
@@ -434,7 +370,6 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
display = gdk_gl_context_get_display (self->gdk_context);
- HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);
gdk_gl_context_make_current (self->gdk_context);
#ifdef HAVE_GST_X11_SUPPORT
@@ -528,8 +463,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 = check_win32_gst_gl_api (self->gdk_context, &platform, &gl_api);
- const gchar *gl_type = is_gles ? "EGL" : "WGL";
+ gboolean is_gles = gdk_gl_context_get_use_es (self->gdk_context);
+ const char *gl_type = is_gles ? "EGL" : "WGL";
+
+ platform = is_gles ? GST_GL_PLATFORM_EGL : GST_GL_PLATFORM_WGL;
+ gl_api = gst_gl_context_get_current_gl_api (platform, NULL, NULL);
GST_DEBUG_OBJECT (self, "got %s on Win32!", gl_type);
@@ -596,12 +534,12 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
g_clear_error (&error);
g_clear_object (&self->gst_gdk_context);
g_clear_object (&self->gst_display);
- HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);
+
return FALSE;
}
else
{
- DEACTIVATE_WGL_CONTEXT (self->gdk_context);
+ gdk_gl_context_clear_current ();
gst_gl_context_activate (self->gst_gdk_context, FALSE);
}
@@ -615,8 +553,6 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
g_clear_object (&self->gst_display);
}
- HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);
- REACTIVATE_WGL_CONTEXT (self->gdk_context);
return succeeded;
}