[Scummvm-git-logs] scummvm master -> 051ff0ed9db0c80cd8bd238ea858c71b6dd05097
aquadran
noreply at scummvm.org
Thu Jun 12 04:35:35 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:
051ff0ed9d WINTERMUTE: Reduce direct access to surface pixel buffers
Commit: 051ff0ed9db0c80cd8bd238ea858c71b6dd05097
https://github.com/scummvm/scummvm/commit/051ff0ed9db0c80cd8bd238ea858c71b6dd05097
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2025-06-12T06:35:31+02:00
Commit Message:
WINTERMUTE: Reduce direct access to surface pixel buffers
Changed paths:
engines/wintermute/base/font/base_font_truetype.cpp
engines/wintermute/base/gfx/base_image.cpp
engines/wintermute/base/gfx/base_image.h
engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp
engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
engines/wintermute/base/gfx/osystem/base_surface_osystem.h
engines/wintermute/base/gfx/osystem/render_ticket.cpp
engines/wintermute/video/video_theora_player.cpp
engines/wintermute/video/video_theora_player.h
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index 26b6e291d4b..69063d6c4f8 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -298,7 +298,9 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat();
uint32 *pixels = (uint32 *)surface->getPixels();
- // This is a Surface we created ourselves, so no empty space between rows.
+ assert(surface->pitch == surface->w * 4);
+ assert(surface->format.bytesPerPixel == 4);
+
for (int i = 0; i < surface->w * surface->h; ++i) {
uint8 a, r, g, b;
format.colorToRGB(*pixels, r, g, b);
diff --git a/engines/wintermute/base/gfx/base_image.cpp b/engines/wintermute/base/gfx/base_image.cpp
index b8fb3267c0a..aece1331ca2 100644
--- a/engines/wintermute/base/gfx/base_image.cpp
+++ b/engines/wintermute/base/gfx/base_image.cpp
@@ -91,16 +91,6 @@ bool BaseImage::loadFile(const Common::String &filename) {
return true;
}
-byte BaseImage::getAlphaAt(int x, int y) const {
- if (!_surface) {
- return 0xFF;
- }
- uint32 color = *(const uint32 *)_surface->getBasePtr(x, y);
- byte r, g, b, a;
- _surface->format.colorToARGB(color, a, r, g, b);
- return a;
-}
-
//////////////////////////////////////////////////////////////////////////
bool BaseImage::saveBMPFile(const Common::String &filename) const {
Common::WriteStream *stream = openSfmFileForWrite(filename);
diff --git a/engines/wintermute/base/gfx/base_image.h b/engines/wintermute/base/gfx/base_image.h
index a5f309573b4..119089f3002 100644
--- a/engines/wintermute/base/gfx/base_image.h
+++ b/engines/wintermute/base/gfx/base_image.h
@@ -58,7 +58,6 @@ public:
uint16 getPaletteCount() const {
return _paletteCount;
}
- byte getAlphaAt(int x, int y) const;
bool writeBMPToStream(Common::WriteStream *stream) const;
bool saveBMPFile(const Common::String &filename) const;
void copyFrom(const Graphics::Surface *surface, int newWidth = 0, int newHeight = 0, byte flip = 0);
diff --git a/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp b/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp
index 692f66164eb..25845f3b106 100644
--- a/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp
@@ -60,8 +60,7 @@ bool BaseSurfaceOpenGL3D::invalidate() {
bool BaseSurfaceOpenGL3D::isTransparentAt(int x, int y) {
prepareToDraw();
- uint8 alpha = reinterpret_cast<uint8 *>(_imageData->getPixels())[y * _width * 4 + x * 4 + 3];
- return alpha < 128;
+ return isTransparentAtLite(x, y);
}
bool BaseSurfaceOpenGL3D::displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha, Graphics::TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index d1fca551cad..bbf61904d7e 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -143,14 +143,14 @@ bool BaseRenderOSystem::initRenderer(int width, int height, bool windowed) {
bool BaseRenderOSystem::indicatorFlip() {
if (_indicatorWidthDrawn > 0 && _indicatorHeight > 0) {
- g_system->copyRectToScreen((byte *)_renderSurface->getBasePtr(_indicatorX, _indicatorY), _renderSurface->pitch, _indicatorX, _indicatorY, _indicatorWidthDrawn, _indicatorHeight);
+ g_system->copyRectToScreen(_renderSurface->getBasePtr(_indicatorX, _indicatorY), _renderSurface->pitch, _indicatorX, _indicatorY, _indicatorWidthDrawn, _indicatorHeight);
g_system->updateScreen();
}
return STATUS_OK;
}
bool BaseRenderOSystem::forcedFlip() {
- g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
+ g_system->copyRectToScreen(_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
g_system->updateScreen();
return STATUS_OK;
}
@@ -196,9 +196,9 @@ bool BaseRenderOSystem::flip() {
if (_needsFlip || _disableDirtyRects || screenChanged) {
if (_disableDirtyRects || screenChanged) {
- g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
+ g_system->copyRectToScreen(_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
}
- // g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height());
+ // g_system->copyRectToScreen(_renderSurface->getPixels(), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height());
delete _dirtyRect;
_dirtyRect = nullptr;
_needsFlip = false;
@@ -452,7 +452,7 @@ void BaseRenderOSystem::drawTickets() {
// Some tickets want redraw but don't actually clip the dirty area (typically the ones that shouldn't become clear-color)
ticket->_wantsDraw = false;
}
- g_system->copyRectToScreen((byte *)_renderSurface->getBasePtr(_dirtyRect->left, _dirtyRect->top), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height());
+ g_system->copyRectToScreen(_renderSurface->getBasePtr(_dirtyRect->left, _dirtyRect->top), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height());
it = _renderQueue.begin();
// Clean out the old tickets
@@ -580,7 +580,7 @@ void BaseRenderOSystem::endSaveLoad() {
_lastFrameIter = _renderQueue.end();
_renderSurface->fillRect(Common::Rect(0, 0, _renderSurface->w, _renderSurface->h), _renderSurface->format.ARGBToColor(255, 0, 0, 0));
- g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
+ g_system->fillScreen(Common::Rect(0, 0, _renderSurface->w, _renderSurface->h), _renderSurface->format.ARGBToColor(255, 0, 0, 0));
g_system->updateScreen();
}
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index 29959ac6d53..083de50e0a8 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -165,16 +165,17 @@ bool BaseSurfaceOSystem::finishLoad() {
// Some Rosemary sprites have non-fully transparent pixels
// In original WME it wasn't seen because sprites were downscaled
// Let's set alpha to 0 if it is smaller then some treshold
- if (BaseEngine::instance().getGameId() == "rosemary" && _filename.hasPrefix("actors") && _surface->format.bytesPerPixel == 4) {
- uint8 treshold = 16;
+ if (BaseEngine::instance().getGameId() == "rosemary" && _filename.hasPrefix("actors") &&
+ _alphaType == Graphics::ALPHA_FULL && _surface->format.aBits() > 4) {
+ uint32 mask = _surface->format.ARGBToColor(255, 0, 0, 0);
+ uint32 treshold = _surface->format.ARGBToColor(16, 0, 0, 0);
+ uint32 blank = _surface->format.ARGBToColor(0, 0, 0, 0);
+
for (int x = 0; x < _surface->w; x++) {
for (int y = 0; y < _surface->h; y++) {
- uint32 pixel = getPixelAt(_surface, x, y);
- uint8 r, g, b, a;
- _surface->format.colorToARGB(pixel, a, r, g, b);
- if (a > 0 && a < treshold) {
- uint32 *p = (uint32 *)_surface->getBasePtr(x, y);
- *p = _surface->format.ARGBToColor(0, 0, 0, 0);
+ uint32 pixel = _surface->getPixel(x, y);
+ if ((pixel & mask) > blank && (pixel & mask) < treshold) {
+ _surface->setPixel(x, y, blank);
}
}
}
@@ -209,7 +210,7 @@ void BaseSurfaceOSystem::genAlphaMask(Graphics::Surface *surface) {
bool hasTransparency = false;
for (int y = 0; y < surface->h; y++) {
for (int x = 0; x < surface->w; x++) {
- uint32 pixel = getPixelAt(surface, x, y);
+ uint32 pixel = surface->getPixel(x, y);
uint8 r, g, b, a;
surface->format.colorToARGB(pixel, a, r, g, b);
@@ -232,41 +233,6 @@ void BaseSurfaceOSystem::genAlphaMask(Graphics::Surface *surface) {
}
}
-//////////////////////////////////////////////////////////////////////////
-uint32 BaseSurfaceOSystem::getPixelAt(Graphics::Surface *surface, int x, int y) {
- int bpp = surface->format.bytesPerPixel;
- /* Here p is the address to the pixel we want to retrieve */
- uint8 *p = (uint8 *)surface->getBasePtr(x, y);
-
- switch (bpp) {
- case 1:
- return *p;
- break;
-
- case 2:
- return *(uint16 *)p;
- break;
-
- case 3:
-#ifdef SCUMM_BIG_ENDIAN
- // if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
- return p[0] << 16 | p[1] << 8 | p[2];
-#else
- //else
- return p[0] | p[1] << 8 | p[2] << 16;
-#endif
- break;
-
- case 4:
- return *(uint32 *)p;
- break;
-
- default:
- return 0; /* shouldn't happen, but avoids warnings */
- }
- return 0;
-}
-
//////////////////////////////////////////////////////////////////////////
bool BaseSurfaceOSystem::create(int width, int height) {
_width = width;
@@ -290,18 +256,14 @@ bool BaseSurfaceOSystem::isTransparentAtLite(int x, int y) {
return true;
}
- if (_surface->format.bytesPerPixel == 4) {
- uint32 pixel = *(uint32 *)_surface->getBasePtr(x, y);
- uint8 r, g, b, a;
- _surface->format.colorToARGB(pixel, a, r, g, b);
- if (a <= 128) {
- return true;
- } else {
- return false;
- }
+ uint32 pixel = _surface->getPixel(x, y);
+ uint8 r, g, b, a;
+ _surface->format.colorToARGB(pixel, a, r, g, b);
+ if (a <= 128) {
+ return true;
+ } else {
+ return false;
}
-
- return false;
}
//////////////////////////////////////////////////////////////////////////
@@ -422,10 +384,8 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
bool BaseSurfaceOSystem::putSurface(const Graphics::Surface &surface, bool hasAlpha) {
_loaded = true;
- if (surface.format == _surface->format && surface.pitch == _surface->pitch && surface.h == _surface->h) {
- const byte *src = (const byte *)surface.getBasePtr(0, 0);
- byte *dst = (byte *)_surface->getBasePtr(0, 0);
- memcpy(dst, src, surface.pitch * surface.h);
+ if (surface.format == _surface->format && surface.w == _surface->w && surface.h == _surface->h) {
+ _surface->copyRectToSurface(surface, 0, 0, Common::Rect(surface.w, surface.h));
} else {
_surface->free();
_surface->copyFrom(surface);
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
index 2e668e556b5..83e1eecd7c8 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -83,7 +83,7 @@ public:
finishLoad();
}
if (_surface) {
- uint32 pixel = getPixelAt(_surface, x, y);
+ uint32 pixel = _surface->getPixel(x, y);
_surface->format.colorToARGB(pixel, *a, *r, *g, *b);
return STATUS_OK;
}
@@ -97,7 +97,6 @@ private:
bool finishLoad();
bool drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, Graphics::TransformStruct transformStruct);
void genAlphaMask(Graphics::Surface *surface);
- uint32 getPixelAt(Graphics::Surface *surface, int x, int y);
float _rotation;
Graphics::AlphaType _alphaType;
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
index 2107601e397..d9d73812073 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
@@ -45,14 +45,12 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s
_wantsDraw(true),
_transform(transform) {
if (surf) {
- _surface = new Graphics::Surface();
- _surface->create((uint16)srcRect->width(), (uint16)srcRect->height(), surf->format);
- assert(_surface->format.bytesPerPixel == 4);
- // Get a clipped copy of the surface
- for (int i = 0; i < _surface->h; i++) {
- memcpy(_surface->getBasePtr(0, i), surf->getBasePtr(srcRect->left, srcRect->top + i), srcRect->width() * _surface->format.bytesPerPixel);
- }
- // Then scale it if necessary
+ assert(surf->format.bytesPerPixel == 4);
+
+ // Get a clipped view of the surface
+ const Graphics::Surface temp = surf->getSubArea(*srcRect);
+
+ // Then copy and scale it as necessary
//
// NB: The numTimesX/numTimesY properties don't yet mix well with
// scaling and rotation, but there is no need for that functionality at
@@ -61,17 +59,14 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s
// (Mirroring should most likely be done before rotation. See also
// TransformTools.)
if (_transform._angle != Graphics::kDefaultAngle) {
- Graphics::Surface *temp = _surface->rotoscale(transform, owner->_gameRef->getBilinearFiltering());
- _surface->free();
- delete _surface;
- _surface = temp;
+ _surface = temp.rotoscale(transform, owner->_gameRef->getBilinearFiltering());
} else if ((dstRect->width() != srcRect->width() ||
dstRect->height() != srcRect->height()) &&
_transform._numTimesX * _transform._numTimesY == 1) {
- Graphics::Surface *temp = _surface->scale(dstRect->width(), dstRect->height(), owner->_gameRef->getBilinearFiltering());
- _surface->free();
- delete _surface;
- _surface = temp;
+ _surface = temp.scale(dstRect->width(), dstRect->height(), owner->_gameRef->getBilinearFiltering());
+ } else {
+ _surface = new Graphics::Surface();
+ _surface->copyFrom(temp);
}
} else {
_surface = nullptr;
diff --git a/engines/wintermute/video/video_theora_player.cpp b/engines/wintermute/video/video_theora_player.cpp
index a1ebba08b02..7953874c38b 100644
--- a/engines/wintermute/video/video_theora_player.cpp
+++ b/engines/wintermute/video/video_theora_player.cpp
@@ -318,10 +318,8 @@ bool VideoTheoraPlayer::update() {
if (!_theoraDecoder->endOfVideo() && _theoraDecoder->getTimeToNextFrame() == 0) {
const Graphics::Surface *decodedFrame = _theoraDecoder->decodeNextFrame();
if (decodedFrame) {
- if (decodedFrame->format == _surface.format && decodedFrame->pitch == _surface.pitch && decodedFrame->h == _surface.h) {
- const byte *src = (const byte *)decodedFrame->getBasePtr(0, 0);
- byte *dst = (byte *)_surface.getBasePtr(0, 0);
- memcpy(dst, src, _surface.pitch * _surface.h);
+ if (decodedFrame->format == _surface.format && decodedFrame->w == _surface.w && decodedFrame->h == _surface.h) {
+ _surface.copyRectToSurface(*decodedFrame, 0, 0, Common::Rect(decodedFrame->w, decodedFrame->h));
} else {
_surface.free();
_surface.copyFrom(*decodedFrame);
@@ -386,7 +384,9 @@ bool VideoTheoraPlayer::writeVideo() {
void VideoTheoraPlayer::writeAlpha() {
if (_alphaImage && _surface.w == _alphaImage->getSurface()->w && _surface.h == _alphaImage->getSurface()->h) {
+ assert(_alphaImage->getSurface()->pitch == _alphaImage->getSurface()->w * 4);
assert(_alphaImage->getSurface()->format.bytesPerPixel == 4);
+ assert(_surface.pitch == _surface.w * 4);
assert(_surface.format.bytesPerPixel == 4);
const byte *alphaData = (const byte *)_alphaImage->getSurface()->getPixels();
#ifdef SCUMM_LITTLE_ENDIAN
@@ -450,16 +450,6 @@ bool VideoTheoraPlayer::setAlphaImage(const Common::String &filename) {
return STATUS_OK;
}
-//////////////////////////////////////////////////////////////////////////
-byte VideoTheoraPlayer::getAlphaAt(int x, int y) const {
- if (_alphaImage) {
- return _alphaImage->getAlphaAt(x, y);
- } else {
- return 0xFF;
- }
-}
-
-
//////////////////////////////////////////////////////////////////////////
inline int intlog(int num) {
int r = 0;
diff --git a/engines/wintermute/video/video_theora_player.h b/engines/wintermute/video/video_theora_player.h
index 4e2bc075f96..4a4123f2670 100644
--- a/engines/wintermute/video/video_theora_player.h
+++ b/engines/wintermute/video/video_theora_player.h
@@ -90,7 +90,6 @@ public:
BaseImage *_alphaImage;
Common::String _alphaFilename;
bool setAlphaImage(const Common::String &filename);
- byte getAlphaAt(int x, int y) const;
void writeAlpha();
bool seekToTime(uint32 Time);
More information about the Scummvm-git-logs
mailing list