diff options
-rw-r--r-- | gdk/win32/gdkglcontext-win32-wgl-private.c | 56 | ||||
-rw-r--r-- | gdk/win32/gdkglcontext-win32-wgl.c | 12 | ||||
-rw-r--r-- | gdk/win32/gdkglcontext-win32.h | 17 | ||||
-rw-r--r-- | gdk/win32/meson.build | 2 | ||||
-rw-r--r-- | modules/media/gtkgstsink.c | 78 |
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; } |