SDL_DirectFB_video.c (15658B)
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_DIRECTFB 24 25 /* 26 * #include "SDL_DirectFB_keyboard.h" 27 */ 28 #include "SDL_DirectFB_modes.h" 29 #include "SDL_DirectFB_opengl.h" 30 #include "SDL_DirectFB_vulkan.h" 31 #include "SDL_DirectFB_window.h" 32 #include "SDL_DirectFB_WM.h" 33 34 35 /* DirectFB video driver implementation. 36 */ 37 38 #include <fcntl.h> 39 #include <unistd.h> 40 #include <sys/mman.h> 41 42 #include <directfb.h> 43 #include <directfb_version.h> 44 #include <directfb_strings.h> 45 46 #include "SDL_video.h" 47 #include "SDL_mouse.h" 48 #include "../SDL_sysvideo.h" 49 #include "../SDL_pixels_c.h" 50 #include "../../events/SDL_events_c.h" 51 #include "SDL_DirectFB_video.h" 52 #include "SDL_DirectFB_events.h" 53 #include "SDL_DirectFB_render.h" 54 #include "SDL_DirectFB_mouse.h" 55 #include "SDL_DirectFB_shape.h" 56 57 58 #include "SDL_DirectFB_dyn.h" 59 60 /* Initialization/Query functions */ 61 static int DirectFB_VideoInit(_THIS); 62 static void DirectFB_VideoQuit(_THIS); 63 64 static SDL_VideoDevice *DirectFB_CreateDevice(int devindex); 65 66 VideoBootStrap DirectFB_bootstrap = { 67 "directfb", "DirectFB", 68 DirectFB_CreateDevice 69 }; 70 71 static const DirectFBSurfaceDrawingFlagsNames(drawing_flags); 72 static const DirectFBSurfaceBlittingFlagsNames(blitting_flags); 73 static const DirectFBAccelerationMaskNames(acceleration_mask); 74 75 /* DirectFB driver bootstrap functions */ 76 77 static void 78 DirectFB_DeleteDevice(SDL_VideoDevice * device) 79 { 80 SDL_DirectFB_UnLoadLibrary(); 81 SDL_DFB_FREE(device->driverdata); 82 SDL_DFB_FREE(device); 83 } 84 85 static SDL_VideoDevice * 86 DirectFB_CreateDevice(int devindex) 87 { 88 SDL_VideoDevice *device; 89 90 if (!SDL_DirectFB_LoadLibrary()) { 91 return NULL; 92 } 93 94 /* Initialize all variables that we clean on shutdown */ 95 SDL_DFB_ALLOC_CLEAR(device, sizeof(SDL_VideoDevice)); 96 97 /* Set the function pointers */ 98 device->VideoInit = DirectFB_VideoInit; 99 device->VideoQuit = DirectFB_VideoQuit; 100 device->GetDisplayModes = DirectFB_GetDisplayModes; 101 device->SetDisplayMode = DirectFB_SetDisplayMode; 102 device->PumpEvents = DirectFB_PumpEventsWindow; 103 device->CreateSDLWindow = DirectFB_CreateWindow; 104 device->CreateSDLWindowFrom = DirectFB_CreateWindowFrom; 105 device->SetWindowTitle = DirectFB_SetWindowTitle; 106 device->SetWindowIcon = DirectFB_SetWindowIcon; 107 device->SetWindowPosition = DirectFB_SetWindowPosition; 108 device->SetWindowSize = DirectFB_SetWindowSize; 109 device->SetWindowOpacity = DirectFB_SetWindowOpacity; 110 device->ShowWindow = DirectFB_ShowWindow; 111 device->HideWindow = DirectFB_HideWindow; 112 device->RaiseWindow = DirectFB_RaiseWindow; 113 device->MaximizeWindow = DirectFB_MaximizeWindow; 114 device->MinimizeWindow = DirectFB_MinimizeWindow; 115 device->RestoreWindow = DirectFB_RestoreWindow; 116 device->SetWindowGrab = DirectFB_SetWindowGrab; 117 device->DestroyWindow = DirectFB_DestroyWindow; 118 device->GetWindowWMInfo = DirectFB_GetWindowWMInfo; 119 120 /* !!! FIXME: implement SetWindowBordered */ 121 122 #if SDL_DIRECTFB_OPENGL 123 device->GL_LoadLibrary = DirectFB_GL_LoadLibrary; 124 device->GL_GetProcAddress = DirectFB_GL_GetProcAddress; 125 device->GL_MakeCurrent = DirectFB_GL_MakeCurrent; 126 127 device->GL_CreateContext = DirectFB_GL_CreateContext; 128 device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval; 129 device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval; 130 device->GL_SwapWindow = DirectFB_GL_SwapWindow; 131 device->GL_DeleteContext = DirectFB_GL_DeleteContext; 132 133 #endif 134 135 /* Shaped window support */ 136 device->shape_driver.CreateShaper = DirectFB_CreateShaper; 137 device->shape_driver.SetWindowShape = DirectFB_SetWindowShape; 138 device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape; 139 140 #if SDL_VIDEO_VULKAN 141 device->Vulkan_LoadLibrary = DirectFB_Vulkan_LoadLibrary; 142 device->Vulkan_UnloadLibrary = DirectFB_Vulkan_UnloadLibrary; 143 device->Vulkan_GetInstanceExtensions = DirectFB_Vulkan_GetInstanceExtensions; 144 device->Vulkan_CreateSurface = DirectFB_Vulkan_CreateSurface; 145 #endif 146 147 device->free = DirectFB_DeleteDevice; 148 149 return device; 150 error: 151 if (device) 152 SDL_free(device); 153 return (0); 154 } 155 156 static void 157 DirectFB_DeviceInformation(IDirectFB * dfb) 158 { 159 DFBGraphicsDeviceDescription desc; 160 int n; 161 162 dfb->GetDeviceDescription(dfb, &desc); 163 164 SDL_DFB_LOG( "DirectFB Device Information"); 165 SDL_DFB_LOG( "==========================="); 166 SDL_DFB_LOG( "Name: %s", desc.name); 167 SDL_DFB_LOG( "Vendor: %s", desc.vendor); 168 SDL_DFB_LOG( "Driver Name: %s", desc.driver.name); 169 SDL_DFB_LOG( "Driver Vendor: %s", desc.driver.vendor); 170 SDL_DFB_LOG( "Driver Version: %d.%d", desc.driver.major, 171 desc.driver.minor); 172 173 SDL_DFB_LOG( "Video memory: %d", desc.video_memory); 174 175 SDL_DFB_LOG( "Blitting flags:"); 176 for (n = 0; blitting_flags[n].flag; n++) { 177 if (desc.blitting_flags & blitting_flags[n].flag) 178 SDL_DFB_LOG( " %s", blitting_flags[n].name); 179 } 180 181 SDL_DFB_LOG( "Drawing flags:"); 182 for (n = 0; drawing_flags[n].flag; n++) { 183 if (desc.drawing_flags & drawing_flags[n].flag) 184 SDL_DFB_LOG( " %s", drawing_flags[n].name); 185 } 186 187 188 SDL_DFB_LOG( "Acceleration flags:"); 189 for (n = 0; acceleration_mask[n].mask; n++) { 190 if (desc.acceleration_mask & acceleration_mask[n].mask) 191 SDL_DFB_LOG( " %s", acceleration_mask[n].name); 192 } 193 194 195 } 196 197 static int readBoolEnv(const char *env_name, int def_val) 198 { 199 char *stemp; 200 201 stemp = SDL_getenv(env_name); 202 if (stemp) 203 return atoi(stemp); 204 else 205 return def_val; 206 } 207 208 static int 209 DirectFB_VideoInit(_THIS) 210 { 211 IDirectFB *dfb = NULL; 212 DFB_DeviceData *devdata = NULL; 213 DFBResult ret; 214 215 SDL_DFB_ALLOC_CLEAR(devdata, sizeof(*devdata)); 216 217 SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL)); 218 219 /* avoid switching to the framebuffer when we 220 * are running X11 */ 221 ret = readBoolEnv(DFBENV_USE_X11_CHECK , 1); 222 if (ret) { 223 if (SDL_getenv("DISPLAY")) 224 DirectFBSetOption("system", "x11"); 225 else 226 DirectFBSetOption("disable-module", "x11input"); 227 } 228 229 devdata->use_linux_input = readBoolEnv(DFBENV_USE_LINUX_INPUT, 1); /* default: on */ 230 231 if (!devdata->use_linux_input) 232 { 233 SDL_DFB_LOG("Disabling linux input\n"); 234 DirectFBSetOption("disable-module", "linux_input"); 235 } 236 237 SDL_DFB_CHECKERR(DirectFBCreate(&dfb)); 238 239 DirectFB_DeviceInformation(dfb); 240 241 devdata->use_yuv_underlays = readBoolEnv(DFBENV_USE_YUV_UNDERLAY, 0); /* default: off */ 242 devdata->use_yuv_direct = readBoolEnv(DFBENV_USE_YUV_DIRECT, 0); /* default is off! */ 243 244 /* Create global Eventbuffer for axis events */ 245 if (devdata->use_linux_input) { 246 SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_ALL, 247 DFB_TRUE, 248 &devdata->events)); 249 } else { 250 SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_AXES 251 /* DICAPS_ALL */ , 252 DFB_TRUE, 253 &devdata->events)); 254 } 255 256 /* simple window manager support */ 257 devdata->has_own_wm = readBoolEnv(DFBENV_USE_WM, 0); 258 259 devdata->initialized = 1; 260 261 devdata->dfb = dfb; 262 devdata->firstwin = NULL; 263 devdata->grabbed_window = NULL; 264 265 _this->driverdata = devdata; 266 267 DirectFB_InitModes(_this); 268 269 #if SDL_DIRECTFB_OPENGL 270 DirectFB_GL_Initialize(_this); 271 #endif 272 273 DirectFB_InitMouse(_this); 274 DirectFB_InitKeyboard(_this); 275 276 return 0; 277 278 279 error: 280 SDL_DFB_FREE(devdata); 281 SDL_DFB_RELEASE(dfb); 282 return -1; 283 } 284 285 static void 286 DirectFB_VideoQuit(_THIS) 287 { 288 DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata; 289 290 DirectFB_QuitModes(_this); 291 DirectFB_QuitKeyboard(_this); 292 DirectFB_QuitMouse(_this); 293 294 devdata->events->Reset(devdata->events); 295 SDL_DFB_RELEASE(devdata->events); 296 SDL_DFB_RELEASE(devdata->dfb); 297 298 #if SDL_DIRECTFB_OPENGL 299 DirectFB_GL_Shutdown(_this); 300 #endif 301 302 devdata->initialized = 0; 303 } 304 305 /* DirectFB driver general support functions */ 306 307 static const struct { 308 DFBSurfacePixelFormat dfb; 309 Uint32 sdl; 310 } pixelformat_tab[] = 311 { 312 { DSPF_RGB32, SDL_PIXELFORMAT_RGB888 }, /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */ 313 { DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 }, /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */ 314 { DSPF_RGB16, SDL_PIXELFORMAT_RGB565 }, /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */ 315 { DSPF_RGB332, SDL_PIXELFORMAT_RGB332 }, /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */ 316 { DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 }, /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */ 317 { DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 }, /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */ 318 { DSPF_RGB24, SDL_PIXELFORMAT_RGB24 }, /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */ 319 { DSPF_RGB444, SDL_PIXELFORMAT_RGB444 }, /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */ 320 { DSPF_YV12, SDL_PIXELFORMAT_YV12 }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */ 321 { DSPF_I420,SDL_PIXELFORMAT_IYUV }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */ 322 { DSPF_YUY2, SDL_PIXELFORMAT_YUY2 }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */ 323 { DSPF_UYVY, SDL_PIXELFORMAT_UYVY }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */ 324 { DSPF_RGB555, SDL_PIXELFORMAT_RGB555 }, /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */ 325 #if (DFB_VERSION_ATLEAST(1,5,0)) 326 { DSPF_ABGR, SDL_PIXELFORMAT_ABGR8888 }, /* 32 bit ABGR (4 byte, alpha 8@24, blue 8@16, green 8@8, red 8@0) */ 327 #endif 328 #if (ENABLE_LUT8) 329 { DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 }, /* 8 bit LUT (8 bit color and alpha lookup from palette) */ 330 #endif 331 332 #if (DFB_VERSION_ATLEAST(1,2,0)) 333 { DSPF_BGR555, SDL_PIXELFORMAT_BGR555 }, /* 16 bit BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */ 334 #else 335 { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR555 }, 336 #endif 337 338 /* Pfff ... nonmatching formats follow */ 339 340 { DSPF_ALUT44, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit ALUT (1 byte, alpha 4@4, color lookup 4@0) */ 341 { DSPF_A8, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit alpha (1 byte, alpha 8@0), e.g. anti-aliased glyphs */ 342 { DSPF_AiRGB, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */ 343 { DSPF_A1, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */ 344 { DSPF_NV12, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CbCr [15:0] plane) */ 345 { DSPF_NV16, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit YUV (8 bit Y plane followed by one 16 bit half width CbCr [15:0] plane) */ 346 { DSPF_ARGB2554, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */ 347 { DSPF_NV21, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CrCb [15:0] plane) */ 348 { DSPF_AYUV, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */ 349 { DSPF_A4, SDL_PIXELFORMAT_UNKNOWN }, /* 4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */ 350 { DSPF_ARGB1666, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (3 byte/ alpha 1@18, red 6@16, green 6@6, blue 6@0) */ 351 { DSPF_ARGB6666, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit alpha (3 byte/ alpha 6@18, red 6@16, green 6@6, blue 6@0) */ 352 { DSPF_RGB18, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit RGB (3 byte/ red 6@16, green 6@6, blue 6@0) */ 353 { DSPF_LUT2, SDL_PIXELFORMAT_UNKNOWN }, /* 2 bit LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */ 354 355 #if (DFB_VERSION_ATLEAST(1,3,0)) 356 { DSPF_RGBA4444, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 4@12, green 4@8, blue 4@4, alpha 4@0) */ 357 #endif 358 359 #if (DFB_VERSION_ATLEAST(1,4,3)) 360 { DSPF_RGBA5551, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 5@11, green 5@6, blue 5@1, alpha 1@0) */ 361 { DSPF_YUV444P, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit full YUV planar (8 bit Y plane followed by an 8 bit Cb and an 8 bit Cr plane) */ 362 { DSPF_ARGB8565, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit ARGB (3 byte, alpha 8@16, red 5@11, green 6@5, blue 5@0) */ 363 { DSPF_AVYU, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AVYU 4:4:4 (4 byte, alpha 8@24, Cr 8@16, Y 8@8, Cb 8@0) */ 364 { DSPF_VYU, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit VYU 4:4:4 (3 byte, Cr 8@16, Y 8@8, Cb 8@0) */ 365 #endif 366 367 { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB }, 368 { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1MSB }, 369 { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4LSB }, 370 { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4MSB }, 371 { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR24 }, 372 { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR888 }, 373 { DSPF_UNKNOWN, SDL_PIXELFORMAT_RGBA8888 }, 374 { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGRA8888 }, 375 { DSPF_UNKNOWN, SDL_PIXELFORMAT_ARGB2101010 }, 376 { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR4444 }, 377 { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR1555 }, 378 { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR565 }, 379 { DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU }, /**< Packed mode: Y0+V0+Y1+U0 (1 pla */ 380 }; 381 382 Uint32 383 DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat) 384 { 385 int i; 386 387 for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++) 388 if (pixelformat_tab[i].dfb == pixelformat) 389 { 390 return pixelformat_tab[i].sdl; 391 } 392 return SDL_PIXELFORMAT_UNKNOWN; 393 } 394 395 DFBSurfacePixelFormat 396 DirectFB_SDLToDFBPixelFormat(Uint32 format) 397 { 398 int i; 399 400 for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++) 401 if (pixelformat_tab[i].sdl == format) 402 { 403 return pixelformat_tab[i].dfb; 404 } 405 return DSPF_UNKNOWN; 406 } 407 408 void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo* ri) 409 { 410 int i, j; 411 412 for (i=0, j=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++) 413 if (pixelformat_tab[i].sdl != SDL_PIXELFORMAT_UNKNOWN) 414 ri->texture_formats[j++] = pixelformat_tab[i].sdl; 415 ri->num_texture_formats = j; 416 } 417 418 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */