Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a93ef63
initial work on porting to webrogue
Destructor17 Dec 20, 2024
230106a
make it work on webrogue
Destructor17 Dec 21, 2024
3efafa4
more webrogue functionality
Destructor17 Jan 4, 2025
70307ec
use gfxstream
Destructor17 Feb 20, 2025
b3e57c3
add some stubs
Destructor17 Feb 22, 2025
620db77
stub event handling
Destructor17 Mar 9, 2025
624dd3d
more webrogue events
Destructor17 Mar 10, 2025
c9f9113
more webrogue events
Destructor17 Mar 10, 2025
3700202
switch from wasix to wasip1-threads
Destructor17 Mar 12, 2025
06d9ab4
update webroguegfx
Destructor17 Apr 14, 2025
3f35d32
SDL2: include dependencies in installed module
Destructor17 Apr 22, 2025
3a76221
get_swap_interval
Destructor17 May 1, 2025
40805fa
events
Destructor17 May 3, 2025
d3a2bc7
resize events
Destructor17 May 7, 2025
2c85c1c
wip vulkan for webrogue
Destructor17 Aug 23, 2025
a52e47a
Use Angle
Destructor17 Dec 1, 2025
6fe091c
better webrogue event handling
Destructor17 Dec 4, 2025
bda6ee9
highdpi fix
Destructor17 Dec 8, 2025
928d853
Webrogue: make OpenGL ES and Vulkan orthogonal
Destructor17 Dec 11, 2025
c6ce9f0
webrogue fix
Destructor17 Dec 11, 2025
b761d0b
Webrogue: handle named_key
Destructor17 Dec 16, 2025
986edbf
Webrogue: weak vulkan libraries linkage
Destructor17 Jan 29, 2026
8c60d9d
Update WebrogueGFX
Destructor17 Feb 6, 2026
bb4d1fb
Webrogue: Software rendering and weak EGL linking
Destructor17 Feb 9, 2026
842a4ab
Webrogue fixes
Destructor17 Feb 9, 2026
add1f81
Webrogue: Vulkan availability checks
Destructor17 Feb 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ endif()
# MSVC runtime library flags are selected by an abstraction.
set(CMAKE_POLICY_DEFAULT_CMP0091 NEW)

cmake_minimum_required(VERSION 3.0.0...3.10)
cmake_minimum_required(VERSION 3.31)
project(SDL2 C)

if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
Expand Down Expand Up @@ -163,13 +163,13 @@ endif()
SDL_DetectCMakePlatform()

# Don't mistake osx for unix
if(UNIX AND NOT ANDROID AND NOT APPLE AND NOT RISCOS)
if(WASI OR UNIX AND NOT ANDROID AND NOT APPLE AND NOT RISCOS )
set(UNIX_SYS ON)
else()
set(UNIX_SYS OFF)
endif()

if(UNIX OR APPLE)
if(WASI OR UNIX OR APPLE)
set(UNIX_OR_MAC_SYS ON)
else()
set(UNIX_OR_MAC_SYS OFF)
Expand Down Expand Up @@ -477,7 +477,7 @@ set_option(SDL_WASAPI "Use the Windows WASAPI audio driver" ${WINDO
set_option(SDL_RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS})
set_option(SDL_RENDER_METAL "Enable the Metal render driver" ${APPLE})
set_option(SDL_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS})
dep_option(SDL_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF)
dep_option(SDL_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS OR WASI" OFF)
set_option(SDL_METAL "Enable Metal support" ${APPLE})
set_option(SDL_KMSDRM "Use KMS DRM video driver" ${UNIX_SYS})
dep_option(SDL_KMSDRM_SHARED "Dynamically load KMS DRM support" ON "SDL_KMSDRM" OFF)
Expand Down Expand Up @@ -1455,7 +1455,7 @@ elseif(EMSCRIPTEN)
CheckPTHREAD()
CheckLibUnwind()

elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
elseif(WASI OR UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
if(SDL_AUDIO)
if(SYSV5 OR SOLARIS OR HPUX)
set(SDL_AUDIO_DRIVER_SUNAUDIO 1)
Expand Down Expand Up @@ -1510,6 +1510,31 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
set(HAVE_VULKAN TRUE)
endif()
CheckQNXScreen()
# FIXME: implement CheckWebrogue()
if(WASI)
file(GLOB WEBROGUE_SOURCES ${SDL2_SOURCE_DIR}/src/video/webrogue/*.c)
list(APPEND SOURCE_FILES ${WEBROGUE_SOURCES})
set(SDL_VIDEO_DRIVER_WEBROGUE 1)
if(SDL_OPENGLES)
set(HAVE_OPENGLES 1)
set(SDL_VIDEO_OPENGL_ES2 1)
set(SDL_VIDEO_OPENGL_EGL 1)
set(SDL_VIDEO_RENDER_OGL_ES2 1)
endif()
set(SDL_VIDEO_RENDER_OGL 0)
set(SDL_VIDEO_OPENGL 0)
if(SDL_VULKAN)
set(SDL_VIDEO_VULKAN 1)
set(HAVE_VULKAN 1)
set(SDL_VIDEO_RENDER_VULKAN 1)
endif()

if(TARGET webroguegfx)
list(APPEND EXTRA_LIBS webroguegfx)
else()
list(APPEND EXTRA_LDFLAGS -lwebroguegfx -lc++ -lc++abi)
endif()
endif()
endif()

if(UNIX)
Expand Down Expand Up @@ -2944,7 +2969,7 @@ elseif(N3DS)
endforeach()
endif()

if(HAVE_VULKAN AND NOT SDL_LOADSO)
if(HAVE_VULKAN AND NOT SDL_LOADSO AND NOT WASI)
message(STATUS "Vulkan support is available, but disabled because there's no loadso.")
set(HAVE_VULKAN FALSE)
set(SDL_VIDEO_VULKAN 0)
Expand Down
3 changes: 3 additions & 0 deletions cmake/sdlchecks.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,9 @@ macro(CheckPTHREAD)
set(PTHREAD_LDFLAGS "-pthread")
elseif(QNX)
# pthread support is baked in
elseif(WASI)
set(PTHREAD_CFLAGS "-D_REENTRANT")
set(PTHREAD_LDFLAGS "-lpthread")
else()
set(PTHREAD_CFLAGS "-D_REENTRANT")
set(PTHREAD_LDFLAGS "-lpthread")
Expand Down
1 change: 1 addition & 0 deletions include/SDL_config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@
#cmakedefine SDL_VIDEO_DRIVER_RISCOS @SDL_VIDEO_DRIVER_RISCOS@
#cmakedefine SDL_VIDEO_DRIVER_PSP @SDL_VIDEO_DRIVER_PSP@
#cmakedefine SDL_VIDEO_DRIVER_PS2 @SDL_VIDEO_DRIVER_PS2@
#cmakedefine SDL_VIDEO_DRIVER_WEBROGUE @SDL_VIDEO_DRIVER_WEBROGUE@

#cmakedefine SDL_VIDEO_DRIVER_KMSDRM @SDL_VIDEO_DRIVER_KMSDRM@
#cmakedefine SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC @SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC@
Expand Down
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
#define SDL_DYNAMIC_API 0 /* The N-Gage doesn't support dynamic linking either */
#elif defined(__3DS__)
#define SDL_DYNAMIC_API 0 /* devkitARM doesn't support dynamic linking */
#elif defined(__wasi__)
#define SDL_DYNAMIC_API 0 /* looks like dynamic linking is barely supported in wasm */
#elif defined(DYNAPI_NEEDS_DLOPEN) && !defined(HAVE_DLOPEN)
#define SDL_DYNAMIC_API 0 /* we need dlopen(), but don't have it.... */
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/filesystem/unix/SDL_sysfilesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ char *SDL_GetBasePath(void)
retval = readSymLink("/proc/self/path/a.out");
#elif defined(__QNXNTO__)
retval = SDL_LoadFile("/proc/self/exefile", NULL);
#elif defined(__wasi__)
retval = SDL_strdup("/main.wasm");
#else
retval = readSymLink("/proc/self/exe"); /* linux. */
if (!retval) {
Expand Down
8 changes: 7 additions & 1 deletion src/misc/unix/SDL_sysurl.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,20 @@

#include "../SDL_sysurl.h"

#include <unistd.h>
#ifndef __wasi__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#endif /* __wasi__ */

int SDL_SYS_OpenURL(const char *url)
{
#ifdef __wasi__
return SDL_SetError("URL handling is currently not implemented for Webrogue");
#else
const pid_t pid1 = fork();
if (pid1 == 0) { /* child process */
#ifdef USE_POSIX_SPAWN
Expand Down Expand Up @@ -77,6 +82,7 @@ int SDL_SYS_OpenURL(const char *url)
return SDL_SetError("Waiting on xdg-open failed: %s", strerror(errno));
}
}
#endif /* __wasi__ */
}

/* vi: set ts=4 sw=4 expandtab: */
10 changes: 6 additions & 4 deletions src/thread/pthread/SDL_systhread.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
#include <pthread_np.h>
#endif

#ifndef __wasi__
#include <signal.h>
#endif
#include <errno.h>

#ifdef __LINUX__
Expand Down Expand Up @@ -60,7 +62,7 @@
#endif


#ifndef __NACL__
#if !defined(__NACL__) && !defined(__wasi__)
/* List of signals to mask in the subthreads */
static const int sig_list[] = {
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
Expand Down Expand Up @@ -122,7 +124,7 @@ int SDL_SYS_CreateThread(SDL_Thread *thread)

void SDL_SYS_SetupThread(const char *name)
{
#if !defined(__NACL__)
#if !defined(__NACL__) && !defined(__wasi__)
int i;
sigset_t mask;
#endif /* !__NACL__ */
Expand Down Expand Up @@ -162,7 +164,7 @@ void SDL_SYS_SetupThread(const char *name)
}

/* NativeClient does not yet support signals.*/
#if !defined(__NACL__)
#if !defined(__NACL__) && !defined(__wasi__)
/* Mask asynchronous signals for this thread */
sigemptyset(&mask);
for (i = 0; sig_list[i]; ++i) {
Expand All @@ -188,7 +190,7 @@ SDL_threadID SDL_ThreadID(void)

int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
#if defined(__NACL__) || defined(__RISCOS__) || defined(__OS2__)
#if defined(__NACL__) || defined(__RISCOS__) || defined(__OS2__) || defined(__wasi__)
/* FIXME: Setting thread priority does not seem to be supported in NACL */
return 0;
#else
Expand Down
1 change: 1 addition & 0 deletions src/video/SDL_sysvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ extern VideoBootStrap NACL_bootstrap;
extern VideoBootStrap VIVANTE_bootstrap;
extern VideoBootStrap Emscripten_bootstrap;
extern VideoBootStrap QNX_bootstrap;
extern VideoBootStrap WEBROGUE_bootstrap;
extern VideoBootStrap OFFSCREEN_bootstrap;
extern VideoBootStrap NGAGE_bootstrap;
extern VideoBootStrap OS2DIVE_bootstrap;
Expand Down
21 changes: 12 additions & 9 deletions src/video/SDL_video.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ static VideoBootStrap *bootstrap[] = {
#ifdef SDL_VIDEO_DRIVER_NGAGE
&NGAGE_bootstrap,
#endif
#ifdef SDL_VIDEO_DRIVER_WEBROGUE
&WEBROGUE_bootstrap,
#endif
#ifdef SDL_VIDEO_DRIVER_OFFSCREEN
&OFFSCREEN_bootstrap,
#endif
Expand Down Expand Up @@ -214,7 +217,7 @@ typedef struct

static Uint32 SDL_DefaultGraphicsBackends(SDL_VideoDevice *_this)
{
#if (defined(SDL_VIDEO_OPENGL) && defined(__MACOSX__)) || (defined(__IPHONEOS__) && !TARGET_OS_MACCATALYST) || defined(__ANDROID__) || defined(__NACL__)
#if (defined(SDL_VIDEO_OPENGL) && defined(__MACOSX__)) || (defined(__IPHONEOS__) && !TARGET_OS_MACCATALYST) || defined(__ANDROID__) || defined(__NACL__) || defined(__wasi__)
if (_this->GL_CreateContext) {
return SDL_WINDOW_OPENGL;
}
Expand Down Expand Up @@ -518,7 +521,7 @@ int SDL_VideoInit(const char *driver_name)
while (driver_attempt && *driver_attempt != 0 && !video) {
const char *driver_attempt_end = SDL_strchr(driver_attempt, ',');
size_t driver_attempt_len = (driver_attempt_end) ? (driver_attempt_end - driver_attempt)
: SDL_strlen(driver_attempt);
: SDL_strlen(driver_attempt);

for (i = 0; bootstrap[i]; ++i) {
if ((driver_attempt_len == SDL_strlen(bootstrap[i]->name)) &&
Expand Down Expand Up @@ -1068,8 +1071,8 @@ static SDL_DisplayMode *SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay *di
}

SDL_DisplayMode *SDL_GetClosestDisplayMode(int displayIndex,
const SDL_DisplayMode *mode,
SDL_DisplayMode *closest)
const SDL_DisplayMode *mode,
SDL_DisplayMode *closest)
{
SDL_VideoDisplay *display;

Expand Down Expand Up @@ -4026,10 +4029,10 @@ int SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
return 0;
}
case SDL_GL_CONTEXT_NO_ERROR:
{
*value = _this->gl_config.no_error;
return 0;
}
{
*value = _this->gl_config.no_error;
return 0;
}
default:
return SDL_SetError("Unknown OpenGL attribute");
}
Expand Down Expand Up @@ -4498,7 +4501,7 @@ int SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
while (driver_attempt && (*driver_attempt != 0) && (retval == -1)) {
const char *driver_attempt_end = SDL_strchr(driver_attempt, ',');
size_t driver_attempt_len = (driver_attempt_end) ? (driver_attempt_end - driver_attempt)
: SDL_strlen(driver_attempt);
: SDL_strlen(driver_attempt);
for (i = 0; bootstrap[i]; ++i) {
if (bootstrap[i]->ShowMessageBox && (driver_attempt_len == SDL_strlen(bootstrap[i]->name)) &&
(SDL_strncasecmp(bootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) {
Expand Down
5 changes: 4 additions & 1 deletion src/video/SDL_vulkan_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "SDL_stdinc.h"

#ifdef SDL_VIDEO_VULKAN
#if defined(SDL_LOADSO_DISABLED) || defined(SDL_LOADSO_DUMMY)
#if (defined(SDL_LOADSO_DISABLED) || defined(SDL_LOADSO_DUMMY)) && !defined(__wasi__)
#error You should not be here.
#endif

Expand Down Expand Up @@ -56,6 +56,9 @@
#define VK_USE_PLATFORM_XLIB_KHR
#define VK_USE_PLATFORM_XCB_KHR
#endif
#ifdef SDL_VIDEO_DRIVER_WEBROGUE
#define VK_USE_PLATFORM_WEBROGUE
#endif

#define VK_NO_PROTOTYPES
#include "./khronos/vulkan/vulkan.h"
Expand Down
6 changes: 6 additions & 0 deletions src/video/khronos/EGL/eglplatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ typedef void *EGLNativeDisplayType;
typedef khronos_uintptr_t EGLNativePixmapType;
typedef khronos_uintptr_t EGLNativeWindowType;

#elif defined(__wasi__)

typedef void *EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;

#else
#error "Platform not recognized"
#endif
Expand Down
8 changes: 8 additions & 0 deletions src/video/khronos/vulkan/vk_icd.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ typedef enum {
VK_ICD_WSI_PLATFORM_GGP,
VK_ICD_WSI_PLATFORM_SCREEN,
VK_ICD_WSI_PLATFORM_FUCHSIA,
VK_ICD_WSI_PLATFORM_WEBROGUE,
} VkIcdWsiPlatform;

typedef struct {
Expand Down Expand Up @@ -242,3 +243,10 @@ typedef struct {
VkIcdSurfaceBase base;
} VkIcdSurfaceImagePipe;
#endif // VK_USE_PLATFORM_FUCHSIA

#ifdef VK_USE_PLATFORM_WEBROGUE
typedef struct {
VkIcdSurfaceBase base;
const void *pWindow;
} VkIcdSurfaceWebrogue;
#endif // VK_USE_PLATFORM_WEBROGUE
2 changes: 1 addition & 1 deletion src/video/khronos/vulkan/vk_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// File: vk_platform.h
//
/*
** Copyright 2014-2024 The Khronos Group Inc.
** Copyright 2014-2025 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
Expand Down
11 changes: 10 additions & 1 deletion src/video/khronos/vulkan/vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define VULKAN_H_ 1

/*
** Copyright 2015-2024 The Khronos Group Inc.
** Copyright 2015-2025 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -92,8 +92,17 @@
#endif


#ifdef VK_USE_PLATFORM_WEBROGUE
#include "vulkan_webrogue.h"
#endif


#ifdef VK_ENABLE_BETA_EXTENSIONS
#include "vulkan_beta.h"
#endif

#ifdef VK_USE_PLATFORM_OHOS
#include "vulkan_ohos.h"
#endif

#endif // VULKAN_H_
8 changes: 7 additions & 1 deletion src/video/khronos/vulkan/vulkan_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define VULKAN_ANDROID_H_ 1

/*
** Copyright 2015-2024 The Khronos Group Inc.
** Copyright 2015-2025 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -35,12 +35,14 @@ typedef struct VkAndroidSurfaceCreateInfoKHR {
typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);

#ifndef VK_NO_PROTOTYPES
#ifndef VK_ONLY_EXPORTED_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
VkInstance instance,
const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#endif


// VK_ANDROID_external_memory_android_hardware_buffer is a preprocessor guard. Do not pass it to API calls.
Expand Down Expand Up @@ -109,16 +111,20 @@ typedef VkResult (VKAPI_PTR *PFN_vkGetAndroidHardwareBufferPropertiesANDROID)(Vk
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryAndroidHardwareBufferANDROID)(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer);

#ifndef VK_NO_PROTOTYPES
#ifndef VK_ONLY_EXPORTED_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetAndroidHardwareBufferPropertiesANDROID(
VkDevice device,
const struct AHardwareBuffer* buffer,
VkAndroidHardwareBufferPropertiesANDROID* pProperties);
#endif

#ifndef VK_ONLY_EXPORTED_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryAndroidHardwareBufferANDROID(
VkDevice device,
const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
struct AHardwareBuffer** pBuffer);
#endif
#endif


// VK_ANDROID_external_format_resolve is a preprocessor guard. Do not pass it to API calls.
Expand Down
Loading