Home - binarycounter/Westonpack GitHub Wiki
Westonpack is a runtime for PortMaster that allows several programs that rely on X11, Wayland and OpenGL to run. It contains a full Wayland/X11 environment and several compatibility layers that bridge the gap between the game and your system. All the various puzzle pieces are controlled by the westonwrap.sh
script, that allows you set up Westonpack in various ways, to best suit your program.
Contact me (@BinaryCounter) on Discord for help!
This runtime provides compatibility for the following engines. This list is not exhaustive, nor does it guarantee compatibility.
- Godot 4
- Java
- LibGDX
- SFML
- SDL2 (X11)
- SDL3
- Allegro
- Ruffle
- Unity (experimental)
- Wine (experimental)
........ Many more.
- Pure XLib games
- Most GL Loaders relying on GLX (GLAD, GLFW, GLEW, etc)
- Most GLES Loaders relying on X11 EGL (GLAD, GLFW)
Westonpack:
- Full Wayland and X11 environment either on screen or offscreen
- OpenGL 2.1 (through GL4ES)
- OpenGL ES 3.2
- Compatibility layer that emulates GLX, EGL and GBM
- Built-in software cursor and FPS counter
Mesapack expansion:
- Desktop OpenGL 4.6 (Software rendered, LLVMPipe)
- Desktop OpenGL 2.1 (Virtualized, VirGL)
- Vulkan 1.3 (Software rendered, Lavapipe)
- DirectX 9 (Gallium Nine, through VirGL or LLVMPipe)
DRM GL System | DRM GL LLVMPipe | DRM GL VirGL | Headless | Headless Crusty GLX | Headless Crusty X11EGL | Headless Crusty GBM | Headless LIBGL_FB=1 | DRM GL LIBGL_FB=3 | |
---|---|---|---|---|---|---|---|---|---|
ArkOS | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
AmberELEC | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
muOS | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Perf. Issues |
Knulli | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
Knulli (a133p) | ✅ | ✅ | Perf. Issues | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
Rocknix (Mali) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
Rocknix (Panfrost) | Bypassed | Bypassed | Bypassed | Bypassed | Bypassed | Bypassed | Bypassed | Bypassed | Bypassed |
Check if there's an example script for your use-case! Otherwise proceed here:
1. Mount the Runtime at a location that is convenient for you (e.g. /tmp/weston
)
weston_dir=/tmp/weston
weston_runtime="weston_pkg_0.2"
if [ ! -f "$controlfolder/libs/${weston_runtime}.squashfs" ]; then
if [ ! -f "$controlfolder/harbourmaster" ]; then
pm_message "This port requires the latest PortMaster to run, please go to https://portmaster.games/ for more info."
sleep 5
exit 1
fi
$ESUDO $controlfolder/harbourmaster --quiet --no-check runtime_check "${weston_runtime}.squashfs"
fi
$ESUDO mkdir -p "${weston_dir}"
if [[ "$PM_CAN_MOUNT" != "N" ]]; then
$ESUDO umount "${weston_dir}"
fi
$ESUDO mount "$controlfolder/libs/${weston_runtime}.squashfs" "${weston_dir}"
2. (If using Mesa) Mount the Mesapack at /tmp/mesa
, and specify your gallium driver (Default is llvmpipe, available are llvmpipe, virpipe, zink) see https://docs.mesa3d.org/envvars.html for more info.
mesa_dir=/tmp/mesa
mesa_runtime="mesa_pkg_0.1"
if [ ! -f "$controlfolder/libs/${mesa_runtime}.squashfs" ]; then
if [ ! -f "$controlfolder/harbourmaster" ]; then
pm_message "This port requires the latest PortMaster to run, please go to https://portmaster.games/ for more info."
sleep 5
exit 1
fi
$ESUDO $controlfolder/harbourmaster --quiet --no-check runtime_check "${mesa_runtime}.squashfs"
fi
$ESUDO mkdir -p "${mesa_dir}"
if [[ "$PM_CAN_MOUNT" != "N" ]]; then
$ESUDO umount "${mesa_dir}"
fi
$ESUDO mount "$controlfolder/libs/${mesa_runtime}.squashfs" "${mesa_dir}"
3. Don't forget to setup your controller, save file directory etc. See https://portmaster.games/packaging.html#the-launchscript-sh for more info.
4. Run the $weston_dir/westonwrap.sh
script from the weston directory with the mode you want to run it in and your game file.
Usage: $ESUDO env [env_vars_1] $weston_dir/westonwrap.sh <backend> <renderer> <shell> <gl_library> [env_vars_2] <path_to_your_app> [your_app_arguments]
Example:
$ESUDO env $weston_dir/westonwrap.sh drm gl kiosk system ./your_executable
This script will set up the requested environment and run Weston and then your executable (using the GL library you specified). It will kill Weston and return when your executable exits.
If you do not specify an executable, this script will start Weston and immediately return. You will need to handle pausing and killing Weston and seatd yourself.
Any environment variables you exported in your script will be ignored (on systems where you're not running as root), unless you include them in either [env_vars_1]
or [env_vars_2]
.
[env_vars_1]
will be made available to the entire stack, [env_vars_2]
will be made available to only your app.
If you wish to specify LD_LIBRARY_PATH
,LD_PRELOAD
you must do so in the [env_vars_1]
section using the replacements WRAPPED_LIBRARY_PATH
and WRAPPED_PRELOAD
.
Ignoring this step will most certainly cause problems.
Example:
$ESUDO env WRAPPED_LIBRARY_PATH=/your/custom/libraries/ SOME_VAR=$SOME_OTHER_VAR $weston_dir/westonwrap.sh headless noop kiosk crusty_glx_gl4es VAR_PASSED_TO_APP=SOME_VALUE ./your_executable --your_arg 123
This package comes with support for different shells and rendering modes. Depending on what game you want to port, you will need to explore different settings. They all have advantages and drawbacks.
- drm: Render the desktop on screen using DRM/GBM. This lets you see Wayland/X11 GUI apps on screen, but currently does not work with GL4ES. Uses Crusty to render into a SDL2 context.
- headless: Do not render the desktop. Weston and Xwayland only serve in the background to let your app interact with them. This is useful when using GL4ES' GBM mode to directly render the GL contents to your screen.
-
auto: Automatic selection. Usually
gl
for thedrm
backend andnoop
for theheadless
backend. - gl: Assembles your final output using GLES. (Note: This does not mean your app itself is accelerated)
- pixman: Assembles your final output in software on the CPU. Slower but sometimes needed for compatibility. (currently not working correctly)
- noop: Does not render output at all. Only compatible with headless backend.
- desktop: A full Wayland desktop with a taskbar and resizable windows.
- kiosk: A minimal display environment that renders only the app you started. Apps are automatically fullscreened, if possible.
-
system: Whatever your system provides.
- Unless you're using Panfrost, you won't have GL at all.
- GL ES 3.2 will be available, only in your system's native platforms (SDL2, maybe fbdev or GBM)
- This mode can also be used to ship your own graphics libraries through
LD_LIBRARY_PATH
andLD_PRELOAD
-
llvmpipe: (needs mesapack)
- Software rendered GL4.5 and GLES 3.2 using the LLVMPipe renderer
- GLX and Wayland EGL are supported in the DRM backend.
- Works with more apps, even software that uses GLX in the background, like firefox, or nwjs.
- Very slow. Expect low framerates.
-
virgl: (needs mesapack)
- Virtualized GL2.1 and GLES 2 using the LLVMPipe renderer
- GLX and Wayland EGL are supported in the DRM backend. Soon also in headless mode.
- Works with most GL2.1 apps, generally more stable than GL4ES, but slower.
-
zink: (needs mesapack)
- Vulkan based GL4.5 using the Zink renderer. Requires device to have Vulkan support
- GLX and Wayland EGL are supported in the DRM backend.
- Works with pretty much all OpenGL apps.
- If Vulkan support is not present, lavapipe will be used to software render it. Generally slower than using LLVMPipe directly, avoid.
- Very slow. Expect low framerates.
-
crusty_gbm:
- Attempts to implement GBM and DRMKMS, using SDL2 to render
- Supports OpenGL ES 3.2 and lower
- Near native performance, meh compatibility.
-
crusty_glx_gl4es:
- Attempts to implement GLX, using SDL2 to render
- uses included GL4ES to provide OpenGL 2.1
- Decent performance and compatibility
-
crusty_x11egl:
- Attempts to implement EGL with X11 extensions, using SDL2 to render
- Supports OpenGL ES 3.2 and lower
- Near native performance and compatibility
-
gl4es: (do not use, low device support)
- Hardware accelerated GL2.1 and GLES2 using ptitSeb' GL4ES library.
- GLX is supported in the headless backend.
- Supports fbdev and GBM backend (with varying degrees of compatibility)
- Usage with the DRM backend might result in empty windows or crashes.
-
crusty_virgl: (needs mesapack) (Not included yet, currently in development)
- Virtualized GL2.1 and GLES 2 using the LLVMPipe renderer
- Works with most GL2.1 apps, generally more stable than GL4ES, but slower.
- Will be faster than normal virgl, due to reduced overhead of the surface through XWayland and Weston via CPU.
Mode | Use Case |
---|---|
drm gl kiosk system |
Your App does not require OpenGL, but uses XLib to draw graphics |
headless noop kiosk crusty_glx_gl4es |
Your app uses OpenGL 2 and GLX, no graphics are drawn using XLib |
headless noop kiosk crusty_x11egl |
Your app uses OpenGL ES and EGL (X11), no graphics are drawn using XLib |
headless noop kiosk crusty_gbm |
Your app was made for GBM/DRMKMS |
drm gl kiosk virgl |
Your app uses OpenGL 2 and GLX/EGL, graphics are drawn using XLib, your app does not have high graphics requirements |
drm gl kiosk llvmpipe |
Your app uses OpenGL 3 or 4 and GLX/EGL, graphics are drawn using XLib, your app has very low graphics requirements |
[env_var_1] section:
-
CRUSTY_RESOLUTION=320x240
: specify a virtual screen resolution that's given to crusty (or weston) -
CRUSTY_SHOW_CURSOR=1
: Enables a software mouse cursor, useful forheadless
modes. -
CRUSTY_FPS=1
: Prints the current FPS to the console every second -
CRUSTY_GLES=32
: Controls the GLES version used by Crusty, valid values are 1,10,11,2,20,21,3,30,31,32. Default is 32. 11 is useful for SFML apps. 31 for running crusty under Panfrost -
WESTON_HEADLESS_WIDTH=320
&WESTON_HEADLESS_HEIGHT=240
: specify a virtual desktop resolution for use with weston headless mode -
WESTON_NO_HEADLESS_INPUT=1
: disable input capturing in weston headless mode, fixes some double input issues with SDL2 apps -
WESTON_KIOSK_NO_RESIZE=1
: disable automatic resizing in weston kiosk mode, fixes some SDL2 apps segfaulting on startup -
WRAPPED_LIBRARY_PATH=/some/libs
: like LD_LIBRARY_PATH, but only applies to your app, not weston or any supporting programs. -
WRAPPED_PRELOAD=/some/lib.so
: like LD_PRELOAD, but only applies to your app, not weston or any supporting programs. -
XCURSOR_SIZE=24
: Change cursor size -
crustydebug=_debug
: Setting this will enable the debug version of crusty that prints a lot of useful information and a full tracelog to the console.
-
$weston_dir/lib_aarch64/
: Contains aarch64/armhf versions of many X11 and Wayland libraries -
$weston_dir/lib_aarch64/graphics/
: Contains different versions of crusty and gl4es -
$weston_dir/tools/drmd
Program that simulates a DRM device (or any other device) being present on your system -
$weston_dir/tools/xtrace
Useful debug tool to trace X11 trafic -
$weston_dir/libexec/
Includes a terminal and virtual keyboard program for Weston -
$mesa_dir/lib/aarch64-linux-gnu/
: Contains Mesa libraries -
$mesa_dir/virgl/
: Contains virgl_test_server, needed for setting up VirGL
- If you have a game with unknown dependencies, try the mode
drm gl kiosk llvmpipe
(with mesapack) first. It'll be slow, but have very high compatibility - The mode
headless noop kiosk crusty_glx_gl4es
has decent compatibility and performance for GL2 and GLES2 games -
strace -f -e file
is your friend to debug library loading issues,crustydebug=_debug
for debugging GL context issues,gdb --args
for debugging segfaults - You can load libraries only on mali or panfrost systems by using
WRAPPED_LIBRARY_PATH_MALI
andWRAPPED_LIBRARY_PATH_PANFROST
. This can help you exclude X11 related libraries on Panfrost systems. - unsetting
LD_PRELOAD=
in[env_var_2]
can in rare cases be useful if the app loads libEGL or libGLX at runtime. There is a quirk with some OSes that causes this to fail if crusty is in LD_PRELOAD. - You can force an app to link against crusty instead of system libraries by replacing the string "libEGL.so" or "libGLX.so" with "libCRU.so". This is useful e.g for GLAD EGL/GLX loaders. This can be done on device aswell with this python3 oneliner:
python3 -c "f=open('game_executable','r+b'); d=f.read().replace(b'libEGL.so', b'libCRU.so').replace(b'libGLX.so', b'libCRU.so'); f.seek(0); f.write(d); f.close()"
- X11: The classic Linux display system for applications with a GUI. A lot of apps and games rely on this to render menus or to simply to open a window to render GL content into.
- Wayland: A new display system that will eventually replace X11. It has an entirely different protocol than X11, so only some apps are compatible with this. (SDL2, GTK3, QT5 based apps are notable examples)
- GLX: An extension to X11 that allows apps to use GL(ES) inside of a X11 window. (Note: Graphics drivers need to support this, yours probably doesn't. See compatibility table for details)
- EGL: An API of your graphics driver that allows apps to use GL(ES) inside various contexts. These contexts need to be seperately supported by your graphics driver as "externsions". (Notable contexts are FBO, GBM, Wayland, X11).
- SDL: A middleware that handles setting up graphics and display systems for you. Every Portmaster device comes with an included version of SDL2 that is specifically made to support their native display hardware. Most ports use SDL2 to display graphics, many also use it for sound and controller input.
- GBM: An API that allows apps to use GL(ES) directly without the use of any display system. It relies on the EGL GBM extension.
- fbdev: Another API that allows apps to use GL(ES) directly without the use of any display system. It relies on the "fbdev" EGL_PLATFORM.
- Weston: A flexible display server that implements the Wayland protocol and supports Xwayland. It comes with a lot of configuration options.
- Xwayland: A compatibility layer to allow X11 applications to run on Wayland
- seatd: A program used by Weston to manage system resources like displays or input devices
- GL4ES: A library by ptitSeb that allows some GL1 and GL2 apps to run when only GLES is available. It also includes a GLX wrapper that allows this to work under X11.
- Mesa: The general purpose linux GL(ES) library. In this context it provides GL and GLX support, rendered in software on the CPU (Slooooow) or virtualized (slightly less slow).
- Gallium: A graphcics driver within Mesa. Common examples are Panfrost, LLVMPipe, VirGL, Zink, v3d...
- VirGL: A Mesa gallium driver that virtualizes OpenGL calls, usually for use with Virtual Machines. We're using the virpipe/vtest variant here, that is usually reserved for testing and not performance optimized. It passes GL commands through a socket to a render server which emulates desktop GL calls on GLES through the "limited environment renderer". The test setup skips a lot of the virtualization, but uses the CPU to composite the final image, which has a lot of overhead.
- LLVMPipe/Lavapipe: A mesa gallium driver that renders graphics in software. LLVMPipe renders OpenGL Lavapipe renders Vulkan.
- Zink: A mesa gallium driver that provides OpenGL support on hardware that supports Vulkan.
- Crusty: My custom wrapper, attempting to bring GLX, Wayland EGL and GBMDRM support to devices that do not support it, to unify the requirements across devices. Highly experimental.
- Mali / Panfrost: Graphics drivers for Rockchip handhelds. Availability depends on device and OS. Panfrost drivers mostly support the EGL Wayland extensions, Mali drivers mostly do not.
- Crusty: Implement enough of Wayland EGL to allow XWayland to use glamor for faster performance
- Crusty: On screen keyboard
- Crusty: Better Wine compatibility
- Mesa: Better Wine compatibility
- Publish source to Weston, Crusty and Mesa
- OpenGL 3 support?
- Cebion
- JanTrueno
- Kdog
- Ganimoth
- Jeod
- kloptops
- JohnnyOnFlame
- beniamino
- Slobters