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
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
#ifdef DISPLAY_OPENGL
|
||||||
|
@ -230,17 +230,19 @@ void FrameBufferGL::drawMediaSource()
|
||||||
{
|
{
|
||||||
const uInt32 bufofs = bufofsY + x;
|
const uInt32 bufofs = bufofsY + x;
|
||||||
uInt8 v = currentFrame[bufofs];
|
uInt8 v = currentFrame[bufofs];
|
||||||
if(v == previousFrame[bufofs] && !theRedrawTIAIndicator)
|
if(v != previousFrame[bufofs] || theRedrawTIAIndicator)
|
||||||
continue;
|
{
|
||||||
|
// 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 )
|
// x << 1 is times 2 ( doubling width )
|
||||||
const uInt32 pos = screenofsY + (x << 1);
|
const uInt32 pos = screenofsY + (x << 1);
|
||||||
buffer[pos] = buffer[pos+1] = (uInt16) myPalette[v];
|
buffer[pos] = buffer[pos+1] = (uInt16) myPalette[v];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// The frame doesn't need to be completely redrawn anymore
|
|
||||||
theRedrawTIAIndicator = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -251,13 +253,17 @@ void FrameBufferGL::preFrameUpdate()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FrameBufferGL::postFrameUpdate()
|
void FrameBufferGL::postFrameUpdate()
|
||||||
{
|
{
|
||||||
|
// 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
|
// Texturemap complete texture to surface so we have free scaling
|
||||||
// and antialiasing
|
// and antialiasing
|
||||||
|
uInt32 w = myBaseDim.w, h = myBaseDim.h;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, myTextureID);
|
glBindTexture(GL_TEXTURE_2D, myTextureID);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h,
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h,
|
||||||
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels);
|
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels);
|
||||||
|
|
||||||
uInt32 w = myBaseDim.w, h = myBaseDim.h;
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0);
|
glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0);
|
||||||
glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(w, 0);
|
glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(w, 0);
|
||||||
|
@ -267,6 +273,17 @@ void FrameBufferGL::postFrameUpdate()
|
||||||
|
|
||||||
// Now show all changes made to the textures
|
// Now show all changes made to the textures
|
||||||
SDL_GL_SwapBuffers();
|
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
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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>
|
#include <sstream>
|
||||||
|
@ -38,14 +38,13 @@
|
||||||
FrameBuffer::FrameBuffer(OSystem* osystem)
|
FrameBuffer::FrameBuffer(OSystem* osystem)
|
||||||
: myOSystem(osystem),
|
: myOSystem(osystem),
|
||||||
theRedrawTIAIndicator(true),
|
theRedrawTIAIndicator(true),
|
||||||
|
theRedrawOverlayIndicator(false),
|
||||||
theZoomLevel(2),
|
theZoomLevel(2),
|
||||||
theMaxZoomLevel(2),
|
theMaxZoomLevel(2),
|
||||||
theAspectRatio(1.0),
|
theAspectRatio(1.0),
|
||||||
myFrameRate(0),
|
myFrameRate(0),
|
||||||
myPauseStatus(false),
|
myPauseStatus(false),
|
||||||
theRedrawOverlayIndicator(false),
|
myMessageTime(-1),
|
||||||
myOverlayRedraws(2),
|
|
||||||
myMessageTime(0),
|
|
||||||
myMessageText(""),
|
myMessageText(""),
|
||||||
myNumRedraws(0)
|
myNumRedraws(0)
|
||||||
{
|
{
|
||||||
|
@ -138,7 +137,6 @@ void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height,
|
||||||
|
|
||||||
// Erase any messages from a previous run
|
// Erase any messages from a previous run
|
||||||
myMessageTime = 0;
|
myMessageTime = 0;
|
||||||
theRedrawTIAIndicator = true; //FIX
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -183,7 +181,10 @@ void FrameBuffer::update()
|
||||||
|
|
||||||
// Erase this message on next update
|
// Erase this message on next update
|
||||||
if(myMessageTime == 0)
|
if(myMessageTime == 0)
|
||||||
theRedrawTIAIndicator = true; // FIX
|
{
|
||||||
|
myMessageTime = -1;
|
||||||
|
theRedrawTIAIndicator = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break; // S_EMULATE
|
break; // S_EMULATE
|
||||||
|
@ -197,55 +198,32 @@ void FrameBuffer::update()
|
||||||
|
|
||||||
// Only update the overlay if it's changed
|
// Only update the overlay if it's changed
|
||||||
if(theRedrawOverlayIndicator)
|
if(theRedrawOverlayIndicator)
|
||||||
{
|
|
||||||
// Then overlay any menu items
|
|
||||||
myOSystem->menu().draw();
|
myOSystem->menu().draw();
|
||||||
|
|
||||||
// This is a performance hack to only draw the overlay when necessary
|
break; // S_MENU
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case EventHandler::S_LAUNCHER:
|
case EventHandler::S_LAUNCHER:
|
||||||
{
|
{
|
||||||
// Only update the screen if it's been invalidated or the overlay have changed
|
// Only update the screen if it's been invalidated or the overlay have changed
|
||||||
if(theRedrawOverlayIndicator)
|
if(theRedrawOverlayIndicator)
|
||||||
{
|
|
||||||
// Overlay the ROM launcher
|
|
||||||
myOSystem->launcher().draw();
|
myOSystem->launcher().draw();
|
||||||
|
|
||||||
// This is a performance hack to only draw the overlay when necessary
|
break; // S_LAUNCHER
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case EventHandler::S_DEBUGGER:
|
case EventHandler::S_DEBUGGER:
|
||||||
{
|
{
|
||||||
// Only update the overlay if it's changed
|
// Only update the overlay if it's changed
|
||||||
|
// This is a performance hack to only draw the menus when necessary
|
||||||
if(theRedrawOverlayIndicator)
|
if(theRedrawOverlayIndicator)
|
||||||
{
|
{
|
||||||
// Overlay the ROM launcher
|
|
||||||
myOSystem->debugger().draw();
|
myOSystem->debugger().draw();
|
||||||
|
|
||||||
// This is a performance hack to only draw the menus when necessary
|
// This needs to be here, otherwise software mode uses a lot
|
||||||
// Software mode is single-buffered, so we don't have to worry
|
// of CPU when drawing the debugger. I'm sure it's a bug,
|
||||||
// However, OpenGL mode is double-buffered, so we need to draw the
|
// but at least it's a documented one :)
|
||||||
// menus at least twice (so they'll be in both buffers)
|
theRedrawOverlayIndicator = false;
|
||||||
// Otherwise, we get horrible flickering
|
|
||||||
myOverlayRedraws--;
|
|
||||||
theRedrawOverlayIndicator = (myOverlayRedraws != 0);
|
|
||||||
}
|
}
|
||||||
break; // S_DEBUGGER
|
break; // S_DEBUGGER
|
||||||
}
|
}
|
||||||
|
@ -279,7 +257,6 @@ void FrameBuffer::refreshOverlay(bool now)
|
||||||
refreshTIA(now);
|
refreshTIA(now);
|
||||||
|
|
||||||
theRedrawOverlayIndicator = true;
|
theRedrawOverlayIndicator = true;
|
||||||
myOverlayRedraws = 2;
|
|
||||||
if(now) update();
|
if(now) update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +265,6 @@ void FrameBuffer::showMessage(const string& message)
|
||||||
{
|
{
|
||||||
myMessageText = message;
|
myMessageText = message;
|
||||||
myMessageTime = myFrameRate << 1; // Show message for 2 seconds
|
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
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
#ifndef FRAMEBUFFER_HXX
|
||||||
|
@ -52,7 +52,7 @@ enum FrameStyle {
|
||||||
All GUI elements (ala ScummVM) are drawn here as well.
|
All GUI elements (ala ScummVM) are drawn here as well.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@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
|
class FrameBuffer
|
||||||
{
|
{
|
||||||
|
@ -414,6 +414,9 @@ class FrameBuffer
|
||||||
// Indicates if the TIA area should be redrawn
|
// Indicates if the TIA area should be redrawn
|
||||||
bool theRedrawTIAIndicator;
|
bool theRedrawTIAIndicator;
|
||||||
|
|
||||||
|
// Indicates if the overlay area should be redrawn
|
||||||
|
bool theRedrawOverlayIndicator;
|
||||||
|
|
||||||
// The SDL video buffer
|
// The SDL video buffer
|
||||||
SDL_Surface* myScreen;
|
SDL_Surface* myScreen;
|
||||||
|
|
||||||
|
@ -448,12 +451,6 @@ class FrameBuffer
|
||||||
// Indicates the current pause status
|
// Indicates the current pause status
|
||||||
bool myPauseStatus;
|
bool myPauseStatus;
|
||||||
|
|
||||||
// Indicates if the overlay area should be redrawn
|
|
||||||
bool theRedrawOverlayIndicator;
|
|
||||||
|
|
||||||
// Number of times menu have been drawn
|
|
||||||
int myOverlayRedraws;
|
|
||||||
|
|
||||||
// Message timer
|
// Message timer
|
||||||
Int32 myMessageTime;
|
Int32 myMessageTime;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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"
|
#include "OSystem.hxx"
|
||||||
|
@ -86,6 +86,7 @@ void DialogContainer::draw()
|
||||||
void DialogContainer::addDialog(Dialog* d)
|
void DialogContainer::addDialog(Dialog* d)
|
||||||
{
|
{
|
||||||
myDialogStack.push(d);
|
myDialogStack.push(d);
|
||||||
|
myOSystem->frameBuffer().refreshTIA();
|
||||||
myOSystem->frameBuffer().refreshOverlay();
|
myOSystem->frameBuffer().refreshOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +96,7 @@ void DialogContainer::removeDialog()
|
||||||
if(!myDialogStack.empty())
|
if(!myDialogStack.empty())
|
||||||
{
|
{
|
||||||
myDialogStack.pop();
|
myDialogStack.pop();
|
||||||
|
myOSystem->frameBuffer().refreshTIA();
|
||||||
myOSystem->frameBuffer().refreshOverlay();
|
myOSystem->frameBuffer().refreshOverlay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +107,7 @@ void DialogContainer::reStack()
|
||||||
// Pop all items from the stack, and then add the base menu
|
// Pop all items from the stack, and then add the base menu
|
||||||
while(!myDialogStack.empty())
|
while(!myDialogStack.empty())
|
||||||
myDialogStack.pop();
|
myDialogStack.pop();
|
||||||
myDialogStack.push(myBaseDialog);
|
addDialog(myBaseDialog);
|
||||||
|
|
||||||
// Now make sure all dialog boxes are in a known (closed) state
|
// Now make sure all dialog boxes are in a known (closed) state
|
||||||
myBaseDialog->reset();
|
myBaseDialog->reset();
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
// Based on code from ScummVM - Scumm Interpreter
|
||||||
// Copyright (C) 2002-2004 The ScummVM project
|
// Copyright (C) 2002-2004 The ScummVM project
|
||||||
|
@ -207,7 +207,6 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 27: // escape FIXME - possibly remove this one?
|
|
||||||
case 9: // tab
|
case 9: // tab
|
||||||
{
|
{
|
||||||
// Tab completion: we complete either commands or labels, but not
|
// Tab completion: we complete either commands or labels, but not
|
||||||
|
|
Loading…
Reference in New Issue