src/video/directfb/SDL_DirectFB_video.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 28 Aug 2018 13:37:11 -0700
changeset 12158 ee7f3955c9fb
parent 11811 5d94cb6b24d3
child 12201 8bdc4d340419
permissions -rw-r--r--
Fixed bug 4229 - Add support for ABGR format in DirectFB renderer

Alexandre

DirectFB supports 32-bit ABGR pixel format via DSPF_ABGR, but SDL doesn't map SDL_PIXELFORMAT_ABGR8888 to DSPF_ABGR.

A patch is attached and should add support for ABGR pixel format devices.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2018 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_window.h"
    31 #include "SDL_DirectFB_WM.h"
    32 
    33 
    34 /* DirectFB video driver implementation.
    35 */
    36 
    37 #include <fcntl.h>
    38 #include <unistd.h>
    39 #include <sys/mman.h>
    40 
    41 #include <directfb.h>
    42 #include <directfb_version.h>
    43 #include <directfb_strings.h>
    44 
    45 #include "SDL_video.h"
    46 #include "SDL_mouse.h"
    47 #include "../SDL_sysvideo.h"
    48 #include "../SDL_pixels_c.h"
    49 #include "../../events/SDL_events_c.h"
    50 #include "SDL_DirectFB_video.h"
    51 #include "SDL_DirectFB_events.h"
    52 #include "SDL_DirectFB_render.h"
    53 #include "SDL_DirectFB_mouse.h"
    54 #include "SDL_DirectFB_shape.h"
    55 
    56 
    57 #include "SDL_DirectFB_dyn.h"
    58 
    59 /* Initialization/Query functions */
    60 static int DirectFB_VideoInit(_THIS);
    61 static void DirectFB_VideoQuit(_THIS);
    62 
    63 static int DirectFB_Available(void);
    64 static SDL_VideoDevice *DirectFB_CreateDevice(int devindex);
    65 
    66 VideoBootStrap DirectFB_bootstrap = {
    67     "directfb", "DirectFB",
    68     DirectFB_Available, 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 int
    78 DirectFB_Available(void)
    79 {
    80     if (!SDL_DirectFB_LoadLibrary())
    81         return 0;
    82     SDL_DirectFB_UnLoadLibrary();
    83     return 1;
    84 }
    85 
    86 static void
    87 DirectFB_DeleteDevice(SDL_VideoDevice * device)
    88 {
    89     SDL_DirectFB_UnLoadLibrary();
    90     SDL_DFB_FREE(device->driverdata);
    91     SDL_DFB_FREE(device);
    92 }
    93 
    94 static SDL_VideoDevice *
    95 DirectFB_CreateDevice(int devindex)
    96 {
    97     SDL_VideoDevice *device;
    98 
    99     if (!SDL_DirectFB_LoadLibrary()) {
   100         return NULL;
   101     }
   102 
   103     /* Initialize all variables that we clean on shutdown */
   104     SDL_DFB_ALLOC_CLEAR(device, sizeof(SDL_VideoDevice));
   105 
   106     /* Set the function pointers */
   107     device->VideoInit = DirectFB_VideoInit;
   108     device->VideoQuit = DirectFB_VideoQuit;
   109     device->GetDisplayModes = DirectFB_GetDisplayModes;
   110     device->SetDisplayMode = DirectFB_SetDisplayMode;
   111     device->PumpEvents = DirectFB_PumpEventsWindow;
   112     device->CreateSDLWindow = DirectFB_CreateWindow;
   113     device->CreateSDLWindowFrom = DirectFB_CreateWindowFrom;
   114     device->SetWindowTitle = DirectFB_SetWindowTitle;
   115     device->SetWindowIcon = DirectFB_SetWindowIcon;
   116     device->SetWindowPosition = DirectFB_SetWindowPosition;
   117     device->SetWindowSize = DirectFB_SetWindowSize;
   118     device->SetWindowOpacity = DirectFB_SetWindowOpacity;
   119     device->ShowWindow = DirectFB_ShowWindow;
   120     device->HideWindow = DirectFB_HideWindow;
   121     device->RaiseWindow = DirectFB_RaiseWindow;
   122     device->MaximizeWindow = DirectFB_MaximizeWindow;
   123     device->MinimizeWindow = DirectFB_MinimizeWindow;
   124     device->RestoreWindow = DirectFB_RestoreWindow;
   125     device->SetWindowGrab = DirectFB_SetWindowGrab;
   126     device->DestroyWindow = DirectFB_DestroyWindow;
   127     device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
   128 
   129     /* !!! FIXME: implement SetWindowBordered */
   130 
   131 #if SDL_DIRECTFB_OPENGL
   132     device->GL_LoadLibrary = DirectFB_GL_LoadLibrary;
   133     device->GL_GetProcAddress = DirectFB_GL_GetProcAddress;
   134     device->GL_MakeCurrent = DirectFB_GL_MakeCurrent;
   135 
   136     device->GL_CreateContext = DirectFB_GL_CreateContext;
   137     device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval;
   138     device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval;
   139     device->GL_SwapWindow = DirectFB_GL_SwapWindow;
   140     device->GL_DeleteContext = DirectFB_GL_DeleteContext;
   141 
   142 #endif
   143 
   144     /* Shaped window support */
   145     device->shape_driver.CreateShaper = DirectFB_CreateShaper;
   146     device->shape_driver.SetWindowShape = DirectFB_SetWindowShape;
   147     device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape;
   148 
   149     device->free = DirectFB_DeleteDevice;
   150 
   151     return device;
   152   error:
   153     if (device)
   154         SDL_free(device);
   155     return (0);
   156 }
   157 
   158 static void
   159 DirectFB_DeviceInformation(IDirectFB * dfb)
   160 {
   161     DFBGraphicsDeviceDescription desc;
   162     int n;
   163 
   164     dfb->GetDeviceDescription(dfb, &desc);
   165 
   166     SDL_DFB_LOG( "DirectFB Device Information");
   167     SDL_DFB_LOG( "===========================");
   168     SDL_DFB_LOG( "Name:           %s", desc.name);
   169     SDL_DFB_LOG( "Vendor:         %s", desc.vendor);
   170     SDL_DFB_LOG( "Driver Name:    %s", desc.driver.name);
   171     SDL_DFB_LOG( "Driver Vendor:  %s", desc.driver.vendor);
   172     SDL_DFB_LOG( "Driver Version: %d.%d", desc.driver.major,
   173             desc.driver.minor);
   174 
   175     SDL_DFB_LOG( "Video memory:   %d", desc.video_memory);
   176 
   177     SDL_DFB_LOG( "Blitting flags:");
   178     for (n = 0; blitting_flags[n].flag; n++) {
   179         if (desc.blitting_flags & blitting_flags[n].flag)
   180             SDL_DFB_LOG( "    %s", blitting_flags[n].name);
   181     }
   182 
   183     SDL_DFB_LOG( "Drawing flags:");
   184     for (n = 0; drawing_flags[n].flag; n++) {
   185         if (desc.drawing_flags & drawing_flags[n].flag)
   186             SDL_DFB_LOG( "    %s", drawing_flags[n].name);
   187     }
   188 
   189 
   190     SDL_DFB_LOG( "Acceleration flags:");
   191     for (n = 0; acceleration_mask[n].mask; n++) {
   192         if (desc.acceleration_mask & acceleration_mask[n].mask)
   193             SDL_DFB_LOG( "    %s", acceleration_mask[n].name);
   194     }
   195 
   196 
   197 }
   198 
   199 static int readBoolEnv(const char *env_name, int def_val)
   200 {
   201     char *stemp;
   202 
   203     stemp = SDL_getenv(env_name);
   204     if (stemp)
   205         return atoi(stemp);
   206     else
   207         return def_val;
   208 }
   209 
   210 static int
   211 DirectFB_VideoInit(_THIS)
   212 {
   213     IDirectFB *dfb = NULL;
   214     DFB_DeviceData *devdata = NULL;
   215     DFBResult ret;
   216 
   217     SDL_DFB_ALLOC_CLEAR(devdata, sizeof(*devdata));
   218 
   219     SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));
   220 
   221     /* avoid switching to the framebuffer when we
   222      * are running X11 */
   223     ret = readBoolEnv(DFBENV_USE_X11_CHECK , 1);
   224     if (ret) {
   225         if (SDL_getenv("DISPLAY"))
   226             DirectFBSetOption("system", "x11");
   227         else
   228             DirectFBSetOption("disable-module", "x11input");
   229     }
   230 
   231     devdata->use_linux_input = readBoolEnv(DFBENV_USE_LINUX_INPUT, 1);       /* default: on */
   232 
   233     if (!devdata->use_linux_input)
   234     {
   235         SDL_DFB_LOG("Disabling linux input\n");
   236         DirectFBSetOption("disable-module", "linux_input");
   237     }
   238 
   239     SDL_DFB_CHECKERR(DirectFBCreate(&dfb));
   240 
   241     DirectFB_DeviceInformation(dfb);
   242 
   243     devdata->use_yuv_underlays = readBoolEnv(DFBENV_USE_YUV_UNDERLAY, 0);     /* default: off */
   244     devdata->use_yuv_direct = readBoolEnv(DFBENV_USE_YUV_DIRECT, 0);      /* default is off! */
   245 
   246     /* Create global Eventbuffer for axis events */
   247     if (devdata->use_linux_input) {
   248         SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_ALL,
   249                                                      DFB_TRUE,
   250                                                      &devdata->events));
   251     } else {
   252         SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_AXES
   253                                                      /* DICAPS_ALL */ ,
   254                                                      DFB_TRUE,
   255                                                      &devdata->events));
   256     }
   257 
   258     /* simple window manager support */
   259     devdata->has_own_wm = readBoolEnv(DFBENV_USE_WM, 0);
   260 
   261     devdata->initialized = 1;
   262 
   263     devdata->dfb = dfb;
   264     devdata->firstwin = NULL;
   265     devdata->grabbed_window = NULL;
   266 
   267     _this->driverdata = devdata;
   268 
   269     DirectFB_InitModes(_this);
   270 
   271 #if SDL_DIRECTFB_OPENGL
   272     DirectFB_GL_Initialize(_this);
   273 #endif
   274 
   275     DirectFB_InitMouse(_this);
   276     DirectFB_InitKeyboard(_this);
   277 
   278     return 0;
   279 
   280 
   281   error:
   282     SDL_DFB_FREE(devdata);
   283     SDL_DFB_RELEASE(dfb);
   284     return -1;
   285 }
   286 
   287 static void
   288 DirectFB_VideoQuit(_THIS)
   289 {
   290     DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata;
   291 
   292     DirectFB_QuitModes(_this);
   293     DirectFB_QuitKeyboard(_this);
   294     DirectFB_QuitMouse(_this);
   295 
   296     devdata->events->Reset(devdata->events);
   297     SDL_DFB_RELEASE(devdata->events);
   298     SDL_DFB_RELEASE(devdata->dfb);
   299 
   300 #if SDL_DIRECTFB_OPENGL
   301     DirectFB_GL_Shutdown(_this);
   302 #endif
   303 
   304     devdata->initialized = 0;
   305 }
   306 
   307 /* DirectFB driver general support functions */
   308 
   309 static const struct {
   310     DFBSurfacePixelFormat dfb;
   311     Uint32 sdl;
   312 } pixelformat_tab[] =
   313 {
   314     { DSPF_RGB32, SDL_PIXELFORMAT_RGB888 },             /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
   315     { DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 },            /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */
   316     { DSPF_RGB16, SDL_PIXELFORMAT_RGB565 },             /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
   317     { DSPF_RGB332, SDL_PIXELFORMAT_RGB332 },            /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
   318     { DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 },        /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */
   319     { DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 },        /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */
   320     { DSPF_RGB24, SDL_PIXELFORMAT_RGB24 },              /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
   321     { DSPF_RGB444, SDL_PIXELFORMAT_RGB444 },            /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */
   322     { DSPF_YV12, SDL_PIXELFORMAT_YV12 },                /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */
   323     { DSPF_I420,SDL_PIXELFORMAT_IYUV },                 /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */
   324     { DSPF_YUY2, SDL_PIXELFORMAT_YUY2 },                /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */
   325     { DSPF_UYVY, SDL_PIXELFORMAT_UYVY },                /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */
   326     { DSPF_RGB555, SDL_PIXELFORMAT_RGB555 },            /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */
   327     { DSPF_ABGR, SDL_PIXELFORMAT_ABGR8888 },		/* 32 bit ABGR (4  byte, alpha 8@24, blue 8@16, green 8@8, red 8@0) */
   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 */