1. SDL_CreateTextureFromSurface() now tries to find surface's pixel format.
authorMike Gorchak <lestat@i.com.ua>
Tue, 09 Jun 2009 08:56:43 +0000
changeset 317872edc980789b
parent 3177 efe3b3971e4f
child 3179 9b34679fda8b
1. SDL_CreateTextureFromSurface() now tries to find surface's pixel format.
2. SDL_CreateTextureFromSurface() now has best texture format search for non-alpha pixel formats.
3. Added comparision for pixels packed order to the video mode sorting callback to avoid mixing 1555/565/4444 pixel formats.
4. Added sorting call for current video mode list after each new video mode addition, because SDL_GetClosestDisplayMode() requires video modes to be sorted, and this is one place only where we can detect video modes addition.
src/video/SDL_video.c
     1.1 --- a/src/video/SDL_video.c	Tue Jun 09 04:34:50 2009 +0000
     1.2 +++ b/src/video/SDL_video.c	Tue Jun 09 08:56:43 2009 +0000
     1.3 @@ -147,6 +147,9 @@
     1.4      if (SDL_BITSPERPIXEL(a.format) != SDL_BITSPERPIXEL(b.format)) {
     1.5          return SDL_BITSPERPIXEL(b.format) - SDL_BITSPERPIXEL(a.format);
     1.6      }
     1.7 +    if (SDL_PIXELLAYOUT(a.format) != SDL_PIXELLAYOUT(b.format)) {
     1.8 +        return SDL_PIXELLAYOUT(b.format) - SDL_PIXELLAYOUT(a.format);
     1.9 +    }
    1.10      if (a.refresh_rate != b.refresh_rate) {
    1.11          return b.refresh_rate - a.refresh_rate;
    1.12      }
    1.13 @@ -408,6 +411,10 @@
    1.14      modes[nmodes] = *mode;
    1.15      display->num_display_modes++;
    1.16  
    1.17 +    /* Re-sort video modes */
    1.18 +    SDL_qsort(display->display_modes, display->num_display_modes,
    1.19 +        sizeof(SDL_DisplayMode), cmpmodes);
    1.20 +
    1.21      return SDL_TRUE;
    1.22  }
    1.23  
    1.24 @@ -1620,15 +1627,105 @@
    1.25              return 0;
    1.26          }
    1.27      } else {
    1.28 -        /* FIXME: Get the best supported texture format */
    1.29          if (surface->format->Amask
    1.30              || !(surface->map->info.flags &
    1.31                   (SDL_COPY_COLORKEY | SDL_COPY_MASK | SDL_COPY_BLEND))) {
    1.32 +            int it;
    1.33 +            int pfmt;
    1.34 +
    1.35 +            /* Pixel formats, sorted by best first */
    1.36 +            static const Uint32 sdl_pformats[]={
    1.37 +               SDL_PIXELFORMAT_ARGB8888,
    1.38 +               SDL_PIXELFORMAT_RGBA8888,
    1.39 +               SDL_PIXELFORMAT_ABGR8888,
    1.40 +               SDL_PIXELFORMAT_BGRA8888,
    1.41 +               SDL_PIXELFORMAT_RGB888,
    1.42 +               SDL_PIXELFORMAT_BGR888,
    1.43 +               SDL_PIXELFORMAT_RGB24,
    1.44 +               SDL_PIXELFORMAT_BGR24,
    1.45 +               SDL_PIXELFORMAT_RGB565,
    1.46 +               SDL_PIXELFORMAT_BGR565,
    1.47 +               SDL_PIXELFORMAT_ARGB1555,
    1.48 +               SDL_PIXELFORMAT_ABGR1555,
    1.49 +               SDL_PIXELFORMAT_RGB555,
    1.50 +               SDL_PIXELFORMAT_BGR555,
    1.51 +               SDL_PIXELFORMAT_ARGB4444,
    1.52 +               SDL_PIXELFORMAT_ABGR4444,
    1.53 +               SDL_PIXELFORMAT_RGB444,
    1.54 +               SDL_PIXELFORMAT_ARGB2101010,
    1.55 +               SDL_PIXELFORMAT_INDEX8,
    1.56 +               SDL_PIXELFORMAT_INDEX4LSB,
    1.57 +               SDL_PIXELFORMAT_INDEX4MSB,
    1.58 +               SDL_PIXELFORMAT_RGB332,
    1.59 +               SDL_PIXELFORMAT_INDEX1LSB,
    1.60 +               SDL_PIXELFORMAT_INDEX1MSB,
    1.61 +               SDL_PIXELFORMAT_UNKNOWN};
    1.62 +
    1.63              bpp = fmt->BitsPerPixel;
    1.64              Rmask = fmt->Rmask;
    1.65              Gmask = fmt->Gmask;
    1.66              Bmask = fmt->Bmask;
    1.67              Amask = fmt->Amask;
    1.68 +
    1.69 +            format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
    1.70 +            if (!format) {
    1.71 +                SDL_SetError("Unknown pixel format");
    1.72 +                return 0;
    1.73 +            }
    1.74 +
    1.75 +            /* Search requested format in the supported texture */
    1.76 +            /* formats by current renderer                      */
    1.77 +            for (it=0; it<renderer->info.num_texture_formats; it++)
    1.78 +            {
    1.79 +                if (renderer->info.texture_formats[it]==format)
    1.80 +                {
    1.81 +                   break;
    1.82 +                }
    1.83 +            }
    1.84 +
    1.85 +            /* If requested format can't be found, search any best */
    1.86 +            /* format which renderer provides                      */
    1.87 +            if (it==renderer->info.num_texture_formats)
    1.88 +            {
    1.89 +                pfmt=0;
    1.90 +                for (;;)
    1.91 +                {
    1.92 +                    if (sdl_pformats[pfmt]==SDL_PIXELFORMAT_UNKNOWN)
    1.93 +                    {
    1.94 +                        break;
    1.95 +                    }
    1.96 +
    1.97 +                    for (it=0; it<renderer->info.num_texture_formats; it++)
    1.98 +                    {
    1.99 +                       if (renderer->info.texture_formats[it]==sdl_pformats[pfmt])
   1.100 +                       {
   1.101 +                          break;
   1.102 +                       }
   1.103 +                    }
   1.104 +
   1.105 +                    if (it!=renderer->info.num_texture_formats)
   1.106 +                    {
   1.107 +                       /* The best format has been found */
   1.108 +                       break;
   1.109 +                    }
   1.110 +                    pfmt++;
   1.111 +                }
   1.112 +
   1.113 +                /* If any format can't be found, then return an error */
   1.114 +                if (it==renderer->info.num_texture_formats)
   1.115 +                {
   1.116 +                    SDL_SetError("Any of the supported pixel formats can't be found");
   1.117 +                    return 0;
   1.118 +                }
   1.119 +
   1.120 +                /* Convert found pixel format back to color masks */
   1.121 +                if (SDL_PixelFormatEnumToMasks(renderer->info.texture_formats[it],
   1.122 +                       &bpp, &Rmask, &Gmask, &Bmask, &Amask)!=SDL_TRUE)
   1.123 +                {
   1.124 +                    SDL_SetError("Unknown pixel format");
   1.125 +                    return 0;
   1.126 +                }
   1.127 +            }
   1.128          } else {
   1.129              /* Need a format with alpha */
   1.130              int it;
   1.131 @@ -1648,11 +1745,21 @@
   1.132                  SDL_PIXELFORMAT_UNKNOWN
   1.133              };
   1.134  
   1.135 -            bpp = 32;
   1.136 -            Rmask = 0x00FF0000;
   1.137 -            Gmask = 0x0000FF00;
   1.138 -            Bmask = 0x000000FF;
   1.139 -            Amask = 0xFF000000;
   1.140 +            if (surface->format->Amask) {
   1.141 +                /* If surface already has alpha, then try an original */
   1.142 +                /* surface format first                               */
   1.143 +                bpp = fmt->BitsPerPixel;
   1.144 +                Rmask = fmt->Rmask;
   1.145 +                Gmask = fmt->Gmask;
   1.146 +                Bmask = fmt->Bmask;
   1.147 +                Amask = fmt->Amask;
   1.148 +            } else {
   1.149 +                bpp = 32;
   1.150 +                Rmask = 0x00FF0000;
   1.151 +                Gmask = 0x0000FF00;
   1.152 +                Bmask = 0x000000FF;
   1.153 +                Amask = 0xFF000000;
   1.154 +            }
   1.155  
   1.156              format =
   1.157                  SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);