Переглянути джерело

Set the texture palette before setting pixel data

This is a better fix for https://github.com/libsdl-org/SDL/issues/16227.

The original problem was that the newly created texture didn't have any palette, so when the surface data was set, colors couldn't be mapped to pixel index values. The old fix temporarily set the texture palette to the surface palette, copied the surface data, and then set the texture palette to a copy of the surface palette. This caused Vulkan validation errors because we were deleting the original palette which was still referenced by the active command buffer. Instead, we'll create the palette that we want the texture to have to start with, then copy the surface data once that's set.
Sam Lantinga 1 тиждень тому
батько
коміт
a55e059f84
1 змінених файлів з 15 додано та 17 видалено
  1. 15 17
      src/render/SDL_render.c

+ 15 - 17
src/render/SDL_render.c

@@ -1700,8 +1700,22 @@ SDL_Texture *SDL_CreateTexture(SDL_Renderer *renderer, SDL_PixelFormat format, S
 
 
 static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, SDL_Surface *surface)
 static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, SDL_Surface *surface)
 {
 {
-    bool direct_update;
+    if (SDL_ISPIXELFORMAT_INDEXED(texture->format) && surface->palette) {
+        // Copy the palette to the new texture
+        SDL_Palette *existing = surface->palette;
+        SDL_Palette *palette = SDL_CreatePalette(existing->ncolors);
+        if (palette &&
+            SDL_SetPaletteColors(palette, existing->colors, 0, existing->ncolors) &&
+            SDL_SetTexturePalette(texture, palette)) {
+            // The texture has a reference to the palette now
+            SDL_DestroyPalette(palette);
+        } else {
+            SDL_DestroyPalette(palette);
+            return false;
+        }
+    }
 
 
+    bool direct_update;
     if (surface->format == texture->format &&
     if (surface->format == texture->format &&
         SDL_GetSurfaceColorspace(surface) == texture->colorspace) {
         SDL_GetSurfaceColorspace(surface) == texture->colorspace) {
         if (SDL_ISPIXELFORMAT_INDEXED(surface->format)) {
         if (SDL_ISPIXELFORMAT_INDEXED(surface->format)) {
@@ -1740,21 +1754,6 @@ static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, S
         }
         }
     }
     }
 
 
-    if (SDL_ISPIXELFORMAT_INDEXED(texture->format) && surface->palette) {
-        // Copy the palette to the new texture
-        SDL_Palette *existing = surface->palette;
-        SDL_Palette *palette = SDL_CreatePalette(existing->ncolors);
-        if (palette &&
-            SDL_SetPaletteColors(palette, existing->colors, 0, existing->ncolors) &&
-            SDL_SetTexturePalette(texture, palette)) {
-            // The texture has a reference to the palette now
-            SDL_DestroyPalette(palette);
-        } else {
-            SDL_DestroyPalette(palette);
-            return false;
-        }
-    }
-
     if (SDL_ISPIXELFORMAT_INDEXED(texture->format) && SDL_SurfaceHasColorKey(surface)) {
     if (SDL_ISPIXELFORMAT_INDEXED(texture->format) && SDL_SurfaceHasColorKey(surface)) {
         Uint32 key;
         Uint32 key;
         SDL_Color col;
         SDL_Color col;
@@ -1885,7 +1884,6 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
     SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
     SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
     SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, surface->w);
     SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, surface->w);
     SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, surface->h);
     SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, surface->h);
-    SDL_SetPointerProperty(props, SDL_PROP_TEXTURE_CREATE_PALETTE_POINTER, surface->palette);
 
 
     texture = SDL_CreateTextureWithProperties(renderer, props);
     texture = SDL_CreateTextureWithProperties(renderer, props);
     SDL_DestroyProperties(props);
     SDL_DestroyProperties(props);