mirror of https://github.com/stella-emu/stella.git
Backtracked a little on the new software surfaces rendering code. The
surfaces are still separate and blitted separately, but the actual screen updates are now done all at once, at the end of the frame (as in the previous code). This makes things a little faster, and eliminates an annoying flicker because of SDL_UpdateRect being called at different times. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1547 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
60da49f3ef
commit
54b5b79414
|
@ -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.104 2008-06-19 12:01:30 stephena Exp $
|
||||
// $Id: FrameBufferGL.cxx,v 1.105 2008-08-04 11:56:11 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifdef DISPLAY_OPENGL
|
||||
|
@ -385,7 +385,7 @@ void FrameBufferGL::drawMediaSource()
|
|||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
if(v != w || theRedrawTIAIndicator)
|
||||
if(v != w || myRedrawEntireFrame)
|
||||
{
|
||||
// If we ever get to this point, we know the current and previous
|
||||
// buffers differ. In that case, make sure the changes are
|
||||
|
@ -403,7 +403,7 @@ void FrameBufferGL::drawMediaSource()
|
|||
else
|
||||
{
|
||||
// Phosphor mode always implies a dirty update,
|
||||
// so we don't care about theRedrawTIAIndicator
|
||||
// so we don't care about myRedrawEntireFrame
|
||||
myDirtyFlag = true;
|
||||
|
||||
uInt32 bufofsY = 0;
|
||||
|
@ -462,7 +462,7 @@ void FrameBufferGL::enablePhosphor(bool enable, int blend)
|
|||
myUsePhosphor = enable;
|
||||
myPhosphorBlend = blend;
|
||||
|
||||
theRedrawTIAIndicator = true;
|
||||
myRedrawEntireFrame = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -488,7 +488,7 @@ void FrameBufferGL::toggleFilter()
|
|||
p_glTexParameteri(myBuffer.target, GL_TEXTURE_MIN_FILTER, myBuffer.filter);
|
||||
|
||||
// The filtering has changed, so redraw the entire screen
|
||||
theRedrawTIAIndicator = true;
|
||||
myRedrawEntireFrame = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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.81 2008-07-04 14:27:17 stephena Exp $
|
||||
// $Id: FrameBufferSoft.cxx,v 1.82 2008-08-04 11:56:11 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
@ -35,6 +35,8 @@
|
|||
FrameBufferSoft::FrameBufferSoft(OSystem* osystem)
|
||||
: FrameBuffer(osystem),
|
||||
myRenderType(kSoftZoom_16),
|
||||
myTiaDirty(false),
|
||||
myInUIMode(false),
|
||||
myRectList(NULL)
|
||||
{
|
||||
}
|
||||
|
@ -131,8 +133,6 @@ void FrameBufferSoft::drawMediaSource()
|
|||
uInt32 width = mediasrc.width();
|
||||
uInt32 height = mediasrc.height();
|
||||
|
||||
bool tiaChanged = false;
|
||||
|
||||
switch(myRenderType)
|
||||
{
|
||||
case kSoftZoom_16:
|
||||
|
@ -155,14 +155,14 @@ void FrameBufferSoft::drawMediaSource()
|
|||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
if(v != w || theRedrawTIAIndicator)
|
||||
if(v != w || myRedrawEntireFrame)
|
||||
{
|
||||
while(xstride--)
|
||||
{
|
||||
buffer[pos++] = (uInt16) myDefPalette[v];
|
||||
buffer[pos++] = (uInt16) myDefPalette[v];
|
||||
}
|
||||
tiaChanged = true;
|
||||
myTiaDirty = true;
|
||||
}
|
||||
else
|
||||
pos += xstride + xstride;
|
||||
|
@ -195,7 +195,7 @@ void FrameBufferSoft::drawMediaSource()
|
|||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
if(v != w || theRedrawTIAIndicator)
|
||||
if(v != w || myRedrawEntireFrame)
|
||||
{
|
||||
uInt32 pixel = myDefPalette[v];
|
||||
uInt8 r = (pixel & myFormat->Rmask) >> myFormat->Rshift;
|
||||
|
@ -207,7 +207,7 @@ void FrameBufferSoft::drawMediaSource()
|
|||
buffer[pos++] = r; buffer[pos++] = g; buffer[pos++] = b;
|
||||
buffer[pos++] = r; buffer[pos++] = g; buffer[pos++] = b;
|
||||
}
|
||||
tiaChanged = true;
|
||||
myTiaDirty = true;
|
||||
}
|
||||
else // try to eliminate multply whereever possible
|
||||
pos += xstride + xstride + xstride + xstride + xstride + xstride;
|
||||
|
@ -240,14 +240,14 @@ void FrameBufferSoft::drawMediaSource()
|
|||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
if(v != w || theRedrawTIAIndicator)
|
||||
if(v != w || myRedrawEntireFrame)
|
||||
{
|
||||
while(xstride--)
|
||||
{
|
||||
buffer[pos++] = (uInt32) myDefPalette[v];
|
||||
buffer[pos++] = (uInt32) myDefPalette[v];
|
||||
}
|
||||
tiaChanged = true;
|
||||
myTiaDirty = true;
|
||||
}
|
||||
else
|
||||
pos += xstride + xstride;
|
||||
|
@ -291,7 +291,7 @@ void FrameBufferSoft::drawMediaSource()
|
|||
bufofsY += width;
|
||||
}
|
||||
SDL_UnlockSurface(myScreen);
|
||||
tiaChanged = true;
|
||||
myTiaDirty = true;
|
||||
break; // kPhosphor_16
|
||||
}
|
||||
|
||||
|
@ -330,7 +330,7 @@ void FrameBufferSoft::drawMediaSource()
|
|||
bufofsY += width;
|
||||
}
|
||||
SDL_UnlockSurface(myScreen);
|
||||
tiaChanged = true;
|
||||
myTiaDirty = true;
|
||||
break; // kPhosphor_24
|
||||
}
|
||||
|
||||
|
@ -365,16 +365,25 @@ void FrameBufferSoft::drawMediaSource()
|
|||
bufofsY += width;
|
||||
}
|
||||
SDL_UnlockSurface(myScreen);
|
||||
tiaChanged = true;
|
||||
myTiaDirty = true;
|
||||
break; // kPhosphor_32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(tiaChanged)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::postFrameUpdate()
|
||||
{
|
||||
if(myTiaDirty && !myInUIMode)
|
||||
{
|
||||
SDL_Flip(myScreen);
|
||||
tiaChanged = false;
|
||||
myTiaDirty = false;
|
||||
}
|
||||
else if(myRectList->numRects() > 0)
|
||||
{
|
||||
SDL_UpdateRects(myScreen, myRectList->numRects(), myRectList->rects());
|
||||
}
|
||||
myRectList->start();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -392,6 +401,9 @@ void FrameBufferSoft::stateChanged(EventHandler::State state)
|
|||
if(!myScreen)
|
||||
return;
|
||||
|
||||
myInUIMode = (state == EventHandler::S_LAUNCHER ||
|
||||
state == EventHandler::S_DEBUGGER);
|
||||
|
||||
// Make sure drawMediaSource() knows which renderer to use
|
||||
switch(myBytesPerPixel)
|
||||
{
|
||||
|
@ -683,6 +695,10 @@ void FBSurfaceSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
|||
}
|
||||
else
|
||||
{
|
||||
SDL_Rect temp;
|
||||
temp.x = myXOrig; temp.y = myYOrig; temp.w = myWidth; temp.h = myHeight;
|
||||
myFB.myRectList->add(&temp);
|
||||
|
||||
// Indicate that at least one dirty rect has been added
|
||||
// This is an optimization for the update() method
|
||||
mySurfaceIsDirty = true;
|
||||
|
@ -751,15 +767,7 @@ void FBSurfaceSoft::update()
|
|||
{
|
||||
// Since this method is called each frame, we only blit the surfaces when
|
||||
// absolutely necessary
|
||||
if(myIsBaseSurface)
|
||||
{
|
||||
if(myFB.myRectList->numRects() > 0)
|
||||
{
|
||||
SDL_UpdateRects(mySurface, myFB.myRectList->numRects(), myFB.myRectList->rects());
|
||||
myFB.myRectList->start();
|
||||
}
|
||||
}
|
||||
else if(mySurfaceIsDirty /* && !myIsBaseSurface */)
|
||||
if(mySurfaceIsDirty /* && !myIsBaseSurface */)
|
||||
{
|
||||
SDL_Rect srcrect;
|
||||
srcrect.x = 0;
|
||||
|
@ -772,17 +780,8 @@ void FBSurfaceSoft::update()
|
|||
dstrect.y = myYOrig;
|
||||
dstrect.w = myWidth;
|
||||
dstrect.h = myHeight;
|
||||
/*
|
||||
cerr << "blit sub-surface:" << endl
|
||||
<< " src x = " << dstrect.x << endl
|
||||
<< " src y = " << dstrect.y << endl
|
||||
<< " dst w = " << dstrect.w << endl
|
||||
<< " dst h = " << dstrect.h << endl
|
||||
<< endl;
|
||||
*/
|
||||
SDL_BlitSurface(mySurface, &srcrect, myFB.myScreen, &dstrect);
|
||||
SDL_UpdateRect(myFB.myScreen, myXOrig, myYOrig, myWidth, myHeight);
|
||||
|
||||
SDL_BlitSurface(mySurface, &srcrect, myFB.myScreen, &dstrect);
|
||||
mySurfaceIsDirty = 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: FrameBufferSoft.hxx,v 1.53 2008-08-01 12:15:57 stephena Exp $
|
||||
// $Id: FrameBufferSoft.hxx,v 1.54 2008-08-04 11:56:11 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_SOFT_HXX
|
||||
|
@ -33,7 +33,7 @@ class RectList;
|
|||
This class implements an SDL software framebuffer.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBufferSoft.hxx,v 1.53 2008-08-01 12:15:57 stephena Exp $
|
||||
@version $Id: FrameBufferSoft.hxx,v 1.54 2008-08-04 11:56:11 stephena Exp $
|
||||
*/
|
||||
class FrameBufferSoft : public FrameBuffer
|
||||
{
|
||||
|
@ -127,6 +127,11 @@ class FrameBufferSoft : public FrameBuffer
|
|||
*/
|
||||
void drawMediaSource();
|
||||
|
||||
/**
|
||||
This method is called after any drawing is done (per-frame).
|
||||
*/
|
||||
void postFrameUpdate();
|
||||
|
||||
/**
|
||||
This method is called to provide information about the FrameBuffer.
|
||||
*/
|
||||
|
@ -154,6 +159,12 @@ class FrameBufferSoft : public FrameBuffer
|
|||
};
|
||||
RenderType myRenderType;
|
||||
|
||||
// Indicates if the TIA image has been modified
|
||||
bool myTiaDirty;
|
||||
|
||||
// Indicates if we're in a purely UI mode
|
||||
bool myInUIMode;
|
||||
|
||||
// Used in the dirty update of rectangles in non-TIA modes
|
||||
RectList* myRectList;
|
||||
};
|
||||
|
@ -162,7 +173,7 @@ class FrameBufferSoft : public FrameBuffer
|
|||
A surface suitable for software rendering mode.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBufferSoft.hxx,v 1.53 2008-08-01 12:15:57 stephena Exp $
|
||||
@version $Id: FrameBufferSoft.hxx,v 1.54 2008-08-04 11:56:11 stephena Exp $
|
||||
*/
|
||||
class FBSurfaceSoft : public FBSurface
|
||||
{
|
||||
|
|
|
@ -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.138 2008-08-01 12:15:59 stephena Exp $
|
||||
// $Id: FrameBuffer.cxx,v 1.139 2008-08-04 11:56:12 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -42,7 +42,7 @@
|
|||
FrameBuffer::FrameBuffer(OSystem* osystem)
|
||||
: myOSystem(osystem),
|
||||
myScreen(0),
|
||||
theRedrawTIAIndicator(true),
|
||||
myRedrawEntireFrame(true),
|
||||
myUsePhosphor(false),
|
||||
myPhosphorBlend(77),
|
||||
myInitializedCount(0),
|
||||
|
@ -168,7 +168,7 @@ void FrameBuffer::update()
|
|||
myStatsMsg.surface->fillRect(0, 0, myStatsMsg.w, myStatsMsg.h, kBGColor);
|
||||
myStatsMsg.surface->drawString(&myOSystem->consoleFont(), msg, 0, 0,
|
||||
myStatsMsg.w, myStatsMsg.color, kTextAlignLeft);
|
||||
myStatsMsg.surface->addDirtyRect(0, 0, 0, 0);
|
||||
myStatsMsg.surface->addDirtyRect(0, 0, 0, 0); // force a full draw
|
||||
myStatsMsg.surface->setPos(myImageRect.x() + 3, myImageRect.y() + 3);
|
||||
myStatsMsg.surface->update();
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ void FrameBuffer::update()
|
|||
case EventHandler::S_PAUSE:
|
||||
{
|
||||
// Only update the screen if it's been invalidated
|
||||
if(theRedrawTIAIndicator)
|
||||
if(myRedrawEntireFrame)
|
||||
drawMediaSource();
|
||||
|
||||
// Show a pause message every 5 seconds
|
||||
|
@ -193,7 +193,7 @@ void FrameBuffer::update()
|
|||
case EventHandler::S_MENU:
|
||||
{
|
||||
// Only update the screen if it's been invalidated
|
||||
if(theRedrawTIAIndicator)
|
||||
if(myRedrawEntireFrame)
|
||||
drawMediaSource();
|
||||
|
||||
myOSystem->menu().draw();
|
||||
|
@ -203,7 +203,7 @@ void FrameBuffer::update()
|
|||
case EventHandler::S_CMDMENU:
|
||||
{
|
||||
// Only update the screen if it's been invalidated
|
||||
if(theRedrawTIAIndicator)
|
||||
if(myRedrawEntireFrame)
|
||||
drawMediaSource();
|
||||
|
||||
myOSystem->commandMenu().draw();
|
||||
|
@ -233,8 +233,11 @@ void FrameBuffer::update()
|
|||
if(myMsg.counter > 0)
|
||||
drawMessage();
|
||||
|
||||
// Do any post-frame stuff
|
||||
postFrameUpdate();
|
||||
|
||||
// The frame doesn't need to be completely redrawn anymore
|
||||
theRedrawTIAIndicator = false;
|
||||
myRedrawEntireFrame = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -244,7 +247,7 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
|
|||
// Erase old messages on the screen
|
||||
if(myMsg.counter > 0)
|
||||
{
|
||||
theRedrawTIAIndicator = true;
|
||||
myRedrawEntireFrame = true;
|
||||
myOSystem->eventHandler().refreshDisplay();
|
||||
}
|
||||
|
||||
|
@ -359,7 +362,7 @@ inline void FrameBuffer::drawMessage()
|
|||
myOSystem->eventHandler().refreshDisplay(true);
|
||||
else
|
||||
{
|
||||
myMsg.surface->addDirtyRect(0, 0, 0, 0);
|
||||
myMsg.surface->addDirtyRect(0, 0, 0, 0); // force a full draw
|
||||
myMsg.surface->update();
|
||||
}
|
||||
}
|
||||
|
@ -367,7 +370,7 @@ inline void FrameBuffer::drawMessage()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::refresh()
|
||||
{
|
||||
theRedrawTIAIndicator = true;
|
||||
myRedrawEntireFrame = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -405,7 +408,7 @@ void FrameBuffer::setTIAPalette(const uInt32* palette)
|
|||
}
|
||||
}
|
||||
|
||||
theRedrawTIAIndicator = true;
|
||||
myRedrawEntireFrame = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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.103 2008-08-01 12:16:00 stephena Exp $
|
||||
// $Id: FrameBuffer.hxx,v 1.104 2008-08-04 11:56:12 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_HXX
|
||||
|
@ -90,7 +90,7 @@ enum {
|
|||
turn drawn here as well.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBuffer.hxx,v 1.103 2008-08-01 12:16:00 stephena Exp $
|
||||
@version $Id: FrameBuffer.hxx,v 1.104 2008-08-04 11:56:12 stephena Exp $
|
||||
*/
|
||||
class FrameBuffer
|
||||
{
|
||||
|
@ -354,6 +354,11 @@ class FrameBuffer
|
|||
*/
|
||||
virtual void drawMediaSource() = 0;
|
||||
|
||||
/**
|
||||
This method is called after any drawing is done (per-frame).
|
||||
*/
|
||||
virtual void postFrameUpdate() = 0;
|
||||
|
||||
/**
|
||||
This method is called to provide information about the FrameBuffer.
|
||||
*/
|
||||
|
@ -369,8 +374,8 @@ class FrameBuffer
|
|||
// SDL initialization flags
|
||||
uInt32 mySDLFlags;
|
||||
|
||||
// Indicates if the TIA area should be redrawn
|
||||
bool theRedrawTIAIndicator;
|
||||
// Indicates if the entire frame need to redrawn
|
||||
bool myRedrawEntireFrame;
|
||||
|
||||
// Use phosphor effect (aka no flicker on 30Hz screens)
|
||||
bool myUsePhosphor;
|
||||
|
@ -511,7 +516,7 @@ class FrameBuffer
|
|||
FrameBuffer type.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBuffer.hxx,v 1.103 2008-08-01 12:16:00 stephena Exp $
|
||||
@version $Id: FrameBuffer.hxx,v 1.104 2008-08-04 11:56:12 stephena Exp $
|
||||
*/
|
||||
// Text alignment modes for drawString()
|
||||
enum TextAlignment {
|
||||
|
|
Loading…
Reference in New Issue