SDL_vivantevideo.c (11656B)
1 /* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2020 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 SDL_VIDEO_DRIVER_VIVANTE 24 25 /* SDL internals */ 26 #include "../SDL_sysvideo.h" 27 #include "SDL_version.h" 28 #include "SDL_syswm.h" 29 #include "SDL_loadso.h" 30 #include "SDL_events.h" 31 #include "../../events/SDL_events_c.h" 32 33 #ifdef SDL_INPUT_LINUXEV 34 #include "../../core/linux/SDL_evdev.h" 35 #endif 36 37 #include "SDL_vivantevideo.h" 38 #include "SDL_vivanteplatform.h" 39 #include "SDL_vivanteopengles.h" 40 #include "SDL_vivantevulkan.h" 41 42 43 static void 44 VIVANTE_Destroy(SDL_VideoDevice * device) 45 { 46 if (device->driverdata != NULL) { 47 SDL_free(device->driverdata); 48 device->driverdata = NULL; 49 } 50 } 51 52 static SDL_VideoDevice * 53 VIVANTE_Create() 54 { 55 SDL_VideoDevice *device; 56 SDL_VideoData *data; 57 58 /* Initialize SDL_VideoDevice structure */ 59 device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); 60 if (device == NULL) { 61 SDL_OutOfMemory(); 62 return NULL; 63 } 64 65 /* Initialize internal data */ 66 data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); 67 if (data == NULL) { 68 SDL_OutOfMemory(); 69 SDL_free(device); 70 return NULL; 71 } 72 73 device->driverdata = data; 74 75 /* Setup amount of available displays */ 76 device->num_displays = 0; 77 78 /* Set device free function */ 79 device->free = VIVANTE_Destroy; 80 81 /* Setup all functions which we can handle */ 82 device->VideoInit = VIVANTE_VideoInit; 83 device->VideoQuit = VIVANTE_VideoQuit; 84 device->GetDisplayModes = VIVANTE_GetDisplayModes; 85 device->SetDisplayMode = VIVANTE_SetDisplayMode; 86 device->CreateSDLWindow = VIVANTE_CreateWindow; 87 device->SetWindowTitle = VIVANTE_SetWindowTitle; 88 device->SetWindowPosition = VIVANTE_SetWindowPosition; 89 device->SetWindowSize = VIVANTE_SetWindowSize; 90 device->ShowWindow = VIVANTE_ShowWindow; 91 device->HideWindow = VIVANTE_HideWindow; 92 device->DestroyWindow = VIVANTE_DestroyWindow; 93 device->GetWindowWMInfo = VIVANTE_GetWindowWMInfo; 94 95 #if SDL_VIDEO_OPENGL_EGL 96 device->GL_LoadLibrary = VIVANTE_GLES_LoadLibrary; 97 device->GL_GetProcAddress = VIVANTE_GLES_GetProcAddress; 98 device->GL_UnloadLibrary = VIVANTE_GLES_UnloadLibrary; 99 device->GL_CreateContext = VIVANTE_GLES_CreateContext; 100 device->GL_MakeCurrent = VIVANTE_GLES_MakeCurrent; 101 device->GL_SetSwapInterval = VIVANTE_GLES_SetSwapInterval; 102 device->GL_GetSwapInterval = VIVANTE_GLES_GetSwapInterval; 103 device->GL_SwapWindow = VIVANTE_GLES_SwapWindow; 104 device->GL_DeleteContext = VIVANTE_GLES_DeleteContext; 105 #endif 106 107 #if SDL_VIDEO_VULKAN 108 device->Vulkan_LoadLibrary = VIVANTE_Vulkan_LoadLibrary; 109 device->Vulkan_UnloadLibrary = VIVANTE_Vulkan_UnloadLibrary; 110 device->Vulkan_GetInstanceExtensions = VIVANTE_Vulkan_GetInstanceExtensions; 111 device->Vulkan_CreateSurface = VIVANTE_Vulkan_CreateSurface; 112 #endif 113 114 device->PumpEvents = VIVANTE_PumpEvents; 115 116 return device; 117 } 118 119 VideoBootStrap VIVANTE_bootstrap = { 120 "vivante", 121 "Vivante EGL Video Driver", 122 VIVANTE_Create 123 }; 124 125 /*****************************************************************************/ 126 /* SDL Video and Display initialization/handling functions */ 127 /*****************************************************************************/ 128 129 static int 130 VIVANTE_AddVideoDisplays(_THIS) 131 { 132 SDL_VideoData *videodata = _this->driverdata; 133 SDL_VideoDisplay display; 134 SDL_DisplayMode current_mode; 135 SDL_DisplayData *data; 136 int pitch = 0, bpp = 0; 137 unsigned long pixels = 0; 138 139 data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); 140 if (data == NULL) { 141 return SDL_OutOfMemory(); 142 } 143 144 SDL_zero(current_mode); 145 #if SDL_VIDEO_DRIVER_VIVANTE_VDK 146 data->native_display = vdkGetDisplay(videodata->vdk_private); 147 148 vdkGetDisplayInfo(data->native_display, ¤t_mode.w, ¤t_mode.h, &pixels, &pitch, &bpp); 149 #else 150 data->native_display = videodata->fbGetDisplayByIndex(0); 151 152 videodata->fbGetDisplayInfo(data->native_display, ¤t_mode.w, ¤t_mode.h, &pixels, &pitch, &bpp); 153 #endif /* SDL_VIDEO_DRIVER_VIVANTE_VDK */ 154 155 switch (bpp) 156 { 157 default: /* Is another format used? */ 158 case 32: 159 current_mode.format = SDL_PIXELFORMAT_ARGB8888; 160 break; 161 case 16: 162 current_mode.format = SDL_PIXELFORMAT_RGB565; 163 break; 164 } 165 /* FIXME: How do we query refresh rate? */ 166 current_mode.refresh_rate = 60; 167 168 SDL_zero(display); 169 display.name = VIVANTE_GetDisplayName(_this); 170 display.desktop_mode = current_mode; 171 display.current_mode = current_mode; 172 display.driverdata = data; 173 SDL_AddVideoDisplay(&display, SDL_FALSE); 174 return 0; 175 } 176 177 int 178 VIVANTE_VideoInit(_THIS) 179 { 180 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; 181 182 #if SDL_VIDEO_DRIVER_VIVANTE_VDK 183 videodata->vdk_private = vdkInitialize(); 184 if (!videodata->vdk_private) { 185 return SDL_SetError("vdkInitialize() failed"); 186 } 187 #else 188 videodata->egl_handle = SDL_LoadObject("libEGL.so.1"); 189 if (!videodata->egl_handle) { 190 videodata->egl_handle = SDL_LoadObject("libEGL.so"); 191 if (!videodata->egl_handle) { 192 return -1; 193 } 194 } 195 #define LOAD_FUNC(NAME) \ 196 videodata->NAME = SDL_LoadFunction(videodata->egl_handle, #NAME); \ 197 if (!videodata->NAME) return -1; 198 199 LOAD_FUNC(fbGetDisplay); 200 LOAD_FUNC(fbGetDisplayByIndex); 201 LOAD_FUNC(fbGetDisplayGeometry); 202 LOAD_FUNC(fbGetDisplayInfo); 203 LOAD_FUNC(fbDestroyDisplay); 204 LOAD_FUNC(fbCreateWindow); 205 LOAD_FUNC(fbGetWindowGeometry); 206 LOAD_FUNC(fbGetWindowInfo); 207 LOAD_FUNC(fbDestroyWindow); 208 #endif 209 210 if (VIVANTE_SetupPlatform(_this) < 0) { 211 return -1; 212 } 213 214 if (VIVANTE_AddVideoDisplays(_this) < 0) { 215 return -1; 216 } 217 218 VIVANTE_UpdateDisplayScale(_this); 219 220 #ifdef SDL_INPUT_LINUXEV 221 if (SDL_EVDEV_Init() < 0) { 222 return -1; 223 } 224 #endif 225 226 return 0; 227 } 228 229 void 230 VIVANTE_VideoQuit(_THIS) 231 { 232 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; 233 234 #ifdef SDL_INPUT_LINUXEV 235 SDL_EVDEV_Quit(); 236 #endif 237 238 VIVANTE_CleanupPlatform(_this); 239 240 #if SDL_VIDEO_DRIVER_VIVANTE_VDK 241 if (videodata->vdk_private) { 242 vdkExit(videodata->vdk_private); 243 videodata->vdk_private = NULL; 244 } 245 #else 246 if (videodata->egl_handle) { 247 SDL_UnloadObject(videodata->egl_handle); 248 videodata->egl_handle = NULL; 249 } 250 #endif 251 } 252 253 void 254 VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay * display) 255 { 256 /* Only one display mode available, the current one */ 257 SDL_AddDisplayMode(display, &display->current_mode); 258 } 259 260 int 261 VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) 262 { 263 return 0; 264 } 265 266 int 267 VIVANTE_CreateWindow(_THIS, SDL_Window * window) 268 { 269 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; 270 SDL_DisplayData *displaydata; 271 SDL_WindowData *data; 272 273 displaydata = SDL_GetDisplayDriverData(0); 274 275 /* Allocate window internal data */ 276 data = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); 277 if (data == NULL) { 278 return SDL_OutOfMemory(); 279 } 280 281 /* Setup driver data for this window */ 282 window->driverdata = data; 283 284 #if SDL_VIDEO_DRIVER_VIVANTE_VDK 285 data->native_window = vdkCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h); 286 #else 287 data->native_window = videodata->fbCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h); 288 #endif 289 if (!data->native_window) { 290 return SDL_SetError("VIVANTE: Can't create native window"); 291 } 292 293 #if SDL_VIDEO_OPENGL_EGL 294 if (window->flags & SDL_WINDOW_OPENGL) { 295 data->egl_surface = SDL_EGL_CreateSurface(_this, data->native_window); 296 if (data->egl_surface == EGL_NO_SURFACE) { 297 return SDL_SetError("VIVANTE: Can't create EGL surface"); 298 } 299 } else { 300 data->egl_surface = EGL_NO_SURFACE; 301 } 302 #endif 303 304 /* Window has been successfully created */ 305 return 0; 306 } 307 308 void 309 VIVANTE_DestroyWindow(_THIS, SDL_Window * window) 310 { 311 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; 312 SDL_WindowData *data; 313 314 data = window->driverdata; 315 if (data) { 316 #if SDL_VIDEO_OPENGL_EGL 317 if (data->egl_surface != EGL_NO_SURFACE) { 318 SDL_EGL_DestroySurface(_this, data->egl_surface); 319 } 320 #endif 321 322 if (data->native_window) { 323 #if SDL_VIDEO_DRIVER_VIVANTE_VDK 324 vdkDestroyWindow(data->native_window); 325 #else 326 videodata->fbDestroyWindow(data->native_window); 327 #endif 328 } 329 330 SDL_free(data); 331 } 332 window->driverdata = NULL; 333 } 334 335 void 336 VIVANTE_SetWindowTitle(_THIS, SDL_Window * window) 337 { 338 #if SDL_VIDEO_DRIVER_VIVANTE_VDK 339 SDL_WindowData *data = window->driverdata; 340 vdkSetWindowTitle(data->native_window, window->title); 341 #endif 342 } 343 344 void 345 VIVANTE_SetWindowPosition(_THIS, SDL_Window * window) 346 { 347 /* FIXME */ 348 } 349 350 void 351 VIVANTE_SetWindowSize(_THIS, SDL_Window * window) 352 { 353 /* FIXME */ 354 } 355 356 void 357 VIVANTE_ShowWindow(_THIS, SDL_Window * window) 358 { 359 #if SDL_VIDEO_DRIVER_VIVANTE_VDK 360 SDL_WindowData *data = window->driverdata; 361 vdkShowWindow(data->native_window); 362 #endif 363 SDL_SetMouseFocus(window); 364 SDL_SetKeyboardFocus(window); 365 } 366 367 void 368 VIVANTE_HideWindow(_THIS, SDL_Window * window) 369 { 370 #if SDL_VIDEO_DRIVER_VIVANTE_VDK 371 SDL_WindowData *data = window->driverdata; 372 vdkHideWindow(data->native_window); 373 #endif 374 } 375 376 /*****************************************************************************/ 377 /* SDL Window Manager function */ 378 /*****************************************************************************/ 379 SDL_bool 380 VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) 381 { 382 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 383 SDL_DisplayData *displaydata = SDL_GetDisplayDriverData(0); 384 385 if (info->version.major == SDL_MAJOR_VERSION && 386 info->version.minor == SDL_MINOR_VERSION) { 387 info->subsystem = SDL_SYSWM_VIVANTE; 388 info->info.vivante.display = displaydata->native_display; 389 info->info.vivante.window = data->native_window; 390 return SDL_TRUE; 391 } else { 392 SDL_SetError("Application not compiled with SDL %d.%d", 393 SDL_MAJOR_VERSION, SDL_MINOR_VERSION); 394 return SDL_FALSE; 395 } 396 } 397 398 /*****************************************************************************/ 399 /* SDL event functions */ 400 /*****************************************************************************/ 401 void VIVANTE_PumpEvents(_THIS) 402 { 403 #ifdef SDL_INPUT_LINUXEV 404 SDL_EVDEV_Poll(); 405 #endif 406 } 407 408 #endif /* SDL_VIDEO_DRIVER_VIVANTE */ 409 410 /* vi: set ts=4 sw=4 expandtab: */