summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/video/offscreen
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/offscreen')
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenevents.c38
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenevents_c.h23
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenframebuffer.c79
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenframebuffer_c.h25
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenopengles.c82
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenopengles.h44
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvideo.c151
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvideo.h28
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvulkan.c261
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvulkan.h38
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenwindow.c90
-rw-r--r--contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenwindow.h40
12 files changed, 899 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenevents.c b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenevents.c
new file mode 100644
index 0000000..256d1a2
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenevents.c
@@ -0,0 +1,38 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_OFFSCREEN
24
25/* Being a offscreen driver, there's no event stream. We just define stubs for
26 most of the API. */
27
28#include "../../events/SDL_events_c.h"
29
30#include "SDL_offscreenvideo.h"
31#include "SDL_offscreenevents_c.h"
32
33void OFFSCREEN_PumpEvents(SDL_VideoDevice *_this)
34{
35 // do nothing.
36}
37
38#endif // SDL_VIDEO_DRIVER_OFFSCREEN
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenevents_c.h b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenevents_c.h
new file mode 100644
index 0000000..c06213c
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenevents_c.h
@@ -0,0 +1,23 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23extern void OFFSCREEN_PumpEvents(SDL_VideoDevice *_this);
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenframebuffer.c b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenframebuffer.c
new file mode 100644
index 0000000..e7f6103
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenframebuffer.c
@@ -0,0 +1,79 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_OFFSCREEN
24
25#include "../SDL_sysvideo.h"
26#include "../../SDL_properties_c.h"
27#include "SDL_offscreenframebuffer_c.h"
28
29#define OFFSCREEN_SURFACE "SDL.internal.window.surface"
30
31
32bool SDL_OFFSCREEN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch)
33{
34 SDL_Surface *surface;
35 const SDL_PixelFormat surface_format = SDL_PIXELFORMAT_XRGB8888;
36 int w, h;
37
38 // Create a new framebuffer
39 SDL_GetWindowSizeInPixels(window, &w, &h);
40 surface = SDL_CreateSurface(w, h, surface_format);
41 if (!surface) {
42 return false;
43 }
44
45 // Save the info and return!
46 SDL_SetSurfaceProperty(SDL_GetWindowProperties(window), OFFSCREEN_SURFACE, surface);
47 *format = surface_format;
48 *pixels = surface->pixels;
49 *pitch = surface->pitch;
50
51 return true;
52}
53
54bool SDL_OFFSCREEN_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects)
55{
56 static int frame_number;
57 SDL_Surface *surface;
58
59 surface = (SDL_Surface *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), OFFSCREEN_SURFACE, NULL);
60 if (!surface) {
61 return SDL_SetError("Couldn't find offscreen surface for window");
62 }
63
64 // Send the data to the display
65 if (SDL_GetHintBoolean(SDL_HINT_VIDEO_OFFSCREEN_SAVE_FRAMES, false)) {
66 char file[128];
67 (void)SDL_snprintf(file, sizeof(file), "SDL_window%" SDL_PRIu32 "-%8.8d.bmp",
68 SDL_GetWindowID(window), ++frame_number);
69 SDL_SaveBMP(surface, file);
70 }
71 return true;
72}
73
74void SDL_OFFSCREEN_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window)
75{
76 SDL_ClearProperty(SDL_GetWindowProperties(window), OFFSCREEN_SURFACE);
77}
78
79#endif // SDL_VIDEO_DRIVER_OFFSCREEN
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenframebuffer_c.h b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenframebuffer_c.h
new file mode 100644
index 0000000..ff39ad6
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenframebuffer_c.h
@@ -0,0 +1,25 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23extern bool SDL_OFFSCREEN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch);
24extern bool SDL_OFFSCREEN_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects);
25extern void SDL_OFFSCREEN_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window);
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenopengles.c b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenopengles.c
new file mode 100644
index 0000000..87eed0e
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenopengles.c
@@ -0,0 +1,82 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#if defined(SDL_VIDEO_DRIVER_OFFSCREEN) && defined(SDL_VIDEO_OPENGL_EGL)
24
25#include "SDL_offscreenopengles.h"
26#include "SDL_offscreenvideo.h"
27#include "SDL_offscreenwindow.h"
28
29// EGL implementation of SDL OpenGL support
30
31bool OFFSCREEN_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path)
32{
33 if (!SDL_EGL_LoadLibraryOnly(_this, path)) {
34 return false;
35 }
36
37 /* driver_loaded gets incremented by SDL_GL_LoadLibrary when we return,
38 but SDL_EGL_InitializeOffscreen checks that we're loaded before then,
39 so temporarily bump it since we know that LoadLibraryOnly succeeded. */
40 bool result;
41 _this->gl_config.driver_loaded++;
42 result = SDL_EGL_InitializeOffscreen(_this, 0);
43 _this->gl_config.driver_loaded--;
44 if (!result) {
45 return false;
46 }
47
48 if (!SDL_EGL_ChooseConfig(_this)) {
49 return false;
50 }
51
52 return true;
53}
54
55SDL_GLContext OFFSCREEN_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
56{
57 SDL_WindowData *offscreen_window = window->internal;
58
59 SDL_GLContext context;
60 context = SDL_EGL_CreateContext(_this, offscreen_window->egl_surface);
61
62 return context;
63}
64
65bool OFFSCREEN_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context)
66{
67 if (window) {
68 EGLSurface egl_surface = window->internal->egl_surface;
69 return SDL_EGL_MakeCurrent(_this, egl_surface, context);
70 } else {
71 return SDL_EGL_MakeCurrent(_this, NULL, NULL);
72 }
73}
74
75bool OFFSCREEN_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
76{
77 SDL_WindowData *offscreen_wind = window->internal;
78
79 return SDL_EGL_SwapBuffers(_this, offscreen_wind->egl_surface);
80}
81
82#endif // SDL_VIDEO_DRIVER_OFFSCREEN && SDL_VIDEO_OPENGL_EGL
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenopengles.h b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenopengles.h
new file mode 100644
index 0000000..d6dfc0a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenopengles.h
@@ -0,0 +1,44 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifndef SDL_offscreenopengles_h
24#define SDL_offscreenopengles_h
25
26#if defined(SDL_VIDEO_DRIVER_OFFSCREEN) && defined(SDL_VIDEO_OPENGL_EGL)
27
28#include "../SDL_sysvideo.h"
29#include "../SDL_egl_c.h"
30
31#define OFFSCREEN_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal
32#define OFFSCREEN_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
33#define OFFSCREEN_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
34#define OFFSCREEN_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
35#define OFFSCREEN_GLES_DestroyContext SDL_EGL_DestroyContext
36
37extern bool OFFSCREEN_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path);
38extern SDL_GLContext OFFSCREEN_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
39extern bool OFFSCREEN_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context);
40extern bool OFFSCREEN_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
41
42#endif // SDL_VIDEO_DRIVER_OFFSCREEN && SDL_VIDEO_OPENGL_EGL
43
44#endif // SDL_offscreenopengles_h
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvideo.c b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvideo.c
new file mode 100644
index 0000000..1ef0f9e
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvideo.c
@@ -0,0 +1,151 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_OFFSCREEN
24
25/* Offscreen video driver is similar to dummy driver, however its purpose
26 * is enabling applications to use some of the SDL video functionality
27 * (notably context creation) while not requiring a display output.
28 *
29 * An example would be running a graphical program on a headless box
30 * for automated testing.
31 */
32
33#include "SDL_offscreenvideo.h"
34#include "SDL_offscreenevents_c.h"
35#include "SDL_offscreenframebuffer_c.h"
36#include "SDL_offscreenopengles.h"
37#include "SDL_offscreenvulkan.h"
38#include "SDL_offscreenwindow.h"
39
40#define OFFSCREENVID_DRIVER_NAME "offscreen"
41
42// Initialization/Query functions
43static bool OFFSCREEN_VideoInit(SDL_VideoDevice *_this);
44static bool OFFSCREEN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
45static void OFFSCREEN_VideoQuit(SDL_VideoDevice *_this);
46
47// OFFSCREEN driver bootstrap functions
48
49static void OFFSCREEN_DeleteDevice(SDL_VideoDevice *device)
50{
51 SDL_free(device);
52}
53
54static bool OFFSCREEN_Available(const char *enable_hint)
55{
56 const char *hint = SDL_GetHint(SDL_HINT_VIDEO_DRIVER);
57 if (hint) {
58 if (SDL_strcmp(hint, enable_hint) == 0) {
59 return true;
60 }
61 }
62 return false;
63}
64
65static SDL_VideoDevice *OFFSCREEN_CreateDevice(void)
66{
67 SDL_VideoDevice *device;
68
69 if (!OFFSCREEN_Available(OFFSCREENVID_DRIVER_NAME)) {
70 return NULL;
71 }
72
73 // Initialize all variables that we clean on shutdown
74 device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
75 if (!device) {
76 return NULL;
77 }
78
79 // General video
80 device->VideoInit = OFFSCREEN_VideoInit;
81 device->VideoQuit = OFFSCREEN_VideoQuit;
82 device->SetDisplayMode = OFFSCREEN_SetDisplayMode;
83 device->PumpEvents = OFFSCREEN_PumpEvents;
84 device->CreateWindowFramebuffer = SDL_OFFSCREEN_CreateWindowFramebuffer;
85 device->UpdateWindowFramebuffer = SDL_OFFSCREEN_UpdateWindowFramebuffer;
86 device->DestroyWindowFramebuffer = SDL_OFFSCREEN_DestroyWindowFramebuffer;
87 device->free = OFFSCREEN_DeleteDevice;
88
89#ifdef SDL_VIDEO_OPENGL_EGL
90 // GL context
91 device->GL_SwapWindow = OFFSCREEN_GLES_SwapWindow;
92 device->GL_MakeCurrent = OFFSCREEN_GLES_MakeCurrent;
93 device->GL_CreateContext = OFFSCREEN_GLES_CreateContext;
94 device->GL_DestroyContext = OFFSCREEN_GLES_DestroyContext;
95 device->GL_LoadLibrary = OFFSCREEN_GLES_LoadLibrary;
96 device->GL_UnloadLibrary = OFFSCREEN_GLES_UnloadLibrary;
97 device->GL_GetProcAddress = OFFSCREEN_GLES_GetProcAddress;
98 device->GL_GetSwapInterval = OFFSCREEN_GLES_GetSwapInterval;
99 device->GL_SetSwapInterval = OFFSCREEN_GLES_SetSwapInterval;
100#endif
101
102#ifdef SDL_VIDEO_VULKAN
103 device->Vulkan_LoadLibrary = OFFSCREEN_Vulkan_LoadLibrary;
104 device->Vulkan_UnloadLibrary = OFFSCREEN_Vulkan_UnloadLibrary;
105 device->Vulkan_GetInstanceExtensions = OFFSCREEN_Vulkan_GetInstanceExtensions;
106 device->Vulkan_CreateSurface = OFFSCREEN_Vulkan_CreateSurface;
107 device->Vulkan_DestroySurface = OFFSCREEN_Vulkan_DestroySurface;
108#endif
109
110 // "Window"
111 device->CreateSDLWindow = OFFSCREEN_CreateWindow;
112 device->DestroyWindow = OFFSCREEN_DestroyWindow;
113 device->SetWindowSize = OFFSCREEN_SetWindowSize;
114
115 return device;
116}
117
118VideoBootStrap OFFSCREEN_bootstrap = {
119 OFFSCREENVID_DRIVER_NAME, "SDL offscreen video driver",
120 OFFSCREEN_CreateDevice,
121 NULL, // no ShowMessageBox implementation
122 false
123};
124
125static bool OFFSCREEN_VideoInit(SDL_VideoDevice *_this)
126{
127 SDL_DisplayMode mode;
128
129 // Use a fake 32-bpp desktop mode
130 SDL_zero(mode);
131 mode.format = SDL_PIXELFORMAT_XRGB8888;
132 mode.w = 1024;
133 mode.h = 768;
134 if (SDL_AddBasicVideoDisplay(&mode) == 0) {
135 return false;
136 }
137
138 // We're done!
139 return true;
140}
141
142static bool OFFSCREEN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
143{
144 return true;
145}
146
147void OFFSCREEN_VideoQuit(SDL_VideoDevice *_this)
148{
149}
150
151#endif // SDL_VIDEO_DRIVER_OFFSCREEN
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvideo.h b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvideo.h
new file mode 100644
index 0000000..f39d8e7
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvideo.h
@@ -0,0 +1,28 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifndef SDL_offscreenvideo_h
24#define SDL_offscreenvideo_h
25
26#include "../SDL_sysvideo.h"
27
28#endif // SDL_offscreenvideo_h
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvulkan.c b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvulkan.c
new file mode 100644
index 0000000..b3dca4a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvulkan.c
@@ -0,0 +1,261 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_OFFSCREEN)
24
25#include "../SDL_vulkan_internal.h"
26#include "../SDL_sysvideo.h"
27
28
29static const char *s_defaultPaths[] = {
30#if defined(SDL_PLATFORM_WINDOWS)
31 "vulkan-1.dll"
32#elif defined(SDL_PLATFORM_APPLE)
33 "vulkan.framework/vulkan",
34 "libvulkan.1.dylib",
35 "libvulkan.dylib",
36 "MoltenVK.framework/MoltenVK",
37 "libMoltenVK.dylib"
38#elif defined(SDL_PLATFORM_OPENBSD)
39 "libvulkan.so"
40#else
41 "libvulkan.so.1"
42#endif
43};
44
45#if defined( SDL_PLATFORM_APPLE )
46#include <dlfcn.h>
47
48// Since libSDL is most likely a .dylib, need RTLD_DEFAULT not RTLD_SELF.
49#define DEFAULT_HANDLE RTLD_DEFAULT
50#endif
51
52/*Should the whole driver fail if it can't create a surface? Rendering to an offscreen buffer is still possible without a surface.
53 At the time of writing. I need the driver to minimally work even if the surface extension isn't present.
54 And account for the inability to create a surface on the consumer side.
55 So for now I'm targeting my specific use case -Dave Kircher*/
56#define HEADLESS_SURFACE_EXTENSION_REQUIRED_TO_LOAD 0
57
58
59bool OFFSCREEN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
60{
61 VkExtensionProperties *extensions = NULL;
62 Uint32 extensionCount = 0;
63 bool hasSurfaceExtension = false;
64 bool hasHeadlessSurfaceExtension = false;
65 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
66 Uint32 i;
67 const char **paths;
68 const char *foundPath = NULL;
69 Uint32 numPaths;
70
71 if (_this->vulkan_config.loader_handle) {
72 return SDL_SetError("Vulkan already loaded");
73 }
74
75 // Load the Vulkan loader library
76 if (!path) {
77 path = SDL_GetHint(SDL_HINT_VULKAN_LIBRARY);
78 }
79
80#if defined(SDL_PLATFORM_APPLE)
81 if (!path) {
82 // Handle the case where Vulkan Portability is linked statically.
83 vkGetInstanceProcAddr =
84 (PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
85 "vkGetInstanceProcAddr");
86 }
87
88 if (vkGetInstanceProcAddr) {
89 _this->vulkan_config.loader_handle = DEFAULT_HANDLE;
90 } else
91#endif
92 {
93 if (path) {
94 paths = &path;
95 numPaths = 1;
96 } else {
97 paths = s_defaultPaths;
98 numPaths = SDL_arraysize(s_defaultPaths);
99 }
100
101 for (i = 0; i < numPaths && _this->vulkan_config.loader_handle == NULL; i++) {
102 foundPath = paths[i];
103 _this->vulkan_config.loader_handle = SDL_LoadObject(foundPath);
104 }
105
106 if (_this->vulkan_config.loader_handle == NULL) {
107 return SDL_SetError("Failed to load Vulkan Portability library");
108 }
109
110 SDL_strlcpy(_this->vulkan_config.loader_path, foundPath,
111 SDL_arraysize(_this->vulkan_config.loader_path));
112 vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
113 _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
114
115 if (!vkGetInstanceProcAddr) {
116 SDL_SetError("Failed to load vkGetInstanceProcAddr from Vulkan Portability library");
117 goto fail;
118 }
119 }
120
121 _this->vulkan_config.vkGetInstanceProcAddr = (SDL_FunctionPointer)vkGetInstanceProcAddr;
122 _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
123 (SDL_FunctionPointer)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
124 VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
125 if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) {
126 goto fail;
127 }
128 extensions = SDL_Vulkan_CreateInstanceExtensionsList(
129 (PFN_vkEnumerateInstanceExtensionProperties)
130 _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
131 &extensionCount);
132 if (!extensions) {
133 goto fail;
134 }
135 for (i = 0; i < extensionCount; i++) {
136 if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
137 hasSurfaceExtension = true;
138 } else if (SDL_strcmp(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
139 hasHeadlessSurfaceExtension = true;
140 }
141 }
142 SDL_free(extensions);
143 if (!hasSurfaceExtension) {
144 SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension");
145 goto fail;
146 }
147 if (!hasHeadlessSurfaceExtension) {
148#if (HEADLESS_SURFACE_EXTENSION_REQUIRED_TO_LOAD != 0)
149 SDL_SetError("Installed Vulkan doesn't implement the " VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME " extension");
150 goto fail;
151#else
152 // Let's at least leave a breadcrumb for people to find if they have issues
153 SDL_Log("Installed Vulkan doesn't implement the " VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME " extension");
154#endif
155 }
156 return true;
157
158fail:
159 SDL_UnloadObject(_this->vulkan_config.loader_handle);
160 _this->vulkan_config.loader_handle = NULL;
161 return false;
162}
163
164void OFFSCREEN_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
165{
166 if (_this->vulkan_config.loader_handle) {
167 SDL_UnloadObject(_this->vulkan_config.loader_handle);
168 _this->vulkan_config.loader_handle = NULL;
169 }
170}
171
172char const *const *OFFSCREEN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
173 Uint32 *count)
174{
175#if (HEADLESS_SURFACE_EXTENSION_REQUIRED_TO_LOAD == 0)
176 VkExtensionProperties *enumerateExtensions = NULL;
177 Uint32 enumerateExtensionCount = 0;
178 bool hasHeadlessSurfaceExtension = false;
179 Uint32 i;
180#endif
181
182 static const char *const returnExtensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME };
183 if (count) {
184# if (HEADLESS_SURFACE_EXTENSION_REQUIRED_TO_LOAD == 0)
185 {
186 /* In optional mode, only return VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME if it's already supported by the instance
187 There's probably a better way to cache the presence of the extension during OFFSCREEN_Vulkan_LoadLibrary().
188 But both SDL_VideoData and SDL_VideoDevice::vulkan_config seem like I'd need to touch a bunch of code to do properly.
189 And I want a smaller footprint for the first pass*/
190 if ( _this->vulkan_config.vkEnumerateInstanceExtensionProperties ) {
191 enumerateExtensions = SDL_Vulkan_CreateInstanceExtensionsList(
192 (PFN_vkEnumerateInstanceExtensionProperties)
193 _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
194 &enumerateExtensionCount);
195 for (i = 0; i < enumerateExtensionCount; i++) {
196 if (SDL_strcmp(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, enumerateExtensions[i].extensionName) == 0) {
197 hasHeadlessSurfaceExtension = true;
198 }
199 }
200 SDL_free(enumerateExtensions);
201 }
202 if ( hasHeadlessSurfaceExtension == true ) {
203 *count = SDL_arraysize(returnExtensions);
204 } else {
205 *count = SDL_arraysize(returnExtensions) - 1; // assumes VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME is last
206 }
207 }
208# else
209 {
210 *count = SDL_arraysize(returnExtensions);
211 }
212# endif
213 }
214 return returnExtensions;
215}
216
217bool OFFSCREEN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
218 SDL_Window *window,
219 VkInstance instance,
220 const struct VkAllocationCallbacks *allocator,
221 VkSurfaceKHR *surface)
222{
223 *surface = VK_NULL_HANDLE;
224
225 if (!_this->vulkan_config.loader_handle) {
226 return SDL_SetError("Vulkan is not loaded");
227 }
228
229 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
230 PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT =
231 (PFN_vkCreateHeadlessSurfaceEXT)vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT");
232 VkHeadlessSurfaceCreateInfoEXT createInfo;
233 VkResult result;
234 if (!vkCreateHeadlessSurfaceEXT) {
235 /* This may be surprising to the consumer when HEADLESS_SURFACE_EXTENSION_REQUIRED_TO_LOAD == 0
236 But this is the tradeoff for allowing offscreen rendering to a buffer to continue working without requiring the extension during driver load */
237 return SDL_SetError(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME
238 " extension is not enabled in the Vulkan instance.");
239 }
240 SDL_zero(createInfo);
241 createInfo.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT;
242 createInfo.pNext = NULL;
243 createInfo.flags = 0;
244 result = vkCreateHeadlessSurfaceEXT(instance, &createInfo, allocator, surface);
245 if (result != VK_SUCCESS) {
246 return SDL_SetError("vkCreateHeadlessSurfaceEXT failed: %s", SDL_Vulkan_GetResultString(result));
247 }
248 return true;
249}
250
251void OFFSCREEN_Vulkan_DestroySurface(SDL_VideoDevice *_this,
252 VkInstance instance,
253 VkSurfaceKHR surface,
254 const struct VkAllocationCallbacks *allocator)
255{
256 if (_this->vulkan_config.loader_handle) {
257 SDL_Vulkan_DestroySurface_Internal(_this->vulkan_config.vkGetInstanceProcAddr, instance, surface, allocator);
258 }
259}
260
261#endif
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvulkan.h b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvulkan.h
new file mode 100644
index 0000000..b9d348e
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenvulkan.h
@@ -0,0 +1,38 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifndef SDL_offscreenvulkan_h
24#define SDL_offscreenvulkan_h
25
26#if defined(SDL_VIDEO_DRIVER_OFFSCREEN) && defined(SDL_VIDEO_VULKAN)
27
28#include "../SDL_sysvideo.h"
29
30extern bool OFFSCREEN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
31extern void OFFSCREEN_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
32extern char const *const *OFFSCREEN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count);
33extern bool OFFSCREEN_Vulkan_CreateSurface(SDL_VideoDevice *_this, SDL_Window *window, VkInstance instance, const struct VkAllocationCallbacks *allocator, VkSurfaceKHR *surface);
34extern void OFFSCREEN_Vulkan_DestroySurface(SDL_VideoDevice *_this, VkInstance instance, VkSurfaceKHR surface, const struct VkAllocationCallbacks *allocator);
35
36#endif // SDL_VIDEO_DRIVER_OFFSCREEN && SDL_VIDEO_VULKAN
37
38#endif // SDL_offscreenvulkan_h
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenwindow.c b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenwindow.c
new file mode 100644
index 0000000..579353b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenwindow.c
@@ -0,0 +1,90 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_OFFSCREEN
24
25#include "../SDL_sysvideo.h"
26#include "../../events/SDL_windowevents_c.h"
27#include "../SDL_egl_c.h"
28
29#include "SDL_offscreenwindow.h"
30
31bool OFFSCREEN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
32{
33 SDL_WindowData *offscreen_window = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
34
35 if (!offscreen_window) {
36 return false;
37 }
38
39 window->internal = offscreen_window;
40
41 if (window->x == SDL_WINDOWPOS_UNDEFINED) {
42 window->x = 0;
43 }
44
45 if (window->y == SDL_WINDOWPOS_UNDEFINED) {
46 window->y = 0;
47 }
48
49 offscreen_window->sdl_window = window;
50
51#ifdef SDL_VIDEO_OPENGL_EGL
52 if (window->flags & SDL_WINDOW_OPENGL) {
53
54 if (!_this->egl_data) {
55 return SDL_SetError("Cannot create an OPENGL window invalid egl_data");
56 }
57
58 offscreen_window->egl_surface = SDL_EGL_CreateOffscreenSurface(_this, window->w, window->h);
59
60 if (offscreen_window->egl_surface == EGL_NO_SURFACE) {
61 return SDL_SetError("Failed to created an offscreen surface (EGL display: %p)",
62 _this->egl_data->egl_display);
63 }
64 } else {
65 offscreen_window->egl_surface = EGL_NO_SURFACE;
66 }
67#endif // SDL_VIDEO_OPENGL_EGL
68
69 return true;
70}
71
72void OFFSCREEN_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
73{
74 SDL_WindowData *offscreen_window = window->internal;
75
76 if (offscreen_window) {
77#ifdef SDL_VIDEO_OPENGL_EGL
78 SDL_EGL_DestroySurface(_this, offscreen_window->egl_surface);
79#endif
80 SDL_free(offscreen_window);
81 }
82
83 window->internal = NULL;
84}
85
86void OFFSCREEN_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
87{
88 SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, window->pending.w, window->pending.h);
89}
90#endif // SDL_VIDEO_DRIVER_OFFSCREEN
diff --git a/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenwindow.h b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenwindow.h
new file mode 100644
index 0000000..0f723c7
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/offscreen/SDL_offscreenwindow.h
@@ -0,0 +1,40 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifndef SDL_offscreenwindow_h
24#define SDL_offscreenwindow_h
25
26#include "SDL_offscreenvideo.h"
27
28struct SDL_WindowData
29{
30 SDL_Window *sdl_window;
31#ifdef SDL_VIDEO_OPENGL_EGL
32 EGLSurface egl_surface;
33#endif
34};
35
36extern bool OFFSCREEN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
37extern void OFFSCREEN_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
38extern void OFFSCREEN_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
39
40#endif // SDL_offscreenwindow_h