[Scummvm-git-logs] scummvm master -> 5432e4ad401958ca25f27dda006d9dbcfe46d30e

ccawley2011 noreply at scummvm.org
Fri Mar 3 09:59:51 UTC 2023


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

Summary:
5cc4607ff4 TINYGL: Add a fast path for rendering opaque BlitImages
526198991b STARK: Use the best pixel format for Bink playback
9f13b979d6 TINYGL: Ensure that Z-buffer images are never converted
f40c2ccfbd TINYGL: Remove unused tglBlitNoBlend function
5432e4ad40 TINYGL: Fix the incorrect use of tglBlitOpaque for additive blends


Commit: 5cc4607ff4d6650e8ad75a43a4e36ed7868f5d29
    https://github.com/scummvm/scummvm/commit/5cc4607ff4d6650e8ad75a43a4e36ed7868f5d29
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-03-03T09:59:41Z

Commit Message:
TINYGL: Add a fast path for rendering opaque BlitImages

Changed paths:
    graphics/tinygl/zblit.cpp
    graphics/tinygl/zbuffer.h


diff --git a/graphics/tinygl/zblit.cpp b/graphics/tinygl/zblit.cpp
index 8a9a65b5adf..bdb96ae78e5 100644
--- a/graphics/tinygl/zblit.cpp
+++ b/graphics/tinygl/zblit.cpp
@@ -27,6 +27,8 @@
 #include "graphics/tinygl/zdirtyrect.h"
 #include "graphics/tinygl/gl.h"
 
+#include "graphics/blit.h"
+
 #include <math.h>
 
 namespace TinyGL {
@@ -36,51 +38,73 @@ Common::Rect rotateRectangle(int x, int y, int width, int height, int rotation,
 
 struct BlitImage {
 public:
-	BlitImage() : _isDisposed(false), _version(0), _binaryTransparent(false), _refcount(1) { }
+	BlitImage() : _isDisposed(false), _version(0), _binaryTransparent(false), _opaque(true), _refcount(1) { }
 
 	void loadData(const Graphics::Surface &surface, uint32 colorKey, bool applyColorKey) {
-		const Graphics::PixelFormat textureFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+		_lines.clear();
+
 		int size = surface.w * surface.h;
-		_surface.create(surface.w, surface.h, textureFormat);
 		Graphics::PixelBuffer buffer(surface.format, (byte *)const_cast<void *>(surface.getPixels()));
-		Graphics::PixelBuffer dataBuffer(textureFormat, (byte *)const_cast<void *>(_surface.getPixels()));
-		dataBuffer.copyBuffer(0, 0, size, buffer);
-		if (applyColorKey) {
+
+		_opaque = true;
+		if (surface.format.aBits() > 0) {
 			for (int x = 0; x < size; x++) {
-				if (buffer.getValueAt(x) == colorKey) {
-					// Color keyed pixels become transparent white.
-					dataBuffer.setPixelAt(x, 0, 255, 255, 255);
+				uint8 r, g, b, a;
+				buffer.getARGBAt(x, a, r, g, b);
+				if (a != 0xFF) {
+					_opaque = false;
 				}
 			}
 		}
 
-		// Create opaque lines data.
-		// A line of pixels can not wrap more that one line of the image, since it would break
-		// blitting of bitmaps with a non-zero x position.
-		Graphics::PixelBuffer srcBuf = dataBuffer;
-		_lines.clear();
-		_binaryTransparent = true;
-		for (int y = 0; y < surface.h; y++) {
-			int start = -1;
-			for (int x = 0; x < surface.w; ++x) {
-				// We found a transparent pixel, so save a line from 'start' to the pixel before this.
-				uint8 r, g, b, a;
-				srcBuf.getARGBAt(x, a, r, g, b);
-				if (a != 0 && a != 0xFF) {
-					_binaryTransparent = false;
-				}
-				if (a == 0 && start >= 0) {
-					_lines.push_back(Line(start, y, x - start, srcBuf.getRawBuffer(start), textureFormat));
-					start = -1;
-				} else if (a != 0 && start == -1) {
-					start = x;
+		if (_opaque && !applyColorKey) {
+			GLContext *c = gl_get_context();
+			_surface.convertFrom(surface, c->fb->getPixelFormat());
+
+			_binaryTransparent = false;
+		} else {
+			const Graphics::PixelFormat textureFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+			_surface.convertFrom(surface, textureFormat);
+
+			Graphics::PixelBuffer dataBuffer(textureFormat, (byte *)const_cast<void *>(_surface.getPixels()));
+
+			if (applyColorKey) {
+				for (int x = 0; x < size; x++) {
+					if (buffer.getValueAt(x) == colorKey) {
+						// Color keyed pixels become transparent white.
+						dataBuffer.setPixelAt(x, 0, 255, 255, 255);
+						_opaque = false;
+					}
 				}
 			}
-			// end of the bitmap line. if start is an actual pixel save the line.
-			if (start >= 0) {
-				_lines.push_back(Line(start, y, surface.w - start, srcBuf.getRawBuffer(start), textureFormat));
+
+			// Create opaque lines data.
+			// A line of pixels can not wrap more that one line of the image, since it would break
+			// blitting of bitmaps with a non-zero x position.
+			Graphics::PixelBuffer srcBuf = dataBuffer;
+			_binaryTransparent = true;
+			for (int y = 0; y < surface.h; y++) {
+				int start = -1;
+				for (int x = 0; x < surface.w; ++x) {
+					// We found a transparent pixel, so save a line from 'start' to the pixel before this.
+					uint8 r, g, b, a;
+					srcBuf.getARGBAt(x, a, r, g, b);
+					if (a != 0 && a != 0xFF) {
+						_binaryTransparent = false;
+					}
+					if (a == 0 && start >= 0) {
+						_lines.push_back(Line(start, y, x - start, srcBuf.getRawBuffer(start), textureFormat));
+						start = -1;
+					} else if (a != 0 && start == -1) {
+						start = x;
+					}
+				}
+				// end of the bitmap line. if start is an actual pixel save the line.
+				if (start >= 0) {
+					_lines.push_back(Line(start, y, surface.w - start, srcBuf.getRawBuffer(start), textureFormat));
+				}
+				srcBuf.shiftBy(surface.w);
 			}
-			srcBuf.shiftBy(surface.w);
 		}
 
 		_version++;
@@ -212,6 +236,8 @@ public:
 		}
 	}
 
+	void tglBlitOpaque(int dstX, int dstY, int srcX, int srcY, int srcWidth, int srcHeight);
+
 	template <bool kDisableColoring, bool kDisableBlending, bool kEnableAlphaBlending>
 	void tglBlitRLE(int dstX, int dstY, int srcX, int srcY, int srcWidth, int srcHeight, float aTint, float rTint, float gTint, float bTint);
 
@@ -229,7 +255,11 @@ public:
 	template <bool kDisableBlending, bool kDisableColoring, bool kDisableTransform, bool kFlipVertical, bool kFlipHorizontal, bool kEnableAlphaBlending>
 	void tglBlitGeneric(const BlitTransform &transform) {
 		if (kDisableTransform) {
-			if ((kDisableBlending || kEnableAlphaBlending) && kFlipVertical == false && kFlipHorizontal == false) {
+			if (kDisableBlending && kDisableColoring && kFlipVertical == false && kFlipHorizontal == false) {
+				tglBlitOpaque(transform._destinationRectangle.left, transform._destinationRectangle.top,
+					transform._sourceRectangle.left, transform._sourceRectangle.top,
+					transform._sourceRectangle.width() , transform._sourceRectangle.height());
+			} else if ((kDisableBlending || kEnableAlphaBlending) && kFlipVertical == false && kFlipHorizontal == false) {
 				tglBlitRLE<kDisableColoring, kDisableBlending, kEnableAlphaBlending>(transform._destinationRectangle.left,
 					transform._destinationRectangle.top, transform._sourceRectangle.left, transform._sourceRectangle.top,
 					transform._sourceRectangle.width() , transform._sourceRectangle.height(), transform._aTint,
@@ -261,9 +291,11 @@ public:
 	void incRefCount() { _refcount++; }
 	void dispose() { if (--_refcount == 0) _isDisposed = true; }
 	bool isDisposed() const { return _isDisposed; }
+	bool isOpaque() const { return _opaque; }
 private:
 	bool _isDisposed;
 	bool _binaryTransparent;
+	bool _opaque;
 	Common::Array<Line> _lines;
 	Graphics::Surface _surface;
 	int _version;
@@ -307,6 +339,21 @@ void tglDeleteBlitImage(TinyGL::BlitImage *blitImage) {
 
 namespace TinyGL {
 
+void BlitImage::tglBlitOpaque(int dstX, int dstY, int srcX, int srcY, int srcWidth, int srcHeight) {
+	GLContext *c = gl_get_context();
+
+	int clampWidth, clampHeight;
+	int width = srcWidth, height = srcHeight;
+	if (clipBlitImage(c, srcX, srcY, srcWidth, srcHeight, width, height, dstX, dstY, clampWidth, clampHeight) == false)
+		return;
+
+	int fbWidth = c->fb->getPixelBufferWidth();
+
+	Graphics::crossBlit(c->fb->getPixelBuffer(dstX + dstY * fbWidth), (const byte *)_surface.getBasePtr(srcX, srcY),
+	                    c->fb->getPixelBufferPitch(), _surface.pitch, clampWidth, clampHeight,
+	                    c->fb->getPixelFormat(), _surface.format);
+}
+
 // This function uses RLE encoding to skip transparent bitmap parts
 // This blit only supports tinting but it will fall back to simpleBlit
 // if flipping is required (or anything more complex than that, including rotationd and scaling).
@@ -711,7 +758,7 @@ void tglBlit(BlitImage *blitImage, const BlitTransform &transform) {
 	GLContext *c = gl_get_context();
 	bool disableColor = transform._aTint == 1.0f && transform._bTint == 1.0f && transform._gTint == 1.0f && transform._rTint == 1.0f;
 	bool disableTransform = transform._destinationRectangle.width() == 0 && transform._destinationRectangle.height() == 0 && transform._rotation == 0;
-	bool disableBlend = c->blending_enabled == false;
+	bool disableBlend = blitImage->isOpaque() || c->blending_enabled == false;
 	bool enableAlphaBlending = c->source_blending_factor == TGL_SRC_ALPHA && c->destination_blending_factor == TGL_ONE_MINUS_SRC_ALPHA;
 
 	if (enableAlphaBlending) {
diff --git a/graphics/tinygl/zbuffer.h b/graphics/tinygl/zbuffer.h
index 3f5861ca438..154917e86ea 100644
--- a/graphics/tinygl/zbuffer.h
+++ b/graphics/tinygl/zbuffer.h
@@ -115,6 +115,10 @@ struct FrameBuffer {
 		return _pbuf.getRawBuffer();
 	}
 
+	byte *getPixelBuffer(int pixel) {
+		return _pbuf.getRawBuffer(pixel);
+	}
+
 	int getPixelBufferWidth() {
 		return _pbufWidth;
 	}
@@ -123,6 +127,10 @@ struct FrameBuffer {
 		return _pbufHeight;
 	}
 
+	int getPixelBufferPitch() {
+		return _pbufPitch;
+	}
+
 	const uint *getZBuffer() {
 		return _zbuf;
 	}


Commit: 526198991b5b34df9f26f069d58e38ea31ab6cc8
    https://github.com/scummvm/scummvm/commit/526198991b5b34df9f26f069d58e38ea31ab6cc8
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-03-03T09:59:41Z

Commit Message:
STARK: Use the best pixel format for Bink playback

Changed paths:
    engines/stark/gfx/bitmap.h
    engines/stark/gfx/openglbitmap.cpp
    engines/stark/gfx/openglbitmap.h
    engines/stark/gfx/tinyglbitmap.cpp
    engines/stark/gfx/tinyglbitmap.h
    engines/stark/ui/world/fmvscreen.cpp
    engines/stark/visual/smacker.cpp


diff --git a/engines/stark/gfx/bitmap.h b/engines/stark/gfx/bitmap.h
index b1d2e7d9cc7..831aa588cae 100644
--- a/engines/stark/gfx/bitmap.h
+++ b/engines/stark/gfx/bitmap.h
@@ -25,6 +25,7 @@
 #include "common/hash-str.h"
 
 namespace Graphics {
+	struct PixelFormat;
 	struct Surface;
 }
 
@@ -53,6 +54,9 @@ public:
 	/** Set the filter used when sampling the texture */
 	virtual void setSamplingFilter(SamplingFilter filter) = 0;
 
+	/** Get the most ideal pixel format for uploading to a texture */
+	virtual Graphics::PixelFormat getBestPixelFormat() const = 0;
+
 	/** Get the texture width */
 	uint32 width() const { return _width; }
 
diff --git a/engines/stark/gfx/openglbitmap.cpp b/engines/stark/gfx/openglbitmap.cpp
index d7aae1b9abc..8fda2926d1f 100644
--- a/engines/stark/gfx/openglbitmap.cpp
+++ b/engines/stark/gfx/openglbitmap.cpp
@@ -88,6 +88,10 @@ void OpenGlBitmap::setSamplingFilter(Bitmap::SamplingFilter filter) {
 	}
 }
 
+Graphics::PixelFormat OpenGlBitmap::getBestPixelFormat() const {
+	return Driver::getRGBAPixelFormat();
+}
+
 } // End of namespace Gfx
 } // End of namespace Stark
 
diff --git a/engines/stark/gfx/openglbitmap.h b/engines/stark/gfx/openglbitmap.h
index 5ec0c08e0fb..59797f954bb 100644
--- a/engines/stark/gfx/openglbitmap.h
+++ b/engines/stark/gfx/openglbitmap.h
@@ -43,6 +43,7 @@ public:
 	void bind() const override;
 	void update(const Graphics::Surface *surface, const byte *palette = nullptr) override;
 	void setSamplingFilter(SamplingFilter filter) override;
+	Graphics::PixelFormat getBestPixelFormat() const override;
 
 protected:
 	GLuint _id;
diff --git a/engines/stark/gfx/tinyglbitmap.cpp b/engines/stark/gfx/tinyglbitmap.cpp
index 61ae32743a6..c543ce3bc6c 100644
--- a/engines/stark/gfx/tinyglbitmap.cpp
+++ b/engines/stark/gfx/tinyglbitmap.cpp
@@ -22,6 +22,7 @@
 #include "engines/stark/gfx/tinyglbitmap.h"
 #include "engines/stark/gfx/driver.h"
 
+#include "common/system.h"
 #include "graphics/surface.h"
 
 namespace Stark {
@@ -43,9 +44,9 @@ void TinyGlBitmap::update(const Graphics::Surface *surface, const byte *palette)
 	_width = surface->w;
 	_height = surface->h;
 
-	if (surface->format != Driver::getRGBAPixelFormat()) {
-		// Convert the surface to bitmap format
-		Graphics::Surface *convertedSurface = surface->convertTo(Driver::getRGBAPixelFormat(), palette);
+	if (palette) {
+		// TinyGL doesn't currently support images with palettes, so we handle conversion here.
+		Graphics::Surface *convertedSurface = surface->convertTo(getBestPixelFormat(), palette);
 		tglUploadBlitImage(_blitImage, *convertedSurface, 0, false);
 		convertedSurface->free();
 		delete convertedSurface;
@@ -57,6 +58,10 @@ void TinyGlBitmap::update(const Graphics::Surface *surface, const byte *palette)
 void TinyGlBitmap::setSamplingFilter(Bitmap::SamplingFilter filter) {
 }
 
+Graphics::PixelFormat TinyGlBitmap::getBestPixelFormat() const {
+	return g_system->getScreenFormat();
+}
+
 TinyGL::BlitImage *TinyGlBitmap::getBlitImage() const {
 	return _blitImage;
 }
diff --git a/engines/stark/gfx/tinyglbitmap.h b/engines/stark/gfx/tinyglbitmap.h
index f3e125ca319..33e4226bc21 100644
--- a/engines/stark/gfx/tinyglbitmap.h
+++ b/engines/stark/gfx/tinyglbitmap.h
@@ -42,6 +42,7 @@ public:
 	TinyGL::BlitImage *getBlitImage() const;
 	void update(const Graphics::Surface *surface, const byte *palette = nullptr) override;
 	void setSamplingFilter(SamplingFilter filter) override;
+	Graphics::PixelFormat getBestPixelFormat() const override;
 
 protected:
 	TinyGL::BlitImage *_blitImage;
diff --git a/engines/stark/ui/world/fmvscreen.cpp b/engines/stark/ui/world/fmvscreen.cpp
index d039ac11aff..fc1a97ea210 100644
--- a/engines/stark/ui/world/fmvscreen.cpp
+++ b/engines/stark/ui/world/fmvscreen.cpp
@@ -37,13 +37,13 @@ FMVScreen::FMVScreen(Gfx::Driver *gfx, Cursor *cursor) :
 	_position = Common::Rect(Gfx::Driver::kOriginalWidth, Gfx::Driver::kOriginalHeight);
 	_visible = true;
 
-	_decoder = new Video::BinkDecoder();
-	_decoder->setDefaultHighColorFormat(Gfx::Driver::getRGBAPixelFormat());
-	_decoder->setSoundType(Audio::Mixer::kSFXSoundType);
-
 	_bitmap = _gfx->createBitmap();
 	_bitmap->setSamplingFilter(StarkSettings->getImageSamplingFilter());
 
+	_decoder = new Video::BinkDecoder();
+	_decoder->setDefaultHighColorFormat(_bitmap->getBestPixelFormat());
+	_decoder->setSoundType(Audio::Mixer::kSFXSoundType);
+
 	_surfaceRenderer = _gfx->createSurfaceRenderer();
 }
 
diff --git a/engines/stark/visual/smacker.cpp b/engines/stark/visual/smacker.cpp
index db08dd7eae2..72db7c8f5a5 100644
--- a/engines/stark/visual/smacker.cpp
+++ b/engines/stark/visual/smacker.cpp
@@ -72,6 +72,7 @@ void VisualSmacker::loadBink(Common::SeekableReadStream *stream) {
 
 	_decoder = new Video::BinkDecoder();
 	_decoder->setSoundType(Audio::Mixer::kSFXSoundType);
+	// We need a format with alpha transparency, so we can't use _bitmap->getBestPixelFormat() here.
 	_decoder->setDefaultHighColorFormat(Gfx::Driver::getRGBAPixelFormat());
 	_decoder->loadStream(stream);
 


Commit: 9f13b979d6f580b9ffd7652afe7cc95c56c9b446
    https://github.com/scummvm/scummvm/commit/9f13b979d6f580b9ffd7652afe7cc95c56c9b446
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-03-03T09:59:41Z

Commit Message:
TINYGL: Ensure that Z-buffer images are never converted

Changed paths:
    engines/grim/gfx_tinygl.cpp
    graphics/tinygl/zblit.cpp
    graphics/tinygl/zblit_public.h


diff --git a/engines/grim/gfx_tinygl.cpp b/engines/grim/gfx_tinygl.cpp
index 61a0b9e5263..a3ce8527c27 100644
--- a/engines/grim/gfx_tinygl.cpp
+++ b/engines/grim/gfx_tinygl.cpp
@@ -916,7 +916,7 @@ void GfxTinyGL::createBitmap(BitmapData *bitmap) {
 			bitmap->_data[pic].free();
 			bitmap->_data[pic] = buffer;
 			imgs[pic] = tglGenBlitImage();
-			tglUploadBlitImage(imgs[pic], bitmap->_data[pic], 0, false);
+			tglUploadBlitImage(imgs[pic], bitmap->_data[pic], 0, false, true);
 		}
 	} else {
 		for (int i = 0; i < bitmap->_numImages; ++i) {
diff --git a/graphics/tinygl/zblit.cpp b/graphics/tinygl/zblit.cpp
index bdb96ae78e5..2b16a1a41f0 100644
--- a/graphics/tinygl/zblit.cpp
+++ b/graphics/tinygl/zblit.cpp
@@ -38,11 +38,17 @@ Common::Rect rotateRectangle(int x, int y, int width, int height, int rotation,
 
 struct BlitImage {
 public:
-	BlitImage() : _isDisposed(false), _version(0), _binaryTransparent(false), _opaque(true), _refcount(1) { }
+	BlitImage() : _isDisposed(false), _version(0), _binaryTransparent(false), _opaque(true), _zBuffer(false), _refcount(1) { }
 
-	void loadData(const Graphics::Surface &surface, uint32 colorKey, bool applyColorKey) {
+	void loadData(const Graphics::Surface &surface, uint32 colorKey, bool applyColorKey, bool zBuffer) {
 		_lines.clear();
 
+		_zBuffer = zBuffer;
+		if (_zBuffer) {
+			_surface.copyFrom(surface);
+			return;
+		}
+
 		int size = surface.w * surface.h;
 		Graphics::PixelBuffer buffer(surface.format, (byte *)const_cast<void *>(surface.getPixels()));
 
@@ -213,6 +219,7 @@ public:
 	// The function only supports clipped blitting without any type of transformation or tinting.
 	void tglBlitZBuffer(int dstX, int dstY) {
 		TinyGL::GLContext *c = TinyGL::gl_get_context();
+		assert(_zBuffer);
 
 		int clampWidth, clampHeight;
 		int width = _surface.w, height = _surface.h;
@@ -254,6 +261,8 @@ public:
 	//Utility function that calls the correct blitting function.
 	template <bool kDisableBlending, bool kDisableColoring, bool kDisableTransform, bool kFlipVertical, bool kFlipHorizontal, bool kEnableAlphaBlending>
 	void tglBlitGeneric(const BlitTransform &transform) {
+		assert(!_zBuffer);
+
 		if (kDisableTransform) {
 			if (kDisableBlending && kDisableColoring && kFlipVertical == false && kFlipHorizontal == false) {
 				tglBlitOpaque(transform._destinationRectangle.left, transform._destinationRectangle.top,
@@ -296,6 +305,7 @@ private:
 	bool _isDisposed;
 	bool _binaryTransparent;
 	bool _opaque;
+	bool _zBuffer;
 	Common::Array<Line> _lines;
 	Graphics::Surface _surface;
 	int _version;
@@ -325,9 +335,9 @@ TinyGL::BlitImage *tglGenBlitImage() {
 	return image;
 }
 
-void tglUploadBlitImage(TinyGL::BlitImage *blitImage, const Graphics::Surface& surface, uint32 colorKey, bool applyColorKey) {
+void tglUploadBlitImage(TinyGL::BlitImage *blitImage, const Graphics::Surface& surface, uint32 colorKey, bool applyColorKey, bool zBuffer) {
 	if (blitImage != nullptr) {
-		blitImage->loadData(surface, colorKey, applyColorKey);
+		blitImage->loadData(surface, colorKey, applyColorKey, zBuffer);
 	}
 }
 
diff --git a/graphics/tinygl/zblit_public.h b/graphics/tinygl/zblit_public.h
index 19c8f4a27ec..1b82291b8ef 100644
--- a/graphics/tinygl/zblit_public.h
+++ b/graphics/tinygl/zblit_public.h
@@ -98,7 +98,7 @@ TinyGL::BlitImage *tglGenBlitImage();
 @param color key value for alpha color keying
 @param boolean that enables alpha color keying
 */
-void tglUploadBlitImage(TinyGL::BlitImage *blitImage, const Graphics::Surface &surface, uint32 colorKey, bool applyColorKey);
+void tglUploadBlitImage(TinyGL::BlitImage *blitImage, const Graphics::Surface &surface, uint32 colorKey, bool applyColorKey, bool zBuffer = false);
 
 /**
 @brief Destroys an instance of blit image.


Commit: f40c2ccfbd1e0fb598e00d423715b9ee84cf2f4d
    https://github.com/scummvm/scummvm/commit/f40c2ccfbd1e0fb598e00d423715b9ee84cf2f4d
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-03-03T09:59:41Z

Commit Message:
TINYGL: Remove unused tglBlitNoBlend function

Changed paths:
    graphics/tinygl/zblit.cpp
    graphics/tinygl/zblit.h
    graphics/tinygl/zblit_public.h
    graphics/tinygl/zdirtyrect.cpp
    graphics/tinygl/zdirtyrect.h


diff --git a/graphics/tinygl/zblit.cpp b/graphics/tinygl/zblit.cpp
index 2b16a1a41f0..d173fc052b8 100644
--- a/graphics/tinygl/zblit.cpp
+++ b/graphics/tinygl/zblit.cpp
@@ -701,11 +701,6 @@ void tglBlit(TinyGL::BlitImage *blitImage, const TinyGL::BlitTransform &transfor
 	c->issueDrawCall(new TinyGL::BlittingDrawCall(blitImage, transform, TinyGL::BlittingDrawCall::BlitMode_Regular));
 }
 
-void tglBlitNoBlend(TinyGL::BlitImage *blitImage, const TinyGL::BlitTransform &transform) {
-	TinyGL::GLContext *c = TinyGL::gl_get_context();
-	c->issueDrawCall(new TinyGL::BlittingDrawCall(blitImage, transform, TinyGL::BlittingDrawCall::BlitMode_NoBlend));
-}
-
 void tglBlitFast(TinyGL::BlitImage *blitImage, int x, int y) {
 	TinyGL::GLContext *c = TinyGL::gl_get_context();
 	TinyGL::BlitTransform transform(x, y);
@@ -778,16 +773,6 @@ void tglBlit(BlitImage *blitImage, const BlitTransform &transform) {
 	}
 }
 
-void tglBlitNoBlend(BlitImage *blitImage, const BlitTransform &transform) {
-	if (transform._flipHorizontally == false && transform._flipVertically == false) {
-		blitImage->tglBlitGeneric<true, false, false, false, false, false>(transform);
-	} else if(transform._flipHorizontally == false) {
-		blitImage->tglBlitGeneric<true, false, false, true, false, false>(transform);
-	} else {
-		blitImage->tglBlitGeneric<true, false, false, false, true, false>(transform);
-	}
-}
-
 void tglBlitFast(BlitImage *blitImage, int x, int y) {
 	BlitTransform transform(x, y);
 	blitImage->tglBlitGeneric<true, true, true, false, false, false>(transform);
diff --git a/graphics/tinygl/zblit.h b/graphics/tinygl/zblit.h
index c899f3c4264..7b6b6eb8722 100644
--- a/graphics/tinygl/zblit.h
+++ b/graphics/tinygl/zblit.h
@@ -40,9 +40,6 @@ namespace Internal {
 	// Documentation for those is the same as the one before, only those function are the one that actually execute the correct code path.
 	void tglBlit(BlitImage *blitImage, const BlitTransform &transform);
 
-	// Disables blending explicitly.
-	void tglBlitNoBlend(BlitImage *blitImage, const BlitTransform &transform);
-
 	// Disables blending, transforms and tinting.
 	void tglBlitFast(BlitImage *blitImage, int x, int y);
 
diff --git a/graphics/tinygl/zblit_public.h b/graphics/tinygl/zblit_public.h
index 1b82291b8ef..36134bda574 100644
--- a/graphics/tinygl/zblit_public.h
+++ b/graphics/tinygl/zblit_public.h
@@ -136,13 +136,6 @@ void tglBlit(TinyGL::BlitImage *blitImage, const TinyGL::BlitTransform &transfor
 */
 void tglBlit(TinyGL::BlitImage *blitImage, int x, int y);
 
-/**
- at brief Blits an image to the color buffer without performing any type of blending.
- at param pointer to the blit image.
- at param blit transform information.
-*/
-void tglBlitNoBlend(TinyGL::BlitImage *blitImage, const TinyGL::BlitTransform &transform);
-
 /**
 @brief Blits an image to the color buffer without performinc any type of blending, image transformation or tinting.
 @param pointer to the blit image.
diff --git a/graphics/tinygl/zdirtyrect.cpp b/graphics/tinygl/zdirtyrect.cpp
index e1f66a82f33..4a066e16f6e 100644
--- a/graphics/tinygl/zdirtyrect.cpp
+++ b/graphics/tinygl/zdirtyrect.cpp
@@ -593,9 +593,6 @@ void BlittingDrawCall::execute(bool restoreState) const {
 	case BlittingDrawCall::BlitMode_Regular:
 		Internal::tglBlit(_image, _transform);
 		break;
-	case BlittingDrawCall::BlitMode_NoBlend:
-		Internal::tglBlitNoBlend(_image, _transform);
-		break;
 	case BlittingDrawCall::BlitMode_Fast:
 		Internal::tglBlitFast(_image, _transform._destinationRectangle.left, _transform._destinationRectangle.top);
 		break;
diff --git a/graphics/tinygl/zdirtyrect.h b/graphics/tinygl/zdirtyrect.h
index 867adb2e5f5..0b49c385670 100644
--- a/graphics/tinygl/zdirtyrect.h
+++ b/graphics/tinygl/zdirtyrect.h
@@ -159,7 +159,6 @@ class BlittingDrawCall : public DrawCall {
 public:
 	enum BlittingMode {
 		BlitMode_Regular,
-		BlitMode_NoBlend,
 		BlitMode_Fast,
 		BlitMode_ZBuffer
 	};


Commit: 5432e4ad401958ca25f27dda006d9dbcfe46d30e
    https://github.com/scummvm/scummvm/commit/5432e4ad401958ca25f27dda006d9dbcfe46d30e
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-03-03T09:59:41Z

Commit Message:
TINYGL: Fix the incorrect use of tglBlitOpaque for additive blends

Changed paths:
    graphics/tinygl/zblit.cpp


diff --git a/graphics/tinygl/zblit.cpp b/graphics/tinygl/zblit.cpp
index d173fc052b8..0d7393381f9 100644
--- a/graphics/tinygl/zblit.cpp
+++ b/graphics/tinygl/zblit.cpp
@@ -259,12 +259,12 @@ public:
 	                      int originX, int originY, float aTint, float rTint, float gTint, float bTint);
 
 	//Utility function that calls the correct blitting function.
-	template <bool kDisableBlending, bool kDisableColoring, bool kDisableTransform, bool kFlipVertical, bool kFlipHorizontal, bool kEnableAlphaBlending>
+	template <bool kDisableBlending, bool kDisableColoring, bool kDisableTransform, bool kFlipVertical, bool kFlipHorizontal, bool kEnableAlphaBlending, bool kEnableOpaqueBlit>
 	void tglBlitGeneric(const BlitTransform &transform) {
 		assert(!_zBuffer);
 
 		if (kDisableTransform) {
-			if (kDisableBlending && kDisableColoring && kFlipVertical == false && kFlipHorizontal == false) {
+			if (kEnableOpaqueBlit && kDisableColoring && kFlipVertical == false && kFlipHorizontal == false) {
 				tglBlitOpaque(transform._destinationRectangle.left, transform._destinationRectangle.top,
 					transform._sourceRectangle.left, transform._sourceRectangle.top,
 					transform._sourceRectangle.width() , transform._sourceRectangle.height());
@@ -717,45 +717,54 @@ void tglBlitZBuffer(TinyGL::BlitImage *blitImage, int x, int y) {
 namespace TinyGL {
 namespace Internal {
 
-template <bool kEnableAlphaBlending, bool kDisableColor, bool kDisableTransform, bool kDisableBlend>
+template <bool kEnableAlphaBlending, bool kEnableOpaqueBlit, bool kDisableColor, bool kDisableTransform, bool kDisableBlend>
 void tglBlit(BlitImage *blitImage, const BlitTransform &transform) {
 	if (transform._flipHorizontally) {
 		if (transform._flipVertically) {
-			blitImage->tglBlitGeneric<kDisableBlend, kDisableColor, kDisableTransform, true, true, kEnableAlphaBlending>(transform);
+			blitImage->tglBlitGeneric<kDisableBlend, kDisableColor, kDisableTransform, true, true, kEnableAlphaBlending, kEnableOpaqueBlit>(transform);
 		} else {
-			blitImage->tglBlitGeneric<kDisableBlend, kDisableColor, kDisableTransform, false, true, kEnableAlphaBlending>(transform);
+			blitImage->tglBlitGeneric<kDisableBlend, kDisableColor, kDisableTransform, false, true, kEnableAlphaBlending, kEnableOpaqueBlit>(transform);
 		}
 	} else if (transform._flipVertically) {
-		blitImage->tglBlitGeneric<kDisableBlend, kDisableColor, kDisableTransform, true, false, kEnableAlphaBlending>(transform);
+		blitImage->tglBlitGeneric<kDisableBlend, kDisableColor, kDisableTransform, true, false, kEnableAlphaBlending, kEnableOpaqueBlit>(transform);
 	} else {
-		blitImage->tglBlitGeneric<kDisableBlend, kDisableColor, kDisableTransform, false, false, kEnableAlphaBlending>(transform);
+		blitImage->tglBlitGeneric<kDisableBlend, kDisableColor, kDisableTransform, false, false, kEnableAlphaBlending, kEnableOpaqueBlit>(transform);
 	}
 }
 
-template <bool kEnableAlphaBlending, bool kDisableColor, bool kDisableTransform>
+template <bool kEnableAlphaBlending, bool kEnableOpaqueBlit, bool kDisableColor, bool kDisableTransform>
 void tglBlit(BlitImage *blitImage, const BlitTransform &transform, bool disableBlend) {
 	if (disableBlend) {
-		tglBlit<kEnableAlphaBlending, kDisableColor, kDisableTransform, true>(blitImage, transform);
+		tglBlit<kEnableAlphaBlending, kEnableOpaqueBlit, kDisableColor, kDisableTransform, true>(blitImage, transform);
 	} else {
-		tglBlit<kEnableAlphaBlending, kDisableColor, kDisableTransform, false>(blitImage, transform);
+		tglBlit<kEnableAlphaBlending, kEnableOpaqueBlit, kDisableColor, kDisableTransform, false>(blitImage, transform);
 	}
 }
 
-template <bool kEnableAlphaBlending, bool kDisableColor>
+template <bool kEnableAlphaBlending, bool kEnableOpaqueBlit, bool kDisableColor>
 void tglBlit(BlitImage *blitImage, const BlitTransform &transform, bool disableTransform, bool disableBlend) {
 	if (disableTransform) {
-		tglBlit<kEnableAlphaBlending, kDisableColor, true>(blitImage, transform, disableBlend);
+		tglBlit<kEnableAlphaBlending, kEnableOpaqueBlit, kDisableColor, true>(blitImage, transform, disableBlend);
 	} else {
-		tglBlit<kEnableAlphaBlending, kDisableColor, false>(blitImage, transform, disableBlend);
+		tglBlit<kEnableAlphaBlending, kEnableOpaqueBlit, kDisableColor, false>(blitImage, transform, disableBlend);
 	}
 }
 
-template <bool kEnableAlphaBlending>
+template <bool kEnableAlphaBlending, bool kEnableOpaqueBlit>
 void tglBlit(BlitImage *blitImage, const BlitTransform &transform, bool disableColor, bool disableTransform, bool disableBlend) {
 	if (disableColor) {
-		tglBlit<kEnableAlphaBlending, true>(blitImage, transform, disableTransform, disableBlend);
+		tglBlit<kEnableAlphaBlending, kEnableOpaqueBlit, true>(blitImage, transform, disableTransform, disableBlend);
+	} else {
+		tglBlit<kEnableAlphaBlending, kEnableOpaqueBlit, false>(blitImage, transform, disableTransform, disableBlend);
+	}
+}
+
+template <bool kEnableAlphaBlending>
+void tglBlit(BlitImage *blitImage, const BlitTransform &transform, bool enableOpaqueBlit, bool disableColor, bool disableTransform, bool disableBlend) {
+	if (enableOpaqueBlit) {
+		tglBlit<kEnableAlphaBlending, true>(blitImage, transform, disableColor, disableTransform, disableBlend);
 	} else {
-		tglBlit<kEnableAlphaBlending, false>(blitImage, transform, disableTransform, disableBlend);
+		tglBlit<kEnableAlphaBlending, false>(blitImage, transform, disableColor, disableTransform, disableBlend);
 	}
 }
 
@@ -763,19 +772,26 @@ void tglBlit(BlitImage *blitImage, const BlitTransform &transform) {
 	GLContext *c = gl_get_context();
 	bool disableColor = transform._aTint == 1.0f && transform._bTint == 1.0f && transform._gTint == 1.0f && transform._rTint == 1.0f;
 	bool disableTransform = transform._destinationRectangle.width() == 0 && transform._destinationRectangle.height() == 0 && transform._rotation == 0;
-	bool disableBlend = blitImage->isOpaque() || c->blending_enabled == false;
+	bool disableBlend = c->blending_enabled == false;
 	bool enableAlphaBlending = c->source_blending_factor == TGL_SRC_ALPHA && c->destination_blending_factor == TGL_ONE_MINUS_SRC_ALPHA;
+	bool enableOpaqueBlit = blitImage->isOpaque()
+	                    && (c->source_blending_factor == TGL_ONE || c->source_blending_factor == TGL_SRC_ALPHA)
+	                    && (c->destination_blending_factor == TGL_ZERO || c->destination_blending_factor == TGL_ONE_MINUS_SRC_ALPHA);
 
 	if (enableAlphaBlending) {
-		tglBlit<true>(blitImage, transform, disableColor, disableTransform, disableBlend);
+		tglBlit<true>(blitImage, transform, enableOpaqueBlit, disableColor, disableTransform, disableBlend);
 	} else {
-		tglBlit<false>(blitImage, transform, disableColor, disableTransform, disableBlend);
+		tglBlit<false>(blitImage, transform, enableOpaqueBlit, disableColor, disableTransform, disableBlend);
 	}
 }
 
 void tglBlitFast(BlitImage *blitImage, int x, int y) {
 	BlitTransform transform(x, y);
-	blitImage->tglBlitGeneric<true, true, true, false, false, false>(transform);
+	if (blitImage->isOpaque()) {
+		blitImage->tglBlitGeneric<true, true, true, false, false, false, true>(transform);
+	} else {
+		blitImage->tglBlitGeneric<true, true, true, false, false, false, false>(transform);
+	}
 }
 
 void tglBlitZBuffer(BlitImage *blitImage, int x, int y) {




More information about the Scummvm-git-logs mailing list