A few fixes:
authorSam Lantinga <slouken@libsdl.org>
Sun, 13 Feb 2011 13:46:10 -0800
changeset 5288d4381f3b0d1e
parent 5287 d1823573d005
child 5289 1916a9e9714d
A few fixes:
Fixed creating render texture framebuffer.
Removed the need for palette watch, added surface format caching.
Added an SDL_DONTFREE flag so you can't free the window and 1.2 shadow surfaces.
include/SDL_pixels.h
include/SDL_surface.h
src/SDL_compat.c
src/render/SDL_render.c
src/render/software/SDL_render_sw.c
src/video/SDL_blit.c
src/video/SDL_blit.h
src/video/SDL_bmp.c
src/video/SDL_pixels.c
src/video/SDL_pixels_c.h
src/video/SDL_surface.c
src/video/SDL_video.c
src/video/directfb/SDL_DirectFB_window.c
src/video/windows/SDL_windowswindow.c
src/video/x11/SDL_x11window.c
     1.1 --- a/include/SDL_pixels.h	Sun Feb 13 01:31:07 2011 -0800
     1.2 +++ b/include/SDL_pixels.h	Sun Feb 13 13:46:10 2011 -0800
     1.3 @@ -253,24 +253,20 @@
     1.4  } SDL_Color;
     1.5  #define SDL_Colour SDL_Color
     1.6  
     1.7 -typedef struct SDL_Palette SDL_Palette;
     1.8 -typedef int (*SDL_PaletteChangedFunc) (void *userdata, SDL_Palette * palette);
     1.9 -typedef struct SDL_PaletteWatch SDL_PaletteWatch;
    1.10 -
    1.11 -struct SDL_Palette
    1.12 +typedef struct SDL_Palette
    1.13  {
    1.14      int ncolors;
    1.15      SDL_Color *colors;
    1.16 -
    1.17 +    Uint32 version;
    1.18      int refcount;
    1.19 -    SDL_PaletteWatch *watch;
    1.20 -};
    1.21 +} SDL_Palette;
    1.22  
    1.23  /**
    1.24   *  \note Everything in the pixel format structure is read-only.
    1.25   */
    1.26  typedef struct SDL_PixelFormat
    1.27  {
    1.28 +    Uint32 format;
    1.29      SDL_Palette *palette;
    1.30      Uint8 BitsPerPixel;
    1.31      Uint8 BytesPerPixel;
    1.32 @@ -286,6 +282,8 @@
    1.33      Uint32 Gmask;
    1.34      Uint32 Bmask;
    1.35      Uint32 Amask;
    1.36 +    int refcount;
    1.37 +    struct SDL_PixelFormat *next;
    1.38  } SDL_PixelFormat;
    1.39  
    1.40  /**
    1.41 @@ -322,6 +320,16 @@
    1.42                                                            Uint32 Amask);
    1.43  
    1.44  /**
    1.45 + *  \brief Create an SDL_PixelFormat structure from a pixel format enum.
    1.46 + */
    1.47 +extern DECLSPEC SDL_PixelFormat * SDLCALL SDL_AllocFormat(Uint32 pixel_format);
    1.48 +
    1.49 +/**
    1.50 + *  \brief Free an SDL_PixelFormat structure.
    1.51 + */
    1.52 +extern DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format);
    1.53 +
    1.54 +/**
    1.55   *  \brief Create a palette structure with the specified number of color 
    1.56   *         entries.
    1.57   *  
    1.58 @@ -334,23 +342,10 @@
    1.59  extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors);
    1.60  
    1.61  /**
    1.62 - *  \brief Add a callback function which is called when the palette changes.
    1.63 - *  
    1.64 - *  \sa SDL_DelPaletteWatch()
    1.65 + *  \brief Set the palette for a pixel format structure.
    1.66   */
    1.67 -extern DECLSPEC int SDLCALL SDL_AddPaletteWatch(SDL_Palette * palette,
    1.68 -                                                SDL_PaletteChangedFunc
    1.69 -                                                callback, void *userdata);
    1.70 -
    1.71 -/**
    1.72 - *  \brief Remove a callback function previously added with 
    1.73 - *         SDL_AddPaletteWatch().
    1.74 - *  
    1.75 - *  \sa SDL_AddPaletteWatch()
    1.76 - */
    1.77 -extern DECLSPEC void SDLCALL SDL_DelPaletteWatch(SDL_Palette * palette,
    1.78 -                                                 SDL_PaletteChangedFunc
    1.79 -                                                 callback, void *userdata);
    1.80 +extern DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat * format,
    1.81 +                                                      SDL_Palette *palette);
    1.82  
    1.83  /**
    1.84   *  \brief Set a range of colors in a palette.
     2.1 --- a/include/SDL_surface.h	Sun Feb 13 01:31:07 2011 -0800
     2.2 +++ b/include/SDL_surface.h	Sun Feb 13 13:46:10 2011 -0800
     2.3 @@ -54,6 +54,7 @@
     2.4  /*@{*/
     2.5  #define SDL_PREALLOC        0x00000001  /**< Surface uses preallocated memory */
     2.6  #define SDL_RLEACCEL        0x00000002  /**< Surface is RLE encoded */
     2.7 +#define SDL_DONTFREE        0x00000004  /**< Surface is referenced internally */
     2.8  /*@}*//*Surface flags*/
     2.9  
    2.10  /**
     3.1 --- a/src/SDL_compat.c	Sun Feb 13 01:31:07 2011 -0800
     3.2 +++ b/src/SDL_compat.c	Sun Feb 13 13:46:10 2011 -0800
     3.3 @@ -93,12 +93,7 @@
     3.4  
     3.5      /* Memory leak, compatibility code, who cares? */
     3.6      if (!info.vfmt && SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode) == 0) {
     3.7 -        int bpp;
     3.8 -        Uint32 Rmask, Gmask, Bmask, Amask;
     3.9 -
    3.10 -        SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask,
    3.11 -                                   &Amask);
    3.12 -        info.vfmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
    3.13 +        info.vfmt = SDL_AllocFormat(mode.format);
    3.14          info.current_w = mode.w;
    3.15          info.current_h = mode.h;
    3.16      }
    3.17 @@ -383,7 +378,7 @@
    3.18      int w, h;
    3.19  
    3.20      /* We can't resize something we don't have... */
    3.21 -    if (!SDL_VideoWindow) {
    3.22 +    if (!SDL_VideoSurface) {
    3.23          return -1;
    3.24      }
    3.25  
    3.26 @@ -396,6 +391,9 @@
    3.27      if (flags != SDL_VideoFlags) {
    3.28          return -1;
    3.29      }
    3.30 +    if (bpp != SDL_VideoSurface->format->BitsPerPixel) {
    3.31 +        return -1;
    3.32 +    }
    3.33  
    3.34      /* Resize the window */
    3.35      SDL_GetWindowSize(SDL_VideoWindow, &w, &h);
    3.36 @@ -469,6 +467,7 @@
    3.37      /* Destroy existing window */
    3.38      SDL_PublicSurface = NULL;
    3.39      if (SDL_ShadowSurface) {
    3.40 +        SDL_ShadowSurface->flags &= ~SDL_DONTFREE;
    3.41          SDL_FreeSurface(SDL_ShadowSurface);
    3.42          SDL_ShadowSurface = NULL;
    3.43      }
    3.44 @@ -564,6 +563,7 @@
    3.45              return NULL;
    3.46          }
    3.47          SDL_ShadowSurface->flags |= surface_flags;
    3.48 +        SDL_ShadowSurface->flags |= SDL_DONTFREE;
    3.49  
    3.50          /* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */
    3.51          if (SDL_ShadowSurface->format->palette) {
    3.52 @@ -670,7 +670,13 @@
    3.53             optimised alpha format is written, add the converter here */
    3.54          break;
    3.55      }
    3.56 -    format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
    3.57 +    format = SDL_AllocFormat(SDL_MasksToPixelFormatEnum(32, rmask,
    3.58 +                                                            gmask,
    3.59 +                                                            bmask,
    3.60 +                                                            amask));
    3.61 +    if (!format) {
    3.62 +        return NULL;
    3.63 +    }
    3.64      converted = SDL_ConvertSurface(surface, format, SDL_RLEACCEL);
    3.65      SDL_FreeFormat(format);
    3.66      return converted;
     4.1 --- a/src/render/SDL_render.c	Sun Feb 13 01:31:07 2011 -0800
     4.2 +++ b/src/render/SDL_render.c	Sun Feb 13 13:46:10 2011 -0800
     4.3 @@ -27,7 +27,6 @@
     4.4  #include "SDL_log.h"
     4.5  #include "SDL_render.h"
     4.6  #include "SDL_sysrender.h"
     4.7 -#include "../video/SDL_pixels_c.h"
     4.8  #include "software/SDL_render_sw_c.h"
     4.9  
    4.10  
    4.11 @@ -306,8 +305,6 @@
    4.12      SDL_bool needAlpha;
    4.13      Uint32 i;
    4.14      Uint32 format;
    4.15 -    int bpp;
    4.16 -    Uint32 Rmask, Gmask, Bmask, Amask;
    4.17      SDL_Texture *texture;
    4.18  
    4.19      CHECK_RENDERER_MAGIC(renderer, NULL);
    4.20 @@ -333,20 +330,13 @@
    4.21          }
    4.22      }
    4.23  
    4.24 -    if (!SDL_PixelFormatEnumToMasks(format, &bpp,
    4.25 -                                    &Rmask, &Gmask, &Bmask, &Amask)) {
    4.26 -        SDL_SetError("Unknown pixel format");
    4.27 -        return NULL;
    4.28 -    }
    4.29 -
    4.30      texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
    4.31                                  surface->w, surface->h);
    4.32      if (!texture) {
    4.33          return NULL;
    4.34      }
    4.35  
    4.36 -    if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask
    4.37 -        && Bmask == fmt->Bmask && Amask == fmt->Amask) {
    4.38 +    if (format == surface->format->format) {
    4.39          if (SDL_MUSTLOCK(surface)) {
    4.40              SDL_LockSurface(surface);
    4.41              SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
    4.42 @@ -359,7 +349,7 @@
    4.43          SDL_Surface *temp = NULL;
    4.44  
    4.45          /* Set up a destination surface for the texture update */
    4.46 -        SDL_InitFormat(&dst_fmt, bpp, Rmask, Gmask, Bmask, Amask);
    4.47 +        SDL_InitFormat(&dst_fmt, format);
    4.48          temp = SDL_ConvertSurface(surface, &dst_fmt, 0);
    4.49          if (temp) {
    4.50              SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
     5.1 --- a/src/render/software/SDL_render_sw.c	Sun Feb 13 01:31:07 2011 -0800
     5.2 +++ b/src/render/software/SDL_render_sw.c	Sun Feb 13 13:46:10 2011 -0800
     5.3 @@ -24,7 +24,6 @@
     5.4  #if !SDL_RENDER_DISABLED
     5.5  
     5.6  #include "../SDL_sysrender.h"
     5.7 -#include "../../video/SDL_pixels_c.h"
     5.8  
     5.9  #include "SDL_draw.h"
    5.10  #include "SDL_blendfillrect.h"
     6.1 --- a/src/video/SDL_blit.c	Sun Feb 13 01:31:07 2011 -0800
     6.2 +++ b/src/video/SDL_blit.c	Sun Feb 13 13:46:10 2011 -0800
     6.3 @@ -221,18 +221,8 @@
     6.4          blit = SDL_CalculateBlitN(surface);
     6.5      }
     6.6      if (blit == NULL) {
     6.7 -        Uint32 src_format =
     6.8 -            SDL_MasksToPixelFormatEnum(surface->format->BitsPerPixel,
     6.9 -                                       surface->format->Rmask,
    6.10 -                                       surface->format->Gmask,
    6.11 -                                       surface->format->Bmask,
    6.12 -                                       surface->format->Amask);
    6.13 -        Uint32 dst_format =
    6.14 -            SDL_MasksToPixelFormatEnum(dst->format->BitsPerPixel,
    6.15 -                                       dst->format->Rmask,
    6.16 -                                       dst->format->Gmask,
    6.17 -                                       dst->format->Bmask,
    6.18 -                                       dst->format->Amask);
    6.19 +        Uint32 src_format = surface->format->format;
    6.20 +        Uint32 dst_format = dst->format->format;
    6.21  
    6.22          blit =
    6.23              SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags,
     7.1 --- a/src/video/SDL_blit.h	Sun Feb 13 01:31:07 2011 -0800
     7.2 +++ b/src/video/SDL_blit.h	Sun Feb 13 13:46:10 2011 -0800
     7.3 @@ -105,7 +105,7 @@
     7.4  
     7.5      /* the version count matches the destination; mismatch indicates
     7.6         an invalid mapping */
     7.7 -    unsigned int format_version;
     7.8 +    Uint32 palette_version;
     7.9  } SDL_BlitMap;
    7.10  
    7.11  /* Functions found in SDL_blit.c */
    7.12 @@ -129,10 +129,6 @@
    7.13  #define DECLARE_ALIGNED(t,v,a)  t v
    7.14  #endif
    7.15  
    7.16 -#define FORMAT_EQUAL(A, B)						\
    7.17 -    ((A)->BitsPerPixel == (B)->BitsPerPixel				\
    7.18 -     && ((A)->Rmask == (B)->Rmask) && ((A)->Amask == (B)->Amask))
    7.19 -
    7.20  /* Load pixel of the specified format from a buffer and get its R-G-B values */
    7.21  /* FIXME: rescale values to 0..255 here? */
    7.22  #define RGB_FROM_PIXEL(Pixel, fmt, r, g, b)				\
     8.1 --- a/src/video/SDL_bmp.c	Sun Feb 13 01:31:07 2011 -0800
     8.2 +++ b/src/video/SDL_bmp.c	Sun Feb 13 13:46:10 2011 -0800
     8.3 @@ -437,17 +437,15 @@
     8.4              /* If the surface has a colorkey or alpha channel we'll save a
     8.5                 32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
     8.6              if (save32bit) {
     8.7 -                SDL_InitFormat(&format, 32,
     8.8 -                               0x00FF0000, 0x0000FF00, 0x000000FF,
     8.9 -                               0xFF000000);
    8.10 +                SDL_InitFormat(&format, 
    8.11 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
    8.12 +                               SDL_PIXELFORMAT_ARGB8888
    8.13 +#else
    8.14 +                               SDL_PIXELFORMAT_BGRA8888
    8.15 +#endif
    8.16 +                               );
    8.17              } else {
    8.18 -                SDL_InitFormat(&format, 24,
    8.19 -#if SDL_BYTEORDER == SDL_LIL_ENDIAN
    8.20 -                               0x00FF0000, 0x0000FF00, 0x000000FF,
    8.21 -#else
    8.22 -                               0x000000FF, 0x0000FF00, 0x00FF0000,
    8.23 -#endif
    8.24 -                               0);
    8.25 +                SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24);
    8.26              }
    8.27              surface = SDL_ConvertSurface(saveme, &format, 0);
    8.28              if (!surface) {
     9.1 --- a/src/video/SDL_pixels.c	Sun Feb 13 01:31:07 2011 -0800
     9.2 +++ b/src/video/SDL_pixels.c	Sun Feb 13 13:46:10 2011 -0800
     9.3 @@ -30,12 +30,6 @@
     9.4  #include "SDL_pixels_c.h"
     9.5  #include "SDL_RLEaccel_c.h"
     9.6  
     9.7 -struct SDL_PaletteWatch
     9.8 -{
     9.9 -    SDL_PaletteChangedFunc callback;
    9.10 -    void *userdata;
    9.11 -    struct SDL_PaletteWatch *next;
    9.12 -};
    9.13  
    9.14  /* Helper functions */
    9.15  
    9.16 @@ -256,6 +250,9 @@
    9.17          }
    9.18          break;
    9.19      case 15:
    9.20 +        if (Rmask == 0) {
    9.21 +            return SDL_PIXELFORMAT_RGB555;
    9.22 +        }
    9.23          if (Rmask == 0x7C00 && Bmask == 0x001F) {
    9.24              return SDL_PIXELFORMAT_RGB555;
    9.25          }
    9.26 @@ -265,6 +262,8 @@
    9.27          break;
    9.28      case 16:
    9.29          switch (Rmask) {
    9.30 +        case 0:
    9.31 +            return SDL_PIXELFORMAT_RGB565;
    9.32          case 0xF000:
    9.33              return SDL_PIXELFORMAT_RGBA4444;
    9.34          case 0x0F00:
    9.35 @@ -295,6 +294,7 @@
    9.36          break;
    9.37      case 24:
    9.38          switch (Rmask) {
    9.39 +        case 0:
    9.40          case 0x00FF0000:
    9.41  #if SDL_BYTEORDER == SDL_BIG_ENDIAN
    9.42              return SDL_PIXELFORMAT_RGB24;
    9.43 @@ -307,10 +307,6 @@
    9.44  #else
    9.45              return SDL_PIXELFORMAT_RGB24;
    9.46  #endif
    9.47 -        case 0x00000000:
    9.48 -            /* FIXME: At this point we can't distinguish */
    9.49 -            /* if this format is RGB24 or BGR24          */
    9.50 -            return SDL_PIXELFORMAT_RGB24;
    9.51          }
    9.52      case 32:
    9.53          switch (Rmask) {
    9.54 @@ -319,6 +315,7 @@
    9.55                  return SDL_PIXELFORMAT_RGBA8888;
    9.56              }
    9.57              break;
    9.58 +        case 0:
    9.59          case 0x00FF0000:
    9.60              if (Amask == 0xFF000000) {
    9.61                  return SDL_PIXELFORMAT_ARGB8888;
    9.62 @@ -345,154 +342,58 @@
    9.63      return SDL_PIXELFORMAT_UNKNOWN;
    9.64  }
    9.65  
    9.66 +static SDL_PixelFormat *formats;
    9.67  
    9.68 -SDL_Palette *
    9.69 -SDL_AllocPalette(int ncolors)
    9.70 +SDL_PixelFormat *
    9.71 +SDL_AllocFormat(Uint32 pixel_format)
    9.72  {
    9.73 -    SDL_Palette *palette;
    9.74 +    SDL_PixelFormat *format;
    9.75  
    9.76 -    palette = (SDL_Palette *) SDL_malloc(sizeof(*palette));
    9.77 -    if (!palette) {
    9.78 -        SDL_OutOfMemory();
    9.79 +    if (SDL_ISPIXELFORMAT_FOURCC(pixel_format)) {
    9.80 +        SDL_SetError("FOURCC pixel formats are not supported");
    9.81          return NULL;
    9.82      }
    9.83 -    palette->colors =
    9.84 -        (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors));
    9.85 -    if (!palette->colors) {
    9.86 -        SDL_free(palette);
    9.87 -        return NULL;
    9.88 -    }
    9.89 -    palette->ncolors = ncolors;
    9.90 -    palette->watch = NULL;
    9.91 -    palette->refcount = 1;
    9.92  
    9.93 -    SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors));
    9.94 -
    9.95 -    return palette;
    9.96 -}
    9.97 -
    9.98 -int
    9.99 -SDL_AddPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback,
   9.100 -                    void *userdata)
   9.101 -{
   9.102 -    SDL_PaletteWatch *watch;
   9.103 -
   9.104 -    if (!palette) {
   9.105 -        return -1;
   9.106 -    }
   9.107 -
   9.108 -    watch = (SDL_PaletteWatch *) SDL_malloc(sizeof(*watch));
   9.109 -    if (!watch) {
   9.110 -        SDL_OutOfMemory();
   9.111 -        return -1;
   9.112 -    }
   9.113 -
   9.114 -    watch->callback = callback;
   9.115 -    watch->userdata = userdata;
   9.116 -    watch->next = palette->watch;
   9.117 -    palette->watch = watch;
   9.118 -    ++palette->refcount;
   9.119 -    return 0;
   9.120 -}
   9.121 -
   9.122 -void
   9.123 -SDL_DelPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback,
   9.124 -                    void *userdata)
   9.125 -{
   9.126 -    SDL_PaletteWatch *prev, *watch;
   9.127 -
   9.128 -    if (!palette) {
   9.129 -        return;
   9.130 -    }
   9.131 -
   9.132 -    for (prev = NULL, watch = palette->watch; watch;
   9.133 -         prev = watch, watch = watch->next) {
   9.134 -        if (watch->callback == callback && watch->userdata == userdata) {
   9.135 -            if (prev) {
   9.136 -                prev->next = watch->next;
   9.137 -            } else {
   9.138 -                palette->watch = watch->next;
   9.139 -            }
   9.140 -            SDL_free(watch);
   9.141 -            SDL_FreePalette(palette);
   9.142 -            return;
   9.143 -        }
   9.144 -    }
   9.145 -}
   9.146 -
   9.147 -int
   9.148 -SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors,
   9.149 -                     int firstcolor, int ncolors)
   9.150 -{
   9.151 -    SDL_PaletteWatch *watch;
   9.152 -    int status = 0;
   9.153 -
   9.154 -    /* Verify the parameters */
   9.155 -    if (!palette) {
   9.156 -        return -1;
   9.157 -    }
   9.158 -    if (ncolors > (palette->ncolors - firstcolor)) {
   9.159 -        ncolors = (palette->ncolors - firstcolor);
   9.160 -        status = -1;
   9.161 -    }
   9.162 -
   9.163 -    if (colors != (palette->colors + firstcolor)) {
   9.164 -        SDL_memcpy(palette->colors + firstcolor, colors,
   9.165 -                   ncolors * sizeof(*colors));
   9.166 -    }
   9.167 -
   9.168 -    for (watch = palette->watch; watch; watch = watch->next) {
   9.169 -        if (watch->callback(watch->userdata, palette) < 0) {
   9.170 -            status = -1;
   9.171 +    /* Look it up in our list of previously allocated formats */
   9.172 +    for (format = formats; format; format = format->next) {
   9.173 +        if (pixel_format == format->format) {
   9.174 +            ++format->refcount;
   9.175 +            return format;
   9.176          }
   9.177      }
   9.178  
   9.179 -    return status;
   9.180 -}
   9.181 -
   9.182 -void
   9.183 -SDL_FreePalette(SDL_Palette * palette)
   9.184 -{
   9.185 -    if (!palette) {
   9.186 -        return;
   9.187 -    }
   9.188 -    if (--palette->refcount > 0) {
   9.189 -        return;
   9.190 -    }
   9.191 -    if (palette->colors) {
   9.192 -        SDL_free(palette->colors);
   9.193 -    }
   9.194 -    SDL_free(palette);
   9.195 -}
   9.196 -
   9.197 -/*
   9.198 - * Allocate a pixel format structure and fill it according to the given info.
   9.199 - */
   9.200 -SDL_PixelFormat *
   9.201 -SDL_AllocFormat(int bpp,
   9.202 -                Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
   9.203 -{
   9.204 -    SDL_PixelFormat *format;
   9.205 -
   9.206 -    /* Allocate an empty pixel format structure */
   9.207 +    /* Allocate an empty pixel format structure, and initialize it */
   9.208      format = SDL_malloc(sizeof(*format));
   9.209      if (format == NULL) {
   9.210          SDL_OutOfMemory();
   9.211          return (NULL);
   9.212      }
   9.213 +    SDL_InitFormat(format, pixel_format);
   9.214  
   9.215 -    /* Set up the format */
   9.216 -    return SDL_InitFormat(format, bpp, Rmask, Gmask, Bmask, Amask);
   9.217 +    if (!SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
   9.218 +        /* Cache the RGB formats */
   9.219 +        format->next = formats;
   9.220 +        formats = format;
   9.221 +    }
   9.222 +    return format;
   9.223  }
   9.224  
   9.225 -SDL_PixelFormat *
   9.226 -SDL_InitFormat(SDL_PixelFormat * format, int bpp, Uint32 Rmask, Uint32 Gmask,
   9.227 -               Uint32 Bmask, Uint32 Amask)
   9.228 +int
   9.229 +SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format)
   9.230  {
   9.231 +    int bpp;
   9.232 +    Uint32 Rmask, Gmask, Bmask, Amask;
   9.233      Uint32 mask;
   9.234  
   9.235 +    if (!SDL_PixelFormatEnumToMasks(pixel_format, &bpp,
   9.236 +                                    &Rmask, &Gmask, &Bmask, &Amask)) {
   9.237 +        SDL_SetError("Unknown pixel format");
   9.238 +        return -1;
   9.239 +    }
   9.240 +
   9.241      /* Set up the format */
   9.242      SDL_zerop(format);
   9.243 +    format->format = pixel_format;
   9.244      format->BitsPerPixel = bpp;
   9.245      format->BytesPerPixel = (bpp + 7) / 8;
   9.246      if (Rmask || Bmask || Gmask) {      /* Packed pixels with custom mask */
   9.247 @@ -561,37 +462,137 @@
   9.248          format->Amask = 0;
   9.249      }
   9.250      format->palette = NULL;
   9.251 +    format->refcount = 1;
   9.252 +    format->next = NULL;
   9.253  
   9.254 -    return format;
   9.255 +    return 0;
   9.256  }
   9.257  
   9.258 -/*
   9.259 - * Change any previous mappings from/to the new surface format
   9.260 - */
   9.261  void
   9.262 -SDL_FormatChanged(SDL_Surface * surface)
   9.263 +SDL_FreeFormat(SDL_PixelFormat *format)
   9.264  {
   9.265 -    static int format_version = 0;
   9.266 -    ++format_version;
   9.267 -    if (format_version < 0) {   /* It wrapped... */
   9.268 -        format_version = 1;
   9.269 -    }
   9.270 -    surface->format_version = format_version;
   9.271 -    SDL_InvalidateMap(surface->map);
   9.272 -}
   9.273 +    SDL_PixelFormat *prev;
   9.274  
   9.275 -/*
   9.276 - * Free a previously allocated format structure
   9.277 - */
   9.278 -void
   9.279 -SDL_FreeFormat(SDL_PixelFormat * format)
   9.280 -{
   9.281      if (!format) {
   9.282          return;
   9.283      }
   9.284 +    if (--format->refcount > 0) {
   9.285 +        return;
   9.286 +    }
   9.287 +
   9.288 +    /* Remove this format from our list */
   9.289 +    if (format == formats) {
   9.290 +        formats = format->next;
   9.291 +    } else if (formats) {
   9.292 +        for (prev = formats; prev->next; prev = prev->next) {
   9.293 +            if (prev->next == format) {
   9.294 +                prev->next = format->next;
   9.295 +                break;
   9.296 +            }
   9.297 +        }
   9.298 +    }
   9.299 +
   9.300 +    if (format->palette) {
   9.301 +        SDL_FreePalette(format->palette);
   9.302 +    }
   9.303      SDL_free(format);
   9.304  }
   9.305  
   9.306 +SDL_Palette *
   9.307 +SDL_AllocPalette(int ncolors)
   9.308 +{
   9.309 +    SDL_Palette *palette;
   9.310 +
   9.311 +    palette = (SDL_Palette *) SDL_malloc(sizeof(*palette));
   9.312 +    if (!palette) {
   9.313 +        SDL_OutOfMemory();
   9.314 +        return NULL;
   9.315 +    }
   9.316 +    palette->colors =
   9.317 +        (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors));
   9.318 +    if (!palette->colors) {
   9.319 +        SDL_free(palette);
   9.320 +        return NULL;
   9.321 +    }
   9.322 +    palette->ncolors = ncolors;
   9.323 +    palette->version = 1;
   9.324 +    palette->refcount = 1;
   9.325 +
   9.326 +    SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors));
   9.327 +
   9.328 +    return palette;
   9.329 +}
   9.330 +
   9.331 +int
   9.332 +SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette)
   9.333 +{
   9.334 +    if (!format) {
   9.335 +        SDL_SetError("SDL_SetPixelFormatPalette() passed NULL format");
   9.336 +        return -1;
   9.337 +    }
   9.338 +
   9.339 +    if (palette && palette->ncolors != (1 << format->BitsPerPixel)) {
   9.340 +        SDL_SetError("SDL_SetPixelFormatPalette() passed a palette that doesn't match the format");
   9.341 +        return -1;
   9.342 +    }
   9.343 +
   9.344 +    if (format->palette == palette) {
   9.345 +        return 0;
   9.346 +    }
   9.347 +
   9.348 +    if (format->palette) {
   9.349 +        SDL_FreePalette(format->palette);
   9.350 +    }
   9.351 +
   9.352 +    format->palette = palette;
   9.353 +
   9.354 +    if (format->palette) {
   9.355 +        ++format->palette->refcount;
   9.356 +    }
   9.357 +}
   9.358 +
   9.359 +int
   9.360 +SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors,
   9.361 +                     int firstcolor, int ncolors)
   9.362 +{
   9.363 +    int status = 0;
   9.364 +
   9.365 +    /* Verify the parameters */
   9.366 +    if (!palette) {
   9.367 +        return -1;
   9.368 +    }
   9.369 +    if (ncolors > (palette->ncolors - firstcolor)) {
   9.370 +        ncolors = (palette->ncolors - firstcolor);
   9.371 +        status = -1;
   9.372 +    }
   9.373 +
   9.374 +    if (colors != (palette->colors + firstcolor)) {
   9.375 +        SDL_memcpy(palette->colors + firstcolor, colors,
   9.376 +                   ncolors * sizeof(*colors));
   9.377 +    }
   9.378 +    ++palette->version;
   9.379 +    if (!palette->version) {
   9.380 +        palette->version = 1;
   9.381 +    }
   9.382 +
   9.383 +    return status;
   9.384 +}
   9.385 +
   9.386 +void
   9.387 +SDL_FreePalette(SDL_Palette * palette)
   9.388 +{
   9.389 +    if (!palette) {
   9.390 +        return;
   9.391 +    }
   9.392 +    if (--palette->refcount > 0) {
   9.393 +        return;
   9.394 +    }
   9.395 +    if (palette->colors) {
   9.396 +        SDL_free(palette->colors);
   9.397 +    }
   9.398 +    SDL_free(palette);
   9.399 +}
   9.400 +
   9.401  /*
   9.402   * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors
   9.403   */
   9.404 @@ -868,7 +869,7 @@
   9.405          return;
   9.406      }
   9.407      map->dst = NULL;
   9.408 -    map->format_version = (unsigned int) -1;
   9.409 +    map->palette_version = 0;
   9.410      if (map->info.table) {
   9.411          SDL_free(map->info.table);
   9.412          map->info.table = NULL;
   9.413 @@ -893,10 +894,8 @@
   9.414      map->identity = 0;
   9.415      srcfmt = src->format;
   9.416      dstfmt = dst->format;
   9.417 -    switch (srcfmt->BytesPerPixel) {
   9.418 -    case 1:
   9.419 -        switch (dstfmt->BytesPerPixel) {
   9.420 -        case 1:
   9.421 +    if (SDL_ISPIXELFORMAT_INDEXED(srcfmt->format)) {
   9.422 +        if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
   9.423              /* Palette --> Palette */
   9.424              map->info.table =
   9.425                  Map1to1(srcfmt->palette, dstfmt->palette, &map->identity);
   9.426 @@ -907,9 +906,7 @@
   9.427              }
   9.428              if (srcfmt->BitsPerPixel != dstfmt->BitsPerPixel)
   9.429                  map->identity = 0;
   9.430 -            break;
   9.431 -
   9.432 -        default:
   9.433 +        } else {
   9.434              /* Palette --> BitField */
   9.435              map->info.table =
   9.436                  Map1toN(srcfmt, src->map->info.r, src->map->info.g,
   9.437 @@ -917,12 +914,9 @@
   9.438              if (map->info.table == NULL) {
   9.439                  return (-1);
   9.440              }
   9.441 -            break;
   9.442          }
   9.443 -        break;
   9.444 -    default:
   9.445 -        switch (dstfmt->BytesPerPixel) {
   9.446 -        case 1:
   9.447 +    } else {
   9.448 +        if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
   9.449              /* BitField --> Palette */
   9.450              map->info.table = MapNto1(srcfmt, dstfmt, &map->identity);
   9.451              if (!map->identity) {
   9.452 @@ -931,18 +925,21 @@
   9.453                  }
   9.454              }
   9.455              map->identity = 0;  /* Don't optimize to copy */
   9.456 -            break;
   9.457 -        default:
   9.458 +        } else {
   9.459              /* BitField --> BitField */
   9.460 -            if (FORMAT_EQUAL(srcfmt, dstfmt))
   9.461 +            if (srcfmt == dstfmt) {
   9.462                  map->identity = 1;
   9.463 -            break;
   9.464 +            }
   9.465          }
   9.466 -        break;
   9.467      }
   9.468  
   9.469      map->dst = dst;
   9.470 -    map->format_version = dst->format_version;
   9.471 +
   9.472 +    if (dstfmt->palette) {
   9.473 +        map->palette_version = dstfmt->palette->version;
   9.474 +    } else {
   9.475 +        map->palette_version = 0;
   9.476 +    }
   9.477  
   9.478      /* Choose your blitters wisely */
   9.479      return (SDL_CalculateBlit(src));
    10.1 --- a/src/video/SDL_pixels_c.h	Sun Feb 13 01:31:07 2011 -0800
    10.2 +++ b/src/video/SDL_pixels_c.h	Sun Feb 13 13:46:10 2011 -0800
    10.3 @@ -26,14 +26,7 @@
    10.4  #include "SDL_blit.h"
    10.5  
    10.6  /* Pixel format functions */
    10.7 -extern SDL_PixelFormat *SDL_AllocFormat(int bpp,
    10.8 -                                        Uint32 Rmask, Uint32 Gmask,
    10.9 -                                        Uint32 Bmask, Uint32 Amask);
   10.10 -extern SDL_PixelFormat *SDL_InitFormat(SDL_PixelFormat * format, int bpp,
   10.11 -                                       Uint32 Rmask, Uint32 Gmask,
   10.12 -                                       Uint32 Bmask, Uint32 Amask);
   10.13 -extern void SDL_FormatChanged(SDL_Surface * surface);
   10.14 -extern void SDL_FreeFormat(SDL_PixelFormat * format);
   10.15 +extern int SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format);
   10.16  
   10.17  /* Blit mapping functions */
   10.18  extern SDL_BlitMap *SDL_AllocBlitMap(void);
    11.1 --- a/src/video/SDL_surface.c	Sun Feb 13 01:31:07 2011 -0800
    11.2 +++ b/src/video/SDL_surface.c	Sun Feb 13 13:46:10 2011 -0800
    11.3 @@ -39,10 +39,18 @@
    11.4                       Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
    11.5  {
    11.6      SDL_Surface *surface;
    11.7 +    Uint32 format;
    11.8  
    11.9      /* The flags are no longer used, make the compiler happy */
   11.10      (void)flags;
   11.11  
   11.12 +    /* Get the pixel format */
   11.13 +    format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
   11.14 +    if (format == SDL_PIXELFORMAT_UNKNOWN) {
   11.15 +        SDL_SetError("Unknown pixel format");
   11.16 +        return NULL;
   11.17 +    }
   11.18 +
   11.19      /* Allocate the surface */
   11.20      surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface));
   11.21      if (surface == NULL) {
   11.22 @@ -50,7 +58,7 @@
   11.23          return NULL;
   11.24      }
   11.25  
   11.26 -    surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
   11.27 +    surface->format = SDL_AllocFormat(format);
   11.28      if (!surface->format) {
   11.29          SDL_FreeSurface(surface);
   11.30          return NULL;
   11.31 @@ -60,7 +68,7 @@
   11.32      surface->pitch = SDL_CalculatePitch(surface);
   11.33      SDL_SetClipRect(surface, NULL);
   11.34  
   11.35 -    if (surface->format->BitsPerPixel <= 8) {
   11.36 +    if (SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) {
   11.37          SDL_Palette *palette =
   11.38              SDL_AllocPalette((1 << surface->format->BitsPerPixel));
   11.39          if (!palette) {
   11.40 @@ -135,7 +143,6 @@
   11.41          SDL_FreeSurface(surface);
   11.42          return NULL;
   11.43      }
   11.44 -    SDL_FormatChanged(surface);
   11.45  
   11.46      /* By default surface with an alpha mask are set up for blending */
   11.47      if (Amask) {
   11.48 @@ -171,46 +178,14 @@
   11.49      return surface;
   11.50  }
   11.51  
   11.52 -static int
   11.53 -SDL_SurfacePaletteChanged(void *userdata, SDL_Palette * palette)
   11.54 -{
   11.55 -    SDL_Surface *surface = (SDL_Surface *) userdata;
   11.56 -
   11.57 -    SDL_FormatChanged(surface);
   11.58 -
   11.59 -    return 0;
   11.60 -}
   11.61 -
   11.62  int
   11.63  SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette)
   11.64  {
   11.65 -    if (!surface || !surface->format) {
   11.66 +    if (!surface) {
   11.67          SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
   11.68          return -1;
   11.69      }
   11.70 -
   11.71 -    if (palette && palette->ncolors != (1 << surface->format->BitsPerPixel)) {
   11.72 -        SDL_SetError
   11.73 -            ("SDL_SetSurfacePalette() passed a palette that doesn't match the surface format");
   11.74 -        return -1;
   11.75 -    }
   11.76 -
   11.77 -    if (surface->format->palette == palette) {
   11.78 -        return 0;
   11.79 -    }
   11.80 -
   11.81 -    if (surface->format->palette) {
   11.82 -        SDL_DelPaletteWatch(surface->format->palette,
   11.83 -                            SDL_SurfacePaletteChanged, surface);
   11.84 -    }
   11.85 -
   11.86 -    surface->format->palette = palette;
   11.87 -
   11.88 -    if (surface->format->palette) {
   11.89 -        SDL_AddPaletteWatch(surface->format->palette,
   11.90 -                            SDL_SurfacePaletteChanged, surface);
   11.91 -    }
   11.92 -    return 0;
   11.93 +    return SDL_SetPixelFormatPalette(surface->format, palette);
   11.94  }
   11.95  
   11.96  int
   11.97 @@ -556,7 +531,8 @@
   11.98  {
   11.99      /* Check to make sure the blit mapping is valid */
  11.100      if ((src->map->dst != dst) ||
  11.101 -        (src->map->dst->format_version != src->map->format_version)) {
  11.102 +        (dst->format->palette &&
  11.103 +         src->map->palette_version != dst->format->palette->version)) {
  11.104          if (SDL_MapSurface(src, dst) < 0) {
  11.105              return (-1);
  11.106          }
  11.107 @@ -801,21 +777,17 @@
  11.108                           void * pixels, int pitch, SDL_Surface * surface, 
  11.109                           SDL_PixelFormat * format, SDL_BlitMap * blitmap)
  11.110  {
  11.111 -    int bpp;
  11.112 -    Uint32 Rmask, Gmask, Bmask, Amask;
  11.113 -
  11.114 -    if (!SDL_PixelFormatEnumToMasks(pixel_format,
  11.115 -                                    &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
  11.116 +    if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
  11.117 +        SDL_SetError("Indexed pixel formats not supported");
  11.118          return SDL_FALSE;
  11.119      }
  11.120 -    if (bpp <= 8) {
  11.121 -        SDL_SetError("Indexed pixel formats not supported");
  11.122 +    if (SDL_InitFormat(format, pixel_format) < 0) {
  11.123          return SDL_FALSE;
  11.124      }
  11.125  
  11.126      SDL_zerop(surface);
  11.127      surface->flags = SDL_PREALLOC;
  11.128 -    surface->format = SDL_InitFormat(format, bpp, Rmask, Gmask, Bmask, Amask);
  11.129 +    surface->format = format;
  11.130      surface->pixels = pixels;
  11.131      surface->w = width;
  11.132      surface->h = height;
  11.133 @@ -830,7 +802,6 @@
  11.134      blitmap->info.b = 0xFF;
  11.135      blitmap->info.a = 0xFF;
  11.136      surface->map = blitmap;
  11.137 -    SDL_FormatChanged(surface);
  11.138  
  11.139      /* The surface is ready to go */
  11.140      surface->refcount = 1;
  11.141 @@ -905,6 +876,9 @@
  11.142      if (surface == NULL) {
  11.143          return;
  11.144      }
  11.145 +    if (surface->flags & SDL_DONTFREE) {
  11.146 +        return;
  11.147 +    }
  11.148      if (--surface->refcount > 0) {
  11.149          return;
  11.150      }
    12.1 --- a/src/video/SDL_video.c	Sun Feb 13 01:31:07 2011 -0800
    12.2 +++ b/src/video/SDL_video.c	Sun Feb 13 13:46:10 2011 -0800
    12.3 @@ -208,7 +208,7 @@
    12.4  SDL_CreateWindowTexture(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
    12.5  {
    12.6      SDL_WindowTextureData *data;
    12.7 -    SDL_Renderer *renderer;
    12.8 +    SDL_Renderer *renderer = NULL;
    12.9      SDL_RendererInfo info;
   12.10      Uint32 i;
   12.11  
   12.12 @@ -1204,7 +1204,7 @@
   12.13  
   12.14      /* Tear down the old native window */
   12.15      if (window->surface) {
   12.16 -        window->surface->refcount = 0;
   12.17 +        window->surface->flags &= ~SDL_DONTFREE;
   12.18          SDL_FreeSurface(window->surface);
   12.19      }
   12.20      if (_this->DestroyWindowFramebuffer) {
   12.21 @@ -1622,13 +1622,13 @@
   12.22  
   12.23      if (!window->surface_valid) {
   12.24          if (window->surface) {
   12.25 -            window->surface->refcount = 0;
   12.26 +            window->surface->flags &= ~SDL_DONTFREE;
   12.27              SDL_FreeSurface(window->surface);
   12.28          }
   12.29          window->surface = SDL_CreateWindowFramebuffer(window);
   12.30          if (window->surface) {
   12.31              window->surface_valid = SDL_TRUE;
   12.32 -            window->surface->refcount = 0x7FFFFFF;
   12.33 +            window->surface->flags |= SDL_DONTFREE;
   12.34          }
   12.35      }
   12.36      return window->surface;
   12.37 @@ -1778,7 +1778,7 @@
   12.38      SDL_UpdateFullscreenMode(window, SDL_FALSE);
   12.39  
   12.40      if (window->surface) {
   12.41 -        window->surface->refcount = 0;
   12.42 +        window->surface->flags &= ~SDL_DONTFREE;
   12.43          SDL_FreeSurface(window->surface);
   12.44      }
   12.45      if (_this->DestroyWindowFramebuffer) {
    13.1 --- a/src/video/directfb/SDL_DirectFB_window.c	Sun Feb 13 01:31:07 2011 -0800
    13.2 +++ b/src/video/directfb/SDL_DirectFB_window.c	Sun Feb 13 13:46:10 2011 -0800
    13.3 @@ -220,8 +220,7 @@
    13.4          int pitch, i;
    13.5  
    13.6          /* Convert the icon to ARGB for modern window managers */
    13.7 -        SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
    13.8 -                       0xFF000000);
    13.9 +        SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
   13.10          surface = SDL_ConvertSurface(icon, &format, 0);
   13.11          if (!surface) {
   13.12              return;
    14.1 --- a/src/video/windows/SDL_windowswindow.c	Sun Feb 13 01:31:07 2011 -0800
    14.2 +++ b/src/video/windows/SDL_windowswindow.c	Sun Feb 13 13:46:10 2011 -0800
    14.3 @@ -332,8 +332,7 @@
    14.4          SDL_WriteLE32(dst, 0);
    14.5  
    14.6          /* Convert the icon to a 32-bit surface with alpha channel */
    14.7 -        SDL_InitFormat(&format, 32,
    14.8 -                       0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
    14.9 +        SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
   14.10          surface = SDL_ConvertSurface(icon, &format, 0);
   14.11          if (surface) {
   14.12              /* Write the pixels upside down into the bitmap buffer */
    15.1 --- a/src/video/x11/SDL_x11window.c	Sun Feb 13 01:31:07 2011 -0800
    15.2 +++ b/src/video/x11/SDL_x11window.c	Sun Feb 13 13:46:10 2011 -0800
    15.3 @@ -666,8 +666,7 @@
    15.4          long *propdata;
    15.5  
    15.6          /* Convert the icon to ARGB for modern window managers */
    15.7 -        SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
    15.8 -                       0xFF000000);
    15.9 +        SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
   15.10          surface = SDL_ConvertSurface(icon, &format, 0);
   15.11          if (!surface) {
   15.12              return;