SDL: Vita: Implement command batching

From 848d7b12542070e7050972587f58ae8620a42afe Mon Sep 17 00:00:00 2001
From: Ivan Epifanov <[EMAIL REDACTED]>
Date: Tue, 2 Nov 2021 16:12:55 +0300
Subject: [PATCH] Vita: Implement command batching

---
 src/render/vitagxm/SDL_render_vita_gxm.c | 102 +++++++++++------------
 1 file changed, 47 insertions(+), 55 deletions(-)

diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c
index dae1211908..fed4bb4862 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm.c
+++ b/src/render/vitagxm/SDL_render_vita_gxm.c
@@ -89,10 +89,6 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
 
 static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
 
-static int VITA_GXM_RenderDrawPoints(SDL_Renderer *renderer, const SDL_RenderCommand *cmd);
-
-static int VITA_GXM_RenderDrawLines(SDL_Renderer *renderer, const SDL_RenderCommand *cmd);
-
 static int VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
 
 static int VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
@@ -462,10 +458,9 @@ VITA_GXM_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const
 
     int color = data->drawstate.color;
 
-    color_vertex *vertex = (color_vertex *)pool_memalign(
+    color_vertex *vertex = (color_vertex *)pool_malloc(
         data,
-        count * sizeof(color_vertex),
-        sizeof(color_vertex)
+        count * sizeof(color_vertex)
     );
 
     cmd->data.draw.first = (size_t)vertex;
@@ -487,10 +482,9 @@ VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const S
     VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
     int color = data->drawstate.color;
 
-    color_vertex *vertex = (color_vertex *)pool_memalign(
+    color_vertex *vertex = (color_vertex *)pool_malloc(
         data,
-        (count-1) * 2 * sizeof(color_vertex),
-        sizeof(color_vertex)
+        (count-1) * 2 * sizeof(color_vertex)
     );
 
     cmd->data.draw.first = (size_t)vertex;
@@ -526,10 +520,9 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
     if (texture) {
         texture_vertex *vertices;
 
-        vertices = (texture_vertex *)pool_memalign(
+        vertices = (texture_vertex *)pool_malloc(
                 data,
-                count * sizeof(texture_vertex),
-                sizeof(texture_vertex));
+                count * sizeof(texture_vertex));
 
         if (!vertices) {
             return -1;
@@ -567,10 +560,9 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
     } else {
         color_vertex *vertices;
 
-        vertices = (color_vertex *)pool_memalign(
+        vertices = (color_vertex *)pool_malloc(
                 data,
-                count * sizeof(color_vertex),
-                sizeof(color_vertex));
+                count * sizeof(color_vertex));
 
         if (!vertices) {
             return -1;
@@ -638,30 +630,6 @@ VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
 }
 
 
-static int
-VITA_GXM_RenderDrawPoints(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
-{
-    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
-
-    sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_POINT);
-    sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_POINTS, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, cmd->data.draw.count);
-    sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL);
-
-    return 0;
-}
-
-static int
-VITA_GXM_RenderDrawLines(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
-{
-    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
-
-    sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_LINE);
-    sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_LINES, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, cmd->data.draw.count);
-    sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL);
-    return 0;
-}
-
-
 static int
 SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
 {
@@ -823,18 +791,6 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
                 break;
             }
 
-            case SDL_RENDERCMD_DRAW_POINTS: {
-                SetDrawState(data, cmd);
-                VITA_GXM_RenderDrawPoints(renderer, cmd);
-                break;
-            }
-
-            case SDL_RENDERCMD_DRAW_LINES: {
-                SetDrawState(data, cmd);
-                VITA_GXM_RenderDrawLines(renderer, cmd);
-                break;
-            }
-
             case SDL_RENDERCMD_FILL_RECTS: /* unused */
                 break;
 
@@ -844,19 +800,55 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
             case SDL_RENDERCMD_COPY_EX: /* unused */
                 break;
 
+            case SDL_RENDERCMD_DRAW_POINTS:
+            case SDL_RENDERCMD_DRAW_LINES:
             case SDL_RENDERCMD_GEOMETRY: {
-                SDL_Texture *texture = cmd->data.draw.texture;
+                SDL_Texture *thistexture = cmd->data.draw.texture;
+                SDL_BlendMode thisblend = cmd->data.draw.blend;
+                const SDL_RenderCommandType thiscmdtype = cmd->command;
+                SDL_RenderCommand *finalcmd = cmd;
+                SDL_RenderCommand *nextcmd = cmd->next;
+                size_t count = cmd->data.draw.count;
                 int ret;
+                while (nextcmd != NULL) {
+                    const SDL_RenderCommandType nextcmdtype = nextcmd->command;
+                    if (nextcmdtype != thiscmdtype) {
+                        break;  /* can't go any further on this draw call, different render command up next. */
+                    } else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) {
+                        break;  /* can't go any further on this draw call, different texture/blendmode copy up next. */
+                    } else {
+                        finalcmd = nextcmd;  /* we can combine copy operations here. Mark this one as the furthest okay command. */
+                        count += cmd->data.draw.count;
+                    }
+                    nextcmd = nextcmd->next;
+                }
 
-                if (texture) {
+                if (thistexture) {
                     ret = SetCopyState(renderer, cmd);
                 } else {
                     ret = SetDrawState(data, cmd);
                 }
 
                 if (ret == 0) {
-                    sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, cmd->data.draw.count);
+                    int op = SCE_GXM_PRIMITIVE_TRIANGLES;
+
+                    if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
+                        sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_POINT);
+                        op = SCE_GXM_PRIMITIVE_POINTS;
+                    } else if (thiscmdtype == SDL_RENDERCMD_DRAW_LINES) {
+                        sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_LINE);
+                        op = SCE_GXM_PRIMITIVE_LINES;
+                    }
+
+                    sceGxmDraw(data->gxm_context, op, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, count);
+
+                    if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS || thiscmdtype == SDL_RENDERCMD_DRAW_LINES) {
+                        sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL);
+                    }
+
                 }
+
+                cmd = finalcmd;  /* skip any copy commands we just combined in here. */
                 break;
             }