Make sure the blit mapping is cleared when undoing RLE encoding

This fixes a crash if a surface is RLE encoded, then locked and unlocked.

We also mark the surface as no longer needing to be locked after undoing RLE encoding
This commit is contained in:
Sam Lantinga
2025-11-08 15:24:49 -08:00
parent 089dc86bcf
commit 704ac98d3f
2 changed files with 8 additions and 2 deletions

View File

@@ -89,6 +89,7 @@
#include "SDL_sysvideo.h" #include "SDL_sysvideo.h"
#include "SDL_surface_c.h" #include "SDL_surface_c.h"
#include "SDL_pixels_c.h"
#include "SDL_RLEaccel_c.h" #include "SDL_RLEaccel_c.h"
#define PIXEL_COPY(to, from, len, bpp) \ #define PIXEL_COPY(to, from, len, bpp) \
@@ -1385,6 +1386,8 @@ void SDL_UnRLESurface(SDL_Surface *surface)
SDL_free(surface->map.data); SDL_free(surface->map.data);
surface->map.data = NULL; surface->map.data = NULL;
SDL_InvalidateMap(&surface->map);
SDL_UpdateSurfaceLockFlag(surface); SDL_UpdateSurfaceLockFlag(surface);
} }
} }

View File

@@ -50,7 +50,9 @@ bool SDL_SurfaceValid(SDL_Surface *surface)
void SDL_UpdateSurfaceLockFlag(SDL_Surface *surface) void SDL_UpdateSurfaceLockFlag(SDL_Surface *surface)
{ {
if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) { // We need to mark the surface as needing unlock while locked
if ((surface->flags & SDL_SURFACE_LOCKED) ||
(surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL)) {
surface->flags |= SDL_SURFACE_LOCK_NEEDED; surface->flags |= SDL_SURFACE_LOCK_NEEDED;
} else { } else {
surface->flags &= ~SDL_SURFACE_LOCK_NEEDED; surface->flags &= ~SDL_SURFACE_LOCK_NEEDED;
@@ -1726,7 +1728,6 @@ bool SDL_LockSurface(SDL_Surface *surface)
// Perform the lock // Perform the lock
if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) { if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) {
SDL_UnRLESurface(surface); SDL_UnRLESurface(surface);
surface->flags |= SDL_SURFACE_LOCK_NEEDED;
} }
#endif #endif
} }
@@ -1734,6 +1735,7 @@ bool SDL_LockSurface(SDL_Surface *surface)
// Increment the surface lock count, for recursive locks // Increment the surface lock count, for recursive locks
++surface->locked; ++surface->locked;
surface->flags |= SDL_SURFACE_LOCKED; surface->flags |= SDL_SURFACE_LOCKED;
SDL_UpdateSurfaceLockFlag(surface);
// Ready to go.. // Ready to go..
return true; return true;
@@ -1754,6 +1756,7 @@ void SDL_UnlockSurface(SDL_Surface *surface)
} }
surface->flags &= ~SDL_SURFACE_LOCKED; surface->flags &= ~SDL_SURFACE_LOCKED;
SDL_UpdateSurfaceLockFlag(surface);
} }
static bool SDL_FlipSurfaceHorizontal(SDL_Surface *surface) static bool SDL_FlipSurfaceHorizontal(SDL_Surface *surface)