[v2 PATCH vkd3d 2/3] vkd3d-shader: Don't allocate memory for a string buffer ahead of time.

Matteo Bruni mbruni at codeweavers.com
Thu Aug 26 11:05:19 CDT 2021


Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
v2: Initialize string buffers with a small local buffer.

This makes vkd3d_string_buffer_init() provide a fully usable string
buffer without doing dynamic allocations and also preserving the
"buffer is never NULL" invariant. Hopefully not too cumbersome.

 libs/vkd3d-shader/vkd3d_shader_main.c    | 22 +++++++++++-----------
 libs/vkd3d-shader/vkd3d_shader_private.h |  1 +
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index ad862181..f65f9b2f 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -25,12 +25,16 @@ VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG");
 
 void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer)
 {
-    memset(buffer, 0, sizeof(*buffer));
+    buffer->buffer = buffer->local_buffer;
+    buffer->buffer_size = sizeof(buffer->local_buffer);
+    buffer->content_size = 0;
+    memset(buffer->local_buffer, 0, sizeof(buffer->local_buffer));
 }
 
 void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer)
 {
-    vkd3d_free(buffer->buffer);
+    if (buffer->buffer != buffer->local_buffer)
+        vkd3d_free(buffer->buffer);
 }
 
 static void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer)
@@ -42,18 +46,22 @@ static void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer)
 static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int rc)
 {
     unsigned int new_buffer_size = max(buffer->buffer_size * 2, 32);
+    char *new_buffer = buffer->buffer == buffer->local_buffer ? NULL : buffer->buffer;
 
     if (rc >= 0 && rc < buffer->buffer_size - buffer->content_size)
         return true;
 
     while (rc > 0 && (unsigned int)rc >= new_buffer_size - buffer->content_size)
         new_buffer_size *= 2;
-    if (!vkd3d_array_reserve((void **)&buffer->buffer, &buffer->buffer_size, new_buffer_size, 1))
+    if (!vkd3d_array_reserve((void **)&new_buffer, &buffer->buffer_size, new_buffer_size, 1))
     {
         ERR("Failed to grow buffer.\n");
         buffer->buffer[buffer->content_size] = '\0';
         return false;
     }
+    if (buffer->buffer == buffer->local_buffer)
+        memcpy(new_buffer, buffer->local_buffer, buffer->content_size);
+    buffer->buffer = new_buffer;
     return true;
 }
 
@@ -63,9 +71,6 @@ int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *
     va_list a;
     int rc;
 
-    if (!buffer->content_size && !vkd3d_string_buffer_resize(buffer, 32))
-        return -1;
-
     for (;;)
     {
         rem = buffer->buffer_size - buffer->content_size;
@@ -144,11 +149,6 @@ struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_c
         if (!(buffer = vkd3d_malloc(sizeof(*buffer))))
             return NULL;
         vkd3d_string_buffer_init(buffer);
-        if (!vkd3d_string_buffer_resize(buffer, 1))
-        {
-            vkd3d_free(buffer);
-            return NULL;
-        }
     }
     else
     {
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 54ac5326..5679e940 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -894,6 +894,7 @@ struct vkd3d_string_buffer
     char *buffer;
     unsigned int buffer_size;
     unsigned int content_size;
+    char local_buffer[16];
 };
 
 struct vkd3d_string_buffer_cache
-- 
2.26.3




More information about the wine-devel mailing list