[Scummvm-git-logs] scummvm master -> b4c0cf3d14358a03e255cb4d84f29e7e9b22f699

bluegr noreply at scummvm.org
Wed Oct 15 18:26:30 UTC 2025


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

Summary:
b4c0cf3d14 ALCACHOFA: Reduce pixel format conversion


Commit: b4c0cf3d14358a03e255cb4d84f29e7e9b22f699
    https://github.com/scummvm/scummvm/commit/b4c0cf3d14358a03e255cb4d84f29e7e9b22f699
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2025-10-15T21:26:26+03:00

Commit Message:
ALCACHOFA: Reduce pixel format conversion

Changed paths:
    engines/alcachofa/alcachofa.cpp
    engines/alcachofa/graphics-opengl-base.cpp
    engines/alcachofa/graphics-opengl-base.h
    engines/alcachofa/graphics-opengl.cpp
    engines/alcachofa/graphics-opengl.h
    engines/alcachofa/graphics-tinygl.cpp
    engines/alcachofa/graphics.cpp
    engines/alcachofa/graphics.h
    engines/alcachofa/menu.cpp


diff --git a/engines/alcachofa/alcachofa.cpp b/engines/alcachofa/alcachofa.cpp
index 027dfcd446e..8aa9bb3aff2 100644
--- a/engines/alcachofa/alcachofa.cpp
+++ b/engines/alcachofa/alcachofa.cpp
@@ -383,7 +383,7 @@ void AlcachofaEngine::getSavegameThumbnail(Graphics::Surface &thumbnail) {
 	}
 
 	// otherwise we have to rerender
-	thumbnail.create(kBigThumbnailWidth, kBigThumbnailHeight, Graphics::PixelFormat::createFormatRGBA32());
+	thumbnail.create(kBigThumbnailWidth, kBigThumbnailHeight, g_engine->renderer().getPixelFormat());
 	if (g_engine->player().currentRoom() == nullptr)
 		return; // but without a room we would render only black anyway
 
diff --git a/engines/alcachofa/graphics-opengl-base.cpp b/engines/alcachofa/graphics-opengl-base.cpp
index 06361664888..e37ce6de554 100644
--- a/engines/alcachofa/graphics-opengl-base.cpp
+++ b/engines/alcachofa/graphics-opengl-base.cpp
@@ -31,52 +31,6 @@ using namespace Math;
 
 namespace Alcachofa {
 
-static bool areComponentsInOrder(const PixelFormat &format, int r, int g, int b, int a) {
-	return format == PixelFormat(4, 8, 8, 8, 8, r * 8, g * 8, b * 8, a * 8);
-}
-
-bool isCompatibleFormat(const PixelFormat &format) {
-	return areComponentsInOrder(format, 0, 1, 2, 3) ||
-		areComponentsInOrder(format, 3, 2, 1, 0);
-}
-
-OpenGLTextureBase::OpenGLTextureBase(int32 w, int32 h, bool withMipmaps)
-	: ITexture({ (int16)w, (int16)h })
-	, _withMipmaps(withMipmaps) {}
-
-void OpenGLTextureBase::update(const Surface &surface) {
-	assert(isCompatibleFormat(surface.format));
-	assert(surface.w == size().x && surface.h == size().y);
-
-	// GLES2 only supports GL_RGBA but we need BlendBlit::getSupportedPixelFormat to use blendBlit
-	// We also do not want to keep surface memory for textures that are not updated repeatedly
-	const void *pixels;
-	if (!areComponentsInOrder(surface.format, 0, 1, 2, 3)) {
-		if (_tmpSurface.empty())
-			_tmpSurface.create(surface.w, surface.h, PixelFormat::createFormatRGBA32());
-		crossBlit(
-			(byte *)_tmpSurface.getPixels(),
-			(const byte *)surface.getPixels(),
-			_tmpSurface.pitch,
-			surface.pitch,
-			surface.w,
-			surface.h,
-			_tmpSurface.format,
-			surface.format);
-		pixels = _tmpSurface.getPixels();
-	} else {
-		pixels = surface.getPixels();
-	}
-
-	updateInner(pixels);
-
-	if (!_tmpSurface.empty()) {
-		if (!_didConvertOnce)
-			_tmpSurface.free();
-		_didConvertOnce = true;
-	}
-}
-
 OpenGLRendererBase::OpenGLRendererBase(Point resolution) : _resolution(resolution) {}
 
 bool OpenGLRendererBase::hasOutput() const {
diff --git a/engines/alcachofa/graphics-opengl-base.h b/engines/alcachofa/graphics-opengl-base.h
index 506a5c0f191..12586ef9243 100644
--- a/engines/alcachofa/graphics-opengl-base.h
+++ b/engines/alcachofa/graphics-opengl-base.h
@@ -28,23 +28,6 @@
 
 namespace Alcachofa {
 
-bool isCompatibleFormat(const Graphics::PixelFormat &format);
-
-class OpenGLTextureBase : public ITexture {
-public:
-	OpenGLTextureBase(int32 w, int32 h, bool withMipmaps);
-	~OpenGLTextureBase() override {}
-	void update(const Graphics::Surface &surface) override;
-
-protected:
-	virtual void updateInner(const void *pixels) = 0; ///< expects pixels to be RGBA32
-
-	bool _withMipmaps;
-	bool _mirrorWrap = true;
-	bool _didConvertOnce = false;
-	Graphics::ManagedSurface _tmpSurface;
-};
-
 class OpenGLRendererBase : public virtual IRenderer {
 public:
 	OpenGLRendererBase(Common::Point resolution);
diff --git a/engines/alcachofa/graphics-opengl.cpp b/engines/alcachofa/graphics-opengl.cpp
index 2562071e588..10b2c495292 100644
--- a/engines/alcachofa/graphics-opengl.cpp
+++ b/engines/alcachofa/graphics-opengl.cpp
@@ -19,6 +19,7 @@
  *
  */
 
+#include "alcachofa/alcachofa.h"
 #include "alcachofa/graphics.h"
 #include "alcachofa/detection.h"
 #include "alcachofa/graphics-opengl.h"
@@ -37,7 +38,8 @@ using namespace Graphics;
 namespace Alcachofa {
 
 OpenGLTexture::OpenGLTexture(int32 w, int32 h, bool withMipmaps)
-	: OpenGLTextureBase(w, h, withMipmaps) {
+	: ITexture({ (int16)w, (int16)h })
+	, _withMipmaps(withMipmaps) {
 	glEnable(GL_TEXTURE_2D); // will error on GLES2, but that is okay
 	OpenGL::clearGLError(); // we will just ignore it
 	GL_CALL(glGenTextures(1, &_handle));
@@ -75,7 +77,12 @@ void OpenGLTexture::setMirrorWrap(bool wrap) {
 	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode));
 }
 
-void OpenGLTexture::updateInner(const void *pixels) {
+void OpenGLTexture::update(const Surface &surface) {
+	assert(surface.format == g_engine->renderer().getPixelFormat());
+	assert(surface.w == size().x && surface.h == size().y);
+
+	const void *pixels = surface.getPixels();
+
 	glEnable(GL_TEXTURE_2D);
 	OpenGL::clearGLError();
 	GL_CALL(glBindTexture(GL_TEXTURE_2D, _handle));
@@ -105,6 +112,10 @@ ScopedPtr<ITexture> OpenGLRenderer::createTexture(int32 w, int32 h, bool withMip
 	return ScopedPtr<ITexture>(new OpenGLTexture(w, h, withMipmaps));
 }
 
+Graphics::PixelFormat OpenGLRenderer::getPixelFormat() const {
+	return Graphics::PixelFormat::createFormatRGBA32();
+}
+
 void OpenGLRenderer::end() {
 	GL_CALL(glFlush());
 
@@ -119,11 +130,6 @@ void OpenGLRenderer::end() {
 			GL_UNSIGNED_BYTE,
 			_currentOutput->getPixels()
 		));
-		if (_currentOutput->format != PixelFormat::createFormatRGBA32()) {
-			auto targetFormat = _currentOutput->format;
-			_currentOutput->format = PixelFormat::createFormatRGBA32();
-			_currentOutput->convertToInPlace(targetFormat);
-		}
 	}
 }
 
@@ -161,7 +167,7 @@ void OpenGLRenderer::setOutput(Surface &output) {
 		debugC(0, kDebugGraphics, "Output is larger than screen, output will be cropped (%d, %d) > (%d, %d)",
 			output.w, output.h, g_system->getWidth(), g_system->getHeight());
 
-	if (!isCompatibleFormat(output.format)) {
+	if (output.format != getPixelFormat()) {
 		auto formatString = output.format.toString();
 		debugC(0, kDebugGraphics, "Cannot use pixelformat of given output surface: %s", formatString.c_str());
 		_currentOutput = nullptr;
diff --git a/engines/alcachofa/graphics-opengl.h b/engines/alcachofa/graphics-opengl.h
index 867b95b8d5f..b53ab590a85 100644
--- a/engines/alcachofa/graphics-opengl.h
+++ b/engines/alcachofa/graphics-opengl.h
@@ -30,17 +30,18 @@
 
 namespace Alcachofa {
 
-class OpenGLTexture : public OpenGLTextureBase {
+class OpenGLTexture : public ITexture {
 public:
 	OpenGLTexture(int32 w, int32 h, bool withMipmaps);
 	~OpenGLTexture() override;
 
 	inline GLuint handle() const { return _handle; }
 	void setMirrorWrap(bool wrap);
+	void update(const Graphics::Surface &surface) override;
 
 protected:
-	void updateInner(const void *pixels) override;
-
+	bool _withMipmaps;
+	bool _mirrorWrap = true;
 	GLuint _handle = 0;
 };
 
@@ -49,6 +50,7 @@ public:
 	OpenGLRenderer(Common::Point resolution);
 
 	Common::ScopedPtr<ITexture> createTexture(int32 w, int32 h, bool withMipmaps) override;
+	Graphics::PixelFormat getPixelFormat() const override;
 	void end() override;
 	void setOutput(Graphics::Surface &output) override;
 
diff --git a/engines/alcachofa/graphics-tinygl.cpp b/engines/alcachofa/graphics-tinygl.cpp
index ff7563ab1ad..00141e25289 100644
--- a/engines/alcachofa/graphics-tinygl.cpp
+++ b/engines/alcachofa/graphics-tinygl.cpp
@@ -35,10 +35,11 @@ using namespace Graphics;
 
 namespace Alcachofa {
 
-class TinyGLTexture : public OpenGLTextureBase {
+class TinyGLTexture : public ITexture {
 public:
 	TinyGLTexture(int32 w, int32 h, bool withMipmaps)
-		: OpenGLTextureBase(w, h, withMipmaps) {
+		: ITexture({ (int16)w, (int16)h })
+		, _withMipmaps(withMipmaps) {
 		tglEnable(TGL_TEXTURE_2D);
 		tglGenTextures(1, &_handle);
 		tglBindTexture(TGL_TEXTURE_2D, _handle);
@@ -55,8 +56,12 @@ public:
 
 	inline TGLuint handle() const { return _handle; }
 
-protected:
-	void updateInner(const void *pixels) override {
+	void update(const Surface &surface) override {
+		assert(surface.format == g_engine->renderer().getPixelFormat());
+		assert(surface.w == size().x && surface.h == size().y);
+
+		const void *pixels = surface.getPixels();
+
 		tglEnable(TGL_TEXTURE_2D);
 		tglBindTexture(TGL_TEXTURE_2D, _handle);
 		tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGBA, size().x, size().y, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, pixels);
@@ -66,6 +71,8 @@ protected:
 			tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAX_LEVEL, 0);
 	}
 
+protected:
+	bool _withMipmaps;
 	TGLuint _handle;
 };
 
@@ -117,6 +124,10 @@ public:
 		return ScopedPtr<ITexture>(new TinyGLTexture(w, h, withMipmaps));
 	}
 
+	Graphics::PixelFormat getPixelFormat() const override {
+		return Graphics::PixelFormat::createFormatRGBA32();
+	}
+
 	void begin() override {
 		resetState();
 		_currentTexture = nullptr;
diff --git a/engines/alcachofa/graphics.cpp b/engines/alcachofa/graphics.cpp
index 14dd5512cf3..b8e13112b04 100644
--- a/engines/alcachofa/graphics.cpp
+++ b/engines/alcachofa/graphics.cpp
@@ -192,7 +192,7 @@ ManagedSurface *AnimationBase::readImage(SeekableReadStream &stream) const {
 	const auto &palette = decoder.getPalette();
 	auto target = new ManagedSurface();
 	target->setPalette(palette.data(), 0, palette.size());
-	target->convertFrom(*source, BlendBlit::getSupportedPixelFormat());
+	target->convertFrom(*source, g_engine->renderer().getPixelFormat());
 	return target;
 }
 
@@ -214,8 +214,10 @@ void AnimationBase::loadMissingAnimation() {
 // unfortunately ScummVMs BLEND_NORMAL does not blend alpha
 // but this also bad, let's find/discuss a better solution later
 void AnimationBase::fullBlend(const ManagedSurface &source, ManagedSurface &destination, int offsetX, int offsetY) {
-	assert(source.format == BlendBlit::getSupportedPixelFormat());
-	assert(destination.format == BlendBlit::getSupportedPixelFormat());
+	// TODO: Support other pixel formats
+	assert(source.format == Graphics::PixelFormat::createFormatRGBA32() ||
+	       source.format == Graphics::PixelFormat::createFormatBGRA32());
+	assert(destination.format == source.format);
 	assert(offsetX >= 0 && offsetX + source.w <= destination.w);
 	assert(offsetY >= 0 && offsetY + source.h <= destination.h);
 
@@ -225,10 +227,10 @@ void AnimationBase::fullBlend(const ManagedSurface &source, ManagedSurface &dest
 		const byte *sourcePixel = sourceLine;
 		byte *destPixel = destinationLine;
 		for (int x = 0; x < source.w; x++) {
-			byte alpha = (*(const uint32 *)sourcePixel) & 0xff;
-			for (int i = 1; i < 4; i++)
+			byte alpha = sourcePixel[3];
+			for (int i = 0; i < 3; i++)
 				destPixel[i] = ((byte)(alpha * sourcePixel[i] / 255)) + ((byte)((255 - alpha) * destPixel[i] / 255));
-			destPixel[0] = alpha + ((byte)((255 - alpha) * destPixel[0] / 255));
+			destPixel[3] = alpha + ((byte)((255 - alpha) * destPixel[3] / 255));
 			sourcePixel += 4;
 			destPixel += 4;
 		}
@@ -250,7 +252,7 @@ void Animation::load() {
 		return;
 	AnimationBase::load();
 	Rect maxBounds = maxFrameBounds();
-	_renderedSurface.create(maxBounds.width(), maxBounds.height(), BlendBlit::getSupportedPixelFormat());
+	_renderedSurface.create(maxBounds.width(), maxBounds.height(), g_engine->renderer().getPixelFormat());
 	_renderedTexture = g_engine->renderer().createTexture(maxBounds.width(), maxBounds.height(), true);
 
 	// We always create mipmaps, even for the backgrounds that usually do not scale much,
@@ -456,7 +458,7 @@ void Font::load() {
 
 	_texMins.resize(_images.size());
 	_texMaxs.resize(_images.size());
-	ManagedSurface atlasSurface(nextPowerOfTwo(cellSize.x * 16), nextPowerOfTwo(cellSize.y * 16), BlendBlit::getSupportedPixelFormat());
+	ManagedSurface atlasSurface(nextPowerOfTwo(cellSize.x * 16), nextPowerOfTwo(cellSize.y * 16), g_engine->renderer().getPixelFormat());
 	cellSize.x = atlasSurface.w / 16;
 	cellSize.y = atlasSurface.h / 16;
 	const float invWidth = 1.0f / atlasSurface.w;
diff --git a/engines/alcachofa/graphics.h b/engines/alcachofa/graphics.h
index 26b8bbd6bdb..fa6dd2452b5 100644
--- a/engines/alcachofa/graphics.h
+++ b/engines/alcachofa/graphics.h
@@ -76,6 +76,7 @@ public:
 	virtual ~IRenderer() {}
 
 	virtual Common::ScopedPtr<ITexture> createTexture(int32 w, int32 h, bool withMipmaps = true) = 0;
+	virtual Graphics::PixelFormat getPixelFormat() const = 0;
 
 	virtual void begin() = 0;
 	virtual void setTexture(ITexture *texture) = 0;
diff --git a/engines/alcachofa/menu.cpp b/engines/alcachofa/menu.cpp
index 471b492665c..9bcc3d6b267 100644
--- a/engines/alcachofa/menu.cpp
+++ b/engines/alcachofa/menu.cpp
@@ -34,10 +34,11 @@ using namespace Graphics;
 namespace Alcachofa {
 
 static void createThumbnail(ManagedSurface &surface) {
-	surface.create(kBigThumbnailWidth, kBigThumbnailHeight, PixelFormat::createFormatRGBA32());
+	surface.create(kBigThumbnailWidth, kBigThumbnailHeight, g_engine->renderer().getPixelFormat());
 }
 
 static void convertToGrayscale(ManagedSurface &surface) {
+	// TODO: Support other pixel formats
 	assert(!surface.empty());
 	assert(surface.format == PixelFormat::createFormatRGBA32());
 	uint32 rgbMask = ~(uint32(0xff) << surface.format.aShift);




More information about the Scummvm-git-logs mailing list