Hack for Win32 performance issues. It seems SDL_UpdateRects() really

kills performance in Windows, so we use SDL_Flip() instead, but only
when something has actually changed onscreen.  At some point after
the next release, I may move to hardware/double-buffered displays,
but the extra work it requires (dirty rect list for each buffer) is
just too much for now.  Besides, I'm hesitant to spend so much time
optimizing for one specific type of software mode when OpenGL is
available, and works much faster anyway.

Fixed bug with pathnames in FSNodeWin32.  The code now assumes that
all paths start with X: (where X is a drive letter).  If not, then
it defaults to C:  So that means relative directories aren't allowed,
only absolute.

Removed hardware support from FrameBufferSoft, since the only port
that uses it is PSP, and that port will soon get its own
FrameBufferPSP class.  So for now, PSP support is broken.  It was
just too difficult to merge the common FrameBufferSoft for PSP
support, since it's starting to use PSP-specific code.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@774 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-09-11 15:44:51 +00:00
parent 79313cc4c4
commit 32f00975ad
7 changed files with 45 additions and 97 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferSoft.cxx,v 1.37 2005-09-01 21:53:44 stephena Exp $
// $Id: FrameBufferSoft.cxx,v 1.38 2005-09-11 15:44:51 stephena Exp $
//============================================================================
#include <SDL.h>
@ -30,11 +30,10 @@
#include "GuiUtils.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferSoft::FrameBufferSoft(OSystem* osystem, bool useHardSurface)
FrameBufferSoft::FrameBufferSoft(OSystem* osystem)
: FrameBuffer(osystem),
myRectList(NULL),
myOverlayRectList(NULL),
myUseHardSurface(useHardSurface)
myOverlayRectList(NULL)
{
}
@ -48,11 +47,6 @@ FrameBufferSoft::~FrameBufferSoft()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSoft::initSubsystem()
{
if(myUseHardSurface)
mySDLFlags |= SDL_HWSURFACE|SDL_DOUBLEBUF;
else
mySDLFlags |= SDL_SWSURFACE;
// Set up the rectangle list to be used in the dirty update
delete myRectList;
myRectList = new RectList();
@ -92,42 +86,19 @@ void FrameBufferSoft::setAspectRatio()
bool FrameBufferSoft::createScreen()
{
myScreenDim.x = myScreenDim.y = 0;
myScreenDim.w = myBaseDim.w * theZoomLevel;
myScreenDim.h = myBaseDim.h * theZoomLevel;
// In software mode, the image and screen dimensions are always the same
myImageDim = myScreenDim;
#ifdef PSP
if (myUseHardSurface)
{
/* double buff is broken */
mySDLFlags = SDL_HWSURFACE;
myScreenDim.w = myDesktopDim.w;
myScreenDim.h = myDesktopDim.w;
#ifdef PSP_DEBUG
fprintf(stdout, "FrameBufferSoft::createScreen Hardware Mode "
"myScreenDim.w='%i' myScreenDim.h='%i'\n",
myScreenDim.w,myScreenDim.h);
#endif
}
else
{
#ifdef PSP_DEBUG
fprintf(stdout, "FrameBufferSoft::createScreen Software Mode "
"myScreenDim.w='%i' myScreenDim.h='%i'\n",
myScreenDim.w,myScreenDim.h);
#endif
}
#endif
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
if(myScreen == NULL)
{
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
return false;
}
myOSystem->eventHandler().refreshDisplay();
return true;
@ -136,34 +107,6 @@ bool FrameBufferSoft::createScreen()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::drawMediaSource()
{
#ifdef PSP
MediaSource& mediasrc = myOSystem->console().mediaSource();
SDL_LockSurface(myScreen);
uInt8* currentFrame = mediasrc.currentFrameBuffer();
uInt32 width = mediasrc.width();
uInt32 height = mediasrc.height();
register uInt32* buffer = (uInt32*) myScreen->pixels;
register uInt32 y;
for(y = 0; y < height; ++y )
{
const uInt32 bufofsY = y * width;
const uInt32 screenofsY = y * (myScreen->pitch >> 3);
register uInt32 x;
for(x = 0; x < width; ++x )
{
const uInt32 off = screenofsY + x << 1;
buffer[off] = buffer[off + 1] = myPalette[currentFrame[bufofsY + x]];
}
}
SDL_UnlockSurface(myScreen);
#else
MediaSource& mediasrc = myOSystem->console().mediaSource();
uInt8* currentFrame = mediasrc.currentFrameBuffer();
@ -217,9 +160,9 @@ void FrameBufferSoft::drawMediaSource()
{
// Can we extend a rectangle or do we have to create a new one?
if((currentCount != 0) &&
(currentRectangles[currentCount - 1].color == *c) &&
((currentRectangles[currentCount - 1].x +
currentRectangles[currentCount - 1].width) == (x + i)))
(currentRectangles[currentCount - 1].color == *c) &&
((currentRectangles[currentCount - 1].x +
currentRectangles[currentCount - 1].width) == (x + i)))
{
currentRectangles[currentCount - 1].width += 1;
}
@ -247,7 +190,7 @@ void FrameBufferSoft::drawMediaSource()
// Can we merge the current rectangle with an active one?
if((current.x == active.x) && (current.width == active.width) &&
(current.color == active.color))
(current.color == active.color))
{
current.y = active.y;
current.height = active.height + 1;
@ -292,7 +235,7 @@ void FrameBufferSoft::drawMediaSource()
currentRectangles = activeRectangles;
activeRectangles = tmp;
activeCount = currentCount;
currentFrame += width;
previousFrame += width;
}
@ -311,13 +254,11 @@ void FrameBufferSoft::drawMediaSource()
myRectList->add(&temp);
SDL_FillRect(myScreen, &temp, myPalette[active.color]);
}
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::preFrameUpdate()
{
#ifndef PSP
// Start a new rectlist on each display update
myRectList->start();
@ -326,16 +267,23 @@ void FrameBufferSoft::preFrameUpdate()
for(unsigned int i = 0; i < myOverlayRectList->numRects(); ++i)
myRectList->add(&dirtyOverlayRects[i]);
myOverlayRectList->start();
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::postFrameUpdate()
{
if(myUseHardSurface)
// This is a performance hack until I have more time to work
// on the Win32 code. It seems that SDL_UpdateRects() is very
// expensive in Windows, so we force a full screen update instead.
#ifdef WIN32
if(myRectList->numRects() > 0)
{
SDL_Flip(myScreen);
else
SDL_UpdateRects(myScreen, myRectList->numRects(), myRectList->rects());
myRectList->start();
}
#else
SDL_UpdateRects(myScreen, myRectList->numRects(), myRectList->rects());
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferSoft.hxx,v 1.22 2005-08-24 01:07:36 stephena Exp $
// $Id: FrameBufferSoft.hxx,v 1.23 2005-09-11 15:44:51 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_SOFT_HXX
@ -35,7 +35,7 @@ class RectList;
This class implements an SDL software framebuffer.
@author Stephen Anthony
@version $Id: FrameBufferSoft.hxx,v 1.22 2005-08-24 01:07:36 stephena Exp $
@version $Id: FrameBufferSoft.hxx,v 1.23 2005-09-11 15:44:51 stephena Exp $
*/
class FrameBufferSoft : public FrameBuffer
{
@ -43,7 +43,7 @@ class FrameBufferSoft : public FrameBuffer
/**
Creates a new software framebuffer
*/
FrameBufferSoft(OSystem* osystem, bool useHardSurface = false);
FrameBufferSoft(OSystem* osystem);
/**
Destructor
@ -200,9 +200,6 @@ class FrameBufferSoft : public FrameBuffer
// Used in the dirty update of the overlay surface
RectList* myOverlayRectList;
// Whether to use hardware or software surface
bool myUseHardSurface;
};
class RectList

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystem.cxx,v 1.37 2005-09-10 16:19:20 bwmott Exp $
// $Id: OSystem.cxx,v 1.38 2005-09-11 15:44:51 stephena Exp $
//============================================================================
#include <cassert>
@ -179,8 +179,6 @@ bool OSystem::createFrameBuffer(bool showmessage)
if(video == "soft")
myFrameBuffer = new FrameBufferSoft(this);
else if(video == "hard")
myFrameBuffer = new FrameBufferSoft(this, true);
#ifdef DISPLAY_OPENGL
else if(video == "gl")
myFrameBuffer = new FrameBufferGL(this);
@ -201,9 +199,7 @@ bool OSystem::createFrameBuffer(bool showmessage)
if(showmessage)
{
if(video == "soft")
myFrameBuffer->showMessage("Software mode (S)");
else if(video == "hard")
myFrameBuffer->showMessage("Software mode (H)");
myFrameBuffer->showMessage("Software mode");
#ifdef DISPLAY_OPENGL
else if(video == "gl")
myFrameBuffer->showMessage("OpenGL mode");
@ -236,8 +232,6 @@ void OSystem::toggleFrameBuffer()
// First figure out which mode to switch to
string video = mySettings->getString("video");
if(video == "soft")
video = "hard";
else if(video == "hard")
video = "gl";
else if(video == "gl")
video = "soft";

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Settings.cxx,v 1.58 2005-09-06 19:42:35 stephena Exp $
// $Id: Settings.cxx,v 1.59 2005-09-11 15:44:51 stephena Exp $
//============================================================================
#include <cassert>
@ -195,7 +195,7 @@ void Settings::validate()
int i;
s = getString("video");
if(s != "soft" && s != "hard" && s != "gl")
if(s != "soft" && s != "gl")
set("video", "soft");
#ifdef DISPLAY_OPENGL

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: VideoDialog.cxx,v 1.23 2005-08-25 15:19:17 stephena Exp $
// $Id: VideoDialog.cxx,v 1.24 2005-09-11 15:44:51 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -72,7 +72,9 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
myRendererPopup = new PopUpWidget(this, xoff, yoff, woff, kLineHeight,
"Renderer: ", labelWidth, kRendererChanged);
myRendererPopup->appendEntry("Software", 1);
#ifdef PSP
myRendererPopup->appendEntry("Hardware", 2);
#endif
#ifdef DISPLAY_OPENGL
myRendererPopup->appendEntry("OpenGL", 3);
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FSNodeWin32.cxx,v 1.6 2005-07-05 00:07:58 stephena Exp $
// $Id: FSNodeWin32.cxx,v 1.7 2005-09-11 15:44:51 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -74,6 +74,16 @@ static const char* lastPathComponent(const string& str)
return cur + 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static string validatePath(const string& p)
{
string path = p;
if(p.size() < 2 || p[1] != ':')
path = "c:";
return path;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
char* WindowsFilesystemNode::toAscii(TCHAR* x)
{
@ -154,8 +164,8 @@ WindowsFilesystemNode::WindowsFilesystemNode()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WindowsFilesystemNode::WindowsFilesystemNode(const string& path)
{
_path = path;
_displayName = lastPathComponent(path);
_path = validatePath(path);
_displayName = lastPathComponent(_path);
_isValid = true;
_isDirectory = true;
_isPseudoRoot = false;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystemWin32.cxx,v 1.5 2005-06-16 01:11:29 stephena Exp $
// $Id: OSystemWin32.cxx,v 1.6 2005-09-11 15:44:51 stephena Exp $
//============================================================================
#include <sstream>
@ -63,9 +63,6 @@ OSystemWin32::OSystemWin32()
string cacheFile = basedir + "stella.cache";
setCacheFile(cacheFile);
myDriverList.push_back("windib");
myDriverList.push_back("directx");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -