SDL: Update colors in SDL_RenderGeometryRaw() if we're doing interpolation in linear space

From 12c31898c1d179cd5e05c3b9b8706fb4e54d73eb Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 31 Jan 2024 10:48:02 -0800
Subject: [PATCH] Update colors in SDL_RenderGeometryRaw() if we're doing
 interpolation in linear space

Testing: Modified testgeometry to clear the background to 0.5 and then changed the triangle color to 0.5, and verified that they were the same color when using the D3D11 renderer.
---
 src/render/SDL_render.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index 6500650c295a..12e2d942868a 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -4030,6 +4030,8 @@ int SDL_RenderGeometryRaw(SDL_Renderer *renderer,
     int i;
     int retval = 0;
     int count = indices ? num_indices : num_vertices;
+    SDL_bool isstack = SDL_FALSE;
+    SDL_FColor *updated_colors = NULL;
 
     CHECK_RENDERER_MAGIC(renderer, -1);
 
@@ -4122,6 +4124,24 @@ int SDL_RenderGeometryRaw(SDL_Renderer *renderer,
                                         indices, num_indices, size_indices);
     }
 
+    /* Transform the colors if necessary */
+    if (renderer->colorspace_conversion &&
+        SDL_COLORSPACETRANSFER(renderer->input_colorspace) == SDL_TRANSFER_CHARACTERISTICS_SRGB) {
+        int num_colors = (color_stride > 0) ? num_vertices : 1;
+        updated_colors = SDL_small_alloc(SDL_FColor, num_colors, &isstack);
+        if (!updated_colors) {
+            return -1;
+        }
+        for (i = 0; i < num_colors; ++i) {
+            updated_colors[i] = *(const SDL_FColor *)(((const Uint8 *)color) + i * color_stride);
+            SDL_ConvertToLinear(renderer, &updated_colors[i]);
+        }
+        color = updated_colors;
+        if (color_stride > 0) {
+            color_stride = sizeof(SDL_FColor);
+        }
+    }
+
     retval = QueueCmdGeometry(renderer, texture,
                               xy, xy_stride, color, color_stride, uv, uv_stride,
                               num_vertices,
@@ -4129,6 +4149,10 @@ int SDL_RenderGeometryRaw(SDL_Renderer *renderer,
                               renderer->view->scale.x,
                               renderer->view->scale.y);
 
+    if (updated_colors) {
+        SDL_small_free(updated_colors, isstack);
+    }
+
     return retval;
 }