From 0b2c80557c2ffeac2c9d4b749d75040dc1bd188d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 10 Jul 2024 23:20:51 -0700 Subject: [PATCH] Update the blit mapping when the palette is set on a surface Make sure you do this even if the palette pointer hasn't changed, as the contents may have. Fixes https://github.com/libsdl-org/SDL/issues/10225 --- src/video/SDL_surface.c | 18 ++++++-------- test/testautomation_surface.c | 46 ++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index a92be28cf3..c86f84e722 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -396,18 +396,16 @@ int SDL_SetSurfacePalette(SDL_Surface *surface, SDL_Palette *palette) return SDL_SetError("SDL_SetSurfacePalette() passed a palette that doesn't match the surface format"); } - if (palette == surface->internal->palette) { - return 0; - } + if (palette != surface->internal->palette) { + if (surface->internal->palette) { + SDL_DestroyPalette(surface->internal->palette); + } - if (surface->internal->palette) { - SDL_DestroyPalette(surface->internal->palette); - } + surface->internal->palette = palette; - surface->internal->palette = palette; - - if (surface->internal->palette) { - ++surface->internal->palette->refcount; + if (surface->internal->palette) { + ++surface->internal->palette->refcount; + } } SDL_InvalidateMap(&surface->internal->map); diff --git a/test/testautomation_surface.c b/test/testautomation_surface.c index b5def09c1f..41284587b1 100644 --- a/test/testautomation_surface.c +++ b/test/testautomation_surface.c @@ -852,6 +852,45 @@ static int surface_testFlip(void *arg) return TEST_COMPLETED; } +static int surface_testPalette(void *arg) +{ + SDL_Surface *surface, *output; + SDL_Palette *palette; + Uint8 *pixels; + int offset; + + surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_INDEX8); + SDLTest_AssertCheck(surface != NULL, "SDL_CreateSurface()"); + + output = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_RGBA32); + SDLTest_AssertCheck(output != NULL, "SDL_CreateSurface()"); + + *(Uint8 *)surface->pixels = 255; + + pixels = (Uint8 *)output->pixels; + offset = 0; + + SDL_BlitSurface(surface, NULL, output, NULL); + SDLTest_AssertCheck(pixels[offset] == 0xFF, + "Expected pixels[%d] == 0xFF got 0x%.2X", offset, pixels[offset]); + + /* Set the palette color and blit again */ + palette = SDL_GetSurfacePalette(surface); + SDLTest_AssertCheck(palette != NULL, "Expected palette != NULL, got %p", palette); + if (palette) { + palette->colors[255].r = 0xAA; + } + SDL_SetSurfacePalette(surface, palette); + SDL_BlitSurface(surface, NULL, output, NULL); + SDLTest_AssertCheck(pixels[offset] == 0xAA, + "Expected pixels[%d] == 0xAA got 0x%.2X", offset, pixels[offset]); + + SDL_DestroySurface(surface); + SDL_DestroySurface(output); + + return TEST_COMPLETED; +} + /* ================= Test References ================== */ @@ -915,11 +954,16 @@ static const SDLTest_TestCaseReference surfaceTestFlip = { surface_testFlip, "surface_testFlip", "Test surface flipping.", TEST_ENABLED }; +static const SDLTest_TestCaseReference surfaceTestPalette = { + surface_testPalette, "surface_testPalette", "Test surface palette operations.", TEST_ENABLED +}; + /* Sequence of Surface test cases */ static const SDLTest_TestCaseReference *surfaceTests[] = { &surfaceTest1, &surfaceTest2, &surfaceTest3, &surfaceTest4, &surfaceTest5, &surfaceTest6, &surfaceTest7, &surfaceTest8, &surfaceTest9, &surfaceTest10, - &surfaceTest11, &surfaceTest12, &surfaceTestOverflow, &surfaceTestFlip, NULL + &surfaceTest11, &surfaceTest12, &surfaceTestOverflow, &surfaceTestFlip, + &surfaceTestPalette, NULL }; /* Surface test suite (global) */