Skip to content

Software Renderer is missing palettes for Scaled/Rotation #14422

@jroatch

Description

@jroatch

Much like in #14419 I notice this with 08-rotating-textures and 09-scaling-textures examples where the paletted sample.png causes those examples to not render, 09-scaling-textures only being broken when clipping with the viewport.
I had just assumed they also used geometry renderer commands internally, which if that were so (by setting renderer->QueueCopy and renderer->QueueCopyEx to NULL) the geometry palette fix would work.

After a bit of poking around I saw that an internal clone needs to have the source surface palette, and maybe that the temporary copy scaling surface sould be the destination format instead of the (possibly paletted) source format.

I really don't know how to navigate github to make a "pull request" out of it so here's a diff

--- a/src/render/software/SDL_render_sw.c
+++ b/src/render/software/SDL_render_sw.c
@@ -401,6 +401,13 @@ static bool SW_RenderCopyEx(SDL_Renderer *renderer, SDL_Surface *surface, SDL_Te
         return false;
     }
 
+    if (SDL_ISPIXELFORMAT_INDEXED(src->format)) {
+               SDL_Palette *clone_palette = SDL_GetSurfacePalette(src);
+        if (!SDL_SetSurfacePalette(src_clone, clone_palette)) {
+            return false;
+        }
+    }
+
     SDL_GetSurfaceBlendMode(src, &blendmode);
     SDL_GetSurfaceAlphaMod(src, &alphaMod);
     SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod);
@@ -880,7 +887,7 @@ static bool SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
 
                 // Prevent to do scaling + clipping on viewport boundaries as it may lose proportion
                 if (dstrect->x < 0 || dstrect->y < 0 || dstrect->x + dstrect->w > surface->w || dstrect->y + dstrect->h > surface->h) {
-                    SDL_Surface *tmp = SDL_CreateSurface(dstrect->w, dstrect->h, src->format);
+                    SDL_Surface *tmp = SDL_CreateSurface(dstrect->w, dstrect->h, surface->format);
                     // Scale to an intermediate surface, then blit
                     if (tmp) {
                         SDL_Rect r;

This is not a complete fix as I also notice huge CPU spikes with the cliprect example and when Logical Presentation draws clipped large scaled bitmaps. CPU spikes larger then if sample.png were a RGB image, and was present before applying this diff. I don't know where that clipping issue may be, and it's possible that using the destination format for the temporary surface made CPU usage worse.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions