Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e7ccb148
Commit
e7ccb148
authored
Sep 14, 2021
by
Alexandros Frantzis
Committed by
Alexandre Julliard
Mar 06, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winewayland.drv: Implement wglSetPixelFormat(WINE).
Introduce the internal wayland_gl_drawable object, which associates a window (and its backing Wayland surface) with an EGL surface.
parent
825ec8c5
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
290 additions
and
6 deletions
+290
-6
configure
configure
+89
-1
configure.ac
configure.ac
+6
-1
Makefile.in
dlls/winewayland.drv/Makefile.in
+2
-2
opengl.c
dlls/winewayland.drv/opengl.c
+183
-2
waylanddrv.h
dlls/winewayland.drv/waylanddrv.h
+6
-0
window.c
dlls/winewayland.drv/window.c
+1
-0
config.h.in
include/config.h.in
+3
-0
No files found.
configure
View file @
e7ccb148
...
...
@@ -702,6 +702,8 @@ INOTIFY_LIBS
INOTIFY_CFLAGS
PCSCLITE_LIBS
PCAP_LIBS
WAYLAND_EGL_LIBS
WAYLAND_EGL_CFLAGS
EGL_LIBS
EGL_CFLAGS
XKBREGISTRY_LIBS
...
...
@@ -1807,6 +1809,8 @@ XKBREGISTRY_CFLAGS
XKBREGISTRY_LIBS
EGL_CFLAGS
EGL_LIBS
WAYLAND_EGL_CFLAGS
WAYLAND_EGL_LIBS
INOTIFY_CFLAGS
INOTIFY_LIBS
DBUS_CFLAGS
...
...
@@ -2635,6 +2639,10 @@ Some influential environment variables:
Linker flags for xkbregistry, overriding pkg-config
EGL_CFLAGS C compiler flags for egl, overriding pkg-config
EGL_LIBS Linker flags for egl, overriding pkg-config
WAYLAND_EGL_CFLAGS
C compiler flags for wayland-egl, overriding pkg-config
WAYLAND_EGL_LIBS
Linker flags for wayland-egl, overriding pkg-config
INOTIFY_CFLAGS
C compiler flags for libinotify, overriding pkg-config
INOTIFY_LIBS
...
...
@@ -16268,9 +16276,87 @@ fi
CPPFLAGS
=
$ac_save_CPPFLAGS
rm
-f
conftest.err
if
${
WAYLAND_EGL_CFLAGS
:+false
}
:
then
:
if
test
${
PKG_CONFIG
+y
}
then
:
WAYLAND_EGL_CFLAGS
=
`
$PKG_CONFIG
--cflags
wayland-egl 2>conftest.err
`
fi
fi
if
${
WAYLAND_EGL_LIBS
:+false
}
:
then
:
if
test
${
PKG_CONFIG
+y
}
then
:
WAYLAND_EGL_LIBS
=
`
$PKG_CONFIG
--libs
wayland-egl 2>/dev/null
`
fi
fi
printf
"%s
\n
"
"
$as_me
:
${
as_lineno
-
$LINENO
}
: wayland-egl cflags:
$WAYLAND_EGL_CFLAGS
"
>
&5
printf
"%s
\n
"
"
$as_me
:
${
as_lineno
-
$LINENO
}
: wayland-egl libs:
$WAYLAND_EGL_LIBS
"
>
&5
if
test
-s
conftest.err
;
then
printf
%s
"
$as_me
:
${
as_lineno
-
$LINENO
}
: wayland-egl errors: "
>
&5
cat
conftest.err
>
&5
fi
rm
-f
conftest.err
ac_save_CPPFLAGS
=
$CPPFLAGS
CPPFLAGS
=
"
$CPPFLAGS
$WAYLAND_EGL_CFLAGS
"
ac_fn_c_check_header_compile
"
$LINENO
"
"wayland-egl.h"
"ac_cv_header_wayland_egl_h"
"
$ac_includes_default
"
if
test
"x
$ac_cv_header_wayland_egl_h
"
=
xyes
then
:
{
printf
"%s
\n
"
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking for wl_egl_window_create in -lwayland-egl"
>
&5
printf
%s
"checking for wl_egl_window_create in -lwayland-egl... "
>
&6
;
}
if
test
${
ac_cv_lib_wayland_egl_wl_egl_window_create
+y
}
then
:
printf
%s
"(cached) "
>
&6
else
$as_nop
ac_check_lib_save_LIBS
=
$LIBS
LIBS
=
"-lwayland-egl
$WAYLAND_EGL_LIBS
$LIBS
"
cat
confdefs.h -
<<
_ACEOF
>conftest.
$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
char wl_egl_window_create ();
int
main (void)
{
return wl_egl_window_create ();
;
return 0;
}
_ACEOF
if
ac_fn_c_try_link
"
$LINENO
"
then
:
ac_cv_lib_wayland_egl_wl_egl_window_create
=
yes
else
$as_nop
ac_cv_lib_wayland_egl_wl_egl_window_create
=
no
fi
rm
-f
core conftest.err conftest.
$ac_objext
conftest.beam
\
conftest
$ac_exeext
conftest.
$ac_ext
LIBS
=
$ac_check_lib_save_LIBS
fi
{
printf
"%s
\n
"
"
$as_me
:
${
as_lineno
-
$LINENO
}
: result:
$ac_cv_lib_wayland_egl_wl_egl_window_create
"
>
&5
printf
"%s
\n
"
"
$ac_cv_lib_wayland_egl_wl_egl_window_create
"
>
&6
;
}
if
test
"x
$ac_cv_lib_wayland_egl_wl_egl_window_create
"
=
xyes
then
:
printf
"%s
\n
"
"#define HAVE_LIBWAYLAND_EGL 1"
>>
confdefs.h
else
$as_nop
WAYLAND_EGL_LIBS
=
""
fi
fi
CPPFLAGS
=
$ac_save_CPPFLAGS
if
test
"x
$with_wayland
"
!=
"x"
then
if
test
-z
"
$ac_cv_lib_soname_EGL
"
if
test
-z
"
$ac_cv_lib_soname_EGL
"
-o
-z
"
$HAVE_LIBWAYLAND_EGL
"
then
:
case
"x
$with_opengl
"
in
x
)
as_fn_append wine_notices
"|EGL
${
notice_platform
}
development files not found, the Wayland driver won't support OpenGL"
;;
...
...
@@ -23914,6 +24000,8 @@ XKBREGISTRY_CFLAGS = $XKBREGISTRY_CFLAGS
XKBREGISTRY_LIBS =
$XKBREGISTRY_LIBS
EGL_CFLAGS =
$EGL_CFLAGS
EGL_LIBS =
$EGL_LIBS
WAYLAND_EGL_CFLAGS =
$WAYLAND_EGL_CFLAGS
WAYLAND_EGL_LIBS =
$WAYLAND_EGL_LIBS
PCAP_LIBS =
$PCAP_LIBS
PCSCLITE_LIBS =
$PCSCLITE_LIBS
INOTIFY_CFLAGS =
$INOTIFY_CFLAGS
...
...
configure.ac
View file @
e7ccb148
...
...
@@ -1385,9 +1385,14 @@ then
WINE_PACKAGE_FLAGS(EGL,[egl],[-lEGL],,,
[AC_CHECK_HEADER([EGL/egl.h],
[WINE_CHECK_SONAME(EGL,eglGetProcAddress,,,[$EGL_LIBS])])])
WINE_PACKAGE_FLAGS(WAYLAND_EGL,[wayland-egl],,,,
[AC_CHECK_HEADER([wayland-egl.h],
[AC_CHECK_LIB(wayland-egl,wl_egl_window_create,
[AC_DEFINE(HAVE_LIBWAYLAND_EGL, 1, [Define if we have the wayland-egl development environment])],
[WAYLAND_EGL_LIBS=""],[$WAYLAND_EGL_LIBS])])])
if test "x$with_wayland" != "x"
then
WINE_NOTICE_WITH(opengl, [test -z "$ac_cv_lib_soname_EGL"],
WINE_NOTICE_WITH(opengl, [test -z "$ac_cv_lib_soname_EGL"
-o -z "$HAVE_LIBWAYLAND_EGL"
],
[EGL ${notice_platform}development files not found, the Wayland driver won't support OpenGL])
fi
fi
...
...
dlls/winewayland.drv/Makefile.in
View file @
e7ccb148
MODULE
=
winewayland.drv
UNIXLIB
=
winewayland.so
UNIX_CFLAGS
=
$(EGL_CFLAGS)
$(WAYLAND_CLIENT_CFLAGS)
$(XKBCOMMON_CFLAGS)
$(XKBREGISTRY_CFLAGS)
UNIX_LIBS
=
-lwin32u
$(WAYLAND_CLIENT_LIBS)
$(XKBCOMMON_LIBS)
$(XKBREGISTRY_LIBS)
$(PTHREAD_LIBS)
-lm
UNIX_CFLAGS
=
$(EGL_CFLAGS)
$(WAYLAND_CLIENT_CFLAGS)
$(
WAYLAND_EGL_CFLAGS)
$(
XKBCOMMON_CFLAGS)
$(XKBREGISTRY_CFLAGS)
UNIX_LIBS
=
-lwin32u
$(WAYLAND_CLIENT_LIBS)
$(
WAYLAND_EGL_LIBS)
$(
XKBCOMMON_LIBS)
$(XKBREGISTRY_LIBS)
$(PTHREAD_LIBS)
-lm
SOURCES
=
\
display.c
\
...
...
dlls/winewayland.drv/opengl.c
View file @
e7ccb148
...
...
@@ -31,11 +31,11 @@
#include "waylanddrv.h"
#include "wine/debug.h"
#if defined(SONAME_LIBEGL)
#if defined(SONAME_LIBEGL)
&& defined(HAVE_LIBWAYLAND_EGL)
WINE_DEFAULT_DEBUG_CHANNEL
(
waylanddrv
);
#
define WL_EGL_PLATFORM 1
#
include <wayland-egl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
...
...
@@ -55,6 +55,8 @@ static const char *opengl_func_names[] = { ALL_WGL_FUNCS };
#define DECL_FUNCPTR(f) static typeof(f) * p_##f
DECL_FUNCPTR
(
eglChooseConfig
);
DECL_FUNCPTR
(
eglCreateWindowSurface
);
DECL_FUNCPTR
(
eglDestroySurface
);
DECL_FUNCPTR
(
eglGetConfigAttrib
);
DECL_FUNCPTR
(
eglGetError
);
DECL_FUNCPTR
(
eglGetPlatformDisplay
);
...
...
@@ -63,6 +65,156 @@ DECL_FUNCPTR(eglInitialize);
DECL_FUNCPTR
(
eglQueryString
);
#undef DECL_FUNCPTR
static
pthread_mutex_t
gl_object_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
struct
list
gl_drawables
=
LIST_INIT
(
gl_drawables
);
struct
wayland_gl_drawable
{
struct
list
entry
;
LONG
ref
;
HWND
hwnd
;
struct
wayland_client_surface
*
client
;
struct
wl_egl_window
*
wl_egl_window
;
EGLSurface
surface
;
};
/* lookup the existing drawable for a window, gl_object_mutex must be held */
static
struct
wayland_gl_drawable
*
find_drawable_for_hwnd
(
HWND
hwnd
)
{
struct
wayland_gl_drawable
*
gl
;
LIST_FOR_EACH_ENTRY
(
gl
,
&
gl_drawables
,
struct
wayland_gl_drawable
,
entry
)
if
(
gl
->
hwnd
==
hwnd
)
return
gl
;
return
NULL
;
}
static
void
wayland_gl_drawable_release
(
struct
wayland_gl_drawable
*
gl
)
{
if
(
InterlockedDecrement
(
&
gl
->
ref
))
return
;
if
(
gl
->
surface
)
p_eglDestroySurface
(
egl_display
,
gl
->
surface
);
if
(
gl
->
wl_egl_window
)
wl_egl_window_destroy
(
gl
->
wl_egl_window
);
if
(
gl
->
client
)
{
HWND
hwnd
=
wl_surface_get_user_data
(
gl
->
client
->
wl_surface
);
struct
wayland_surface
*
wayland_surface
=
wayland_surface_lock_hwnd
(
hwnd
);
if
(
wayland_client_surface_release
(
gl
->
client
)
&&
wayland_surface
)
wayland_surface
->
client
=
NULL
;
if
(
wayland_surface
)
pthread_mutex_unlock
(
&
wayland_surface
->
mutex
);
}
free
(
gl
);
}
static
struct
wayland_gl_drawable
*
wayland_gl_drawable_create
(
HWND
hwnd
,
int
format
)
{
struct
wayland_gl_drawable
*
gl
;
struct
wayland_surface
*
wayland_surface
;
int
client_width
=
0
,
client_height
=
0
;
TRACE
(
"hwnd=%p format=%d
\n
"
,
hwnd
,
format
);
gl
=
calloc
(
1
,
sizeof
(
*
gl
));
if
(
!
gl
)
return
NULL
;
gl
->
ref
=
1
;
gl
->
hwnd
=
hwnd
;
/* Get the client surface for the HWND. If don't have a wayland surface
* (e.g., HWND_MESSAGE windows) just create a dummy surface to act as the
* target render surface. */
if
((
wayland_surface
=
wayland_surface_lock_hwnd
(
hwnd
)))
{
gl
->
client
=
wayland_surface_get_client
(
wayland_surface
);
client_width
=
wayland_surface
->
window
.
client_rect
.
right
-
wayland_surface
->
window
.
client_rect
.
left
;
client_height
=
wayland_surface
->
window
.
client_rect
.
bottom
-
wayland_surface
->
window
.
client_rect
.
top
;
if
(
client_width
==
0
||
client_height
==
0
)
client_width
=
client_height
=
1
;
pthread_mutex_unlock
(
&
wayland_surface
->
mutex
);
}
else
if
((
wayland_surface
=
wayland_surface_create
(
0
)))
{
gl
->
client
=
wayland_surface_get_client
(
wayland_surface
);
client_width
=
client_height
=
1
;
/* It's fine to destroy the wayland surface, the client surface
* can safely outlive it. */
wayland_surface_destroy
(
wayland_surface
);
}
if
(
!
gl
->
client
)
goto
err
;
gl
->
wl_egl_window
=
wl_egl_window_create
(
gl
->
client
->
wl_surface
,
client_width
,
client_height
);
if
(
!
gl
->
wl_egl_window
)
{
ERR
(
"Failed to create wl_egl_window
\n
"
);
goto
err
;
}
gl
->
surface
=
p_eglCreateWindowSurface
(
egl_display
,
egl_configs
[
format
-
1
],
gl
->
wl_egl_window
,
NULL
);
if
(
!
gl
->
surface
)
{
ERR
(
"Failed to create EGL surface
\n
"
);
goto
err
;
}
TRACE
(
"hwnd=%p egl_surface=%p
\n
"
,
gl
->
hwnd
,
gl
->
surface
);
return
gl
;
err:
wayland_gl_drawable_release
(
gl
);
return
NULL
;
}
static
void
wayland_update_gl_drawable
(
HWND
hwnd
,
struct
wayland_gl_drawable
*
new
)
{
struct
wayland_gl_drawable
*
old
;
pthread_mutex_lock
(
&
gl_object_mutex
);
if
((
old
=
find_drawable_for_hwnd
(
hwnd
)))
list_remove
(
&
old
->
entry
);
if
(
new
)
list_add_head
(
&
gl_drawables
,
&
new
->
entry
);
pthread_mutex_unlock
(
&
gl_object_mutex
);
if
(
old
)
wayland_gl_drawable_release
(
old
);
}
static
BOOL
set_pixel_format
(
HDC
hdc
,
int
format
,
BOOL
internal
)
{
HWND
hwnd
=
NtUserWindowFromDC
(
hdc
);
struct
wayland_gl_drawable
*
gl
;
int
prev
=
0
;
if
(
!
hwnd
||
hwnd
==
NtUserGetDesktopWindow
())
{
WARN
(
"not a proper window DC %p/%p
\n
"
,
hdc
,
hwnd
);
return
FALSE
;
}
if
(
format
<
0
||
format
>=
num_egl_configs
)
{
WARN
(
"Invalid format %d
\n
"
,
format
);
return
FALSE
;
}
TRACE
(
"%p/%p format %d
\n
"
,
hdc
,
hwnd
,
format
);
/* Even for internal pixel format fail setting it if the app has already set a
* different pixel format. Let wined3d create a backup GL context instead.
* Switching pixel format involves drawable recreation and is much more expensive
* than blitting from backup context. */
if
((
prev
=
win32u_get_window_pixel_format
(
hwnd
)))
return
prev
==
format
;
if
(
!
(
gl
=
wayland_gl_drawable_create
(
hwnd
,
format
)))
return
FALSE
;
wayland_update_gl_drawable
(
hwnd
,
gl
);
win32u_set_window_pixel_format
(
hwnd
,
format
,
internal
);
return
TRUE
;
}
static
BOOL
has_opengl
(
void
);
static
int
wayland_wglDescribePixelFormat
(
HDC
hdc
,
int
fmt
,
UINT
size
,
...
...
@@ -138,6 +290,17 @@ static PROC wayland_wglGetProcAddress(LPCSTR name)
return
(
PROC
)
p_eglGetProcAddress
(
name
);
}
static
BOOL
wayland_wglSetPixelFormat
(
HDC
hdc
,
int
format
,
const
PIXELFORMATDESCRIPTOR
*
pfd
)
{
return
set_pixel_format
(
hdc
,
format
,
FALSE
);
}
static
BOOL
wayland_wglSetPixelFormatWINE
(
HDC
hdc
,
int
format
)
{
return
set_pixel_format
(
hdc
,
format
,
TRUE
);
}
static
BOOL
has_extension
(
const
char
*
list
,
const
char
*
ext
)
{
size_t
len
=
strlen
(
ext
);
...
...
@@ -179,6 +342,9 @@ static BOOL init_opengl_funcs(void)
register_extension
(
"WGL_EXT_extensions_string"
);
opengl_funcs
.
ext
.
p_wglGetExtensionsStringEXT
=
wayland_wglGetExtensionsStringEXT
;
register_extension
(
"WGL_WINE_pixel_format_passthrough"
);
opengl_funcs
.
ext
.
p_wglSetPixelFormatWINE
=
wayland_wglSetPixelFormatWINE
;
return
TRUE
;
}
...
...
@@ -273,6 +439,8 @@ static void init_opengl(void)
{ ERR("Failed to load symbol %s\n", #func); goto err; } \
} while(0)
LOAD_FUNCPTR_EGL
(
eglChooseConfig
);
LOAD_FUNCPTR_EGL
(
eglCreateWindowSurface
);
LOAD_FUNCPTR_EGL
(
eglDestroySurface
);
LOAD_FUNCPTR_EGL
(
eglGetConfigAttrib
);
LOAD_FUNCPTR_EGL
(
eglGetError
);
LOAD_FUNCPTR_EGL
(
eglGetPlatformDisplay
);
...
...
@@ -317,6 +485,7 @@ static struct opengl_funcs opengl_funcs =
{
.
p_wglDescribePixelFormat
=
wayland_wglDescribePixelFormat
,
.
p_wglGetProcAddress
=
wayland_wglGetProcAddress
,
.
p_wglSetPixelFormat
=
wayland_wglSetPixelFormat
,
}
};
...
...
@@ -335,6 +504,14 @@ struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version)
return
&
opengl_funcs
;
}
/**********************************************************************
* wayland_destroy_gl_drawable
*/
void
wayland_destroy_gl_drawable
(
HWND
hwnd
)
{
wayland_update_gl_drawable
(
hwnd
,
NULL
);
}
#else
/* No GL */
struct
opengl_funcs
*
WAYLAND_wine_get_wgl_driver
(
UINT
version
)
...
...
@@ -342,4 +519,8 @@ struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version)
return
NULL
;
}
void
wayland_destroy_gl_drawable
(
HWND
hwnd
)
{
}
#endif
dlls/winewayland.drv/waylanddrv.h
View file @
e7ccb148
...
...
@@ -293,6 +293,12 @@ void wayland_pointer_deinit(void);
void
wayland_pointer_clear_constraint
(
void
);
/**********************************************************************
* OpenGL
*/
void
wayland_destroy_gl_drawable
(
HWND
hwnd
);
/**********************************************************************
* Helpers
*/
...
...
dlls/winewayland.drv/window.c
View file @
e7ccb148
...
...
@@ -402,6 +402,7 @@ void WAYLAND_DestroyWindow(HWND hwnd)
if
(
!
(
data
=
wayland_win_data_get
(
hwnd
)))
return
;
wayland_win_data_destroy
(
data
);
wayland_destroy_gl_drawable
(
hwnd
);
}
/***********************************************************************
...
...
include/config.h.in
View file @
e7ccb148
...
...
@@ -132,6 +132,9 @@
/* Define to 1 if you have the `unwind' library (-lunwind). */
#undef HAVE_LIBUNWIND
/* Define if we have the wayland-egl development environment */
#undef HAVE_LIBWAYLAND_EGL
/* Define if you have the X Shape extension */
#undef HAVE_LIBXSHAPE
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment