[Scummvm-git-logs] scummvm master -> 0cf9a8628657f5ae25674a8c48cde0728f4fc025
dreammaster
dreammaster at scummvm.org
Mon Jul 12 03:06:58 UTC 2021
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
0cf9a86286 AGS: Further optimization for 32-bit screen rendering
Commit: 0cf9a8628657f5ae25674a8c48cde0728f4fc025
https://github.com/scummvm/scummvm/commit/0cf9a8628657f5ae25674a8c48cde0728f4fc025
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-11T20:06:32-07:00
Commit Message:
AGS: Further optimization for 32-bit screen rendering
I tried once again to refactor the AGS codebase to use an RGBA
format that can directly blitted to the screen for performance,
but once again couldn't locate all the places that assume that
specific pixel format. So to at least provide some optimization,
I've implemented two fast for loops that handle converting the
AGS surface pixels to RGBA or ABGR for rendering
Changed paths:
engines/ags/ags.cpp
engines/ags/engine/gfx/ali_3d_scummvm.cpp
engines/ags/engine/gfx/ali_3d_scummvm.h
diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp
index 396a850afa..5d372ea681 100644
--- a/engines/ags/ags.cpp
+++ b/engines/ags/ags.cpp
@@ -217,7 +217,6 @@ void AGSEngine::setGraphicsMode(size_t w, size_t h, int colorDepth) {
Graphics::PixelFormat format;
if (!getPixelFormat(colorDepth, format))
error("Unsupported color depth %d", colorDepth);
- //Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
initGraphics(w, h, &format);
}
diff --git a/engines/ags/engine/gfx/ali_3d_scummvm.cpp b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
index 951347aae4..79d9b27db6 100644
--- a/engines/ags/engine/gfx/ali_3d_scummvm.cpp
+++ b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
@@ -374,29 +374,85 @@ void ScummVMRendererGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch
void ScummVMRendererGraphicsDriver::BlitToScreen() {
const Graphics::Surface &src =
virtualScreen->GetAllegroBitmap()->getSurface();
+ int i;
+ const uint32 *srcP;
+ uint32 *destP;
+
+ enum {
+ kRenderInitial, kRenderDirect, kRenderToABGR, kRenderToRGBA,
+ kRenderOther
+ } renderMode;
+
+ // Check for rendering to use. The virtual screen can change, so I'm
+ // playing it safe and checking the render mode for each frame
+ const Graphics::PixelFormat screenFormat = g_system->getScreenFormat();
+
+ if (src.format == screenFormat) {
+ // The virtual surface can be directly blitted to the screen
+ renderMode = kRenderDirect;
+ } else if (src.format != Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24)) {
+ // Not a 32-bit surface, so will have to use an intermediate
+ // surface to correct the virtual screen to the correct format
+ renderMode = kRenderOther;
+ } else if (screenFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) {
+ renderMode = kRenderToRGBA;
+ } else if (screenFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) {
+ renderMode = kRenderToABGR;
+ } else {
+ renderMode = kRenderOther;
+ }
- if (!_screen && !_useVirtScreenDirectly) {
- // Check whether whether the AGS surface format matches the screen
- _useVirtScreenDirectly = src.format == g_system->getScreenFormat();
+ if (renderMode != kRenderDirect && !_screen)
+ _screen = new Graphics::Screen();
+
+ switch (renderMode) {
+ case kRenderToABGR:
+ // ARGB to ABGR
+ assert(src.w == _screen->w && src.h == _screen->h);
+ srcP = (const uint32 *)src.getPixels();
+ destP = (uint32 *)_screen->getPixels();
+ for (i = 0; i < src.w * src.h; ++i, ++srcP, ++destP) {
+ *destP = (*srcP & 0xff00ff00) |
+ ((*srcP & 0xff) << 16) |
+ ((*srcP >> 16) & 0xff);
+ }
+ break;
- if (!_useVirtScreenDirectly)
- _screen = new Graphics::Screen();
- }
+ case kRenderToRGBA:
+ // ARGB to RGBA
+ assert(src.w == _screen->w && src.h == _screen->h);
+ srcP = (const uint32 *)src.getPixels();
+ destP = (uint32 *)_screen->getPixels();
+ for (i = 0; i < src.w * src.h; ++i, ++srcP, ++destP) {
+ *destP = ((*srcP & 0xffffff) << 8) |
+ ((*srcP >> 24) & 0xff);
+ }
+ break;
- if (_screen) {
+ case kRenderOther: {
// Blit the surface to the temporary screen, ignoring the alphas.
// This takes care of converting to the screen format
Graphics::Surface srcCopy = src;
srcCopy.format.aLoss = 8;
_screen->blitFrom(srcCopy);
- _screen->update();
+ break;
+ }
- } else {
+ case kRenderDirect:
// Blit the virtual surface directly to the screen
g_system->copyRectToScreen(src.getPixels(), src.pitch,
0, 0, src.w, src.h);
g_system->updateScreen();
+ return;
+
+ default:
+ break;
+ }
+
+ if (_screen) {
+ _screen->addDirtyRect(Common::Rect(0, 0, src.w, src.h));
+ _screen->update();
}
}
diff --git a/engines/ags/engine/gfx/ali_3d_scummvm.h b/engines/ags/engine/gfx/ali_3d_scummvm.h
index fb215522da..ab988382bb 100644
--- a/engines/ags/engine/gfx/ali_3d_scummvm.h
+++ b/engines/ags/engine/gfx/ali_3d_scummvm.h
@@ -234,7 +234,6 @@ public:
private:
Graphics::Screen *_screen = nullptr;
- bool _useVirtScreenDirectly = false;
PSDLRenderFilter _filter;
bool _hasGamma = false;
More information about the Scummvm-git-logs
mailing list