aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/base
diff options
context:
space:
mode:
authorEinar Johan Trøan Sømåen2012-08-07 16:04:47 +0200
committerEinar Johan Trøan Sømåen2012-08-07 16:05:36 +0200
commit8883a9ffd587de0cfca9a42925d2f1071d4ccb35 (patch)
tree6ac8097a1497559dbde5007710b4a70d42fe01e1 /engines/wintermute/base
parent3abccb2e339144191553555756e3ff43222c3a36 (diff)
downloadscummvm-rg350-8883a9ffd587de0cfca9a42925d2f1071d4ccb35.tar.gz
scummvm-rg350-8883a9ffd587de0cfca9a42925d2f1071d4ccb35.tar.bz2
scummvm-rg350-8883a9ffd587de0cfca9a42925d2f1071d4ccb35.zip
WINTERMUTE: Optimize blitting (Do opaque blits for opaque images, and do fill with memcpy)
Diffstat (limited to 'engines/wintermute/base')
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.cpp40
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.h6
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp6
3 files changed, 40 insertions, 12 deletions
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index f12478f7b3..3ec04b1ab1 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -40,8 +40,8 @@
namespace WinterMute {
-RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY) : _owner(owner),
- _srcRect(*srcRect), _dstRect(*dstRect), _drawNum(0), _isValid(true), _wantsDraw(true), _hasAlpha(true) {
+RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY, bool disableAlpha) : _owner(owner),
+ _srcRect(*srcRect), _dstRect(*dstRect), _drawNum(0), _isValid(true), _wantsDraw(true), _hasAlpha(!disableAlpha) {
_colorMod = 0;
_mirror = TransparentSurface::FLIP_NONE;
if (mirrorX) {
@@ -97,6 +97,7 @@ BaseRenderer *makeOSystemRenderer(BaseGame *inGame) {
//////////////////////////////////////////////////////////////////////////
BaseRenderOSystem::BaseRenderOSystem(BaseGame *inGame) : BaseRenderer(inGame) {
_renderSurface = new Graphics::Surface();
+ _blankSurface = new Graphics::Surface();
_drawNum = 1;
_needsFlip = true;
@@ -111,6 +112,8 @@ BaseRenderOSystem::BaseRenderOSystem(BaseGame *inGame) : BaseRenderer(inGame) {
BaseRenderOSystem::~BaseRenderOSystem() {
_renderSurface->free();
delete _renderSurface;
+ _blankSurface->free();
+ delete _blankSurface;
}
//////////////////////////////////////////////////////////////////////////
@@ -166,6 +169,8 @@ bool BaseRenderOSystem::initRenderer(int width, int height, bool windowed) {
g_system->showMouse(false);
_renderSurface->create(g_system->getWidth(), g_system->getHeight(), g_system->getScreenFormat());
+ _blankSurface->create(g_system->getWidth(), g_system->getHeight(), g_system->getScreenFormat());
+ _blankSurface->fillRect(Common::Rect(0, 0, g_system->getHeight(), g_system->getWidth()), _blankSurface->format.ARGBToColor(255, 0, 0, 0));
_active = true;
_clearColor = _renderSurface->format.ARGBToColor(255, 0, 0, 0);
@@ -217,6 +222,11 @@ bool BaseRenderOSystem::fill(byte r, byte g, byte b, Common::Rect *rect) {
return STATUS_OK;
}
if (!rect) {
+ if (r == 0 && g == 0 && b == 0) {
+ // Simply memcpy from the buffered black-surface, way faster than Surface::fillRect.
+ memcpy(_renderSurface->pixels, _blankSurface->pixels, _renderSurface->pitch * _renderSurface->h);
+ return STATUS_OK;
+ }
rect = &_renderRect;
}
// TODO: This doesn't work with dirty rects
@@ -281,12 +291,12 @@ Graphics::PixelFormat BaseRenderOSystem::getPixelFormat() const {
return _renderSurface->format;
}
-void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY) {
+void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY, bool disableAlpha) {
if (_disableDirtyRects) {
- RenderTicket renderTicket(owner, surf, srcRect, dstRect, mirrorX, mirrorY);
+ RenderTicket renderTicket(owner, surf, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
// HINT: The surface-data contains other info than it should.
// drawFromSurface(renderTicket._surface, srcRect, dstRect, NULL, mirrorX, mirrorY);
- drawFromSurface(renderTicket.getSurface(), &renderTicket._srcRect, &renderTicket._dstRect, NULL, renderTicket._mirror);
+ drawFromSurface(&renderTicket, NULL);
return;
}
// Skip rects that are completely outside the screen:
@@ -295,7 +305,7 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
}
if (owner) { // Fade-tickets are owner-less
- RenderTicket compare(owner, NULL, srcRect, dstRect, mirrorX, mirrorY);
+ RenderTicket compare(owner, NULL, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
compare._colorMod = _colorMod;
RenderQueueIterator it;
for (it = _renderQueue.begin(); it != _renderQueue.end(); it++) {
@@ -306,7 +316,7 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
}
}
}
- RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, mirrorX, mirrorY);
+ RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
ticket->_colorMod = _colorMod;
drawFromTicket(ticket);
}
@@ -445,6 +455,22 @@ void BaseRenderOSystem::drawTickets() {
}
// Replacement for SDL2's SDL_RenderCopy
+void BaseRenderOSystem::drawFromSurface(RenderTicket *ticket, Common::Rect *clipRect) {
+ TransparentSurface src(*ticket->getSurface(), false);
+ bool doDelete = false;
+ if (!clipRect) {
+ doDelete = true;
+ clipRect = new Common::Rect();
+ clipRect->setWidth(ticket->getSurface()->w);
+ clipRect->setHeight(ticket->getSurface()->h);
+ }
+
+ src._enableAlphaBlit = ticket->_hasAlpha;
+ src.blit(*_renderSurface, ticket->_dstRect.left, ticket->_dstRect.top, ticket->_mirror, clipRect, _colorMod, clipRect->width(), clipRect->height());
+ if (doDelete) {
+ delete clipRect;
+ }
+}
void BaseRenderOSystem::drawFromSurface(const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, Common::Rect *clipRect, uint32 mirror) {
TransparentSurface src(*surf, false);
bool doDelete = false;
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.h b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
index 08fd6cf9ab..070ddf9241 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
@@ -39,7 +39,7 @@ class BaseSurfaceOSystem;
class RenderTicket {
Graphics::Surface *_surface;
public:
- RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRest, bool mirrorX = false, bool mirrorY = false);
+ RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRest, bool mirrorX = false, bool mirrorY = false, bool disableAlpha = false);
RenderTicket() : _isValid(true), _wantsDraw(false), _drawNum(0) {}
~RenderTicket();
const Graphics::Surface *getSurface() { return _surface; }
@@ -97,11 +97,12 @@ public:
return _ratioY;
}
- void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY);
+ void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY, bool disableAlpha = false);
BaseSurface *createSurface();
private:
void addDirtyRect(const Common::Rect &rect);
void drawTickets();
+ void drawFromSurface(RenderTicket *ticket, Common::Rect *clipRect);
void drawFromSurface(const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, Common::Rect *clipRect, uint32 mirror);
typedef Common::List<RenderTicket *>::iterator RenderQueueIterator;
Common::Rect *_dirtyRect;
@@ -110,6 +111,7 @@ private:
uint32 _drawNum;
Common::Rect _renderRect;
Graphics::Surface *_renderSurface;
+ Graphics::Surface *_blankSurface;
int _borderLeft;
int _borderTop;
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index 9f0e605f39..7845390871 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -396,17 +396,17 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, float zoomX, flo
// But no checking is in place for that yet.
// TODO: Optimize by not doing alpha-blits if we lack or disable alpha
-/* bool hasAlpha;
+ bool hasAlpha;
if (_hasAlpha && !alphaDisable) {
hasAlpha = true;
} else {
hasAlpha = false;
- }*/
+ }
if (alphaDisable) {
warning("BaseSurfaceOSystem::drawSprite - AlphaDisable ignored");
}
- renderer->drawSurface(this, _surface, &srcRect, &position, mirrorX, mirrorY);
+ renderer->drawSurface(this, _surface, &srcRect, &position, mirrorX, mirrorY, !hasAlpha);
return STATUS_OK;
}