From f4936d10d6ccc64f2e9ae0d1729fb08417e58911 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 4 Jun 2026 18:11:27 -0400 Subject: [PATCH] hints: Add SDL_HINT_CREATE_SURFACE_CLEAR. This also tries to use SDL_calloc instead of SDL_malloc in the no-SIMD-align path, in case the system offers a faster way to obtain zero'd bytes through calloc. Fixes #15715. Closes #15736. --- include/SDL3/SDL_hints.h | 23 +++++++++++++++++++++++ src/video/SDL_surface.c | 14 ++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index d23577fa8c..7759e8aa34 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -702,6 +702,29 @@ extern "C" { */ #define SDL_HINT_CPU_FEATURE_MASK "SDL_CPU_FEATURE_MASK" +/** + * A variable that decides whether SDL_CreateSurface() clears pixels. + * + * By default, SDL_CreateSurface() will clear the newly-created surface by + * setting all bytes of its `pixels` buffer to zero; for many formats this + * clears the surface black, as a reasonable default. + * + * However, clearing the surface is wasted effort if the app plans to + * initialize the entire surface immediately after creation. Disabling this + * hint leaves the newly-allocated buffer of pixels uninitialized, and the + * app will be responsible for setting every pixel before its first use. + * + * The variable can be set to the following values: + * + * - "0": Surface pixels will _not_ be initialized during creation. + * - "1": Surface pixels will be zeroed during creation. (default) + * + * This hint can be set anytime, affecting later calls to SDL_CreateSurface(). + * + * \since This hint is available since SDL 3.6.0. + */ +#define SDL_HINT_CREATE_SURFACE_CLEAR "SDL_CREATE_SURFACE_CLEAR" + /** * A variable controlling whether DirectInput should be used for controllers. * diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index d38d9a48ce..592441f396 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -228,9 +228,15 @@ SDL_Surface *SDL_CreateSurface(int width, int height, SDL_PixelFormat format) } if (surface->w && surface->h && format != SDL_PIXELFORMAT_MJPG) { + bool must_clear = SDL_GetHintBoolean(SDL_HINT_CREATE_SURFACE_CLEAR, true); surface->flags &= ~SDL_SURFACE_PREALLOCATED; if (SDL_GetHintBoolean("SDL_SURFACE_MALLOC", false)) { - surface->pixels = SDL_malloc(size); + if (must_clear) { + surface->pixels = SDL_calloc(1, size); + must_clear = false; // SDL_calloc already did it, don't memset again, below. + } else { + surface->pixels = SDL_malloc(size); + } } else { surface->flags |= SDL_SURFACE_SIMD_ALIGNED; surface->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), size); @@ -239,9 +245,9 @@ SDL_Surface *SDL_CreateSurface(int width, int height, SDL_PixelFormat format) SDL_DestroySurface(surface); return NULL; } - - // This is important for bitmaps - SDL_memset(surface->pixels, 0, size); + if (must_clear) { + SDL_memset(surface->pixels, 0, size); + } } return surface; }