Przeglądaj źródła

Added SDL_aligned_alloc_zero()

Sam Lantinga 1 dzień temu
rodzic
commit
55908f14f8

+ 27 - 1
include/SDL3/SDL_stdinc.h

@@ -1362,7 +1362,9 @@ extern SDL_DECLSPEC SDL_MALLOC void * SDLCALL SDL_malloc(size_t size);
  *
  *
  * If the allocation is successful, the returned pointer is guaranteed to be
  * If the allocation is successful, the returned pointer is guaranteed to be
  * aligned to either the *fundamental alignment* (`alignof(max_align_t)` in
  * aligned to either the *fundamental alignment* (`alignof(max_align_t)` in
- * C11 and later) or `2 * sizeof(void *)`, whichever is smaller.
+ * C11 and later) or `2 * sizeof(void *)`, whichever is smaller. Use
+ * SDL_aligned_alloc_zero() if you need to allocate memory aligned to an
+ * alignment greater than this guarantee.
  *
  *
  * \param nmemb the number of elements in the array.
  * \param nmemb the number of elements in the array.
  * \param size the size of each element of the array.
  * \param size the size of each element of the array.
@@ -1616,6 +1618,30 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_f
  */
  */
 extern SDL_DECLSPEC SDL_MALLOC void * SDLCALL SDL_aligned_alloc(size_t alignment, size_t size);
 extern SDL_DECLSPEC SDL_MALLOC void * SDLCALL SDL_aligned_alloc(size_t alignment, size_t size);
 
 
+/**
+ * Allocate zero-initialized memory aligned to a specific alignment.
+ *
+ * The memory returned by this function must be freed with SDL_aligned_free(),
+ * _not_ SDL_free().
+ *
+ * If `alignment` is less than the size of `void *`, it will be increased to
+ * match that.
+ *
+ * The returned memory address will be a multiple of the alignment value, and
+ * the size of the memory allocated will be a multiple of the alignment value.
+ *
+ * \param alignment the alignment of the memory.
+ * \param size the size to allocate.
+ * \returns a pointer to the aligned memory, or NULL if allocation failed.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.6.0.
+ *
+ * \sa SDL_aligned_free
+ */
+extern SDL_DECLSPEC SDL_MALLOC void * SDLCALL SDL_aligned_alloc_zero(size_t alignment, size_t size);
+
 /**
 /**
  * Free memory allocated by SDL_aligned_alloc().
  * Free memory allocated by SDL_aligned_alloc().
  *
  *

+ 1 - 0
src/dynapi/SDL_dynapi.exports

@@ -1290,3 +1290,4 @@ _SDL_LoadJPG
 _SDL_HasSVE2
 _SDL_HasSVE2
 _SDL_GamepadHasCapSense
 _SDL_GamepadHasCapSense
 _SDL_GetGamepadCapSense
 _SDL_GetGamepadCapSense
+_SDL_aligned_alloc_zero

+ 1 - 0
src/dynapi/SDL_dynapi.sym

@@ -1291,6 +1291,7 @@ SDL3_0.0.0 {
     SDL_HasSVE2;
     SDL_HasSVE2;
     SDL_GamepadHasCapSense;
     SDL_GamepadHasCapSense;
     SDL_GetGamepadCapSense;
     SDL_GetGamepadCapSense;
+    SDL_aligned_alloc_zero;
     # extra symbols go here (don't modify this line)
     # extra symbols go here (don't modify this line)
   local: *;
   local: *;
 };
 };

+ 1 - 0
src/dynapi/SDL_dynapi_overrides.h

@@ -1317,3 +1317,4 @@
 #define SDL_HasSVE2 SDL_HasSVE2_REAL
 #define SDL_HasSVE2 SDL_HasSVE2_REAL
 #define SDL_GamepadHasCapSense SDL_GamepadHasCapSense_REAL
 #define SDL_GamepadHasCapSense SDL_GamepadHasCapSense_REAL
 #define SDL_GetGamepadCapSense SDL_GetGamepadCapSense_REAL
 #define SDL_GetGamepadCapSense SDL_GetGamepadCapSense_REAL
+#define SDL_aligned_alloc_zero SDL_aligned_alloc_zero_REAL

+ 1 - 0
src/dynapi/SDL_dynapi_procs.h

@@ -1325,3 +1325,4 @@ SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadJPG,(const char *a),(a),return)
 SDL_DYNAPI_PROC(bool,SDL_HasSVE2,(void),(),return)
 SDL_DYNAPI_PROC(bool,SDL_HasSVE2,(void),(),return)
 SDL_DYNAPI_PROC(bool,SDL_GamepadHasCapSense,(SDL_Gamepad *a,SDL_GamepadCapSenseType b),(a,b),return)
 SDL_DYNAPI_PROC(bool,SDL_GamepadHasCapSense,(SDL_Gamepad *a,SDL_GamepadCapSenseType b),(a,b),return)
 SDL_DYNAPI_PROC(bool,SDL_GetGamepadCapSense,(SDL_Gamepad *a,SDL_GamepadCapSenseType b),(a,b),return)
 SDL_DYNAPI_PROC(bool,SDL_GetGamepadCapSense,(SDL_Gamepad *a,SDL_GamepadCapSenseType b),(a,b),return)
+SDL_DYNAPI_PROC(void*,SDL_aligned_alloc_zero,(size_t a,size_t b),(a,b),return)

+ 12 - 2
src/stdlib/SDL_stdlib.c

@@ -523,7 +523,7 @@ int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A' + ((x) - 'a'
 int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a' + ((x) - 'A')) : (x); }
 int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a' + ((x) - 'A')) : (x); }
 int SDL_isblank(int x) { return ((x) == ' ') || ((x) == '\t'); }
 int SDL_isblank(int x) { return ((x) == ' ') || ((x) == '\t'); }
 
 
-void *SDL_aligned_alloc(size_t alignment, size_t size)
+static void *SDL_aligned_alloc_internal(size_t alignment, size_t size, bool clear_memory)
 {
 {
     size_t padding;
     size_t padding;
     Uint8 *result = NULL;
     Uint8 *result = NULL;
@@ -537,7 +537,7 @@ void *SDL_aligned_alloc(size_t alignment, size_t size)
     if (SDL_size_add_check_overflow(size, alignment, &size) &&
     if (SDL_size_add_check_overflow(size, alignment, &size) &&
         SDL_size_add_check_overflow(size, sizeof(void *), &size) &&
         SDL_size_add_check_overflow(size, sizeof(void *), &size) &&
         SDL_size_add_check_overflow(size, padding, &size)) {
         SDL_size_add_check_overflow(size, padding, &size)) {
-        void *original = SDL_malloc(size);
+        void *original = clear_memory ? SDL_calloc(1, size) : SDL_malloc(size);
         if (original) {
         if (original) {
             // Make sure we have enough space to store the original pointer
             // Make sure we have enough space to store the original pointer
             result = (Uint8 *)original + sizeof(original);
             result = (Uint8 *)original + sizeof(original);
@@ -557,6 +557,16 @@ void *SDL_aligned_alloc(size_t alignment, size_t size)
     return result;
     return result;
 }
 }
 
 
+void *SDL_aligned_alloc(size_t alignment, size_t size)
+{
+	return SDL_aligned_alloc_internal(alignment, size, false);
+}
+
+void *SDL_aligned_alloc_zero(size_t alignment, size_t size)
+{
+	return SDL_aligned_alloc_internal(alignment, size, true);
+}
+
 void SDL_aligned_free(void *mem)
 void SDL_aligned_free(void *mem)
 {
 {
     if (mem) {
     if (mem) {

+ 10 - 6
src/video/SDL_surface.c

@@ -230,19 +230,23 @@ static SDL_Surface *SDL_CreateSurfaceInternal(int width, int height, SDL_PixelFo
     if (surface->w && surface->h && format != SDL_PIXELFORMAT_MJPG) {
     if (surface->w && surface->h && format != SDL_PIXELFORMAT_MJPG) {
         surface->flags &= ~SDL_SURFACE_PREALLOCATED;
         surface->flags &= ~SDL_SURFACE_PREALLOCATED;
         if (SDL_GetHintBoolean("SDL_SURFACE_MALLOC", false)) {
         if (SDL_GetHintBoolean("SDL_SURFACE_MALLOC", false)) {
-            surface->pixels = SDL_malloc(size);
+            if (clear_surface) {
+                surface->pixels = SDL_calloc(1, size);
+            } else {
+                surface->pixels = SDL_malloc(size);
+            }
         } else {
         } else {
             surface->flags |= SDL_SURFACE_SIMD_ALIGNED;
             surface->flags |= SDL_SURFACE_SIMD_ALIGNED;
-            surface->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), size);
+            if (clear_surface) {
+                surface->pixels = SDL_aligned_alloc_zero(SDL_GetSIMDAlignment(), size);
+            } else {
+                surface->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), size);
+            }
         }
         }
         if (!surface->pixels) {
         if (!surface->pixels) {
             SDL_DestroySurface(surface);
             SDL_DestroySurface(surface);
             return NULL;
             return NULL;
         }
         }
-
-        if (clear_surface) {
-            SDL_memset(surface->pixels, 0, size);
-        }
     }
     }
     return surface;
     return surface;
 }
 }