mirror of https://github.com/stella-emu/stella.git
The framebuffer now recognizes double-buffering based on whether the render backend is accelerated, and the refresh method uses this to refresh buffers. This fixes the flashing that appears in OpenGL in Windows and OSX. Interestingly, Direct3D in Windows and OpenGL in Linux didn't exhibit this issue.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2871 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
c878fd926d
commit
0b3bf4b659
|
@ -42,7 +42,8 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem* osystem)
|
||||||
myRenderer(NULL),
|
myRenderer(NULL),
|
||||||
myWindowFlags(0),
|
myWindowFlags(0),
|
||||||
myTiaSurface(NULL),
|
myTiaSurface(NULL),
|
||||||
myDirtyFlag(true)
|
myDirtyFlag(true),
|
||||||
|
myDblBufferedFlag(true)
|
||||||
{
|
{
|
||||||
// Initialize SDL2 context
|
// Initialize SDL2 context
|
||||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
|
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
|
||||||
|
@ -211,7 +212,12 @@ bool FrameBufferSDL2::setVideoMode(const string& title, VideoMode& mode, bool fu
|
||||||
}
|
}
|
||||||
SDL_RendererInfo renderinfo;
|
SDL_RendererInfo renderinfo;
|
||||||
if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0)
|
if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0)
|
||||||
|
{
|
||||||
myOSystem->settings().setValue("video", renderinfo.name);
|
myOSystem->settings().setValue("video", renderinfo.name);
|
||||||
|
// For now, accelerated renderers imply double buffering
|
||||||
|
// Eventually, SDL may be updated to query this from the render backend
|
||||||
|
myDblBufferedFlag = renderinfo.flags & SDL_RENDERER_ACCELERATED;
|
||||||
|
}
|
||||||
|
|
||||||
// The framebuffer only takes responsibility for TIA surfaces
|
// The framebuffer only takes responsibility for TIA surfaces
|
||||||
// Other surfaces (such as the ones used for dialogs) are allocated
|
// Other surfaces (such as the ones used for dialogs) are allocated
|
||||||
|
|
|
@ -113,9 +113,9 @@ class FrameBufferSDL2 : public FrameBuffer
|
||||||
{ return SDL_MapRGB(myPixelFormat, r, g, b); }
|
{ return SDL_MapRGB(myPixelFormat, r, g, b); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to query the type of the FrameBuffer.
|
This method is called to query the buffering type of the FrameBuffer.
|
||||||
*/
|
*/
|
||||||
BufferType type() const { return kDoubleBuffer; }
|
bool isDoubleBuffered() const { return myDblBufferedFlag; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to query the TV effects in use by the FrameBuffer.
|
This method is called to query the TV effects in use by the FrameBuffer.
|
||||||
|
@ -238,6 +238,9 @@ class FrameBufferSDL2 : public FrameBuffer
|
||||||
|
|
||||||
// Indicates that the texture has been modified, and should be redrawn
|
// Indicates that the texture has been modified, and should be redrawn
|
||||||
bool myDirtyFlag;
|
bool myDirtyFlag;
|
||||||
|
|
||||||
|
// Indicates whether the backend is using double buffering
|
||||||
|
bool myDblBufferedFlag;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -317,7 +317,7 @@ void FrameBuffer::update()
|
||||||
{
|
{
|
||||||
// When onscreen messages are enabled in double-buffer mode,
|
// When onscreen messages are enabled in double-buffer mode,
|
||||||
// a full redraw is required
|
// a full redraw is required
|
||||||
myOSystem->menu().draw(myMsg.enabled && type() == kDoubleBuffer);
|
myOSystem->menu().draw(myMsg.enabled && isDoubleBuffered());
|
||||||
break; // S_MENU
|
break; // S_MENU
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +325,7 @@ void FrameBuffer::update()
|
||||||
{
|
{
|
||||||
// When onscreen messages are enabled in double-buffer mode,
|
// When onscreen messages are enabled in double-buffer mode,
|
||||||
// a full redraw is required
|
// a full redraw is required
|
||||||
myOSystem->commandMenu().draw(myMsg.enabled && type() == kDoubleBuffer);
|
myOSystem->commandMenu().draw(myMsg.enabled && isDoubleBuffered());
|
||||||
break; // S_CMDMENU
|
break; // S_CMDMENU
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ void FrameBuffer::update()
|
||||||
{
|
{
|
||||||
// When onscreen messages are enabled in double-buffer mode,
|
// When onscreen messages are enabled in double-buffer mode,
|
||||||
// a full redraw is required
|
// a full redraw is required
|
||||||
myOSystem->launcher().draw(myMsg.enabled && type() == kDoubleBuffer);
|
myOSystem->launcher().draw(myMsg.enabled && isDoubleBuffered());
|
||||||
break; // S_LAUNCHER
|
break; // S_LAUNCHER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ void FrameBuffer::update()
|
||||||
{
|
{
|
||||||
// When onscreen messages are enabled in double-buffer mode,
|
// When onscreen messages are enabled in double-buffer mode,
|
||||||
// a full redraw is required
|
// a full redraw is required
|
||||||
myOSystem->debugger().draw(myMsg.enabled && type() == kDoubleBuffer);
|
myOSystem->debugger().draw(myMsg.enabled && isDoubleBuffered());
|
||||||
break; // S_DEBUGGER
|
break; // S_DEBUGGER
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -510,14 +510,13 @@ void FrameBuffer::refresh()
|
||||||
// This method is in essence a FULL refresh, putting all rendering
|
// This method is in essence a FULL refresh, putting all rendering
|
||||||
// buffers in a known, fully redrawn state
|
// buffers in a known, fully redrawn state
|
||||||
|
|
||||||
bool doubleBuffered = (type() == kDoubleBuffer);
|
|
||||||
switch(myOSystem->eventHandler().state())
|
switch(myOSystem->eventHandler().state())
|
||||||
{
|
{
|
||||||
case EventHandler::S_EMULATE:
|
case EventHandler::S_EMULATE:
|
||||||
case EventHandler::S_PAUSE:
|
case EventHandler::S_PAUSE:
|
||||||
invalidate();
|
invalidate();
|
||||||
drawTIA(true);
|
drawTIA(true);
|
||||||
if(doubleBuffered)
|
if(isDoubleBuffered())
|
||||||
{
|
{
|
||||||
postFrameUpdate();
|
postFrameUpdate();
|
||||||
invalidate();
|
invalidate();
|
||||||
|
@ -529,7 +528,7 @@ void FrameBuffer::refresh()
|
||||||
invalidate();
|
invalidate();
|
||||||
drawTIA(true);
|
drawTIA(true);
|
||||||
myOSystem->menu().draw(true);
|
myOSystem->menu().draw(true);
|
||||||
if(doubleBuffered)
|
if(isDoubleBuffered())
|
||||||
{
|
{
|
||||||
postFrameUpdate();
|
postFrameUpdate();
|
||||||
invalidate();
|
invalidate();
|
||||||
|
@ -542,7 +541,7 @@ void FrameBuffer::refresh()
|
||||||
invalidate();
|
invalidate();
|
||||||
drawTIA(true);
|
drawTIA(true);
|
||||||
myOSystem->commandMenu().draw(true);
|
myOSystem->commandMenu().draw(true);
|
||||||
if(doubleBuffered)
|
if(isDoubleBuffered())
|
||||||
{
|
{
|
||||||
postFrameUpdate();
|
postFrameUpdate();
|
||||||
invalidate();
|
invalidate();
|
||||||
|
@ -554,7 +553,7 @@ void FrameBuffer::refresh()
|
||||||
case EventHandler::S_LAUNCHER:
|
case EventHandler::S_LAUNCHER:
|
||||||
invalidate();
|
invalidate();
|
||||||
myOSystem->launcher().draw(true);
|
myOSystem->launcher().draw(true);
|
||||||
if(doubleBuffered)
|
if(isDoubleBuffered())
|
||||||
{
|
{
|
||||||
postFrameUpdate();
|
postFrameUpdate();
|
||||||
invalidate();
|
invalidate();
|
||||||
|
@ -566,7 +565,7 @@ void FrameBuffer::refresh()
|
||||||
case EventHandler::S_DEBUGGER:
|
case EventHandler::S_DEBUGGER:
|
||||||
invalidate();
|
invalidate();
|
||||||
myOSystem->debugger().draw(true);
|
myOSystem->debugger().draw(true);
|
||||||
if(doubleBuffered)
|
if(isDoubleBuffered())
|
||||||
{
|
{
|
||||||
postFrameUpdate();
|
postFrameUpdate();
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
|
@ -39,12 +39,6 @@ namespace GUI {
|
||||||
#include "Variant.hxx"
|
#include "Variant.hxx"
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
|
||||||
// Different types of framebuffer derived objects
|
|
||||||
enum BufferType {
|
|
||||||
kSingleBuffer,
|
|
||||||
kDoubleBuffer
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return values for initialization of framebuffer window
|
// Return values for initialization of framebuffer window
|
||||||
enum FBInitStatus {
|
enum FBInitStatus {
|
||||||
kSuccess,
|
kSuccess,
|
||||||
|
@ -365,9 +359,9 @@ class FrameBuffer
|
||||||
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) const = 0;
|
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to query the type of the FrameBuffer.
|
This method is called to query the buffering type of the FrameBuffer.
|
||||||
*/
|
*/
|
||||||
virtual BufferType type() const = 0;
|
virtual bool isDoubleBuffered() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to get the specified scanline data from the
|
This method is called to get the specified scanline data from the
|
||||||
|
|
|
@ -37,10 +37,8 @@
|
||||||
Settings::Settings(OSystem* osystem)
|
Settings::Settings(OSystem* osystem)
|
||||||
: myOSystem(osystem)
|
: myOSystem(osystem)
|
||||||
{
|
{
|
||||||
// Add options that are common to all versions of Stella
|
|
||||||
setInternal("video", "soft");
|
|
||||||
|
|
||||||
// Video-related options
|
// Video-related options
|
||||||
|
setInternal("video", "");
|
||||||
setInternal("vsync", "true");
|
setInternal("vsync", "true");
|
||||||
setInternal("fullscreen", "0");
|
setInternal("fullscreen", "0");
|
||||||
setInternal("fullres", "auto");
|
setInternal("fullres", "auto");
|
||||||
|
@ -275,21 +273,16 @@ void Settings::validate()
|
||||||
string s;
|
string s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
s = getString("video");
|
|
||||||
if(s != "soft" && s != "gl") setInternal("video", "soft");
|
|
||||||
|
|
||||||
s = getString("timing");
|
s = getString("timing");
|
||||||
if(s != "sleep" && s != "busy") setInternal("timing", "sleep");
|
if(s != "sleep" && s != "busy") setInternal("timing", "sleep");
|
||||||
|
|
||||||
//FIXSDL
|
|
||||||
i = getInt("tia.aspectn");
|
i = getInt("tia.aspectn");
|
||||||
if(i < 80 || i > 120) setInternal("tia.aspectn", "100");
|
if(i < 80 || i > 120) setInternal("tia.aspectn", "90");
|
||||||
i = getInt("tia.aspectp");
|
i = getInt("tia.aspectp");
|
||||||
if(i < 80 || i > 120) setInternal("tia.aspectp", "100");
|
if(i < 80 || i > 120) setInternal("tia.aspectp", "100");
|
||||||
|
|
||||||
i = getInt("tv.filter");
|
i = getInt("tv.filter");
|
||||||
if(i < 0 || i > 5) setInternal("tv.filter", "0");
|
if(i < 0 || i > 5) setInternal("tv.filter", "0");
|
||||||
//////////////////
|
|
||||||
|
|
||||||
#ifdef SOUND_SUPPORT
|
#ifdef SOUND_SUPPORT
|
||||||
i = getInt("volume");
|
i = getInt("volume");
|
||||||
|
|
Loading…
Reference in New Issue