mirror of https://github.com/stella-emu/stella.git
Minor refactoring of the FrameBuffer classes. OpenGL mode is now
quite fast, and is approaching software rendering speed for lower resolutions. In higher resolutions, OpenGL always beats software mode. Screen redraws are now done as rarely as possible. For example, when switching to menu/debugger mode or pausing emulation, CPU usage normally drops to almost nothing. This hasn't been tested in Windows yet, so I'm sure there'll be some issues (there always are ...) git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@682 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
1694cff72d
commit
d15978825a
|
@ -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: FrameBufferGL.cxx,v 1.34 2005-07-02 01:28:42 stephena Exp $
|
||||
// $Id: FrameBufferGL.cxx,v 1.35 2005-07-20 15:52:57 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifdef DISPLAY_OPENGL
|
||||
|
@ -230,17 +230,19 @@ void FrameBufferGL::drawMediaSource()
|
|||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
if(v == previousFrame[bufofs] && !theRedrawTIAIndicator)
|
||||
continue;
|
||||
if(v != previousFrame[bufofs] || theRedrawTIAIndicator)
|
||||
{
|
||||
// If we ever get to this point, we know the current and previous
|
||||
// buffers differ. In that case, make sure the changes are
|
||||
// are drawn in postFrameUpdate()
|
||||
theRedrawTIAIndicator = true;
|
||||
|
||||
// x << 1 is times 2 ( doubling width )
|
||||
const uInt32 pos = screenofsY + (x << 1);
|
||||
buffer[pos] = buffer[pos+1] = (uInt16) myPalette[v];
|
||||
// x << 1 is times 2 ( doubling width )
|
||||
const uInt32 pos = screenofsY + (x << 1);
|
||||
buffer[pos] = buffer[pos+1] = (uInt16) myPalette[v];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The frame doesn't need to be completely redrawn anymore
|
||||
theRedrawTIAIndicator = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -251,22 +253,37 @@ void FrameBufferGL::preFrameUpdate()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::postFrameUpdate()
|
||||
{
|
||||
// Texturemap complete texture to surface so we have free scaling
|
||||
// and antialiasing
|
||||
glBindTexture(GL_TEXTURE_2D, myTextureID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h,
|
||||
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels);
|
||||
// Do the following twice, since OpenGL mode is double-buffered,
|
||||
// and we need the contents placed in both buffers
|
||||
if(theRedrawTIAIndicator || theRedrawOverlayIndicator)
|
||||
{
|
||||
// Texturemap complete texture to surface so we have free scaling
|
||||
// and antialiasing
|
||||
uInt32 w = myBaseDim.w, h = myBaseDim.h;
|
||||
|
||||
uInt32 w = myBaseDim.w, h = myBaseDim.h;
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(w, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(w, h);
|
||||
glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, h);
|
||||
glEnd();
|
||||
glBindTexture(GL_TEXTURE_2D, myTextureID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h,
|
||||
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(w, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(w, h);
|
||||
glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, h);
|
||||
glEnd();
|
||||
|
||||
// Now show all changes made to the textures
|
||||
SDL_GL_SwapBuffers();
|
||||
// Now show all changes made to the textures
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(w, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(w, h);
|
||||
glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, h);
|
||||
glEnd();
|
||||
|
||||
// The frame doesn't need to be completely redrawn anymore
|
||||
theRedrawTIAIndicator = theRedrawOverlayIndicator = false;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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: FrameBuffer.cxx,v 1.54 2005-07-19 18:21:27 stephena Exp $
|
||||
// $Id: FrameBuffer.cxx,v 1.55 2005-07-20 15:52:57 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
@ -38,14 +38,13 @@
|
|||
FrameBuffer::FrameBuffer(OSystem* osystem)
|
||||
: myOSystem(osystem),
|
||||
theRedrawTIAIndicator(true),
|
||||
theRedrawOverlayIndicator(false),
|
||||
theZoomLevel(2),
|
||||
theMaxZoomLevel(2),
|
||||
theAspectRatio(1.0),
|
||||
myFrameRate(0),
|
||||
myPauseStatus(false),
|
||||
theRedrawOverlayIndicator(false),
|
||||
myOverlayRedraws(2),
|
||||
myMessageTime(0),
|
||||
myMessageTime(-1),
|
||||
myMessageText(""),
|
||||
myNumRedraws(0)
|
||||
{
|
||||
|
@ -138,7 +137,6 @@ void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height,
|
|||
|
||||
// Erase any messages from a previous run
|
||||
myMessageTime = 0;
|
||||
theRedrawTIAIndicator = true; //FIX
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -183,7 +181,10 @@ void FrameBuffer::update()
|
|||
|
||||
// Erase this message on next update
|
||||
if(myMessageTime == 0)
|
||||
theRedrawTIAIndicator = true; // FIX
|
||||
{
|
||||
myMessageTime = -1;
|
||||
theRedrawTIAIndicator = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break; // S_EMULATE
|
||||
|
@ -197,55 +198,32 @@ void FrameBuffer::update()
|
|||
|
||||
// Only update the overlay if it's changed
|
||||
if(theRedrawOverlayIndicator)
|
||||
{
|
||||
// Then overlay any menu items
|
||||
myOSystem->menu().draw();
|
||||
|
||||
// This is a performance hack to only draw the overlay when necessary
|
||||
// Software mode is single-buffered, so we don't have to worry
|
||||
// However, OpenGL mode is double-buffered, so we need to draw the
|
||||
// menus at least twice (so they'll be in both buffers)
|
||||
// Otherwise, we get horrible flickering
|
||||
myOverlayRedraws--;
|
||||
theRedrawOverlayIndicator = (myOverlayRedraws != 0);
|
||||
}
|
||||
break;
|
||||
break; // S_MENU
|
||||
}
|
||||
|
||||
case EventHandler::S_LAUNCHER:
|
||||
{
|
||||
// Only update the screen if it's been invalidated or the overlay have changed
|
||||
if(theRedrawOverlayIndicator)
|
||||
{
|
||||
// Overlay the ROM launcher
|
||||
myOSystem->launcher().draw();
|
||||
|
||||
// This is a performance hack to only draw the overlay when necessary
|
||||
// Software mode is single-buffered, so we don't have to worry
|
||||
// However, OpenGL mode is double-buffered, so we need to draw the
|
||||
// menus at least twice (so they'll be in both buffers)
|
||||
// Otherwise, we get horrible flickering
|
||||
myOverlayRedraws--;
|
||||
theRedrawOverlayIndicator = (myOverlayRedraws != 0);
|
||||
}
|
||||
break;
|
||||
break; // S_LAUNCHER
|
||||
}
|
||||
|
||||
case EventHandler::S_DEBUGGER:
|
||||
{
|
||||
// Only update the overlay if it's changed
|
||||
// This is a performance hack to only draw the menus when necessary
|
||||
if(theRedrawOverlayIndicator)
|
||||
{
|
||||
// Overlay the ROM launcher
|
||||
myOSystem->debugger().draw();
|
||||
|
||||
// This is a performance hack to only draw the menus when necessary
|
||||
// Software mode is single-buffered, so we don't have to worry
|
||||
// However, OpenGL mode is double-buffered, so we need to draw the
|
||||
// menus at least twice (so they'll be in both buffers)
|
||||
// Otherwise, we get horrible flickering
|
||||
myOverlayRedraws--;
|
||||
theRedrawOverlayIndicator = (myOverlayRedraws != 0);
|
||||
// This needs to be here, otherwise software mode uses a lot
|
||||
// of CPU when drawing the debugger. I'm sure it's a bug,
|
||||
// but at least it's a documented one :)
|
||||
theRedrawOverlayIndicator = false;
|
||||
}
|
||||
break; // S_DEBUGGER
|
||||
}
|
||||
|
@ -279,7 +257,6 @@ void FrameBuffer::refreshOverlay(bool now)
|
|||
refreshTIA(now);
|
||||
|
||||
theRedrawOverlayIndicator = true;
|
||||
myOverlayRedraws = 2;
|
||||
if(now) update();
|
||||
}
|
||||
|
||||
|
@ -288,7 +265,6 @@ void FrameBuffer::showMessage(const string& message)
|
|||
{
|
||||
myMessageText = message;
|
||||
myMessageTime = myFrameRate << 1; // Show message for 2 seconds
|
||||
theRedrawTIAIndicator = true; // FIXME
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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: FrameBuffer.hxx,v 1.49 2005-07-19 18:21:28 stephena Exp $
|
||||
// $Id: FrameBuffer.hxx,v 1.50 2005-07-20 15:52:58 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_HXX
|
||||
|
@ -52,7 +52,7 @@ enum FrameStyle {
|
|||
All GUI elements (ala ScummVM) are drawn here as well.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBuffer.hxx,v 1.49 2005-07-19 18:21:28 stephena Exp $
|
||||
@version $Id: FrameBuffer.hxx,v 1.50 2005-07-20 15:52:58 stephena Exp $
|
||||
*/
|
||||
class FrameBuffer
|
||||
{
|
||||
|
@ -414,6 +414,9 @@ class FrameBuffer
|
|||
// Indicates if the TIA area should be redrawn
|
||||
bool theRedrawTIAIndicator;
|
||||
|
||||
// Indicates if the overlay area should be redrawn
|
||||
bool theRedrawOverlayIndicator;
|
||||
|
||||
// The SDL video buffer
|
||||
SDL_Surface* myScreen;
|
||||
|
||||
|
@ -448,12 +451,6 @@ class FrameBuffer
|
|||
// Indicates the current pause status
|
||||
bool myPauseStatus;
|
||||
|
||||
// Indicates if the overlay area should be redrawn
|
||||
bool theRedrawOverlayIndicator;
|
||||
|
||||
// Number of times menu have been drawn
|
||||
int myOverlayRedraws;
|
||||
|
||||
// Message timer
|
||||
Int32 myMessageTime;
|
||||
|
||||
|
|
|
@ -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: DialogContainer.cxx,v 1.11 2005-06-23 14:33:11 stephena Exp $
|
||||
// $Id: DialogContainer.cxx,v 1.12 2005-07-20 15:52:58 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include "OSystem.hxx"
|
||||
|
@ -86,6 +86,7 @@ void DialogContainer::draw()
|
|||
void DialogContainer::addDialog(Dialog* d)
|
||||
{
|
||||
myDialogStack.push(d);
|
||||
myOSystem->frameBuffer().refreshTIA();
|
||||
myOSystem->frameBuffer().refreshOverlay();
|
||||
}
|
||||
|
||||
|
@ -95,6 +96,7 @@ void DialogContainer::removeDialog()
|
|||
if(!myDialogStack.empty())
|
||||
{
|
||||
myDialogStack.pop();
|
||||
myOSystem->frameBuffer().refreshTIA();
|
||||
myOSystem->frameBuffer().refreshOverlay();
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +107,7 @@ void DialogContainer::reStack()
|
|||
// Pop all items from the stack, and then add the base menu
|
||||
while(!myDialogStack.empty())
|
||||
myDialogStack.pop();
|
||||
myDialogStack.push(myBaseDialog);
|
||||
addDialog(myBaseDialog);
|
||||
|
||||
// Now make sure all dialog boxes are in a known (closed) state
|
||||
myBaseDialog->reset();
|
||||
|
|
|
@ -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: PromptWidget.cxx,v 1.27 2005-07-16 16:09:38 urchlay Exp $
|
||||
// $Id: PromptWidget.cxx,v 1.28 2005-07-20 15:52:58 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -207,7 +207,6 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers)
|
|||
break;
|
||||
}
|
||||
|
||||
case 27: // escape FIXME - possibly remove this one?
|
||||
case 9: // tab
|
||||
{
|
||||
// Tab completion: we complete either commands or labels, but not
|
||||
|
|
Loading…
Reference in New Issue