mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-25 05:34:27 +00:00
GRAPHICS,SDL: Change oldSrcScale api
More bookkeeping is kept in common scaler code instead of the backend. Plugins inheriting SourceScaler will have this functionality. TODO: Some new functions may still be able to be combined to simplify the API.
This commit is contained in:
parent
c915efa452
commit
c5c5662330
@ -120,7 +120,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
|
||||
#if defined(WIN32) && !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
_originalBitsPerPixel(0),
|
||||
#endif
|
||||
_screen(0), _tmpscreen(0), _oldscreen(0), _destbuffer(0),
|
||||
_screen(0), _tmpscreen(0), _destbuffer(0),
|
||||
_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
|
||||
_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
|
||||
_useOldSrc(false),
|
||||
@ -682,17 +682,8 @@ void SurfaceSdlGraphicsManager::setGraphicsModeIntern() {
|
||||
_extraPixels = (*_scalerPlugin)->extraPixels();
|
||||
_useOldSrc = (*_scalerPlugin)->useOldSrc();
|
||||
if (_useOldSrc) {
|
||||
if (!_oldscreen) {
|
||||
_oldscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + _maxExtraPixels * 2,
|
||||
_videoMode.screenHeight + _maxExtraPixels * 2,
|
||||
16,
|
||||
_hwscreen->format->Rmask,
|
||||
_hwscreen->format->Gmask,
|
||||
_hwscreen->format->Bmask,
|
||||
_hwscreen->format->Amask);
|
||||
if (_oldscreen == NULL)
|
||||
error("allocating _oldscreen failed");
|
||||
}
|
||||
(*_scalerPlugin)->setSource((byte *)_tmpscreen->pixels, _tmpscreen->pitch,
|
||||
_videoMode.screenWidth, _videoMode.screenHeight, _maxExtraPixels, SRC_SCREEN);
|
||||
if (!_destbuffer) {
|
||||
_destbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth * _videoMode.scaleFactor,
|
||||
_videoMode.screenHeight * _videoMode.scaleFactor,
|
||||
@ -989,15 +980,8 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
|
||||
|
||||
if (_useOldSrc) {
|
||||
// Create surface containing previous frame's data to pass to scaler
|
||||
_oldscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + _maxExtraPixels * 2,
|
||||
_videoMode.screenHeight + _maxExtraPixels * 2,
|
||||
16,
|
||||
_hwscreen->format->Rmask,
|
||||
_hwscreen->format->Gmask,
|
||||
_hwscreen->format->Bmask,
|
||||
_hwscreen->format->Amask);
|
||||
if (_oldscreen == NULL)
|
||||
error("allocating _oldscreen failed");
|
||||
(*_scalerPlugin)->setSource((byte *)_tmpscreen->pixels, _tmpscreen->pitch,
|
||||
_videoMode.screenWidth, _videoMode.screenHeight, _maxExtraPixels, SRC_SCREEN);
|
||||
|
||||
// Create surface containing the raw output from the scaler
|
||||
_destbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth * _videoMode.scaleFactor,
|
||||
@ -1057,11 +1041,6 @@ void SurfaceSdlGraphicsManager::unloadGFXMode() {
|
||||
_tmpscreen = NULL;
|
||||
}
|
||||
|
||||
if (_oldscreen) {
|
||||
SDL_FreeSurface(_oldscreen);
|
||||
_oldscreen = NULL;
|
||||
}
|
||||
|
||||
if (_destbuffer) {
|
||||
SDL_FreeSurface(_destbuffer);
|
||||
_destbuffer = NULL;
|
||||
@ -1110,6 +1089,7 @@ bool SurfaceSdlGraphicsManager::hotswapGFXMode() {
|
||||
_overlayscreen = NULL;
|
||||
|
||||
// Release the HW screen surface
|
||||
<<<<<<< HEAD
|
||||
if (_hwScreen) {
|
||||
SDL_FreeSurface(_hwScreen);
|
||||
_hwScreen = NULL;
|
||||
@ -1118,10 +1098,6 @@ bool SurfaceSdlGraphicsManager::hotswapGFXMode() {
|
||||
SDL_FreeSurface(_tmpscreen);
|
||||
_tmpscreen = NULL;
|
||||
}
|
||||
if (_oldscreen) {
|
||||
SDL_FreeSurface(_oldscreen);
|
||||
_oldscreen = NULL;
|
||||
}
|
||||
if (_destbuffer) {
|
||||
SDL_FreeSurface(_destbuffer);
|
||||
_destbuffer = NULL;
|
||||
@ -1277,7 +1253,6 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
|
||||
SDL_LockSurface(srcSurf);
|
||||
SDL_LockSurface(_hwScreen);
|
||||
if (_useOldSrc && !_overlayVisible) {
|
||||
SDL_LockSurface(_oldscreen);
|
||||
SDL_LockSurface(_destbuffer);
|
||||
}
|
||||
|
||||
@ -1322,10 +1297,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
|
||||
} else {
|
||||
if (_useOldSrc) {
|
||||
// scale into _destbuffer instead of _hwscreen to avoid AR problems
|
||||
(*_scalerPlugin)->oldSrcScale((byte *)srcSurf->pixels + (r->x + _maxExtraPixels) * 2 + (r->y + _maxExtraPixels) * srcPitch, srcPitch,
|
||||
(byte *)_destbuffer->pixels + rx1 * 2 + orig_dst_y * scale1 * _destbuffer->pitch, _destbuffer->pitch,
|
||||
(byte *)_oldscreen->pixels + (r->x + _maxExtraPixels) * 2 + (r->y + _maxExtraPixels) * _oldscreen->pitch, _oldscreen->pitch,
|
||||
r->w, dst_h, r->x, r->y);
|
||||
(*_scalerPlugin)->oldSrcScale((byte *)_destbuffer->pixels, _destbuffer->pitch, SRC_SCREEN);
|
||||
} else
|
||||
(*_scalerPlugin)->scale((byte *)srcSurf->pixels + (r->x + _maxExtraPixels) * 2 + (r->y + _maxExtraPixels) * srcPitch, srcPitch,
|
||||
(byte *)_hwscreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h, r->x, r->y);
|
||||
@ -1363,14 +1335,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
|
||||
SDL_UnlockSurface(_hwScreen);
|
||||
|
||||
if (_useOldSrc && !_overlayVisible) {
|
||||
SDL_UnlockSurface(_oldscreen);
|
||||
SDL_UnlockSurface(_destbuffer);
|
||||
|
||||
// Swap old and new screen
|
||||
SDL_Surface *tmp;
|
||||
tmp = _oldscreen;
|
||||
_oldscreen = _tmpscreen;
|
||||
_tmpscreen = tmp;
|
||||
}
|
||||
|
||||
// Readjust the dirty rect list in case we are doing a full update.
|
||||
|
@ -216,8 +216,6 @@ protected:
|
||||
|
||||
/** Temporary screen (for scalers) */
|
||||
SDL_Surface *_tmpscreen;
|
||||
/** Previous frame's screen (for scalers) */
|
||||
SDL_Surface *_oldscreen;
|
||||
/** Previous frame's raw scaled screen (for scalers) */
|
||||
SDL_Surface *_destbuffer;
|
||||
/** Temporary screen (for scalers) */
|
||||
|
@ -31,6 +31,7 @@ MODULE_OBJS := \
|
||||
primitives.o \
|
||||
renderer.o \
|
||||
scaler.o \
|
||||
scalerplugin.o \
|
||||
scaler/thumbnail_intern.o \
|
||||
screen.o \
|
||||
scaler/normal.o \
|
||||
|
@ -3561,8 +3561,8 @@ void EdgePlugin::scale(const uint8 *srcPtr, uint32 srcPitch,
|
||||
}
|
||||
}
|
||||
|
||||
void EdgePlugin::oldSrcScale(const uint8 *srcPtr, uint32 srcPitch,
|
||||
uint8 *dstPtr, uint32 dstPitch, const uint8 *oldSrcPtr, uint32 oldSrcPitch, int width, int height, int x, int y) {
|
||||
void EdgePlugin::internScale(const uint8 *srcPtr, uint32 srcPitch,
|
||||
uint8 *dstPtr, uint32 dstPitch, const uint8 *oldSrcPtr, uint32 oldSrcPitch, int width, int height) {
|
||||
if (_format.bytesPerPixel == 2) {
|
||||
if (_factor == 2) {
|
||||
if (_format.gLoss == 2)
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "graphics/scalerplugin.h"
|
||||
|
||||
class EdgePlugin : public ScalerPluginObject {
|
||||
class EdgePlugin : public SourceScaler {
|
||||
public:
|
||||
|
||||
EdgePlugin();
|
||||
@ -32,10 +32,10 @@ public:
|
||||
virtual void deinitialize();
|
||||
virtual void scale(const uint8 *srcPtr, uint32 srcPitch,
|
||||
uint8 *dstPtr, uint32 dstPitch, int width, int height, int x, int y);
|
||||
virtual void oldSrcScale(const uint8 *srcPtr, uint32 srcPitch,
|
||||
virtual void internScale(const uint8 *srcPtr, uint32 srcPitch,
|
||||
uint8 *dstPtr, uint32 dstPitch,
|
||||
const uint8 *oldSrcPtr, uint32 oldSrcPitch,
|
||||
int width, int height, int x, int y);
|
||||
int width, int height);
|
||||
virtual uint increaseFactor();
|
||||
virtual uint decreaseFactor();
|
||||
virtual uint getFactor() const { return _factor; }
|
||||
|
54
graphics/scalerplugin.cpp
Normal file
54
graphics/scalerplugin.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "graphics/scalerplugin.h"
|
||||
|
||||
SourceScaler::SourceScaler() {
|
||||
for (int i = 0; i < SRC_MAX; ++i) {
|
||||
oldSrcs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SourceScaler::setSource(byte *src, uint pitch, int width, int height, int padding, SourceType type) {
|
||||
widths[type] = width;
|
||||
heights[type] = height;
|
||||
pitches[type] = pitch;
|
||||
newSrcs[type] = src;
|
||||
paddings[type] = padding;
|
||||
|
||||
if (oldSrcs[type] != NULL)
|
||||
free(oldSrcs[type]);
|
||||
|
||||
int size = (height + _format.bytesPerPixel * padding) * 2 * pitch;
|
||||
oldSrcs[type] = new byte[size];
|
||||
memset(oldSrcs[type], 0, size);
|
||||
}
|
||||
|
||||
void SourceScaler::oldSrcScale(byte *dst, uint dstPitch, SourceType type) {
|
||||
// Call user defined scale function
|
||||
internScale(newSrcs[type] + paddings[type] * 2 + pitches[type] * paddings[type], pitches[type],
|
||||
dst, dstPitch,
|
||||
oldSrcs[type] + paddings[type] * 2 + pitches[type] * paddings[type], pitches[type],
|
||||
widths[type], heights[type]);
|
||||
// Update old src
|
||||
memcpy(oldSrcs[type], newSrcs[type], (heights[type] + _format.bytesPerPixel * paddings[type]) * 2 * pitches[type]);
|
||||
}
|
||||
|
@ -25,6 +25,15 @@
|
||||
#include "base/plugins.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
|
||||
enum SourceType {
|
||||
SRC_SCREEN = 0,
|
||||
SRC_CURSOR,
|
||||
SRC_OTHER,
|
||||
|
||||
SRC_MAX
|
||||
};
|
||||
|
||||
|
||||
class ScalerPluginObject : public PluginObject {
|
||||
public:
|
||||
|
||||
@ -96,18 +105,29 @@ public:
|
||||
* optionally call it.
|
||||
*
|
||||
* @see oldSourceScale
|
||||
* @see setSource
|
||||
*/
|
||||
virtual bool useOldSrc() const { return false; }
|
||||
|
||||
/**
|
||||
* Secondary scaling method for computationally intense scalers.
|
||||
* Set the source to be used when scaling and copying to the old buffer.
|
||||
*
|
||||
* @see useOldSource
|
||||
* @param padding The number of pixels on the border (Used to prevent memory access crashes)
|
||||
* @param type The surface type. This source will only be used when calling oldSrcScale with the same type.
|
||||
*/
|
||||
virtual void oldSrcScale(const uint8 *srcPtr, uint32 srcPitch,
|
||||
uint8 *dstPtr, uint32 dstPitch,
|
||||
const uint8 *oldSrcPtr, uint32 oldSrcPitch,
|
||||
int width, int height, int x, int y) {
|
||||
virtual void setSource(byte *src, uint pitch, int width, int height, int padding, SourceType type) {
|
||||
// Should not be called unless overriden
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale using the source from setSource called with the same value as type.
|
||||
* The source will be compared against previous frames to avoid computations
|
||||
* on unchanged pixels.
|
||||
*
|
||||
* @param type The surface type set previously with setSource
|
||||
*/
|
||||
virtual void oldSrcScale(byte *dst, uint dstPitch, SourceType type) {
|
||||
// Should not be called unless overriden
|
||||
assert(0);
|
||||
}
|
||||
@ -118,6 +138,40 @@ protected:
|
||||
Graphics::PixelFormat _format;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience class that implements some bookkeeping for keeping track of
|
||||
* old source images.
|
||||
*/
|
||||
class SourceScaler : public ScalerPluginObject {
|
||||
|
||||
public:
|
||||
|
||||
SourceScaler();
|
||||
|
||||
virtual void setSource(byte *src, uint pitch, int width, int height, int padding, SourceType type);
|
||||
virtual void oldSrcScale(byte *dst, uint dstPitch, SourceType type);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Scalers must implement this function. It will be called by oldSrcScale.
|
||||
* If by comparing the src and oldsrc images it is discovered that no change
|
||||
* is necessary, do not write a pixel.
|
||||
*/
|
||||
virtual void internScale(const uint8 *srcPtr, uint32 srcPitch,
|
||||
uint8 *dstPtr, uint32 dstPitch,
|
||||
const uint8 *oldSrcPtr, uint32 oldSrcPitch,
|
||||
int width, int height) = 0;
|
||||
|
||||
int widths[SRC_MAX];
|
||||
int heights[SRC_MAX];
|
||||
uint paddings[SRC_MAX];
|
||||
uint pitches[SRC_MAX];
|
||||
|
||||
byte *newSrcs[SRC_MAX];
|
||||
byte *oldSrcs[SRC_MAX];
|
||||
};
|
||||
|
||||
typedef PluginSubclass<ScalerPluginObject> ScalerPlugin;
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user