From ff06fc4426a077067dba83f9ab2ce1ab32ce9075 Mon Sep 17 00:00:00 2001 From: Mike Gorchak Date: Tue, 9 Jun 2009 08:56:43 +0000 Subject: [PATCH] 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 | 119 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 113 insertions(+), 6 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index eacb60977..47f5a12d3 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -147,6 +147,9 @@ cmpmodes(const void *A, const void *B) if (SDL_BITSPERPIXEL(a.format) != SDL_BITSPERPIXEL(b.format)) { return SDL_BITSPERPIXEL(b.format) - SDL_BITSPERPIXEL(a.format); } + if (SDL_PIXELLAYOUT(a.format) != SDL_PIXELLAYOUT(b.format)) { + return SDL_PIXELLAYOUT(b.format) - SDL_PIXELLAYOUT(a.format); + } if (a.refresh_rate != b.refresh_rate) { return b.refresh_rate - a.refresh_rate; } @@ -408,6 +411,10 @@ SDL_AddDisplayMode(int displayIndex, const SDL_DisplayMode * mode) modes[nmodes] = *mode; display->num_display_modes++; + /* Re-sort video modes */ + SDL_qsort(display->display_modes, display->num_display_modes, + sizeof(SDL_DisplayMode), cmpmodes); + return SDL_TRUE; } @@ -1620,15 +1627,105 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) return 0; } } else { - /* FIXME: Get the best supported texture format */ if (surface->format->Amask || !(surface->map->info.flags & (SDL_COPY_COLORKEY | SDL_COPY_MASK | SDL_COPY_BLEND))) { + int it; + int pfmt; + + /* Pixel formats, sorted by best first */ + static const Uint32 sdl_pformats[]={ + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_RGBA8888, + SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_BGR888, + SDL_PIXELFORMAT_RGB24, + SDL_PIXELFORMAT_BGR24, + SDL_PIXELFORMAT_RGB565, + SDL_PIXELFORMAT_BGR565, + SDL_PIXELFORMAT_ARGB1555, + SDL_PIXELFORMAT_ABGR1555, + SDL_PIXELFORMAT_RGB555, + SDL_PIXELFORMAT_BGR555, + SDL_PIXELFORMAT_ARGB4444, + SDL_PIXELFORMAT_ABGR4444, + SDL_PIXELFORMAT_RGB444, + SDL_PIXELFORMAT_ARGB2101010, + SDL_PIXELFORMAT_INDEX8, + SDL_PIXELFORMAT_INDEX4LSB, + SDL_PIXELFORMAT_INDEX4MSB, + SDL_PIXELFORMAT_RGB332, + SDL_PIXELFORMAT_INDEX1LSB, + SDL_PIXELFORMAT_INDEX1MSB, + SDL_PIXELFORMAT_UNKNOWN}; + bpp = fmt->BitsPerPixel; Rmask = fmt->Rmask; Gmask = fmt->Gmask; Bmask = fmt->Bmask; Amask = fmt->Amask; + + format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask); + if (!format) { + SDL_SetError("Unknown pixel format"); + return 0; + } + + /* Search requested format in the supported texture */ + /* formats by current renderer */ + for (it=0; itinfo.num_texture_formats; it++) + { + if (renderer->info.texture_formats[it]==format) + { + break; + } + } + + /* If requested format can't be found, search any best */ + /* format which renderer provides */ + if (it==renderer->info.num_texture_formats) + { + pfmt=0; + for (;;) + { + if (sdl_pformats[pfmt]==SDL_PIXELFORMAT_UNKNOWN) + { + break; + } + + for (it=0; itinfo.num_texture_formats; it++) + { + if (renderer->info.texture_formats[it]==sdl_pformats[pfmt]) + { + break; + } + } + + if (it!=renderer->info.num_texture_formats) + { + /* The best format has been found */ + break; + } + pfmt++; + } + + /* If any format can't be found, then return an error */ + if (it==renderer->info.num_texture_formats) + { + SDL_SetError("Any of the supported pixel formats 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; + } + } } else { /* Need a format with alpha */ int it; @@ -1648,11 +1745,21 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) SDL_PIXELFORMAT_UNKNOWN }; - bpp = 32; - Rmask = 0x00FF0000; - Gmask = 0x0000FF00; - Bmask = 0x000000FF; - Amask = 0xFF000000; + if (surface->format->Amask) { + /* If surface already has alpha, then try an original */ + /* surface format first */ + bpp = fmt->BitsPerPixel; + Rmask = fmt->Rmask; + Gmask = fmt->Gmask; + Bmask = fmt->Bmask; + Amask = fmt->Amask; + } else { + bpp = 32; + Rmask = 0x00FF0000; + Gmask = 0x0000FF00; + Bmask = 0x000000FF; + Amask = 0xFF000000; + } format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);