Просмотр исходного кода

Improved performance scaling 8-bit surfaces

Sam Lantinga 4 месяцев назад
Родитель
Сommit
d145e78cd6
3 измененных файлов с 26 добавлено и 12 удалено
  1. 18 11
      src/video/SDL_pixels.c
  2. 1 0
      src/video/SDL_pixels_c.h
  3. 7 1
      src/video/SDL_surface.c

+ 18 - 11
src/video/SDL_pixels.c

@@ -1441,24 +1441,31 @@ void SDL_GetRGBA(Uint32 pixelvalue, const SDL_PixelFormatDetails *format, const
     }
 }
 
+bool SDL_IsSamePalette(const SDL_Palette *src, const SDL_Palette *dst)
+{
+    if (src->ncolors <= dst->ncolors) {
+        // If an identical palette, no need to map
+        if (src == dst ||
+            (SDL_memcmp(src->colors, dst->colors,
+                        src->ncolors * sizeof(SDL_Color)) == 0)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 // Map from Palette to Palette
 static Uint8 *Map1to1(const SDL_Palette *src, const SDL_Palette *dst, int *identical)
 {
     Uint8 *map;
     int i;
 
-    if (identical) {
-        if (src->ncolors <= dst->ncolors) {
-            // If an identical palette, no need to map
-            if (src == dst ||
-                (SDL_memcmp(src->colors, dst->colors,
-                            src->ncolors * sizeof(SDL_Color)) == 0)) {
-                *identical = 1;
-                return NULL;
-            }
-        }
-        *identical = 0;
+    if (SDL_IsSamePalette(src, dst)) {
+        *identical = 1;
+        return NULL;
     }
+    *identical = 0;
+
     map = (Uint8 *)SDL_calloc(256, sizeof(Uint8));
     if (!map) {
         return NULL;

+ 1 - 0
src/video/SDL_pixels_c.h

@@ -48,6 +48,7 @@ extern void SDL_InvalidateMap(SDL_BlitMap *map);
 extern bool SDL_MapSurface(SDL_Surface *src, SDL_Surface *dst);
 
 // Miscellaneous functions
+extern bool SDL_IsSamePalette(const SDL_Palette *src, const SDL_Palette *dst);
 extern void SDL_DitherPalette(SDL_Palette *palette);
 extern Uint8 SDL_FindColor(const SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
 extern Uint8 SDL_LookupRGBAColor(SDL_HashTable *palette_map, Uint32 pixelvalue, const SDL_Palette *pal);

+ 7 - 1
src/video/SDL_surface.c

@@ -1252,7 +1252,8 @@ bool SDL_BlitSurfaceUncheckedScaled(SDL_Surface *src, const SDL_Rect *srcrect, S
     if (scaleMode == SDL_SCALEMODE_NEAREST || scaleMode == SDL_SCALEMODE_PIXELART) {
         if (!(src->map.info.flags & complex_copy_flags) &&
             src->format == dst->format &&
-            !SDL_ISPIXELFORMAT_INDEXED(src->format) &&
+            (!SDL_ISPIXELFORMAT_INDEXED(src->format) ||
+             (SDL_BITSPERPIXEL(src->format) == 8 && SDL_IsSamePalette(src->palette, dst->palette))) &&
             SDL_BYTESPERPIXEL(src->format) <= 4) {
             return SDL_StretchSurface(src, srcrect, dst, dstrect, SDL_SCALEMODE_NEAREST);
         } else if (SDL_BITSPERPIXEL(src->format) < 8) {
@@ -2244,6 +2245,11 @@ SDL_Surface *SDL_ScaleSurface(SDL_Surface *surface, int width, int height, SDL_S
         return result;
     }
 
+    if (SDL_ISPIXELFORMAT_INDEXED(surface->format)) {
+        // Linear scaling requires conversion to RGBA and then slow pixel color lookup
+        scaleMode = SDL_SCALEMODE_NEAREST;
+    }
+
     // Create a new surface with the desired size
     if (surface->pixels || SDL_MUSTLOCK(surface)) {
         convert = SDL_CreateSurface(width, height, surface->format);