sdl12-compat: Handle SDL12_Surface::refcount in SDL_FreeSurface

From 201670ec0a3324fd959acf6dadda51bd8041b3f8 Mon Sep 17 00:00:00 2001
From: David Gow <[EMAIL REDACTED]>
Date: Wed, 9 Mar 2022 21:29:50 +0800
Subject: [PATCH] Handle SDL12_Surface::refcount in SDL_FreeSurface

SDL_Surface has a refcount field, and surfaces shouldn't be destroyed
until it's zero.

Confusingly, in sdl12-compat, there are two refcount fields: one for the
SDL 1.2 surface, and one for the SDL 2.0 surface used to implement it.

There are two ways this could be implemented:
1) Keep the SDL12_Surface and SDL20_Surface refcounts synchronised
   across every call into SDL2.
2) Completely separate the refcounts.

This implements option 2: the SDL12_Surface's refcount is set to 1 when
created, not to be equal to the SDL2 surface's refcount. We then
decrement this and free it as required.

This is safe for two reasons:
- As long as the 1.2 surface's refcount is > 0, there must be at least
  one reference to the 2.0 surface.
- It turns out nothing in SDL 2 is actually using the SDL 2 surface

This makes "frogatto"[1] not crash on startup with a double-free of
SDL_Surfaces, as it makes heavy use of the SDL 1.2 refcount field[2].

 src/SDL12_compat.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index 733ece6..3677856 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -4325,6 +4325,9 @@ DECLSPEC void SDLCALL
 SDL_FreeSurface(SDL12_Surface *surface12)
     if (surface12 && (surface12 != VideoSurface12)) {
+        surface12->refcount--;
+        if (surface12->refcount)
+            return;
         if (surface12->format) {