mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 22:10:08 +00:00
Merge branch 'alternative-fix-5685' into 'main'
GDK/Win32: Use wgl* functions directly as needed (fix #5685) Closes #5685 See merge request GNOME/gtk!5702
This commit is contained in:
commit
d209f55677
56
gdk/win32/gdkglcontext-win32-wgl-private.c
Normal file
56
gdk/win32/gdkglcontext-win32-wgl-private.c
Normal file
@ -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);
|
||||
}
|
@ -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)
|
||||
|
@ -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__ */
|
||||
|
@ -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',
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user