mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-29 04:21:03 +08:00
Copy the palette instead of referencing it when creating a texture
Fixes https://github.com/libsdl-org/SDL/issues/14213
This commit is contained in:
+33
-23
@@ -1686,7 +1686,6 @@ static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, S
|
|||||||
bool direct_update;
|
bool direct_update;
|
||||||
|
|
||||||
if (surface->format == texture->format &&
|
if (surface->format == texture->format &&
|
||||||
surface->palette == texture->public_palette &&
|
|
||||||
SDL_GetSurfaceColorspace(surface) == texture->colorspace) {
|
SDL_GetSurfaceColorspace(surface) == texture->colorspace) {
|
||||||
if (SDL_ISPIXELFORMAT_ALPHA(surface->format) && SDL_SurfaceHasColorKey(surface)) {
|
if (SDL_ISPIXELFORMAT_ALPHA(surface->format) && SDL_SurfaceHasColorKey(surface)) {
|
||||||
/* Surface and Renderer formats are identical.
|
/* Surface and Renderer formats are identical.
|
||||||
@@ -1721,6 +1720,21 @@ static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (texture->format == surface->format && surface->palette) {
|
||||||
|
// Copy the palette to the new texture
|
||||||
|
SDL_Palette *existing = surface->palette;
|
||||||
|
SDL_Palette *palette = SDL_CreatePalette(existing->ncolors);
|
||||||
|
if (palette &&
|
||||||
|
SDL_SetPaletteColors(palette, existing->colors, 0, existing->ncolors) &&
|
||||||
|
SDL_SetTexturePalette(texture, palette)) {
|
||||||
|
// The texture has a reference to the palette now
|
||||||
|
SDL_DestroyPalette(palette);
|
||||||
|
} else {
|
||||||
|
SDL_DestroyPalette(palette);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Uint8 r, g, b, a;
|
Uint8 r, g, b, a;
|
||||||
SDL_BlendMode blendMode;
|
SDL_BlendMode blendMode;
|
||||||
@@ -1745,10 +1759,8 @@ static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, S
|
|||||||
|
|
||||||
SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *surface)
|
SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *surface)
|
||||||
{
|
{
|
||||||
bool needAlpha;
|
|
||||||
int i;
|
int i;
|
||||||
SDL_PixelFormat format = SDL_PIXELFORMAT_UNKNOWN;
|
SDL_PixelFormat format = SDL_PIXELFORMAT_UNKNOWN;
|
||||||
SDL_Palette *palette;
|
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
SDL_PropertiesID props;
|
SDL_PropertiesID props;
|
||||||
SDL_Colorspace surface_colorspace = SDL_COLORSPACE_UNKNOWN;
|
SDL_Colorspace surface_colorspace = SDL_COLORSPACE_UNKNOWN;
|
||||||
@@ -1761,23 +1773,6 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// See what the best texture format is
|
|
||||||
if (SDL_ISPIXELFORMAT_ALPHA(surface->format) || SDL_SurfaceHasColorKey(surface)) {
|
|
||||||
needAlpha = true;
|
|
||||||
} else {
|
|
||||||
needAlpha = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If palette contains alpha values, promotes to alpha format
|
|
||||||
palette = SDL_GetSurfacePalette(surface);
|
|
||||||
if (palette) {
|
|
||||||
bool is_opaque, has_alpha_channel;
|
|
||||||
SDL_DetectPalette(palette, &is_opaque, &has_alpha_channel);
|
|
||||||
if (!is_opaque) {
|
|
||||||
needAlpha = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to have the best pixel format for the texture
|
// Try to have the best pixel format for the texture
|
||||||
// No alpha, but a colorkey => promote to alpha
|
// No alpha, but a colorkey => promote to alpha
|
||||||
if (!SDL_ISPIXELFORMAT_ALPHA(surface->format) && SDL_SurfaceHasColorKey(surface)) {
|
if (!SDL_ISPIXELFORMAT_ALPHA(surface->format) && SDL_SurfaceHasColorKey(surface)) {
|
||||||
@@ -1830,6 +1825,24 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
|||||||
// Fallback, choose a valid pixel format
|
// Fallback, choose a valid pixel format
|
||||||
if (format == SDL_PIXELFORMAT_UNKNOWN) {
|
if (format == SDL_PIXELFORMAT_UNKNOWN) {
|
||||||
format = renderer->texture_formats[0];
|
format = renderer->texture_formats[0];
|
||||||
|
|
||||||
|
// See what the best texture format is
|
||||||
|
bool needAlpha;
|
||||||
|
if (SDL_ISPIXELFORMAT_ALPHA(surface->format) || SDL_SurfaceHasColorKey(surface)) {
|
||||||
|
needAlpha = true;
|
||||||
|
} else {
|
||||||
|
needAlpha = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If palette contains alpha values, promotes to alpha format
|
||||||
|
if (surface->palette) {
|
||||||
|
bool is_opaque, has_alpha_channel;
|
||||||
|
SDL_DetectPalette(surface->palette, &is_opaque, &has_alpha_channel);
|
||||||
|
if (!is_opaque) {
|
||||||
|
needAlpha = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < renderer->num_texture_formats; ++i) {
|
for (i = 0; i < renderer->num_texture_formats; ++i) {
|
||||||
if (!SDL_ISPIXELFORMAT_FOURCC(renderer->texture_formats[i]) &&
|
if (!SDL_ISPIXELFORMAT_FOURCC(renderer->texture_formats[i]) &&
|
||||||
SDL_ISPIXELFORMAT_ALPHA(renderer->texture_formats[i]) == needAlpha) {
|
SDL_ISPIXELFORMAT_ALPHA(renderer->texture_formats[i]) == needAlpha) {
|
||||||
@@ -1865,9 +1878,6 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
|||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, surface->w);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, surface->w);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, surface->h);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, surface->h);
|
||||||
if (format == surface->format && palette) {
|
|
||||||
SDL_SetPointerProperty(props, SDL_PROP_TEXTURE_CREATE_PALETTE_POINTER, palette);
|
|
||||||
}
|
|
||||||
texture = SDL_CreateTextureWithProperties(renderer, props);
|
texture = SDL_CreateTextureWithProperties(renderer, props);
|
||||||
SDL_DestroyProperties(props);
|
SDL_DestroyProperties(props);
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
|
|||||||
Reference in New Issue
Block a user