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

bluegr noreply at scummvm.org
Fri Sep 4 10:48:38 UTC 2026


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:
b6c66aabdd STARK: Reduce surface copying when creating viewport screenshots


Commit: b6c66aabdd7c46010d9ea8297cdaeb1167093c00
    https://github.com/scummvm/scummvm/commit/b6c66aabdd7c46010d9ea8297cdaeb1167093c00
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2026-09-04T13:48:35+03:00

Commit Message:
STARK: Reduce surface copying when creating viewport screenshots

Changed paths:
    engines/stark/gfx/driver.cpp
    engines/stark/gfx/driver.h
    engines/stark/gfx/opengl.cpp
    engines/stark/gfx/opengl.h
    engines/stark/gfx/opengls.cpp
    engines/stark/gfx/opengls.h
    engines/stark/gfx/tinygl.cpp
    engines/stark/gfx/tinygl.h
    engines/stark/savemetadata.cpp
    engines/stark/savemetadata.h
    engines/stark/services/userinterface.cpp
    engines/stark/ui/window.cpp
    engines/stark/ui/window.h


diff --git a/engines/stark/gfx/driver.cpp b/engines/stark/gfx/driver.cpp
index 58de9a97f13..8a32ec83bab 100644
--- a/engines/stark/gfx/driver.cpp
+++ b/engines/stark/gfx/driver.cpp
@@ -149,17 +149,6 @@ uint Driver::scaleHeightCurrentToOriginal(uint height) const {
 	return kOriginalHeight * height / _screenViewport.height();
 }
 
-void Driver::flipVertical(Graphics::Surface *s) {
-	for (int y = 0; y < s->h / 2; ++y) {
-		// Flip the lines
-		byte *line1P = (byte *)s->getBasePtr(0, y);
-		byte *line2P = (byte *)s->getBasePtr(0, s->h - y - 1);
-
-		for (int x = 0; x < s->pitch; ++x)
-			SWAP(line1P[x], line2P[x]);
-	}
-}
-
 bool Driver::isPosInScreenBounds(const Common::Point &point) const {
 	return _screenViewport.contains(point);
 }
diff --git a/engines/stark/gfx/driver.h b/engines/stark/gfx/driver.h
index 0279be9b370..13c4493d5fe 100644
--- a/engines/stark/gfx/driver.h
+++ b/engines/stark/gfx/driver.h
@@ -135,8 +135,8 @@ public:
 	 */
 	static const Graphics::PixelFormat getRGBAPixelFormat();
 
-	/** Grab a screenshot of the currently active viewport as defined by setViewport */
-	virtual Graphics::Surface *getViewportScreenshot() const = 0;
+	/** Grab a scaled screenshot of the currently active viewport as defined by setViewport */
+	virtual Graphics::Surface *getViewportScreenshot(uint w, uint h) const = 0;
 
 	virtual void set3DMode() = 0;
 	virtual bool computeLightsEnabled() = 0;
@@ -153,8 +153,6 @@ public:
 	static const int32 kGameViewportWidth = 640;
 
 protected:
-	static void flipVertical(Graphics::Surface *s);
-
 	Common::Rect _screenViewport;
 	bool         _computeLights;
 };
diff --git a/engines/stark/gfx/opengl.cpp b/engines/stark/gfx/opengl.cpp
index 8a9fd46e53c..a5ad6dd1c5a 100644
--- a/engines/stark/gfx/opengl.cpp
+++ b/engines/stark/gfx/opengl.cpp
@@ -269,14 +269,17 @@ Common::Rect OpenGLDriver::getUnscaledViewport() const {
 	return _unscaledViewport;
 }
 
-Graphics::Surface *OpenGLDriver::getViewportScreenshot() const {
-	Graphics::Surface *s = new Graphics::Surface();
-	s->create(_viewport.width(), _viewport.height(), getRGBAPixelFormat());
+Graphics::Surface *OpenGLDriver::getViewportScreenshot(uint w, uint h) const {
+	Graphics::Surface *tmp = new Graphics::Surface();
+	tmp->create(_viewport.width(), _viewport.height(), Graphics::PixelFormat::createFormatRGBA32());
 
 	glReadPixels(_viewport.left, g_system->getHeight() - _viewport.bottom, _viewport.width(), _viewport.height(),
-	             GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());
+	             GL_RGBA, GL_UNSIGNED_BYTE, tmp->getPixels());
 
-	flipVertical(s);
+	Graphics::Surface *s = tmp->scale(w, h, false, Graphics::FLIP_V);
+
+	tmp->free();
+	delete tmp;
 
 	return s;
 }
diff --git a/engines/stark/gfx/opengl.h b/engines/stark/gfx/opengl.h
index 7db8fea015e..5efda21e377 100644
--- a/engines/stark/gfx/opengl.h
+++ b/engines/stark/gfx/opengl.h
@@ -64,7 +64,7 @@ public:
 	Common::Rect getUnscaledViewport() const;
 	void setupLights(const LightEntryArray &lights);
 
-	Graphics::Surface *getViewportScreenshot() const override;
+	Graphics::Surface *getViewportScreenshot(uint w, uint h) const override;
 
 private:
 	Common::Rect _viewport;
diff --git a/engines/stark/gfx/opengls.cpp b/engines/stark/gfx/opengls.cpp
index 86068d15b43..55ff3cd5e7b 100644
--- a/engines/stark/gfx/opengls.cpp
+++ b/engines/stark/gfx/opengls.cpp
@@ -232,14 +232,17 @@ OpenGL::Shader *OpenGLSDriver::createShadowShaderInstance() {
 	return _shadowShader->clone();
 }
 
-Graphics::Surface *OpenGLSDriver::getViewportScreenshot() const {
-	Graphics::Surface *s = new Graphics::Surface();
-	s->create(_viewport.width(), _viewport.height(), getRGBAPixelFormat());
+Graphics::Surface *OpenGLSDriver::getViewportScreenshot(uint w, uint h) const {
+	Graphics::Surface *tmp = new Graphics::Surface();
+	tmp->create(_viewport.width(), _viewport.height(), Graphics::PixelFormat::createFormatRGBA32());
 
 	glReadPixels(_viewport.left, g_system->getHeight() - _viewport.bottom, _viewport.width(), _viewport.height(),
-	             GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());
+	             GL_RGBA, GL_UNSIGNED_BYTE, tmp->getPixels());
 
-	flipVertical(s);
+	Graphics::Surface *s = tmp->scale(w, h, false, Graphics::FLIP_V);
+
+	tmp->free();
+	delete tmp;
 
 	return s;
 }
diff --git a/engines/stark/gfx/opengls.h b/engines/stark/gfx/opengls.h
index b19f8eddb82..46643b29df3 100644
--- a/engines/stark/gfx/opengls.h
+++ b/engines/stark/gfx/opengls.h
@@ -71,7 +71,7 @@ public:
 	Common::Rect getViewport() const;
 	Common::Rect getUnscaledViewport() const;
 
-	Graphics::Surface *getViewportScreenshot() const override;
+	Graphics::Surface *getViewportScreenshot(uint w, uint h) const override;
 
 private:
 	Common::Rect _viewport;
diff --git a/engines/stark/gfx/tinygl.cpp b/engines/stark/gfx/tinygl.cpp
index 616acce266f..f345333ad1c 100644
--- a/engines/stark/gfx/tinygl.cpp
+++ b/engines/stark/gfx/tinygl.cpp
@@ -172,16 +172,12 @@ Common::Rect TinyGLDriver::getUnscaledViewport() const {
 	return _unscaledViewport;
 }
 
-Graphics::Surface *TinyGLDriver::getViewportScreenshot() const {
-	Graphics::Surface *tmp = TinyGL::copyFromFrameBuffer(getRGBAPixelFormat());
-	Graphics::Surface *s = new Graphics::Surface();
-	s->create(_viewport.width(), _viewport.height(), getRGBAPixelFormat());
-	byte *src = (byte *)tmp->getPixels();
-	s->copyRectToSurface(src + tmp->pitch * _viewport.top + _viewport.left * tmp->format.bytesPerPixel,
-	                     tmp->pitch, 0, 0, _viewport.width(), _viewport.height());
-	tmp->free();
-	delete tmp;
-	return s;
+Graphics::Surface *TinyGLDriver::getViewportScreenshot(uint w, uint h) const {
+	Graphics::Surface glBuffer;
+	TinyGL::getSurfaceRef(glBuffer);
+
+	const Graphics::Surface subArea = glBuffer.getSubArea(_viewport);
+	return subArea.scale(w, h);
 }
 
 } // End of namespace Gfx
diff --git a/engines/stark/gfx/tinygl.h b/engines/stark/gfx/tinygl.h
index d3ebaf2070c..ce1c9bf05db 100644
--- a/engines/stark/gfx/tinygl.h
+++ b/engines/stark/gfx/tinygl.h
@@ -63,7 +63,7 @@ public:
 	Common::Rect getUnscaledViewport() const;
 	void setupLights(const LightEntryArray &lights);
 
-	Graphics::Surface *getViewportScreenshot() const override;
+	Graphics::Surface *getViewportScreenshot(uint w, uint h) const override;
 
 	bool supportsModdedAssets() const override { return false; }
 
diff --git a/engines/stark/savemetadata.cpp b/engines/stark/savemetadata.cpp
index a4cd5839df1..85494c6bf7b 100644
--- a/engines/stark/savemetadata.cpp
+++ b/engines/stark/savemetadata.cpp
@@ -136,7 +136,7 @@ void SaveMetadata::skipGameScreenThumbnail(Common::SeekableReadStream *stream) {
 
 Graphics::Surface *SaveMetadata::readGameScreenThumbnail(Common::SeekableReadStream *stream) {
 	Graphics::Surface *thumb = new Graphics::Surface();
-	thumb->create(kThumbnailWidth, kThumbnailHeight, Gfx::Driver::getRGBAPixelFormat());
+	thumb->create(kThumbnailWidth, kThumbnailHeight, getPixelFormat());
 
 	stream->read(thumb->getPixels(), kThumbnailSize);
 
diff --git a/engines/stark/savemetadata.h b/engines/stark/savemetadata.h
index acecfda1025..b8b3f39747a 100644
--- a/engines/stark/savemetadata.h
+++ b/engines/stark/savemetadata.h
@@ -79,6 +79,10 @@ public:
 	/** Write the game screen thumbnail to a stream */
 	void writeGameScreenThumbnail(Common::WriteStream *stream);
 
+	static constexpr inline Graphics::PixelFormat getPixelFormat() {
+		return Graphics::PixelFormat::createFormatRGBA32();
+	}
+
 private:
 	void saveLoad(ResourceSerializer *s);
 	static void syncResourceIndexAsString(ResourceSerializer *s, uint &index);
diff --git a/engines/stark/services/userinterface.cpp b/engines/stark/services/userinterface.cpp
index 136a0f3811c..e8abdf2bb51 100644
--- a/engines/stark/services/userinterface.cpp
+++ b/engines/stark/services/userinterface.cpp
@@ -55,6 +55,8 @@
 #include "engines/stark/resources/knowledgeset.h"
 #include "engines/stark/resources/item.h"
 
+#include "engines/stark/savemetadata.h"
+
 #include "gui/message.h"
 
 namespace Stark {
@@ -353,26 +355,8 @@ void UserInterface::saveGameScreenThumbnail() {
 		_gameScreen->render();
 	}
 
-	Graphics::Surface *big = _gameScreen->getGameWindow()->getScreenshot();
-	assert(big->format.bytesPerPixel == 4);
-
-	_gameWindowThumbnail = new Graphics::Surface();
-	_gameWindowThumbnail->create(kThumbnailWidth, kThumbnailHeight, big->format);
-
-	uint32 *dst = (uint32 *)_gameWindowThumbnail->getPixels();
-	for (int i = 0; i < _gameWindowThumbnail->h; i++) {
-		for (int j = 0; j < _gameWindowThumbnail->w; j++) {
-			uint32 srcX = big->w * j / _gameWindowThumbnail->w;
-			uint32 srcY = big->h * i / _gameWindowThumbnail->h;
-			uint32 *src = (uint32 *)big->getBasePtr(srcX, srcY);
-
-			// Copy RGBA pixel
-			*dst++ = *src;
-		}
-	}
-
-	big->free();
-	delete big;
+	_gameWindowThumbnail = _gameScreen->getGameWindow()->getScreenshot(kThumbnailWidth, kThumbnailHeight);
+	_gameWindowThumbnail->convertToInPlace(SaveMetadata::getPixelFormat());
 }
 
 void UserInterface::freeGameScreenThumbnail() {
diff --git a/engines/stark/ui/window.cpp b/engines/stark/ui/window.cpp
index 88afabea1b9..02ff515cdb1 100644
--- a/engines/stark/ui/window.cpp
+++ b/engines/stark/ui/window.cpp
@@ -53,13 +53,13 @@ void Window::render() {
 	onRender();
 }
 
-Graphics::Surface *Window::getScreenshot() const {
+Graphics::Surface *Window::getScreenshot(uint w, uint h) const {
 	if (!_visible) {
 		return nullptr;
 	}
 
 	_gfx->setViewport(_position);
-	return _gfx->getViewportScreenshot();
+	return _gfx->getViewportScreenshot(w, h);
 }
 
 bool Window::isMouseInside() const {
diff --git a/engines/stark/ui/window.h b/engines/stark/ui/window.h
index eb91d540ca4..bbd07aee1d1 100644
--- a/engines/stark/ui/window.h
+++ b/engines/stark/ui/window.h
@@ -81,7 +81,7 @@ public:
 	bool isVisible() const;
 
 	/** Grab a screenshot of the window if it is visible */
-	Graphics::Surface *getScreenshot() const;
+	Graphics::Surface *getScreenshot(uint w, uint h) const;
 
 protected:
 	virtual void onMouseMove(const Common::Point &pos) {}




More information about the Scummvm-git-logs mailing list