SDL: GLES2 backend: cast with SDL_Vertex and SDL_VertexSolid

From 50d49c63edd023107fddb29ebb5ec15def608222 Mon Sep 17 00:00:00 2001
From: Sylvain <[EMAIL REDACTED]>
Date: Thu, 16 Dec 2021 10:52:36 +0100
Subject: [PATCH] GLES2 backend: cast with SDL_Vertex and SDL_VertexSolid

---
 src/render/SDL_sysrender.h              |   7 ++
 src/render/opengles2/SDL_render_gles2.c | 144 ++++++++++++++++--------
 2 files changed, 101 insertions(+), 50 deletions(-)

diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h
index 2c49c1525f8..d3992dd9de1 100644
--- a/src/render/SDL_sysrender.h
+++ b/src/render/SDL_sysrender.h
@@ -107,6 +107,13 @@ typedef struct SDL_RenderCommand
 } SDL_RenderCommand;
 
 
+typedef struct SDL_VertexSolid
+{
+    SDL_FPoint position;
+    SDL_Color  color;
+} SDL_VertexSolid;
+
+
 /* Define the SDL renderer structure */
 struct SDL_Renderer
 {
diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c
index ae495033dfa..167d8ee6f31 100644
--- a/src/render/opengles2/SDL_render_gles2.c
+++ b/src/render/opengles2/SDL_render_gles2.c
@@ -663,8 +663,7 @@ static int
 GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
 {
     const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
-    const size_t vertlen = (2 * sizeof (float) + sizeof (int)) * count;
-    GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
+    SDL_VertexSolid *verts = (SDL_VertexSolid *) SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first);
     int i;
     SDL_Color color;
     color.r = cmd->data.draw.r;
@@ -684,9 +683,10 @@ GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL
 
     cmd->data.draw.count = count;
     for (i = 0; i < count; i++) {
-        *(verts++) = 0.5f + points[i].x;
-        *(verts++) = 0.5f + points[i].y;
-        *((SDL_Color *)verts++) = color;
+        verts->position.y = 0.5f + points[i].x;
+        verts->position.x = 0.5f + points[i].y;
+        verts->color = color;
+        verts++;
     }
 
     return 0;
@@ -698,8 +698,7 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
     const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
     int i;
     GLfloat prevx, prevy;
-    const size_t vertlen = ((2 * sizeof (float)) + sizeof (int)) * count;
-    GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
+    SDL_VertexSolid *verts = (SDL_VertexSolid *) SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first);
     SDL_Color color;
     color.r = cmd->data.draw.r;
     color.g = cmd->data.draw.g;
@@ -721,9 +720,10 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
     /* 0.5f offset to hit the center of the pixel. */
     prevx = 0.5f + points->x;
     prevy = 0.5f + points->y;
-    *(verts++) = prevx;
-    *(verts++) = prevy;
-    *((SDL_Color*)verts++) = color;
+    verts->position.x = prevx;
+    verts->position.y = prevy;
+    verts->color = color;
+    verts++;
 
     /* bump the end of each line segment out a quarter of a pixel, to provoke
        the diamond-exit rule. Without this, you won't just drop the last
@@ -740,9 +740,10 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
         const GLfloat angle = SDL_atan2f(deltay, deltax);
         prevx = xend + (SDL_cosf(angle) * 0.25f);
         prevy = yend + (SDL_sinf(angle) * 0.25f);
-        *(verts++) = prevx;
-        *(verts++) = prevy;
-        *((SDL_Color*)verts++) = color;
+        verts->position.x = prevx;
+        verts->position.y = prevy;
+        verts->color = color;
+        verts++;
     }
 
     return 0;
@@ -757,48 +758,85 @@ GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
     int i;
     const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
     int count = indices ? num_indices : num_vertices;
-    const size_t vertlen = (2 * sizeof (float) + sizeof (int) + (texture ? 2 : 0) * sizeof (float)) * count;
-    GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
-
-    if (!verts) {
-        return -1;
-    }
 
     cmd->data.draw.count = count;
     size_indices = indices ? size_indices : 0;
 
-    for (i = 0; i < count; i++) {
-        int j;
-        float *xy_;
-        SDL_Color col_;
-        if (size_indices == 4) {
-            j = ((const Uint32 *)indices)[i];
-        } else if (size_indices == 2) {
-            j = ((const Uint16 *)indices)[i];
-        } else if (size_indices == 1) {
-            j = ((const Uint8 *)indices)[i];
-        } else {
-            j = i;
+    if (texture) {
+        SDL_Vertex *verts = (SDL_Vertex *) SDL_AllocateRenderVertices(renderer, count * sizeof (*verts), 0, &cmd->data.draw.first);
+        if (!verts) {
+            return -1;
         }
 
-        xy_ = (float *)((char*)xy + j * xy_stride);
-        col_ = *(SDL_Color *)((char*)color + j * color_stride);
+        for (i = 0; i < count; i++) {
+            int j;
+            float *xy_;
+            SDL_Color col_;
+            float *uv_;
+            if (size_indices == 4) {
+                j = ((const Uint32 *)indices)[i];
+            } else if (size_indices == 2) {
+                j = ((const Uint16 *)indices)[i];
+            } else if (size_indices == 1) {
+                j = ((const Uint8 *)indices)[i];
+            } else {
+                j = i;
+            }
+
+            xy_ = (float *)((char*)xy + j * xy_stride);
+            col_ = *(SDL_Color *)((char*)color + j * color_stride);
+            uv_ = (float *)((char*)uv + j * uv_stride);
 
-        *(verts++) = xy_[0] * scale_x;
-        *(verts++) = xy_[1] * scale_y;
+            verts->position.x = xy_[0] * scale_x;
+            verts->position.y = xy_[1] * scale_y;
 
-        if (colorswap) {
-            Uint8 r = col_.r;
-            col_.r = col_.b;
-            col_.b = r;
+            if (colorswap) {
+                Uint8 r = col_.r;
+                col_.r = col_.b;
+                col_.b = r;
+            }
+
+            verts->color = col_;
+            verts->tex_coord.x = uv_[0];
+            verts->tex_coord.y = uv_[1];
+            verts++;
         }
 
-        *((SDL_Color *)verts++) = col_;
+    } else {
+        SDL_VertexSolid *verts = (SDL_VertexSolid *) SDL_AllocateRenderVertices(renderer, count * sizeof (*verts), 0, &cmd->data.draw.first);
+        if (!verts) {
+            return -1;
+        }
 
-        if (texture) {
-            float *uv_ = (float *)((char*)uv + j * uv_stride);
-            *(verts++) = uv_[0];
-            *(verts++) = uv_[1];
+        for (i = 0; i < count; i++) {
+            int j;
+            float *xy_;
+            SDL_Color col_;
+
+            if (size_indices == 4) {
+                j = ((const Uint32 *)indices)[i];
+            } else if (size_indices == 2) {
+                j = ((const Uint16 *)indices)[i];
+            } else if (size_indices == 1) {
+                j = ((const Uint8 *)indices)[i];
+            } else {
+                j = i;
+            }
+
+            xy_ = (float *)((char*)xy + j * xy_stride);
+            col_ = *(SDL_Color *)((char*)color + j * color_stride);
+
+            verts->position.x = xy_[0] * scale_x;
+            verts->position.y = xy_[1] * scale_y;
+
+            if (colorswap) {
+                Uint8 r = col_.r;
+                col_.r = col_.b;
+                col_.b = r;
+            }
+
+            verts->color = col_;
+            verts++;
         }
     }
 
@@ -811,7 +849,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
     SDL_Texture *texture = cmd->data.draw.texture;
     const SDL_BlendMode blend = cmd->data.draw.blend;
     GLES2_ProgramCacheEntry *program;
-    int stride = sizeof (GLfloat) * 2 /* position */ + sizeof (int) /* color */;
+    int stride;
 
     SDL_assert((texture != NULL) == (imgsrc != GLES2_IMAGESOURCE_SOLID));
 
@@ -882,11 +920,14 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
     }
 
     if (texture) {
-        stride += sizeof (GLfloat) * 2; /* tex coord */
+        stride = sizeof(SDL_Vertex);
+    } else {
+        stride = sizeof(SDL_VertexSolid);
     }
 
     if (texture) {
-        data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + sizeof (GLfloat) * (2 + 1)));
+        SDL_Vertex *verts = (SDL_Vertex *) (cmd->data.draw.first);
+        data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *)&verts->tex_coord);
     }
 
     if (GLES2_SelectProgram(data, imgsrc, texture ? texture->w : 0, texture ? texture->h : 0) < 0) {
@@ -918,8 +959,11 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
     }
 
     /* all drawing commands use this */
-    data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) (uintptr_t) cmd->data.draw.first);
-    data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + sizeof (GLfloat) * 2));
+    {
+        SDL_VertexSolid *verts = (SDL_VertexSolid *) (cmd->data.draw.first);
+        data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) &verts->position);
+        data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *) &verts->color);
+    }
 
     return 0;
 }
@@ -1206,7 +1250,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
                 if (ret == 0) {
                     int op = GL_TRIANGLES; /* SDL_RENDERCMD_GEOMETRY */
                     if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
-                        op = GL_POINTS; 
+                        op = GL_POINTS;
                     }
                     data->glDrawArrays(op, 0, (GLsizei) count);
                 }