diff src/video/SDL_video.c @ 3166:3a63a5824557

Best pixel formats with alpha search code has been added to function which converts surface to texture with enabled color keys. Now "testsprite2 --renderer opengl_es" works fine with all pixel formats with alpha. This affects other renderers too.
author Mike Gorchak <lestat@i.com.ua>
date Fri, 05 Jun 2009 07:35:06 +0000
parents dc1eb82ffdaa
children f294338ca6eb
line wrap: on
line diff
--- a/src/video/SDL_video.c	Fri Jun 05 07:30:51 2009 +0000
+++ b/src/video/SDL_video.c	Fri Jun 05 07:35:06 2009 +0000
@@ -48,7 +48,7 @@
 #endif /* SDL_VIDEO_OPENGL */
 
 /* Available video drivers */
-static const VideoBootStrap *const bootstrap[] = {
+static VideoBootStrap *bootstrap[] = {
 #if SDL_VIDEO_DRIVER_COCOA
     &COCOA_bootstrap,
 #endif
@@ -1598,6 +1598,7 @@
     SDL_TextureID textureID;
     Uint32 requested_format = format;
     SDL_PixelFormat *fmt;
+    SDL_Renderer *renderer;
     int bpp;
     Uint32 Rmask, Gmask, Bmask, Amask;
 
@@ -1607,6 +1608,11 @@
     }
     fmt = surface->format;
 
+    renderer = SDL_CurrentDisplay.current_renderer;
+    if (!renderer) {
+        return 0;
+    }
+
     if (format) {
         if (!SDL_PixelFormatEnumToMasks
             (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
@@ -1625,12 +1631,89 @@
             Amask = fmt->Amask;
         } else {
             /* Need a format with alpha */
+            int it;
+            int apfmt;
+
+            /* Pixel formats with alpha, sorted by best first */
+            static const Uint32 sdl_alpha_pformats[]={
+               SDL_PIXELFORMAT_ARGB8888,
+               SDL_PIXELFORMAT_RGBA8888,
+               SDL_PIXELFORMAT_ABGR8888,
+               SDL_PIXELFORMAT_BGRA8888,
+               SDL_PIXELFORMAT_ARGB1555,
+               SDL_PIXELFORMAT_ABGR1555,
+               SDL_PIXELFORMAT_ARGB4444,
+               SDL_PIXELFORMAT_ABGR4444,
+               SDL_PIXELFORMAT_ARGB2101010,
+               SDL_PIXELFORMAT_UNKNOWN};
+
             bpp = 32;
             Rmask = 0x00FF0000;
             Gmask = 0x0000FF00;
             Bmask = 0x000000FF;
             Amask = 0xFF000000;
+
+            format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
+            if (!format) {
+                SDL_SetError("Unknown pixel format");
+                return 0;
+            }
+
+            /* Search this format in the supported texture formats */
+            /* by current renderer                                 */
+            for (it=0; it<renderer->info.num_texture_formats; it++)
+            {
+                if (renderer->info.texture_formats[it]==format)
+                {
+                   break;
+                }
+            }
+
+            /* If this format can't be found, search any best       */
+            /* compatible format with alpha which renderer provides */
+            if (it==renderer->info.num_texture_formats)
+            {
+                apfmt=0;
+                for (;;)
+                {
+                    if (sdl_alpha_pformats[apfmt]==SDL_PIXELFORMAT_UNKNOWN)
+                    {
+                        break;
+                    }
+
+                    for (it=0; it<renderer->info.num_texture_formats; it++)
+                    {
+                       if (renderer->info.texture_formats[it]==sdl_alpha_pformats[apfmt])
+                       {
+                          break;
+                       }
+                    }
+
+                    if (it!=renderer->info.num_texture_formats)
+                    {
+                       /* Compatible format has been found */
+                       break;
+                    }
+                    apfmt++;
+                }
+
+                /* If compatible format can't be found, then return an error */
+                if (it==renderer->info.num_texture_formats)
+                {
+                    SDL_SetError("Compatible pixel format can't be found");
+                    return 0;
+                }
+
+                /* Convert found pixel format back to color masks */
+                if (SDL_PixelFormatEnumToMasks(renderer->info.texture_formats[it],
+                       &bpp, &Rmask, &Gmask, &Bmask, &Amask)!=SDL_TRUE)
+                {
+                    SDL_SetError("Unknown pixel format");
+                    return 0;
+                }
+            }
         }
+
         format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
         if (!format) {
             SDL_SetError("Unknown pixel format");