summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/video/vivante/SDL_vivantevideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/vivante/SDL_vivantevideo.c')
-rw-r--r--contrib/SDL-3.2.8/src/video/vivante/SDL_vivantevideo.c363
1 files changed, 363 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/video/vivante/SDL_vivantevideo.c b/contrib/SDL-3.2.8/src/video/vivante/SDL_vivantevideo.c
new file mode 100644
index 0000000..245c496
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/vivante/SDL_vivantevideo.c
@@ -0,0 +1,363 @@
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_VIVANTE
24
25// SDL internals
26#include "../SDL_sysvideo.h"
27#include "../../events/SDL_events_c.h"
28
29#ifdef SDL_INPUT_LINUXEV
30#include "../../core/linux/SDL_evdev.h"
31#endif
32
33#include "SDL_vivantevideo.h"
34#include "SDL_vivanteplatform.h"
35#include "SDL_vivanteopengles.h"
36#include "SDL_vivantevulkan.h"
37
38static void VIVANTE_Destroy(SDL_VideoDevice *device)
39{
40 SDL_free(device->internal);
41 SDL_free(device);
42}
43
44static SDL_VideoDevice *VIVANTE_Create(void)
45{
46 SDL_VideoDevice *device;
47 SDL_VideoData *data;
48
49 // Initialize SDL_VideoDevice structure
50 device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
51 if (!device) {
52 return NULL;
53 }
54
55 // Initialize internal data
56 data = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
57 if (!data) {
58 SDL_free(device);
59 return NULL;
60 }
61
62 device->internal = data;
63
64 // Setup amount of available displays
65 device->num_displays = 0;
66
67 // Set device free function
68 device->free = VIVANTE_Destroy;
69
70 // Setup all functions which we can handle
71 device->VideoInit = VIVANTE_VideoInit;
72 device->VideoQuit = VIVANTE_VideoQuit;
73 device->CreateSDLWindow = VIVANTE_CreateWindow;
74 device->SetWindowTitle = VIVANTE_SetWindowTitle;
75 device->SetWindowPosition = VIVANTE_SetWindowPosition;
76 device->SetWindowSize = VIVANTE_SetWindowSize;
77 device->ShowWindow = VIVANTE_ShowWindow;
78 device->HideWindow = VIVANTE_HideWindow;
79 device->DestroyWindow = VIVANTE_DestroyWindow;
80
81#ifdef SDL_VIDEO_OPENGL_EGL
82 device->GL_LoadLibrary = VIVANTE_GLES_LoadLibrary;
83 device->GL_GetProcAddress = VIVANTE_GLES_GetProcAddress;
84 device->GL_UnloadLibrary = VIVANTE_GLES_UnloadLibrary;
85 device->GL_CreateContext = VIVANTE_GLES_CreateContext;
86 device->GL_MakeCurrent = VIVANTE_GLES_MakeCurrent;
87 device->GL_SetSwapInterval = VIVANTE_GLES_SetSwapInterval;
88 device->GL_GetSwapInterval = VIVANTE_GLES_GetSwapInterval;
89 device->GL_SwapWindow = VIVANTE_GLES_SwapWindow;
90 device->GL_DestroyContext = VIVANTE_GLES_DestroyContext;
91#endif
92
93#ifdef SDL_VIDEO_VULKAN
94 device->Vulkan_LoadLibrary = VIVANTE_Vulkan_LoadLibrary;
95 device->Vulkan_UnloadLibrary = VIVANTE_Vulkan_UnloadLibrary;
96 device->Vulkan_GetInstanceExtensions = VIVANTE_Vulkan_GetInstanceExtensions;
97 device->Vulkan_CreateSurface = VIVANTE_Vulkan_CreateSurface;
98 device->Vulkan_DestroySurface = VIVANTE_Vulkan_DestroySurface;
99#endif
100
101 device->PumpEvents = VIVANTE_PumpEvents;
102
103 return device;
104}
105
106VideoBootStrap VIVANTE_bootstrap = {
107 "vivante",
108 "Vivante EGL Video Driver",
109 VIVANTE_Create,
110 NULL, // no ShowMessageBox implementation
111 false
112};
113
114/*****************************************************************************/
115// SDL Video and Display initialization/handling functions
116/*****************************************************************************/
117
118static bool VIVANTE_AddVideoDisplays(SDL_VideoDevice *_this)
119{
120 SDL_VideoData *videodata = _this->internal;
121 SDL_VideoDisplay display;
122 SDL_DisplayMode mode;
123 SDL_DisplayData *data;
124 int pitch = 0, bpp = 0;
125 unsigned long pixels = 0;
126
127 data = (SDL_DisplayData *)SDL_calloc(1, sizeof(SDL_DisplayData));
128 if (!data) {
129 return false;
130 }
131
132 SDL_zero(mode);
133#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK
134 data->native_display = vdkGetDisplay(videodata->vdk_private);
135
136 vdkGetDisplayInfo(data->native_display, &mode.w, &mode.h, &pixels, &pitch,
137 &bpp);
138#else
139 data->native_display = videodata->fbGetDisplayByIndex(0);
140
141 videodata->fbGetDisplayInfo(data->native_display, &mode.w, &mode.h,
142 &pixels, &pitch, &bpp);
143#endif // SDL_VIDEO_DRIVER_VIVANTE_VDK
144
145 switch (bpp) {
146 default: // Is another format used?
147 case 32:
148 mode.format = SDL_PIXELFORMAT_ARGB8888;
149 break;
150 case 16:
151 mode.format = SDL_PIXELFORMAT_RGB565;
152 break;
153 }
154 // FIXME: How do we query refresh rate?
155 mode.refresh_rate = 60.0f;
156
157 SDL_zero(display);
158 display.name = VIVANTE_GetDisplayName(_this);
159 display.desktop_mode = mode;
160 display.internal = data;
161 if (SDL_AddVideoDisplay(&display, false) == 0) {
162 return false;
163 }
164 return true;
165}
166
167bool VIVANTE_VideoInit(SDL_VideoDevice *_this)
168{
169 SDL_VideoData *videodata = _this->internal;
170
171#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK
172 videodata->vdk_private = vdkInitialize();
173 if (!videodata->vdk_private) {
174 return SDL_SetError("vdkInitialize() failed");
175 }
176#else
177 videodata->egl_handle = SDL_LoadObject("libEGL.so.1");
178 if (!videodata->egl_handle) {
179 videodata->egl_handle = SDL_LoadObject("libEGL.so");
180 if (!videodata->egl_handle) {
181 return false;
182 }
183 }
184#define LOAD_FUNC(TYPE, NAME) \
185 videodata->NAME = (TYPE)SDL_LoadFunction(videodata->egl_handle, #NAME); \
186 if (!videodata->NAME) \
187 return false;
188
189 LOAD_FUNC(EGLNativeDisplayType (EGLAPIENTRY *)(void *), fbGetDisplay);
190 LOAD_FUNC(EGLNativeDisplayType (EGLAPIENTRY *)(int), fbGetDisplayByIndex);
191 LOAD_FUNC(void (EGLAPIENTRY *)(EGLNativeDisplayType, int *, int *), fbGetDisplayGeometry);
192 LOAD_FUNC(void (EGLAPIENTRY *)(EGLNativeDisplayType, int *, int *, unsigned long *, int *, int *), fbGetDisplayInfo);
193 LOAD_FUNC(void (EGLAPIENTRY *)(EGLNativeDisplayType), fbDestroyDisplay);
194 LOAD_FUNC(EGLNativeWindowType (EGLAPIENTRY *)(EGLNativeDisplayType, int, int, int, int), fbCreateWindow);
195 LOAD_FUNC(void (EGLAPIENTRY *)(EGLNativeWindowType, int *, int *, int *, int *), fbGetWindowGeometry);
196 LOAD_FUNC(void (EGLAPIENTRY *)(EGLNativeWindowType, int *, int *, int *, int *, int *, unsigned int *), fbGetWindowInfo);
197 LOAD_FUNC(void (EGLAPIENTRY *)(EGLNativeWindowType), fbDestroyWindow);
198#endif
199
200 if (!VIVANTE_SetupPlatform(_this)) {
201 return false;
202 }
203
204 if (!VIVANTE_AddVideoDisplays(_this)) {
205 return false;
206 }
207
208 VIVANTE_UpdateDisplayScale(_this);
209
210#ifdef SDL_INPUT_LINUXEV
211 if (!SDL_EVDEV_Init()) {
212 return false;
213 }
214#endif
215
216 return true;
217}
218
219void VIVANTE_VideoQuit(SDL_VideoDevice *_this)
220{
221 SDL_VideoData *videodata = _this->internal;
222
223#ifdef SDL_INPUT_LINUXEV
224 SDL_EVDEV_Quit();
225#endif
226
227 VIVANTE_CleanupPlatform(_this);
228
229#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK
230 if (videodata->vdk_private) {
231 vdkExit(videodata->vdk_private);
232 videodata->vdk_private = NULL;
233 }
234#else
235 if (videodata->egl_handle) {
236 SDL_UnloadObject(videodata->egl_handle);
237 videodata->egl_handle = NULL;
238 }
239#endif
240}
241
242bool VIVANTE_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
243{
244 SDL_VideoData *videodata = _this->internal;
245 SDL_DisplayData *displaydata;
246 SDL_WindowData *data;
247
248 displaydata = SDL_GetDisplayDriverData(SDL_GetPrimaryDisplay());
249
250 // Allocate window internal data
251 data = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
252 if (!data) {
253 return false;
254 }
255
256 // Setup driver data for this window
257 window->internal = data;
258
259 SDL_PropertiesID props = SDL_GetWindowProperties(window);
260 SDL_SetPointerProperty(props, SDL_PROP_WINDOW_VIVANTE_DISPLAY_POINTER, displaydata->native_display);
261
262#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK
263 data->native_window = vdkCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h);
264#else
265 data->native_window = videodata->fbCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h);
266#endif
267 if (!data->native_window) {
268 return SDL_SetError("VIVANTE: Can't create native window");
269 }
270 SDL_SetPointerProperty(props, SDL_PROP_WINDOW_VIVANTE_WINDOW_POINTER, data->native_window);
271
272#ifdef SDL_VIDEO_OPENGL_EGL
273 if (window->flags & SDL_WINDOW_OPENGL) {
274 data->egl_surface = SDL_EGL_CreateSurface(_this, window, data->native_window);
275 if (data->egl_surface == EGL_NO_SURFACE) {
276 return SDL_SetError("VIVANTE: Can't create EGL surface");
277 }
278 } else {
279 data->egl_surface = EGL_NO_SURFACE;
280 }
281 SDL_SetPointerProperty(props, SDL_PROP_WINDOW_VIVANTE_SURFACE_POINTER, data->egl_surface);
282#endif
283
284 // Window has been successfully created
285 return true;
286}
287
288void VIVANTE_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
289{
290 SDL_VideoData *videodata = _this->internal;
291 SDL_WindowData *data;
292
293 data = window->internal;
294 if (data) {
295#ifdef SDL_VIDEO_OPENGL_EGL
296 if (data->egl_surface != EGL_NO_SURFACE) {
297 SDL_EGL_DestroySurface(_this, data->egl_surface);
298 }
299#endif
300
301 if (data->native_window) {
302#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK
303 vdkDestroyWindow(data->native_window);
304#else
305 videodata->fbDestroyWindow(data->native_window);
306#endif
307 }
308
309 SDL_free(data);
310 }
311 window->internal = NULL;
312}
313
314void VIVANTE_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
315{
316#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK
317 SDL_WindowData *data = window->internal;
318 vdkSetWindowTitle(data->native_window, window->title);
319#endif
320}
321
322bool VIVANTE_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
323{
324 // FIXME
325 return SDL_Unsupported();
326}
327
328void VIVANTE_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
329{
330 // FIXME
331}
332
333void VIVANTE_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
334{
335#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK
336 SDL_WindowData *data = window->internal;
337 vdkShowWindow(data->native_window);
338#endif
339 SDL_SetMouseFocus(window);
340 SDL_SetKeyboardFocus(window);
341}
342
343void VIVANTE_HideWindow(SDL_VideoDevice *_this, SDL_Window *window)
344{
345#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK
346 SDL_WindowData *data = window->internal;
347 vdkHideWindow(data->native_window);
348#endif
349 SDL_SetMouseFocus(NULL);
350 SDL_SetKeyboardFocus(NULL);
351}
352
353/*****************************************************************************/
354// SDL event functions
355/*****************************************************************************/
356void VIVANTE_PumpEvents(SDL_VideoDevice *_this)
357{
358#ifdef SDL_INPUT_LINUXEV
359 SDL_EVDEV_Poll();
360#endif
361}
362
363#endif // SDL_VIDEO_DRIVER_VIVANTE