Open KyunLFA opened 10 months ago
wayland_process_init Wayland compositor doesn't support wl_subcompositor
hmmm looks like wine is complaining that gamescope doesn’t implement wl_subcompositor
, which apparently is a feature that allows applications to offload compositing-related work to the compositor.
Not sure if that is the sole reason wayland wine isn’t running w/ gamescope… But if it is the underlying issue, the two solutions I can think of would be either:
wl_subcompositor
in gamescopeOR a partial solution (would only work in nested sessions, on wayland hosts):
wl_subcompositor
that forwards the wl_subcompositor
feature from the wayland host compositor that gamescope would be running under in a nested session? (Now that I think about it, this second idea would probably be a waste of time I guess???)Since I won't be creating a new issue, I don't feel too bad tagging some potential parties of interest. Not requesting the feature here, it's just the data for posterity. If you are one of the tagged, please disregard if occupied or simply uninterested. Apologies in advance for pinging. Barebones UGLY HACKY diff for getting a window running in the post below. TL;DR in the end.
@Joshua-Ashton @emersion @romangg @sharkautarch
Here are the findings:
0 (skip if caught up). Originally this was about announcing that Wine waylanddrv wasn't rendering in Gamescope due to missing wl_subcompositor. See the reg edit above to enable on newer Wine.
It already works on git HEAD. But only for nested, with an envvar override. Use gamescope --expose-wayland -- env WAYLAND_DISPLAY=wayland-foo wine PROGRAMHERE
(foo = 0 for Plasma 6, 1 for Sway, depends on the compositor);
wl_subcompositor is needed for embedded mode. It's very straightforward to "implement" in Gamescope;
zwp_pointer_constraints_v1, turns out is another hard requirement that reared after wl_subcompositor. With a quick&dirty diff (subcompositor+contraints hack, see the post below), it's enough to render a window in embedded mode...
...That will quickly segfault on (an invisible) cursor movement. You may then think it would be due to hacky unimplemented constraints, yet after I attempted to port back https://github.com/ValveSoftware/gamescope/pull/28, although it proved too difficult to do properly with my extremely limited skills, turns out the cause of the segfaults was not the wrong contraints, but a C++ stdlib runtime throw, std::get bad variant access with a wrong index (full backtrace below), from xwayland() calls in steamcompmgr.cpp in MouseCursor::paint, in the following lines:
uint32_t sourceWidth = window->xwayland().a.width;
uint32_t sourceHeight = window->xwayland().a.height;
Additionally, after applying a hack to proceed, same throw in the lines:
scaledX = (winX - window->xwayland().a.x) * currentScaleRatio_x + cursorOffsetX;
scaledY = (winY - window->xwayland().a.y) * currentScaleRatio_y + cursorOffsetY;
After hacking some resolution values to sourceWidth/Height and scaledX/Y, finally, at last we're rendering on Gamescope embedded without segfaulting, but since I could not implement valid pointer constraints, the cursor was stuck to the leftmost top side (only appears after moving);
Visual bugs plague the window in my system. Some of the text flashes in and out, window elements may be drawn as black rectangles or flicker, window is never fullscreen (pillarboxed) unless it randomly is, and popups like context menus fill the window. Here I'm at a loss what is causing it;
There is already a micro-compositor (Wayland kiosk) with Wine Wayland support (kind of)! That could be useful for figuring out exactly what is happening by checking their work. Cage, with the https://github.com/cage-kiosk/cage/pull/300 PR applied on top, renders a wine notepad.exe window correctly in fullscreen.
TL;DR. 1.Nested already works; 2.wl_subcompositor is missing; 3/5.zwp_pointer_constraints_v1 implementation is needed; 4.There's a C++ runtime throw in MouseCursor::paint; 6.Text and window elements flicker and black textures where there aren't any; 7.Cage Kiosk already works embedded, looking there may prove useful.
Note: I will be away from the PC soon, so likely I won't be able to reply for a few hours, so sorry.
HACKHACKHACK
diff --git a/src/wlserver.cpp b/src/wlserver.cpp
index 82dc230..29f58eb 100644
--- a/src/wlserver.cpp
+++ b/src/wlserver.cpp
@@ -27,8 +27,10 @@
#include <wlr/render/wlr_renderer.h>
#include <wlr/render/timeline.h>
#include <wlr/types/wlr_compositor.h>
+#include <wlr/types/wlr_subcompositor.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_pointer.h>
+#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_touch.h>
#include <wlr/types/wlr_drm.h>
@@ -1594,6 +1596,10 @@ bool wlserver_init( void ) {
wlserver.wlr.compositor = wlr_compositor_create(wlserver.display, 5, wlserver.wlr.renderer);
+ wlserver.wlr.subcompositor = wlr_subcompositor_create(wlserver.display);
+
+ wlserver.wlr.constraints = wlr_pointer_constraints_v1_create(wlserver.display);
+
wl_signal_add( &wlserver.wlr.compositor->events.new_surface, &new_surface_listener );
create_ime_manager( &wlserver );
diff --git a/src/wlserver.hpp b/src/wlserver.hpp
index aa018dd..020ea81 100644
--- a/src/wlserver.hpp
+++ b/src/wlserver.hpp
@@ -127,6 +127,8 @@ struct wlserver_t {
struct wlr_renderer *renderer;
struct wlr_compositor *compositor;
+ struct wlr_subcompositor *subcompositor;
+ struct wlr_pointer_constraints_v1 *constraints;
struct wlr_session *session;
struct wlr_seat *seat;
struct wlr_linux_drm_syncobj_manager_v1 *drm_syncobj_manager_v1;
Full backtrace of 4.:
#0 0x00007c826a4a053b in pthread_kill () at /usr/lib/libc.so.6
#1 0x00007c826a442048 in raise () at /usr/lib/libc.so.6
#2 0x00007c826a424478 in abort () at /usr/lib/libc.so.6
#3 0x00007c826a897b42 in __gnu_cxx::__verbose_terminate_handler () at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/vterminate.cc:95
#4 0x00007c826a8acbfc in __cxxabiv1::__terminate (handler=<optimized out>) at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:48
#5 0x00007c826a8acc69 in std::terminate () at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:58
#6 0x00007c826a8acefc in __cxxabiv1::__cxa_throw
(obj=<optimized out>, tinfo=0x5c7e32737c00 <typeinfo for std::bad_variant_access>, dest=0x5c7e32528130 <std::bad_variant_access::~bad_variant_access()>)
at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_throw.cc:98
#7 0x00005c7e325280ed in std::__throw_bad_variant_access (__what=0x5c7e3237a1d0 "std::get: wrong index for variant")
at /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/variant:1325
#8 0x00005c7e32528067 in std::__throw_bad_variant_access (__valueless=false) at /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/variant:1333
#9 0x00005c7e32527ff3 in std::get<0ul, steamcompmgr_xwayland_win_t, steamcompmgr_xdg_win_t>
(__v=std::variant<steamcompmgr_xwayland_win_t, steamcompmgr_xdg_win_t> [index 1] = {...})
at /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/variant:1692
#10 0x00005c7e32527fad in std::get<steamcompmgr_xwayland_win_t, steamcompmgr_xwayland_win_t, steamcompmgr_xdg_win_t>
(__v=std::variant<steamcompmgr_xwayland_win_t, steamcompmgr_xdg_win_t> [index 1] = {...})
at /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/variant:1128
#11 0x00005c7e32521b9c in steamcompmgr_win_t::xwayland (this=0x5c7e604b4ec0) at ../gamescope/src/steamcompmgr_shared.hpp:141
#12 0x00005c7e324ec27f in MouseCursor::paint (this=0x7c8248248e50, window=0x5c7e604b4ec0, fit=0x0, frameInfo=0x7c82517ff350) at ../gamescope/src/steamcompmgr.cpp:1998
#13 0x00005c7e324fbf19 in paint_all (async=false) at ../gamescope/src/steamcompmgr.cpp:2574
#14 0x00005c7e324f9428 in steamcompmgr_main (argc=5, argv=0x7ffd1068d8c8) at ../gamescope/src/steamcompmgr.cpp:7886
#15 0x00005c7e32552d8f in steamCompMgrThreadRun (argc=5, argv=0x7ffd1068d8c8) at ../gamescope/src/main.cpp:933
#16 0x00005c7e325538fa in std::__invoke_impl<void, void (*)(int, char**), int, char**>
(__f=@0x5c7e6050d3a8: 0x5c7e32552d60 <steamCompMgrThreadRun(int, char**)>, __args=@0x5c7e6050d3a0: 5, __args=@0x5c7e6050d398: 0x7ffd1068d8c8)
at /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/invoke.h:61
#17 0x00005c7e32553865 in std::__invoke<void (*)(int, char**), int, char**>
(__fn=@0x5c7e6050d3a8: 0x5c7e32552d60 <steamCompMgrThreadRun(int, char**)>, __args=@0x5c7e6050d3a0: 5, __args=@0x5c7e6050d398: 0x7ffd1068d8c8)
at /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/invoke.h:96
#18 0x00005c7e32553833 in std::thread::_Invoker<std::tuple<void (*)(int, char**), int, char**> >::_M_invoke<0ul, 1ul, 2ul> (this=0x5c7e6050d398)
at /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/std_thread.h:292
#19 0x00005c7e325537e5 in std::thread::_Invoker<std::tuple<void (*)(int, char**), int, char**> >::operator() (this=0x5c7e6050d398)
at /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/std_thread.h:299
#20 0x00005c7e32553669 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(int, char**), int, char**> > >::_M_run (this=0x5c7e6050d390)
at /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/std_thread.h:244
#21 0x00007c826a8f3843 in std::execute_native_thread_routine (__p=0x5c7e6050d390) at /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:104
#22 0x00007c826a49e55c in ??? () at /usr/lib/libc.so.6
#23 0x00007c826a52b95c in ??? () at /usr/lib/libc.so.6
Update!! Wine wayland on embedded mode progress thanks to @sharkautarch !! The solution (for now) of the bad variant access was adding && input->type == steamcompmgr_win_type_t::XWAYLAND
to the line if (input && !bForceHideCursor
in steamcompmgr.cpp!! Will now move on to attempt to get a working cursor... Updates to be posted shortly over at my fork.
edit: Nope, couldn't get a working cursor :/ Not skilled enough atm
I just realized, setting WAYLAND_DISPLAY to something other than gamescope's wayland display just runs the app without gamescope :/
Not sure if Wine bug or a Gamescope bug.
Wine's wayland driver works correctly, but not under gamescope by using the flag
--expose-wayland
Forcing a new enough (or patched) wine to use (non x)wayland with "
wine reg.exe add HKCU\\Software\\Wine\\Drivers /v Graphics /d wayland
" (does not need to unset DISPLAY in this way) makes it so launching undergamescope --expose-wayland -- wine (insert program)
cannot produce a viable window with the following logs:For notepad or
gamescope --expose-wayland --debug-layers --debug-focus --debug-events -- wine notepad
:Log without gamescope (opens correctly):
For a game running on DXVK/Vulkan or
gamescope --expose-wayland --debug-layers --debug-focus --debug-events -- wine DBXV2.exe
:Log without gamescope (opens correctly) :
Setting
WAYLAND_DISPLAY
and/orDISPLAY
on the right side of gamescope command to various strings including blank,wayland-0
andgamescope-0
does not help like it does to Firefox for example (#808). Foregoing--expose-wayland
doesn't help either as, as stated above, with this registry edit wine will ONLY use native wayland, which rules out theDISPLAY=""
requirement and associated interfecences with gamescope.I have observed the same behavior from at least one other user, and I'm waiting on a second. A quick and dirty way to get access to a precompiled wine with wayland driver ability if your distro does not offer it is to grab one of the binaries over at Tk-Glitch's wine-tkg avaiable for a variety of distros: link
gamescope: git master (dc81258cec01ad137056191b8db990adcbba6341) wine: 9.0.r2.ge045af48 ( TkG Staging Esync Fsync ) wm: sway 1.9-dev-ae33f4eb mesa: 24.1.0-devel (git-c3a64f8dd1) kernel: 6.7.1 (CachyOS)