[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