A few fixes:
authorSam Lantinga <slouken@libsdl.org>
Sun, 13 Feb 2011 13:46:10 -0800
changeset 5288 d4381f3b0d1e
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
--- a/include/SDL_pixels.h	Sun Feb 13 01:31:07 2011 -0800
+++ b/include/SDL_pixels.h	Sun Feb 13 13:46:10 2011 -0800
@@ -253,24 +253,20 @@
 } SDL_Color;
 #define SDL_Colour SDL_Color
 
-typedef struct SDL_Palette SDL_Palette;
-typedef int (*SDL_PaletteChangedFunc) (void *userdata, SDL_Palette * palette);
-typedef struct SDL_PaletteWatch SDL_PaletteWatch;
-
-struct SDL_Palette
+typedef struct SDL_Palette
 {
     int ncolors;
     SDL_Color *colors;
-
+    Uint32 version;
     int refcount;
-    SDL_PaletteWatch *watch;
-};
+} SDL_Palette;
 
 /**
  *  \note Everything in the pixel format structure is read-only.
  */
 typedef struct SDL_PixelFormat
 {
+    Uint32 format;
     SDL_Palette *palette;
     Uint8 BitsPerPixel;
     Uint8 BytesPerPixel;
@@ -286,6 +282,8 @@
     Uint32 Gmask;
     Uint32 Bmask;
     Uint32 Amask;
+    int refcount;
+    struct SDL_PixelFormat *next;
 } SDL_PixelFormat;
 
 /**
@@ -322,6 +320,16 @@
                                                           Uint32 Amask);
 
 /**
+ *  \brief Create an SDL_PixelFormat structure from a pixel format enum.
+ */
+extern DECLSPEC SDL_PixelFormat * SDLCALL SDL_AllocFormat(Uint32 pixel_format);
+
+/**
+ *  \brief Free an SDL_PixelFormat structure.
+ */
+extern DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format);
+
+/**
  *  \brief Create a palette structure with the specified number of color 
  *         entries.
  *  
@@ -334,23 +342,10 @@
 extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors);
 
 /**
- *  \brief Add a callback function which is called when the palette changes.
- *  
- *  \sa SDL_DelPaletteWatch()
+ *  \brief Set the palette for a pixel format structure.
  */
-extern DECLSPEC int SDLCALL SDL_AddPaletteWatch(SDL_Palette * palette,
-                                                SDL_PaletteChangedFunc
-                                                callback, void *userdata);
-
-/**
- *  \brief Remove a callback function previously added with 
- *         SDL_AddPaletteWatch().
- *  
- *  \sa SDL_AddPaletteWatch()
- */
-extern DECLSPEC void SDLCALL SDL_DelPaletteWatch(SDL_Palette * palette,
-                                                 SDL_PaletteChangedFunc
-                                                 callback, void *userdata);
+extern DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat * format,
+                                                      SDL_Palette *palette);
 
 /**
  *  \brief Set a range of colors in a palette.
--- a/include/SDL_surface.h	Sun Feb 13 01:31:07 2011 -0800
+++ b/include/SDL_surface.h	Sun Feb 13 13:46:10 2011 -0800
@@ -54,6 +54,7 @@
 /*@{*/
 #define SDL_PREALLOC        0x00000001  /**< Surface uses preallocated memory */
 #define SDL_RLEACCEL        0x00000002  /**< Surface is RLE encoded */
+#define SDL_DONTFREE        0x00000004  /**< Surface is referenced internally */
 /*@}*//*Surface flags*/
 
 /**
--- a/src/SDL_compat.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/SDL_compat.c	Sun Feb 13 13:46:10 2011 -0800
@@ -93,12 +93,7 @@
 
     /* Memory leak, compatibility code, who cares? */
     if (!info.vfmt && SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode) == 0) {
-        int bpp;
-        Uint32 Rmask, Gmask, Bmask, Amask;
-
-        SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask,
-                                   &Amask);
-        info.vfmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
+        info.vfmt = SDL_AllocFormat(mode.format);
         info.current_w = mode.w;
         info.current_h = mode.h;
     }
@@ -383,7 +378,7 @@
     int w, h;
 
     /* We can't resize something we don't have... */
-    if (!SDL_VideoWindow) {
+    if (!SDL_VideoSurface) {
         return -1;
     }
 
@@ -396,6 +391,9 @@
     if (flags != SDL_VideoFlags) {
         return -1;
     }
+    if (bpp != SDL_VideoSurface->format->BitsPerPixel) {
+        return -1;
+    }
 
     /* Resize the window */
     SDL_GetWindowSize(SDL_VideoWindow, &w, &h);
@@ -469,6 +467,7 @@
     /* Destroy existing window */
     SDL_PublicSurface = NULL;
     if (SDL_ShadowSurface) {
+        SDL_ShadowSurface->flags &= ~SDL_DONTFREE;
         SDL_FreeSurface(SDL_ShadowSurface);
         SDL_ShadowSurface = NULL;
     }
@@ -564,6 +563,7 @@
             return NULL;
         }
         SDL_ShadowSurface->flags |= surface_flags;
+        SDL_ShadowSurface->flags |= SDL_DONTFREE;
 
         /* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */
         if (SDL_ShadowSurface->format->palette) {
@@ -670,7 +670,13 @@
            optimised alpha format is written, add the converter here */
         break;
     }
-    format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
+    format = SDL_AllocFormat(SDL_MasksToPixelFormatEnum(32, rmask,
+                                                            gmask,
+                                                            bmask,
+                                                            amask));
+    if (!format) {
+        return NULL;
+    }
     converted = SDL_ConvertSurface(surface, format, SDL_RLEACCEL);
     SDL_FreeFormat(format);
     return converted;
--- a/src/render/SDL_render.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/render/SDL_render.c	Sun Feb 13 13:46:10 2011 -0800
@@ -27,7 +27,6 @@
 #include "SDL_log.h"
 #include "SDL_render.h"
 #include "SDL_sysrender.h"
-#include "../video/SDL_pixels_c.h"
 #include "software/SDL_render_sw_c.h"
 
 
@@ -306,8 +305,6 @@
     SDL_bool needAlpha;
     Uint32 i;
     Uint32 format;
-    int bpp;
-    Uint32 Rmask, Gmask, Bmask, Amask;
     SDL_Texture *texture;
 
     CHECK_RENDERER_MAGIC(renderer, NULL);
@@ -333,20 +330,13 @@
         }
     }
 
-    if (!SDL_PixelFormatEnumToMasks(format, &bpp,
-                                    &Rmask, &Gmask, &Bmask, &Amask)) {
-        SDL_SetError("Unknown pixel format");
-        return NULL;
-    }
-
     texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
                                 surface->w, surface->h);
     if (!texture) {
         return NULL;
     }
 
-    if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask
-        && Bmask == fmt->Bmask && Amask == fmt->Amask) {
+    if (format == surface->format->format) {
         if (SDL_MUSTLOCK(surface)) {
             SDL_LockSurface(surface);
             SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
@@ -359,7 +349,7 @@
         SDL_Surface *temp = NULL;
 
         /* Set up a destination surface for the texture update */
-        SDL_InitFormat(&dst_fmt, bpp, Rmask, Gmask, Bmask, Amask);
+        SDL_InitFormat(&dst_fmt, format);
         temp = SDL_ConvertSurface(surface, &dst_fmt, 0);
         if (temp) {
             SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
--- a/src/render/software/SDL_render_sw.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/render/software/SDL_render_sw.c	Sun Feb 13 13:46:10 2011 -0800
@@ -24,7 +24,6 @@
 #if !SDL_RENDER_DISABLED
 
 #include "../SDL_sysrender.h"
-#include "../../video/SDL_pixels_c.h"
 
 #include "SDL_draw.h"
 #include "SDL_blendfillrect.h"
--- a/src/video/SDL_blit.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/SDL_blit.c	Sun Feb 13 13:46:10 2011 -0800
@@ -221,18 +221,8 @@
         blit = SDL_CalculateBlitN(surface);
     }
     if (blit == NULL) {
-        Uint32 src_format =
-            SDL_MasksToPixelFormatEnum(surface->format->BitsPerPixel,
-                                       surface->format->Rmask,
-                                       surface->format->Gmask,
-                                       surface->format->Bmask,
-                                       surface->format->Amask);
-        Uint32 dst_format =
-            SDL_MasksToPixelFormatEnum(dst->format->BitsPerPixel,
-                                       dst->format->Rmask,
-                                       dst->format->Gmask,
-                                       dst->format->Bmask,
-                                       dst->format->Amask);
+        Uint32 src_format = surface->format->format;
+        Uint32 dst_format = dst->format->format;
 
         blit =
             SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags,
--- a/src/video/SDL_blit.h	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/SDL_blit.h	Sun Feb 13 13:46:10 2011 -0800
@@ -105,7 +105,7 @@
 
     /* the version count matches the destination; mismatch indicates
        an invalid mapping */
-    unsigned int format_version;
+    Uint32 palette_version;
 } SDL_BlitMap;
 
 /* Functions found in SDL_blit.c */
@@ -129,10 +129,6 @@
 #define DECLARE_ALIGNED(t,v,a)  t v
 #endif
 
-#define FORMAT_EQUAL(A, B)						\
-    ((A)->BitsPerPixel == (B)->BitsPerPixel				\
-     && ((A)->Rmask == (B)->Rmask) && ((A)->Amask == (B)->Amask))
-
 /* Load pixel of the specified format from a buffer and get its R-G-B values */
 /* FIXME: rescale values to 0..255 here? */
 #define RGB_FROM_PIXEL(Pixel, fmt, r, g, b)				\
--- a/src/video/SDL_bmp.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/SDL_bmp.c	Sun Feb 13 13:46:10 2011 -0800
@@ -437,17 +437,15 @@
             /* If the surface has a colorkey or alpha channel we'll save a
                32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
             if (save32bit) {
-                SDL_InitFormat(&format, 32,
-                               0x00FF0000, 0x0000FF00, 0x000000FF,
-                               0xFF000000);
-            } else {
-                SDL_InitFormat(&format, 24,
+                SDL_InitFormat(&format, 
 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
-                               0x00FF0000, 0x0000FF00, 0x000000FF,
+                               SDL_PIXELFORMAT_ARGB8888
 #else
-                               0x000000FF, 0x0000FF00, 0x00FF0000,
+                               SDL_PIXELFORMAT_BGRA8888
 #endif
-                               0);
+                               );
+            } else {
+                SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24);
             }
             surface = SDL_ConvertSurface(saveme, &format, 0);
             if (!surface) {
--- a/src/video/SDL_pixels.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/SDL_pixels.c	Sun Feb 13 13:46:10 2011 -0800
@@ -30,12 +30,6 @@
 #include "SDL_pixels_c.h"
 #include "SDL_RLEaccel_c.h"
 
-struct SDL_PaletteWatch
-{
-    SDL_PaletteChangedFunc callback;
-    void *userdata;
-    struct SDL_PaletteWatch *next;
-};
 
 /* Helper functions */
 
@@ -256,6 +250,9 @@
         }
         break;
     case 15:
+        if (Rmask == 0) {
+            return SDL_PIXELFORMAT_RGB555;
+        }
         if (Rmask == 0x7C00 && Bmask == 0x001F) {
             return SDL_PIXELFORMAT_RGB555;
         }
@@ -265,6 +262,8 @@
         break;
     case 16:
         switch (Rmask) {
+        case 0:
+            return SDL_PIXELFORMAT_RGB565;
         case 0xF000:
             return SDL_PIXELFORMAT_RGBA4444;
         case 0x0F00:
@@ -295,6 +294,7 @@
         break;
     case 24:
         switch (Rmask) {
+        case 0:
         case 0x00FF0000:
 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
             return SDL_PIXELFORMAT_RGB24;
@@ -307,10 +307,6 @@
 #else
             return SDL_PIXELFORMAT_RGB24;
 #endif
-        case 0x00000000:
-            /* FIXME: At this point we can't distinguish */
-            /* if this format is RGB24 or BGR24          */
-            return SDL_PIXELFORMAT_RGB24;
         }
     case 32:
         switch (Rmask) {
@@ -319,6 +315,7 @@
                 return SDL_PIXELFORMAT_RGBA8888;
             }
             break;
+        case 0:
         case 0x00FF0000:
             if (Amask == 0xFF000000) {
                 return SDL_PIXELFORMAT_ARGB8888;
@@ -345,154 +342,58 @@
     return SDL_PIXELFORMAT_UNKNOWN;
 }
 
-
-SDL_Palette *
-SDL_AllocPalette(int ncolors)
-{
-    SDL_Palette *palette;
+static SDL_PixelFormat *formats;
 
-    palette = (SDL_Palette *) SDL_malloc(sizeof(*palette));
-    if (!palette) {
-        SDL_OutOfMemory();
-        return NULL;
-    }
-    palette->colors =
-        (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors));
-    if (!palette->colors) {
-        SDL_free(palette);
+SDL_PixelFormat *
+SDL_AllocFormat(Uint32 pixel_format)
+{
+    SDL_PixelFormat *format;
+
+    if (SDL_ISPIXELFORMAT_FOURCC(pixel_format)) {
+        SDL_SetError("FOURCC pixel formats are not supported");
         return NULL;
     }
-    palette->ncolors = ncolors;
-    palette->watch = NULL;
-    palette->refcount = 1;
-
-    SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors));
-
-    return palette;
-}
-
-int
-SDL_AddPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback,
-                    void *userdata)
-{
-    SDL_PaletteWatch *watch;
-
-    if (!palette) {
-        return -1;
-    }
-
-    watch = (SDL_PaletteWatch *) SDL_malloc(sizeof(*watch));
-    if (!watch) {
-        SDL_OutOfMemory();
-        return -1;
-    }
 
-    watch->callback = callback;
-    watch->userdata = userdata;
-    watch->next = palette->watch;
-    palette->watch = watch;
-    ++palette->refcount;
-    return 0;
-}
-
-void
-SDL_DelPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback,
-                    void *userdata)
-{
-    SDL_PaletteWatch *prev, *watch;
-
-    if (!palette) {
-        return;
-    }
-
-    for (prev = NULL, watch = palette->watch; watch;
-         prev = watch, watch = watch->next) {
-        if (watch->callback == callback && watch->userdata == userdata) {
-            if (prev) {
-                prev->next = watch->next;
-            } else {
-                palette->watch = watch->next;
-            }
-            SDL_free(watch);
-            SDL_FreePalette(palette);
-            return;
-        }
-    }
-}
-
-int
-SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors,
-                     int firstcolor, int ncolors)
-{
-    SDL_PaletteWatch *watch;
-    int status = 0;
-
-    /* Verify the parameters */
-    if (!palette) {
-        return -1;
-    }
-    if (ncolors > (palette->ncolors - firstcolor)) {
-        ncolors = (palette->ncolors - firstcolor);
-        status = -1;
-    }
-
-    if (colors != (palette->colors + firstcolor)) {
-        SDL_memcpy(palette->colors + firstcolor, colors,
-                   ncolors * sizeof(*colors));
-    }
-
-    for (watch = palette->watch; watch; watch = watch->next) {
-        if (watch->callback(watch->userdata, palette) < 0) {
-            status = -1;
+    /* Look it up in our list of previously allocated formats */
+    for (format = formats; format; format = format->next) {
+        if (pixel_format == format->format) {
+            ++format->refcount;
+            return format;
         }
     }
 
-    return status;
-}
-
-void
-SDL_FreePalette(SDL_Palette * palette)
-{
-    if (!palette) {
-        return;
-    }
-    if (--palette->refcount > 0) {
-        return;
-    }
-    if (palette->colors) {
-        SDL_free(palette->colors);
-    }
-    SDL_free(palette);
-}
-
-/*
- * Allocate a pixel format structure and fill it according to the given info.
- */
-SDL_PixelFormat *
-SDL_AllocFormat(int bpp,
-                Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
-{
-    SDL_PixelFormat *format;
-
-    /* Allocate an empty pixel format structure */
+    /* Allocate an empty pixel format structure, and initialize it */
     format = SDL_malloc(sizeof(*format));
     if (format == NULL) {
         SDL_OutOfMemory();
         return (NULL);
     }
+    SDL_InitFormat(format, pixel_format);
 
-    /* Set up the format */
-    return SDL_InitFormat(format, bpp, Rmask, Gmask, Bmask, Amask);
+    if (!SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
+        /* Cache the RGB formats */
+        format->next = formats;
+        formats = format;
+    }
+    return format;
 }
 
-SDL_PixelFormat *
-SDL_InitFormat(SDL_PixelFormat * format, int bpp, Uint32 Rmask, Uint32 Gmask,
-               Uint32 Bmask, Uint32 Amask)
+int
+SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format)
 {
+    int bpp;
+    Uint32 Rmask, Gmask, Bmask, Amask;
     Uint32 mask;
 
+    if (!SDL_PixelFormatEnumToMasks(pixel_format, &bpp,
+                                    &Rmask, &Gmask, &Bmask, &Amask)) {
+        SDL_SetError("Unknown pixel format");
+        return -1;
+    }
+
     /* Set up the format */
     SDL_zerop(format);
+    format->format = pixel_format;
     format->BitsPerPixel = bpp;
     format->BytesPerPixel = (bpp + 7) / 8;
     if (Rmask || Bmask || Gmask) {      /* Packed pixels with custom mask */
@@ -561,37 +462,137 @@
         format->Amask = 0;
     }
     format->palette = NULL;
+    format->refcount = 1;
+    format->next = NULL;
 
-    return format;
+    return 0;
 }
 
-/*
- * Change any previous mappings from/to the new surface format
- */
 void
-SDL_FormatChanged(SDL_Surface * surface)
+SDL_FreeFormat(SDL_PixelFormat *format)
 {
-    static int format_version = 0;
-    ++format_version;
-    if (format_version < 0) {   /* It wrapped... */
-        format_version = 1;
-    }
-    surface->format_version = format_version;
-    SDL_InvalidateMap(surface->map);
-}
+    SDL_PixelFormat *prev;
 
-/*
- * Free a previously allocated format structure
- */
-void
-SDL_FreeFormat(SDL_PixelFormat * format)
-{
     if (!format) {
         return;
     }
+    if (--format->refcount > 0) {
+        return;
+    }
+
+    /* Remove this format from our list */
+    if (format == formats) {
+        formats = format->next;
+    } else if (formats) {
+        for (prev = formats; prev->next; prev = prev->next) {
+            if (prev->next == format) {
+                prev->next = format->next;
+                break;
+            }
+        }
+    }
+
+    if (format->palette) {
+        SDL_FreePalette(format->palette);
+    }
     SDL_free(format);
 }
 
+SDL_Palette *
+SDL_AllocPalette(int ncolors)
+{
+    SDL_Palette *palette;
+
+    palette = (SDL_Palette *) SDL_malloc(sizeof(*palette));
+    if (!palette) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    palette->colors =
+        (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors));
+    if (!palette->colors) {
+        SDL_free(palette);
+        return NULL;
+    }
+    palette->ncolors = ncolors;
+    palette->version = 1;
+    palette->refcount = 1;
+
+    SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors));
+
+    return palette;
+}
+
+int
+SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette)
+{
+    if (!format) {
+        SDL_SetError("SDL_SetPixelFormatPalette() passed NULL format");
+        return -1;
+    }
+
+    if (palette && palette->ncolors != (1 << format->BitsPerPixel)) {
+        SDL_SetError("SDL_SetPixelFormatPalette() passed a palette that doesn't match the format");
+        return -1;
+    }
+
+    if (format->palette == palette) {
+        return 0;
+    }
+
+    if (format->palette) {
+        SDL_FreePalette(format->palette);
+    }
+
+    format->palette = palette;
+
+    if (format->palette) {
+        ++format->palette->refcount;
+    }
+}
+
+int
+SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors,
+                     int firstcolor, int ncolors)
+{
+    int status = 0;
+
+    /* Verify the parameters */
+    if (!palette) {
+        return -1;
+    }
+    if (ncolors > (palette->ncolors - firstcolor)) {
+        ncolors = (palette->ncolors - firstcolor);
+        status = -1;
+    }
+
+    if (colors != (palette->colors + firstcolor)) {
+        SDL_memcpy(palette->colors + firstcolor, colors,
+                   ncolors * sizeof(*colors));
+    }
+    ++palette->version;
+    if (!palette->version) {
+        palette->version = 1;
+    }
+
+    return status;
+}
+
+void
+SDL_FreePalette(SDL_Palette * palette)
+{
+    if (!palette) {
+        return;
+    }
+    if (--palette->refcount > 0) {
+        return;
+    }
+    if (palette->colors) {
+        SDL_free(palette->colors);
+    }
+    SDL_free(palette);
+}
+
 /*
  * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors
  */
@@ -868,7 +869,7 @@
         return;
     }
     map->dst = NULL;
-    map->format_version = (unsigned int) -1;
+    map->palette_version = 0;
     if (map->info.table) {
         SDL_free(map->info.table);
         map->info.table = NULL;
@@ -893,10 +894,8 @@
     map->identity = 0;
     srcfmt = src->format;
     dstfmt = dst->format;
-    switch (srcfmt->BytesPerPixel) {
-    case 1:
-        switch (dstfmt->BytesPerPixel) {
-        case 1:
+    if (SDL_ISPIXELFORMAT_INDEXED(srcfmt->format)) {
+        if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
             /* Palette --> Palette */
             map->info.table =
                 Map1to1(srcfmt->palette, dstfmt->palette, &map->identity);
@@ -907,9 +906,7 @@
             }
             if (srcfmt->BitsPerPixel != dstfmt->BitsPerPixel)
                 map->identity = 0;
-            break;
-
-        default:
+        } else {
             /* Palette --> BitField */
             map->info.table =
                 Map1toN(srcfmt, src->map->info.r, src->map->info.g,
@@ -917,12 +914,9 @@
             if (map->info.table == NULL) {
                 return (-1);
             }
-            break;
         }
-        break;
-    default:
-        switch (dstfmt->BytesPerPixel) {
-        case 1:
+    } else {
+        if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
             /* BitField --> Palette */
             map->info.table = MapNto1(srcfmt, dstfmt, &map->identity);
             if (!map->identity) {
@@ -931,18 +925,21 @@
                 }
             }
             map->identity = 0;  /* Don't optimize to copy */
-            break;
-        default:
+        } else {
             /* BitField --> BitField */
-            if (FORMAT_EQUAL(srcfmt, dstfmt))
+            if (srcfmt == dstfmt) {
                 map->identity = 1;
-            break;
+            }
         }
-        break;
     }
 
     map->dst = dst;
-    map->format_version = dst->format_version;
+
+    if (dstfmt->palette) {
+        map->palette_version = dstfmt->palette->version;
+    } else {
+        map->palette_version = 0;
+    }
 
     /* Choose your blitters wisely */
     return (SDL_CalculateBlit(src));
--- a/src/video/SDL_pixels_c.h	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/SDL_pixels_c.h	Sun Feb 13 13:46:10 2011 -0800
@@ -26,14 +26,7 @@
 #include "SDL_blit.h"
 
 /* Pixel format functions */
-extern SDL_PixelFormat *SDL_AllocFormat(int bpp,
-                                        Uint32 Rmask, Uint32 Gmask,
-                                        Uint32 Bmask, Uint32 Amask);
-extern SDL_PixelFormat *SDL_InitFormat(SDL_PixelFormat * format, int bpp,
-                                       Uint32 Rmask, Uint32 Gmask,
-                                       Uint32 Bmask, Uint32 Amask);
-extern void SDL_FormatChanged(SDL_Surface * surface);
-extern void SDL_FreeFormat(SDL_PixelFormat * format);
+extern int SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format);
 
 /* Blit mapping functions */
 extern SDL_BlitMap *SDL_AllocBlitMap(void);
--- a/src/video/SDL_surface.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/SDL_surface.c	Sun Feb 13 13:46:10 2011 -0800
@@ -39,10 +39,18 @@
                      Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
 {
     SDL_Surface *surface;
+    Uint32 format;
 
     /* The flags are no longer used, make the compiler happy */
     (void)flags;
 
+    /* Get the pixel format */
+    format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
+    if (format == SDL_PIXELFORMAT_UNKNOWN) {
+        SDL_SetError("Unknown pixel format");
+        return NULL;
+    }
+
     /* Allocate the surface */
     surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface));
     if (surface == NULL) {
@@ -50,7 +58,7 @@
         return NULL;
     }
 
-    surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
+    surface->format = SDL_AllocFormat(format);
     if (!surface->format) {
         SDL_FreeSurface(surface);
         return NULL;
@@ -60,7 +68,7 @@
     surface->pitch = SDL_CalculatePitch(surface);
     SDL_SetClipRect(surface, NULL);
 
-    if (surface->format->BitsPerPixel <= 8) {
+    if (SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) {
         SDL_Palette *palette =
             SDL_AllocPalette((1 << surface->format->BitsPerPixel));
         if (!palette) {
@@ -135,7 +143,6 @@
         SDL_FreeSurface(surface);
         return NULL;
     }
-    SDL_FormatChanged(surface);
 
     /* By default surface with an alpha mask are set up for blending */
     if (Amask) {
@@ -171,46 +178,14 @@
     return surface;
 }
 
-static int
-SDL_SurfacePaletteChanged(void *userdata, SDL_Palette * palette)
-{
-    SDL_Surface *surface = (SDL_Surface *) userdata;
-
-    SDL_FormatChanged(surface);
-
-    return 0;
-}
-
 int
 SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette)
 {
-    if (!surface || !surface->format) {
+    if (!surface) {
         SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
         return -1;
     }
-
-    if (palette && palette->ncolors != (1 << surface->format->BitsPerPixel)) {
-        SDL_SetError
-            ("SDL_SetSurfacePalette() passed a palette that doesn't match the surface format");
-        return -1;
-    }
-
-    if (surface->format->palette == palette) {
-        return 0;
-    }
-
-    if (surface->format->palette) {
-        SDL_DelPaletteWatch(surface->format->palette,
-                            SDL_SurfacePaletteChanged, surface);
-    }
-
-    surface->format->palette = palette;
-
-    if (surface->format->palette) {
-        SDL_AddPaletteWatch(surface->format->palette,
-                            SDL_SurfacePaletteChanged, surface);
-    }
-    return 0;
+    return SDL_SetPixelFormatPalette(surface->format, palette);
 }
 
 int
@@ -556,7 +531,8 @@
 {
     /* Check to make sure the blit mapping is valid */
     if ((src->map->dst != dst) ||
-        (src->map->dst->format_version != src->map->format_version)) {
+        (dst->format->palette &&
+         src->map->palette_version != dst->format->palette->version)) {
         if (SDL_MapSurface(src, dst) < 0) {
             return (-1);
         }
@@ -801,21 +777,17 @@
                          void * pixels, int pitch, SDL_Surface * surface, 
                          SDL_PixelFormat * format, SDL_BlitMap * blitmap)
 {
-    int bpp;
-    Uint32 Rmask, Gmask, Bmask, Amask;
-
-    if (!SDL_PixelFormatEnumToMasks(pixel_format,
-                                    &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
+    if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
+        SDL_SetError("Indexed pixel formats not supported");
         return SDL_FALSE;
     }
-    if (bpp <= 8) {
-        SDL_SetError("Indexed pixel formats not supported");
+    if (SDL_InitFormat(format, pixel_format) < 0) {
         return SDL_FALSE;
     }
 
     SDL_zerop(surface);
     surface->flags = SDL_PREALLOC;
-    surface->format = SDL_InitFormat(format, bpp, Rmask, Gmask, Bmask, Amask);
+    surface->format = format;
     surface->pixels = pixels;
     surface->w = width;
     surface->h = height;
@@ -830,7 +802,6 @@
     blitmap->info.b = 0xFF;
     blitmap->info.a = 0xFF;
     surface->map = blitmap;
-    SDL_FormatChanged(surface);
 
     /* The surface is ready to go */
     surface->refcount = 1;
@@ -905,6 +876,9 @@
     if (surface == NULL) {
         return;
     }
+    if (surface->flags & SDL_DONTFREE) {
+        return;
+    }
     if (--surface->refcount > 0) {
         return;
     }
--- a/src/video/SDL_video.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/SDL_video.c	Sun Feb 13 13:46:10 2011 -0800
@@ -208,7 +208,7 @@
 SDL_CreateWindowTexture(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
 {
     SDL_WindowTextureData *data;
-    SDL_Renderer *renderer;
+    SDL_Renderer *renderer = NULL;
     SDL_RendererInfo info;
     Uint32 i;
 
@@ -1204,7 +1204,7 @@
 
     /* Tear down the old native window */
     if (window->surface) {
-        window->surface->refcount = 0;
+        window->surface->flags &= ~SDL_DONTFREE;
         SDL_FreeSurface(window->surface);
     }
     if (_this->DestroyWindowFramebuffer) {
@@ -1622,13 +1622,13 @@
 
     if (!window->surface_valid) {
         if (window->surface) {
-            window->surface->refcount = 0;
+            window->surface->flags &= ~SDL_DONTFREE;
             SDL_FreeSurface(window->surface);
         }
         window->surface = SDL_CreateWindowFramebuffer(window);
         if (window->surface) {
             window->surface_valid = SDL_TRUE;
-            window->surface->refcount = 0x7FFFFFF;
+            window->surface->flags |= SDL_DONTFREE;
         }
     }
     return window->surface;
@@ -1778,7 +1778,7 @@
     SDL_UpdateFullscreenMode(window, SDL_FALSE);
 
     if (window->surface) {
-        window->surface->refcount = 0;
+        window->surface->flags &= ~SDL_DONTFREE;
         SDL_FreeSurface(window->surface);
     }
     if (_this->DestroyWindowFramebuffer) {
--- a/src/video/directfb/SDL_DirectFB_window.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/directfb/SDL_DirectFB_window.c	Sun Feb 13 13:46:10 2011 -0800
@@ -220,8 +220,7 @@
         int pitch, i;
 
         /* Convert the icon to ARGB for modern window managers */
-        SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
-                       0xFF000000);
+        SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
         surface = SDL_ConvertSurface(icon, &format, 0);
         if (!surface) {
             return;
--- a/src/video/windows/SDL_windowswindow.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/windows/SDL_windowswindow.c	Sun Feb 13 13:46:10 2011 -0800
@@ -332,8 +332,7 @@
         SDL_WriteLE32(dst, 0);
 
         /* Convert the icon to a 32-bit surface with alpha channel */
-        SDL_InitFormat(&format, 32,
-                       0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+        SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
         surface = SDL_ConvertSurface(icon, &format, 0);
         if (surface) {
             /* Write the pixels upside down into the bitmap buffer */
--- a/src/video/x11/SDL_x11window.c	Sun Feb 13 01:31:07 2011 -0800
+++ b/src/video/x11/SDL_x11window.c	Sun Feb 13 13:46:10 2011 -0800
@@ -666,8 +666,7 @@
         long *propdata;
 
         /* Convert the icon to ARGB for modern window managers */
-        SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
-                       0xFF000000);
+        SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
         surface = SDL_ConvertSurface(icon, &format, 0);
         if (!surface) {
             return;