From 4ee4e49e4904d7472360188343744652167a150d Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Sat, 15 Oct 2022 12:36:07 +0100 Subject: [PATCH] Select the best pixel formats for use in the software renderer --- src/render/software/SDL_render_sw.c | 108 +++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 9 deletions(-) diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index 6ba77d46e..6e54b67c6 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -1011,6 +1011,100 @@ SW_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } +static void +SW_SelectBestFormats(SDL_Renderer *renderer, Uint32 format) +{ + /* Prefer the format used by the framebuffer by default. */ + renderer->info.texture_formats[renderer->info.num_texture_formats++] = format; + + switch (format) { + case SDL_PIXELFORMAT_XRGB4444: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_ARGB4444; + break; + case SDL_PIXELFORMAT_XBGR4444: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_ABGR4444; + break; + case SDL_PIXELFORMAT_ARGB4444: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_XRGB4444; + break; + case SDL_PIXELFORMAT_ABGR4444: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_XBGR4444; + break; + + case SDL_PIXELFORMAT_XRGB1555: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_ARGB1555; + break; + case SDL_PIXELFORMAT_XBGR1555: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_ABGR1555; + break; + case SDL_PIXELFORMAT_ARGB1555: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_XRGB1555; + break; + case SDL_PIXELFORMAT_ABGR1555: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_XBGR1555; + break; + + case SDL_PIXELFORMAT_XRGB8888: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_ARGB8888; + break; + case SDL_PIXELFORMAT_RGBX8888: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_RGBA8888; + break; + case SDL_PIXELFORMAT_XBGR8888: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_ABGR8888; + break; + case SDL_PIXELFORMAT_BGRX8888: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_BGRA8888; + break; + case SDL_PIXELFORMAT_ARGB8888: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_XRGB8888; + break; + case SDL_PIXELFORMAT_RGBA8888: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_RGBX8888; + break; + case SDL_PIXELFORMAT_ABGR8888: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_XBGR8888; + break; + case SDL_PIXELFORMAT_BGRA8888: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_BGRX8888; + break; + } + + /* Ensure that we always have a SDL_PACKEDLAYOUT_8888 format. Having a matching component order increases the + * chances of getting a fast path for blitting. + */ + if (SDL_ISPIXELFORMAT_PACKED(format)) { + if (SDL_PIXELLAYOUT(format) != SDL_PACKEDLAYOUT_8888) { + switch (SDL_PIXELORDER(format)) { + case SDL_PACKEDORDER_BGRX: + case SDL_PACKEDORDER_BGRA: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_BGRX8888; + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_BGRA8888; + break; + case SDL_PACKEDORDER_RGBX: + case SDL_PACKEDORDER_RGBA: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_RGBX8888; + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_RGBA8888; + break; + case SDL_PACKEDORDER_XBGR: + case SDL_PACKEDORDER_ABGR: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_XBGR8888; + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_ABGR8888; + break; + case SDL_PACKEDORDER_XRGB: + case SDL_PACKEDORDER_ARGB: + default: + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_XRGB8888; + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_ARGB8888; + break; + } + } + } else { + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_XRGB8888; + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_ARGB8888; + } +} + SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface * surface) { @@ -1061,6 +1155,8 @@ SW_CreateRendererForSurface(SDL_Surface * surface) renderer->info = SW_RenderDriver.info; renderer->driverdata = data; + SW_SelectBestFormats(renderer, surface->format->format); + SW_ActivateRenderer(renderer); return renderer; @@ -1103,16 +1199,10 @@ SDL_RenderDriver SW_RenderDriver = { { "software", SDL_RENDERER_SOFTWARE | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE, - 8, + 0, { - SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_ABGR8888, - SDL_PIXELFORMAT_RGBA8888, - SDL_PIXELFORMAT_BGRA8888, - SDL_PIXELFORMAT_RGB888, - SDL_PIXELFORMAT_BGR888, - SDL_PIXELFORMAT_RGB565, - SDL_PIXELFORMAT_RGB555 + /* formats filled in later */ + SDL_PIXELFORMAT_UNKNOWN }, 0, 0}