[Scummvm-git-logs] scummvm master -> 2ed690b9a6104159c1d40d7a16019f85e07703e7

lephilousophe noreply at scummvm.org
Sun Jul 6 17:02:05 UTC 2025


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
be9a106da7 COMMON: Add utility functions for rotating 32-bit integers
f377815eb6 GRAPHICS: Add fast paths for converting between 32-bit pixel formats
8eb0dcba6c OPENGL: Remove TextureSurfaceRGBA8888Swap
324ccbb274 GRAPHICS: Allow fast blit functions to be stored for repeated use
2ed690b9a6 GRAPHICS: Check bytes per pixel before looking up fast blit routines


Commit: be9a106da761e2a5f38a32f0ce03433ceb6b5d2f
    https://github.com/scummvm/scummvm/commit/be9a106da761e2a5f38a32f0ce03433ceb6b5d2f
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2025-07-06T19:02:01+02:00

Commit Message:
COMMON: Add utility functions for rotating 32-bit integers

Changed paths:
    common/util.h


diff --git a/common/util.h b/common/util.h
index f4a1933b650..ea1fdcb4e0e 100644
--- a/common/util.h
+++ b/common/util.h
@@ -83,6 +83,16 @@ template<typename T> inline T CLIP(T v, T amin, T amax)
  */
 template<typename T> inline void SWAP(T &a, T &b) { T tmp = a; a = b; b = tmp; }
 
+/** Function to rotate the 32-bit integer @p x left by @p r bits */
+static inline uint32 ROTATE_LEFT_32(const uint32 x, const uint32 r) {
+	return (x >> (32 - r)) | (x << r);
+}
+
+/** Function to rotate the 32-bit integer @p x right by @p bits */
+static inline uint32 ROTATE_RIGHT_32(const uint32 x, const uint32 r) {
+	return (x << (32 - r)) | (x >> r);
+}
+
 #ifdef ARRAYSIZE
 #undef ARRAYSIZE
 #endif


Commit: f377815eb6d460b5791cc6bc6f0039937c3d30ad
    https://github.com/scummvm/scummvm/commit/f377815eb6d460b5791cc6bc6f0039937c3d30ad
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2025-07-06T19:02:01+02:00

Commit Message:
GRAPHICS: Add fast paths for converting between 32-bit pixel formats

Changed paths:
  A graphics/blit/blit-fast.cpp
    graphics/blit/blit.cpp
    graphics/module.mk


diff --git a/graphics/blit/blit-fast.cpp b/graphics/blit/blit-fast.cpp
new file mode 100644
index 00000000000..f2bcd91b194
--- /dev/null
+++ b/graphics/blit/blit-fast.cpp
@@ -0,0 +1,102 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "graphics/blit.h"
+#include "graphics/pixelformat.h"
+#include "common/endian.h"
+
+namespace Graphics {
+
+namespace {
+
+template<bool bswap, int rotate>
+static void swapBlit(byte *dst, const byte *src, const uint w, const uint h,
+							const uint srcDelta, const uint dstDelta) {
+	for (uint y = 0; y < h; ++y) {
+		for (uint x = 0; x < w; ++x) {
+			uint32 col = *(const uint32 *)src;
+
+			if (bswap)
+				col = SWAP_BYTES_32(col);
+			if (rotate != 0)
+				col = ROTATE_RIGHT_32(col, rotate);
+
+			*(uint32 *)dst = col;
+
+			src += sizeof(uint32);
+			dst += sizeof(uint32);
+		}
+		src += srcDelta;
+		dst += dstDelta;
+	}
+}
+
+} // End of anonymous namespace
+
+// TODO: Add fast 24<->32bpp conversion
+// TODO: Add fast 16<->16bpp conversion
+static const struct {
+	void(*func)(byte *, const byte *, const uint, const uint, const uint, const uint);
+	Graphics::PixelFormat srcFmt, dstFmt;
+} fastBlitFuncs[] = {
+	// 32-bit byteswap
+	{ swapBlit<true,   0>, Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24), Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0) }, // ABGR8888 -> RGBA8888
+	{ swapBlit<true,   0>, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0), Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24) }, // RGBA8888 -> ABGR8888
+	{ swapBlit<true,   0>, Graphics::PixelFormat(4, 8, 8, 8, 8, 16,  8,  0, 24), Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0) }, // ARGB8888 -> BGRA8888
+	{ swapBlit<true,   0>, Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0), Graphics::PixelFormat(4, 8, 8, 8, 8, 16,  8,  0, 24) }, // BGRA8888 -> ARGB8888
+
+	// 32-bit rotate right
+	{ swapBlit<false,  8>, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0), Graphics::PixelFormat(4, 8, 8, 8, 8, 16,  8,  0, 24) }, // RGBA8888 -> ARGB8888
+	{ swapBlit<false,  8>, Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0), Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24) }, // BGRA8888 -> ABGR8888
+
+	// 32-bit rotate left
+	{ swapBlit<false, 24>, Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24), Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0) }, // ABGR8888 -> BGRA8888
+	{ swapBlit<false, 24>, Graphics::PixelFormat(4, 8, 8, 8, 8, 16,  8,  0, 24), Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0) }, // ARGB8888 -> RGBA8888
+
+	// 32-bit byteswap and rotate right
+	{ swapBlit<true,   8>, Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24), Graphics::PixelFormat(4, 8, 8, 8, 8, 16,  8,  0, 24) }, // ABGR8888 -> ARGB8888
+	{ swapBlit<true,   8>, Graphics::PixelFormat(4, 8, 8, 8, 8, 16,  8,  0, 24), Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24) }, // ARGB8888 -> ABGR8888
+
+	// 32-bit byteswap and rotate left
+	{ swapBlit<true,  24>, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0), Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0) }, // RGBA8888 -> BGRA8888
+	{ swapBlit<true,  24>, Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0), Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0) }  // BGRA8888 -> RGBA8888
+};
+
+bool fastBlit(byte *dst, const byte *src, const uint w, const uint h,
+							const PixelFormat &srcFmt, const PixelFormat &dstFmt,
+							const uint srcPitch, const uint dstPitch) {
+	for (size_t i = 0; i < ARRAYSIZE(fastBlitFuncs); i++) {
+		if (srcFmt != fastBlitFuncs[i].srcFmt)
+			continue;
+		if (dstFmt != fastBlitFuncs[i].dstFmt)
+			continue;
+
+		// Faster, but larger, to provide optimized handling for each case.
+		const uint srcDelta = (srcPitch - w * srcFmt.bytesPerPixel);
+		const uint dstDelta = (dstPitch - w * dstFmt.bytesPerPixel);
+
+		fastBlitFuncs[i].func(dst, src, w, h, srcDelta, dstDelta);
+		return true;
+	}
+	return false;
+}
+
+} // End of namespace Graphics
diff --git a/graphics/blit/blit.cpp b/graphics/blit/blit.cpp
index 0d42547efc6..d9fca815d3f 100644
--- a/graphics/blit/blit.cpp
+++ b/graphics/blit/blit.cpp
@@ -305,6 +305,10 @@ inline bool crossBlitHelper(byte *dst, const byte *src, const byte *mask, const
 
 } // End of anonymous namespace
 
+bool fastBlit(byte *dst, const byte *src, const uint w, const uint h,
+							const PixelFormat &srcFmt, const PixelFormat &dstFmt,
+							const uint srcPitch, const uint dstPitch);
+
 // Function to blit a rect from one color format to another
 bool crossBlit(byte *dst, const byte *src,
 				const uint dstPitch, const uint srcPitch,
@@ -321,6 +325,11 @@ bool crossBlit(byte *dst, const byte *src,
 		return true;
 	}
 
+	// Attempt to use a faster method if possible
+	if (fastBlit(dst, src, w, h, srcFmt, dstFmt, srcPitch, dstPitch)) {
+		return true;
+	}
+
 	return crossBlitHelper<false, false>(dst, src, nullptr, w, h, srcFmt, dstFmt, srcPitch, dstPitch, 0, 0);
 }
 
diff --git a/graphics/module.mk b/graphics/module.mk
index 55a3e9b6379..2339657e181 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
 	big5.o \
 	blit/blit.o \
 	blit/blit-alpha.o \
+	blit/blit-fast.o \
 	blit/blit-generic.o \
 	blit/blit-scale.o \
 	color_quantizer.o \


Commit: 8eb0dcba6c6c96822cd94e475d10b00e1f477859
    https://github.com/scummvm/scummvm/commit/8eb0dcba6c6c96822cd94e475d10b00e1f477859
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2025-07-06T19:02:01+02:00

Commit Message:
OPENGL: Remove TextureSurfaceRGBA8888Swap

Graphics::crossBlit() now contains faster routines that can be used instead.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h


diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 1319f4a4519..ec48fee945d 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -1702,8 +1702,6 @@ Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &forma
 		// hope for this to change anytime soon) we use pixel format
 		// conversion to a supported texture format.
 		return new TextureSurfaceRGB555();
-	} else if (format == Graphics::PixelFormat::createFormatABGR32()) {
-		return new TextureSurfaceRGBA8888Swap();
 	} else {
 		return new FakeTextureSurface(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, OpenGL::Texture::getRGBAPixelFormat(), format);
 	}
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index f1d4feeea54..4e7927270b5 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -367,42 +367,6 @@ void TextureSurfaceRGB555::updateGLTexture() {
 	TextureSurface::updateGLTexture();
 }
 
-TextureSurfaceRGBA8888Swap::TextureSurfaceRGBA8888Swap()
-	: FakeTextureSurface(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, OpenGL::Texture::getRGBAPixelFormat(), Graphics::PixelFormat::createFormatABGR32())
-	  {
-}
-
-void TextureSurfaceRGBA8888Swap::updateGLTexture() {
-	if (!isDirty()) {
-		return;
-	}
-
-	// Convert color space.
-	Graphics::Surface *outSurf = TextureSurface::getSurface();
-
-	const Common::Rect dirtyArea = getDirtyArea();
-
-	uint32 *dst = (uint32 *)outSurf->getBasePtr(dirtyArea.left, dirtyArea.top);
-	const uint dstAdd = outSurf->pitch - 4 * dirtyArea.width();
-
-	const uint32 *src = (const uint32 *)_rgbData.getBasePtr(dirtyArea.left, dirtyArea.top);
-	const uint srcAdd = _rgbData.pitch - 4 * dirtyArea.width();
-
-	for (int height = dirtyArea.height(); height > 0; --height) {
-		for (int width = dirtyArea.width(); width > 0; --width) {
-			const uint32 color = *src++;
-
-			*dst++ = SWAP_BYTES_32(color);
-		}
-
-		src = (const uint32 *)((const byte *)src + srcAdd);
-		dst = (uint32 *)((byte *)dst + dstAdd);
-	}
-
-	// Do generic handling of updating the texture.
-	TextureSurface::updateGLTexture();
-}
-
 #ifdef USE_SCALERS
 
 ScaledTextureSurface::ScaledTextureSurface(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format, const Graphics::PixelFormat &fakeFormat)
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 5f530f7f518..9ea8255c500 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -243,14 +243,6 @@ public:
 	void updateGLTexture() override;
 };
 
-class TextureSurfaceRGBA8888Swap : public FakeTextureSurface {
-public:
-	TextureSurfaceRGBA8888Swap();
-	~TextureSurfaceRGBA8888Swap() override {}
-
-	void updateGLTexture() override;
-};
-
 #ifdef USE_SCALERS
 class ScaledTextureSurface : public FakeTextureSurface {
 public:


Commit: 324ccbb27453b498ea19337121141ced5d149475
    https://github.com/scummvm/scummvm/commit/324ccbb27453b498ea19337121141ced5d149475
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2025-07-06T19:02:01+02:00

Commit Message:
GRAPHICS: Allow fast blit functions to be stored for repeated use

Changed paths:
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h
    graphics/blit.h
    graphics/blit/blit-fast.cpp
    graphics/blit/blit.cpp


diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 4e7927270b5..b0c14345121 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -210,10 +210,13 @@ FakeTextureSurface::FakeTextureSurface(GLenum glIntFormat, GLenum glFormat, GLen
 	: TextureSurface(glIntFormat, glFormat, glType, format),
 	  _fakeFormat(fakeFormat),
 	  _rgbData(),
+	  _blitFunc(nullptr),
 	  _palette(nullptr),
 	  _mask(nullptr) {
 	if (_fakeFormat.isCLUT8()) {
 		_palette = new uint32[256]();
+	} else {
+		_blitFunc = Graphics::getFastBlitFunc(format, fakeFormat);
 	}
 }
 
@@ -299,6 +302,8 @@ void FakeTextureSurface::updateGLTexture() {
 void FakeTextureSurface::applyPaletteAndMask(byte *dst, const byte *src, uint dstPitch, uint srcPitch, uint srcWidth, const Common::Rect &dirtyArea, const Graphics::PixelFormat &dstFormat, const Graphics::PixelFormat &srcFormat) const {
 	if (_palette) {
 		Graphics::crossBlitMap(dst, src, dstPitch, srcPitch, dirtyArea.width(), dirtyArea.height(), dstFormat.bytesPerPixel, _palette);
+	} else if (_blitFunc) {
+		_blitFunc(dst, src, dstPitch, srcPitch, dirtyArea.width(), dirtyArea.height());
 	} else {
 		Graphics::crossBlit(dst, src, dstPitch, srcPitch, dirtyArea.width(), dirtyArea.height(), dstFormat, srcFormat);
 	}
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 9ea8255c500..15bf163ac6a 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -28,6 +28,7 @@
 
 #include "graphics/pixelformat.h"
 #include "graphics/surface.h"
+#include "graphics/blit.h"
 
 #include "common/rect.h"
 #include "common/rotationmode.h"
@@ -231,6 +232,7 @@ protected:
 
 	Graphics::Surface _rgbData;
 	Graphics::PixelFormat _fakeFormat;
+	Graphics::FastBlitFunc _blitFunc;
 	uint32 *_palette;
 	uint8 *_mask;
 };
diff --git a/graphics/blit.h b/graphics/blit.h
index 126e790804b..a023dc1cd29 100644
--- a/graphics/blit.h
+++ b/graphics/blit.h
@@ -210,6 +210,29 @@ bool crossMaskBlitMap(byte *dst, const byte *src, const byte *mask,
 			   const uint w, const uint h,
 			   const uint bytesPerPixel, const uint32 *map);
 
+typedef void (*FastBlitFunc)(byte *, const byte *, const uint, const uint, const uint, const uint);
+
+/**
+ * Look up optimised routines for converting between pixel formats.
+ *
+ * @param dstFmt	the desired pixel format
+ * @param srcFmt	the original pixel format
+ * @return			a function pointer to an optimised routine,
+ *					or nullptr if none are available.
+ *
+ * @note Not all combinations of pixel formats are supported on
+ *       all platforms. Users of this function should provide a
+ *       fallback using crossBlit() if no optimised functions
+ *       can be found.
+ * @note This can convert a surface in place, regardless of the
+ *       source and destination format, as long as there is enough
+ *       space for the destination. The dstPitch / srcPitch ratio
+ *       must at least equal the dstBpp / srcBpp ratio for
+ *       dstPitch >= srcPitch and at most dstBpp / srcBpp for
+ *       dstPitch < srcPitch though.
+ */
+FastBlitFunc getFastBlitFunc(const PixelFormat &dstFmt, const PixelFormat &srcFmt);
+
 bool scaleBlit(byte *dst, const byte *src,
 			   const uint dstPitch, const uint srcPitch,
 			   const uint dstW, const uint dstH,
diff --git a/graphics/blit/blit-fast.cpp b/graphics/blit/blit-fast.cpp
index f2bcd91b194..18c1e551cf2 100644
--- a/graphics/blit/blit-fast.cpp
+++ b/graphics/blit/blit-fast.cpp
@@ -28,8 +28,13 @@ namespace Graphics {
 namespace {
 
 template<bool bswap, int rotate>
-static void swapBlit(byte *dst, const byte *src, const uint w, const uint h,
-							const uint srcDelta, const uint dstDelta) {
+static void swapBlit(byte *dst, const byte *src,
+                     const uint dstPitch, const uint srcPitch,
+                     const uint w, const uint h) {
+	// Faster, but larger, to provide optimized handling for each case.
+	const uint srcDelta = (srcPitch - w * sizeof(uint32));
+	const uint dstDelta = (dstPitch - w * sizeof(uint32));
+
 	for (uint y = 0; y < h; ++y) {
 		for (uint x = 0; x < w; ++x) {
 			uint32 col = *(const uint32 *)src;
@@ -54,7 +59,7 @@ static void swapBlit(byte *dst, const byte *src, const uint w, const uint h,
 // TODO: Add fast 24<->32bpp conversion
 // TODO: Add fast 16<->16bpp conversion
 static const struct {
-	void(*func)(byte *, const byte *, const uint, const uint, const uint, const uint);
+	FastBlitFunc func;
 	Graphics::PixelFormat srcFmt, dstFmt;
 } fastBlitFuncs[] = {
 	// 32-bit byteswap
@@ -80,23 +85,16 @@ static const struct {
 	{ swapBlit<true,  24>, Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0), Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0) }  // BGRA8888 -> RGBA8888
 };
 
-bool fastBlit(byte *dst, const byte *src, const uint w, const uint h,
-							const PixelFormat &srcFmt, const PixelFormat &dstFmt,
-							const uint srcPitch, const uint dstPitch) {
+FastBlitFunc getFastBlitFunc(const PixelFormat &dstFmt, const PixelFormat &srcFmt) {
 	for (size_t i = 0; i < ARRAYSIZE(fastBlitFuncs); i++) {
 		if (srcFmt != fastBlitFuncs[i].srcFmt)
 			continue;
 		if (dstFmt != fastBlitFuncs[i].dstFmt)
 			continue;
 
-		// Faster, but larger, to provide optimized handling for each case.
-		const uint srcDelta = (srcPitch - w * srcFmt.bytesPerPixel);
-		const uint dstDelta = (dstPitch - w * dstFmt.bytesPerPixel);
-
-		fastBlitFuncs[i].func(dst, src, w, h, srcDelta, dstDelta);
-		return true;
+		return fastBlitFuncs[i].func;
 	}
-	return false;
+	return nullptr;
 }
 
 } // End of namespace Graphics
diff --git a/graphics/blit/blit.cpp b/graphics/blit/blit.cpp
index d9fca815d3f..88510e4edbc 100644
--- a/graphics/blit/blit.cpp
+++ b/graphics/blit/blit.cpp
@@ -305,10 +305,6 @@ inline bool crossBlitHelper(byte *dst, const byte *src, const byte *mask, const
 
 } // End of anonymous namespace
 
-bool fastBlit(byte *dst, const byte *src, const uint w, const uint h,
-							const PixelFormat &srcFmt, const PixelFormat &dstFmt,
-							const uint srcPitch, const uint dstPitch);
-
 // Function to blit a rect from one color format to another
 bool crossBlit(byte *dst, const byte *src,
 				const uint dstPitch, const uint srcPitch,
@@ -326,7 +322,9 @@ bool crossBlit(byte *dst, const byte *src,
 	}
 
 	// Attempt to use a faster method if possible
-	if (fastBlit(dst, src, w, h, srcFmt, dstFmt, srcPitch, dstPitch)) {
+	FastBlitFunc blitFunc = getFastBlitFunc(dstFmt, dstFmt);
+	if (blitFunc) {
+		blitFunc(dst, src, dstPitch, srcPitch, w, h);
 		return true;
 	}
 


Commit: 2ed690b9a6104159c1d40d7a16019f85e07703e7
    https://github.com/scummvm/scummvm/commit/2ed690b9a6104159c1d40d7a16019f85e07703e7
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2025-07-06T19:02:01+02:00

Commit Message:
GRAPHICS: Check bytes per pixel before looking up fast blit routines

Changed paths:
    graphics/blit/blit-fast.cpp


diff --git a/graphics/blit/blit-fast.cpp b/graphics/blit/blit-fast.cpp
index 18c1e551cf2..f391bccf6b0 100644
--- a/graphics/blit/blit-fast.cpp
+++ b/graphics/blit/blit-fast.cpp
@@ -58,10 +58,12 @@ static void swapBlit(byte *dst, const byte *src,
 
 // TODO: Add fast 24<->32bpp conversion
 // TODO: Add fast 16<->16bpp conversion
-static const struct {
+struct FastBlitLookup {
 	FastBlitFunc func;
 	Graphics::PixelFormat srcFmt, dstFmt;
-} fastBlitFuncs[] = {
+};
+
+static const FastBlitLookup fastBlitFuncs_4to4[] = {
 	// 32-bit byteswap
 	{ swapBlit<true,   0>, Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24), Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0) }, // ABGR8888 -> RGBA8888
 	{ swapBlit<true,   0>, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0), Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24) }, // RGBA8888 -> ABGR8888
@@ -86,13 +88,25 @@ static const struct {
 };
 
 FastBlitFunc getFastBlitFunc(const PixelFormat &dstFmt, const PixelFormat &srcFmt) {
-	for (size_t i = 0; i < ARRAYSIZE(fastBlitFuncs); i++) {
-		if (srcFmt != fastBlitFuncs[i].srcFmt)
+	const uint dstBpp = dstFmt.bytesPerPixel;
+	const uint srcBpp = srcFmt.bytesPerPixel;
+	const FastBlitLookup *table = nullptr;
+	size_t length = 0;
+
+	if (srcBpp == 4 && dstBpp == 4) {
+		table = fastBlitFuncs_4to4;
+		length = ARRAYSIZE(fastBlitFuncs_4to4);
+	} else {
+		return nullptr;
+	}
+
+	for (size_t i = 0; i < length; i++) {
+		if (srcFmt != table[i].srcFmt)
 			continue;
-		if (dstFmt != fastBlitFuncs[i].dstFmt)
+		if (dstFmt != table[i].dstFmt)
 			continue;
 
-		return fastBlitFuncs[i].func;
+		return table[i].func;
 	}
 	return nullptr;
 }




More information about the Scummvm-git-logs mailing list