From 2510d6ccc14b0000612887ca3d7df68bc6ae87e9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 13 Feb 2011 13:46:10 -0800 Subject: [PATCH] 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 | 43 ++- include/SDL_surface.h | 1 + src/SDL_compat.c | 22 +- src/render/SDL_render.c | 14 +- src/render/software/SDL_render_sw.c | 1 - src/video/SDL_blit.c | 14 +- src/video/SDL_blit.h | 6 +- src/video/SDL_bmp.c | 14 +- src/video/SDL_pixels.c | 341 +++++++++++------------ src/video/SDL_pixels_c.h | 9 +- src/video/SDL_surface.c | 68 ++--- src/video/SDL_video.c | 10 +- src/video/directfb/SDL_DirectFB_window.c | 3 +- src/video/windows/SDL_windowswindow.c | 3 +- src/video/x11/SDL_x11window.c | 3 +- 15 files changed, 244 insertions(+), 308 deletions(-) diff --git a/include/SDL_pixels.h b/include/SDL_pixels.h index e112894f0..eb253ec36 100644 --- a/include/SDL_pixels.h +++ b/include/SDL_pixels.h @@ -253,24 +253,20 @@ typedef struct SDL_Color } 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 @@ typedef struct SDL_PixelFormat Uint32 Gmask; Uint32 Bmask; Uint32 Amask; + int refcount; + struct SDL_PixelFormat *next; } SDL_PixelFormat; /** @@ -321,6 +319,16 @@ extern DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, Uint32 Bmask, 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 Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors); /** - * \brief Add a callback function which is called when the palette changes. - * - * \sa SDL_DelPaletteWatch() - */ -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() + * \brief Set the palette for a pixel format structure. */ -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. diff --git a/include/SDL_surface.h b/include/SDL_surface.h index 0d092ae7f..7bbbb0af2 100644 --- a/include/SDL_surface.h +++ b/include/SDL_surface.h @@ -54,6 +54,7 @@ extern "C" { /*@{*/ #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*/ /** diff --git a/src/SDL_compat.c b/src/SDL_compat.c index cabf7747a..8ff4dd861 100644 --- a/src/SDL_compat.c +++ b/src/SDL_compat.c @@ -93,12 +93,7 @@ SDL_GetVideoInfo(void) /* 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 @@ SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags) int w, h; /* We can't resize something we don't have... */ - if (!SDL_VideoWindow) { + if (!SDL_VideoSurface) { return -1; } @@ -396,6 +391,9 @@ SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags) 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 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) /* 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 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) 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 @@ SDL_DisplayFormatAlpha(SDL_Surface * surface) 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; diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index cfb4c23c0..09f97b448 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -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_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface) 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 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface) } } - 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_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface) 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); diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index d77404ff4..df75ac35b 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -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" diff --git a/src/video/SDL_blit.c b/src/video/SDL_blit.c index 346b2e84d..1040d63e2 100644 --- a/src/video/SDL_blit.c +++ b/src/video/SDL_blit.c @@ -221,18 +221,8 @@ SDL_CalculateBlit(SDL_Surface * surface) 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, diff --git a/src/video/SDL_blit.h b/src/video/SDL_blit.h index 2754a79de..7a283da56 100644 --- a/src/video/SDL_blit.h +++ b/src/video/SDL_blit.h @@ -105,7 +105,7 @@ typedef struct SDL_BlitMap /* 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 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface * surface); #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) \ diff --git a/src/video/SDL_bmp.c b/src/video/SDL_bmp.c index 47e4a16a5..82cd4d628 100644 --- a/src/video/SDL_bmp.c +++ b/src/video/SDL_bmp.c @@ -437,17 +437,15 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) /* 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) { diff --git a/src/video/SDL_pixels.c b/src/video/SDL_pixels.c index 2630394c7..e6b920ea6 100644 --- a/src/video/SDL_pixels.c +++ b/src/video/SDL_pixels.c @@ -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 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, } break; case 15: + if (Rmask == 0) { + return SDL_PIXELFORMAT_RGB555; + } if (Rmask == 0x7C00 && Bmask == 0x001F) { return SDL_PIXELFORMAT_RGB555; } @@ -265,6 +262,8 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, break; case 16: switch (Rmask) { + case 0: + return SDL_PIXELFORMAT_RGB565; case 0xF000: return SDL_PIXELFORMAT_RGBA4444; case 0x0F00: @@ -295,6 +294,7 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, break; case 24: switch (Rmask) { + case 0: case 0x00FF0000: #if SDL_BYTEORDER == SDL_BIG_ENDIAN return SDL_PIXELFORMAT_RGB24; @@ -307,10 +307,6 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, #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 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, return SDL_PIXELFORMAT_RGBA8888; } break; + case 0: case 0x00FF0000: if (Amask == 0xFF000000) { return SDL_PIXELFORMAT_ARGB8888; @@ -345,154 +342,58 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, return SDL_PIXELFORMAT_UNKNOWN; } +static SDL_PixelFormat *formats; -SDL_Palette * -SDL_AllocPalette(int ncolors) +SDL_PixelFormat * +SDL_AllocFormat(Uint32 pixel_format) { - SDL_Palette *palette; + SDL_PixelFormat *format; - 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); + 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,35 +462,135 @@ SDL_InitFormat(SDL_PixelFormat * format, int bpp, Uint32 Rmask, Uint32 Gmask, 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; + SDL_PixelFormat *prev; + + 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); } - surface->format_version = format_version; - SDL_InvalidateMap(surface->map); + SDL_free(format); } -/* - * Free a previously allocated format structure - */ -void -SDL_FreeFormat(SDL_PixelFormat * 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; } - SDL_free(format); + if (--palette->refcount > 0) { + return; + } + if (palette->colors) { + SDL_free(palette->colors); + } + SDL_free(palette); } /* @@ -868,7 +869,7 @@ SDL_InvalidateMap(SDL_BlitMap * map) 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 @@ SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) 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 @@ SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) } 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 @@ SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) 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 @@ SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) } } 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)); diff --git a/src/video/SDL_pixels_c.h b/src/video/SDL_pixels_c.h index 657bb7e37..58fe221f8 100644 --- a/src/video/SDL_pixels_c.h +++ b/src/video/SDL_pixels_c.h @@ -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); diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index e18868989..73cca3b60 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -39,10 +39,18 @@ SDL_CreateRGBSurface(Uint32 flags, 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 @@ SDL_CreateRGBSurface(Uint32 flags, 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 @@ SDL_CreateRGBSurface(Uint32 flags, 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_CreateRGBSurface(Uint32 flags, 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 @@ SDL_CreateRGBSurfaceFrom(void *pixels, 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 @@ SDL_LowerBlit(SDL_Surface * src, SDL_Rect * srcrect, { /* 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 @@ SDL_CreateSurfaceOnStack(int width, int height, Uint32 pixel_format, 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 @@ SDL_CreateSurfaceOnStack(int width, int height, Uint32 pixel_format, 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 @@ SDL_FreeSurface(SDL_Surface * surface) if (surface == NULL) { return; } + if (surface->flags & SDL_DONTFREE) { + return; + } if (--surface->refcount > 0) { return; } diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index be95910ce..23472fc44 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -208,7 +208,7 @@ static int 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 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) /* 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 @@ SDL_GetWindowSurface(SDL_Window * window) 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_DestroyWindow(SDL_Window * window) SDL_UpdateFullscreenMode(window, SDL_FALSE); if (window->surface) { - window->surface->refcount = 0; + window->surface->flags &= ~SDL_DONTFREE; SDL_FreeSurface(window->surface); } if (_this->DestroyWindowFramebuffer) { diff --git a/src/video/directfb/SDL_DirectFB_window.c b/src/video/directfb/SDL_DirectFB_window.c index 2de921ef9..43bfe5fbd 100644 --- a/src/video/directfb/SDL_DirectFB_window.c +++ b/src/video/directfb/SDL_DirectFB_window.c @@ -220,8 +220,7 @@ DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) 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; diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index bf6db3be4..c6c4c847a 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -332,8 +332,7 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) 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 */ diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index e21ccdfba..241991762 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -666,8 +666,7 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) 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;