Skip to content

Commit

Permalink
Fixed bug 4469 - make SDL_CreateTextureFromSurface pick a more approp…
Browse files Browse the repository at this point in the history
…riate format

Sylvain

Currently SDL_CreateTextureFromSurface picks first valid format, and do a conversion.

    format = renderer->info.texture_formats[0];
    for (i = 0; i < renderer->info.num_texture_formats; ++i) {
        if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
            SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) {
            format = renderer->info.texture_formats[i];
            break;

It could try to find a better format, for instance :

 if SDL_Surface has no Amask, but a colorkey :
   if surface fmt is RGB888, try to pick ARGB8888 renderer fmt
   if surface fmt is BGR888, try to pick ABGR8888 renderer fmt
 else
   try to pick the same renderer format as surface fmt

if no format has been picked, use the fallback.


I think it goes with bug 4290 fastpath BlitNtoN
when you expand a surface with pixel format of size 24 to 32, there is a fast path possible.


So with this issue:

- if you have a surface with colorkey (RGB or BGR, not palette), it takes a renderer format where the conversion is faster.
  (it avoids, if possible, RGB -> ABGR which means switching RGB to BGR)

- if you have a surface ABGR format, it try to take the ABGR from the renderer.
  (it avoids, if possible, ABGR -> ARGB, which means switch RGB to BGR)
  • Loading branch information
slouken committed May 19, 2019
1 parent c377de5 commit 41c718d
Showing 1 changed file with 38 additions and 7 deletions.
45 changes: 38 additions & 7 deletions src/render/SDL_render.c
Expand Up @@ -1189,7 +1189,7 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
SDL_bool needAlpha;
SDL_bool direct_update;
int i;
Uint32 format;
Uint32 format = SDL_PIXELFORMAT_UNKNOWN;
SDL_Texture *texture;

CHECK_RENDERER_MAGIC(renderer, NULL);
Expand Down Expand Up @@ -1218,12 +1218,43 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
}
}

format = renderer->info.texture_formats[0];
for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) {
if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) {
format = renderer->info.texture_formats[i];
break;
/* Try to have the best pixel format for the texture */
/* No alpha, but a colorkey => promote to alpha */
if (!fmt->Amask && SDL_HasColorKey(surface)) {
if (fmt->format == SDL_PIXELFORMAT_RGB888) {
for (i = 0; i < renderer->info.num_texture_formats; ++i) {
if (renderer->info.texture_formats[i] == SDL_PIXELFORMAT_ARGB8888) {
format = SDL_PIXELFORMAT_ARGB8888;
break;
}
}
} else if (fmt->format == SDL_PIXELFORMAT_BGR888) {
for (i = 0; i < renderer->info.num_texture_formats; ++i) {
if (renderer->info.texture_formats[i] == SDL_PIXELFORMAT_ABGR8888) {
format = SDL_PIXELFORMAT_ABGR8888;
break;
}
}
}
} else {
/* Exact match would be fine */
for (i = 0; i < renderer->info.num_texture_formats; ++i) {
if (renderer->info.texture_formats[i] == fmt->format) {
format = fmt->format;
break;
}
}
}

/* Fallback, choose a valid pixel format */
if (format == SDL_PIXELFORMAT_UNKNOWN) {
format = renderer->info.texture_formats[0];
for (i = 0; i < renderer->info.num_texture_formats; ++i) {
if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) {
format = renderer->info.texture_formats[i];
break;
}
}
}

Expand Down

0 comments on commit 41c718d

Please sign in to comment.