mirror of https://github.com/stella-emu/stella.git
Removed concept of single vs. double buffering, and simply update the frame
on every call to FrameBuffer::update(). This will the same CPU usage for TIA mode, and a slight increase CPU usage for launcher and debugger modes. The code to do this was just too fragile, and not worth the extra effort. This fixes several rendering issues, such as garbage in fullscreen mode in Linux when using Intel GPU, triple-buffering issues in Windows, etc. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@3148 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
6f194fcd76
commit
6d8b115b34
|
@ -12,7 +12,7 @@
|
|||
Release History
|
||||
===========================================================================
|
||||
|
||||
4.5 to 4.6: (February xx, 2015)
|
||||
4.5 to 4.6: (March xx, 2015)
|
||||
|
||||
* Reverted some minor C++11 features (std::regex and cbegin/cend
|
||||
iterators) in a few places, since otherwise GCC 4.9 is required to
|
||||
|
@ -20,6 +20,12 @@
|
|||
changes allow Stella to be built with GCC 4.8, which is present in
|
||||
the latest 'long term release' of Ubuntu.
|
||||
|
||||
* Finally fixed fullscreen rendering issues on some OpenGL
|
||||
implementations in Linux (mostly Intel-specific). Basically, the
|
||||
concept of 'dirty updates' as been removed; the window is now
|
||||
updated continuously. This may also fix issues some people were
|
||||
having with triple-buffering, etc.
|
||||
|
||||
* Fixed error messages on state loading; sometimes multiple messages
|
||||
were being added together and displayed.
|
||||
|
||||
|
|
|
@ -90,11 +90,6 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
inline Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) const
|
||||
{ return SDL_MapRGB(myPixelFormat, r, g, b); }
|
||||
|
||||
/**
|
||||
This method is called to query the buffering type of the FrameBuffer.
|
||||
*/
|
||||
bool isDoubleBuffered() const { return myDblBufferedFlag; }
|
||||
|
||||
/**
|
||||
This method is called to get a copy of the specified ARGB data from the
|
||||
viewable FrameBuffer area. Note that this isn't the same as any
|
||||
|
|
|
@ -491,7 +491,6 @@ void Console::changeYStart(int direction)
|
|||
|
||||
myTIA->setYStart(ystart);
|
||||
myTIA->frameReset();
|
||||
myOSystem.frameBuffer().refresh();
|
||||
|
||||
ostringstream val;
|
||||
val << ystart;
|
||||
|
|
|
@ -812,10 +812,10 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int)
|
|||
{
|
||||
switch(e)
|
||||
{
|
||||
#if 0
|
||||
case EVENT_WINDOW_EXPOSED:
|
||||
myOSystem.frameBuffer().refresh();
|
||||
break;
|
||||
#if 0
|
||||
case EVENT_WINDOW_MINIMIZED:
|
||||
if(myState == S_EMULATE) enterMenuMode(S_MENU);
|
||||
break;
|
||||
|
|
|
@ -255,6 +255,8 @@ void FrameBuffer::update()
|
|||
// Determine which mode we are in (from the EventHandler)
|
||||
// Take care of S_EMULATE mode here, otherwise let the GUI
|
||||
// figure out what to draw
|
||||
|
||||
invalidate();
|
||||
switch(myOSystem.eventHandler().state())
|
||||
{
|
||||
case EventHandler::S_EMULATE:
|
||||
|
@ -294,6 +296,8 @@ void FrameBuffer::update()
|
|||
|
||||
case EventHandler::S_PAUSE:
|
||||
{
|
||||
drawTIA();
|
||||
|
||||
// Show a pause message every 5 seconds
|
||||
if(myPausedCount++ >= 7*myOSystem.frameRate())
|
||||
{
|
||||
|
@ -305,26 +309,28 @@ void FrameBuffer::update()
|
|||
|
||||
case EventHandler::S_MENU:
|
||||
{
|
||||
myOSystem.menu().draw();
|
||||
drawTIA();
|
||||
myOSystem.menu().draw(true);
|
||||
break; // S_MENU
|
||||
}
|
||||
|
||||
case EventHandler::S_CMDMENU:
|
||||
{
|
||||
myOSystem.commandMenu().draw();
|
||||
drawTIA();
|
||||
myOSystem.commandMenu().draw(true);
|
||||
break; // S_CMDMENU
|
||||
}
|
||||
|
||||
case EventHandler::S_LAUNCHER:
|
||||
{
|
||||
myOSystem.launcher().draw();
|
||||
myOSystem.launcher().draw(true);
|
||||
break; // S_LAUNCHER
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
case EventHandler::S_DEBUGGER:
|
||||
{
|
||||
myOSystem.debugger().draw();
|
||||
myOSystem.debugger().draw(true);
|
||||
break; // S_DEBUGGER
|
||||
}
|
||||
#endif
|
||||
|
@ -349,10 +355,6 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
|
|||
if(!(force || myOSystem.settings().getBool("uimessages")))
|
||||
return;
|
||||
|
||||
// Erase old messages on the screen
|
||||
if(myMsg.counter > 0)
|
||||
refresh();
|
||||
|
||||
// Precompute the message coordinates
|
||||
myMsg.text = message;
|
||||
myMsg.counter = uInt32(myOSystem.frameRate()) << 1; // Show message for 2 seconds
|
||||
|
@ -377,7 +379,6 @@ void FrameBuffer::showFrameStats(bool enable)
|
|||
{
|
||||
myOSystem.settings().setValue("stats", enable);
|
||||
myStatsMsg.enabled = enable;
|
||||
refresh();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -396,8 +397,7 @@ void FrameBuffer::enableMessages(bool enable)
|
|||
// Erase old messages on the screen
|
||||
myMsg.enabled = false;
|
||||
myMsg.counter = 0;
|
||||
|
||||
refresh();
|
||||
update(); // Force update immediately
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,20 +458,16 @@ inline void FrameBuffer::drawMessage()
|
|||
myMsg.surface->box(0, 0, myMsg.w, myMsg.h, kColor, kShadowColor);
|
||||
myMsg.surface->drawString(font(), myMsg.text, 4, 4,
|
||||
myMsg.w, myMsg.color, kTextAlignLeft);
|
||||
myMsg.counter--;
|
||||
|
||||
// Either erase the entire message (when time is reached),
|
||||
// or show again this frame
|
||||
if(myMsg.counter == 0) // Force an immediate update
|
||||
{
|
||||
myMsg.enabled = false;
|
||||
refresh();
|
||||
}
|
||||
else
|
||||
if(myMsg.counter-- > 0)
|
||||
{
|
||||
myMsg.surface->setDirty();
|
||||
myMsg.surface->render();
|
||||
}
|
||||
else
|
||||
myMsg.enabled = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -480,81 +476,6 @@ inline void FrameBuffer::drawTIA()
|
|||
myTIASurface->render();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::refresh()
|
||||
{
|
||||
// This method partly duplicates the behaviour in ::update()
|
||||
// Here, however, make sure to redraw *all* surfaces applicable to the
|
||||
// current EventHandler state
|
||||
// We also check for double-buffered modes, and when present
|
||||
// update both buffers accordingly
|
||||
//
|
||||
// This method is in essence a FULL refresh, putting all rendering
|
||||
// buffers in a known, fully redrawn state
|
||||
|
||||
switch(myOSystem.eventHandler().state())
|
||||
{
|
||||
case EventHandler::S_EMULATE:
|
||||
case EventHandler::S_PAUSE:
|
||||
invalidate();
|
||||
drawTIA();
|
||||
break;
|
||||
|
||||
case EventHandler::S_MENU:
|
||||
invalidate();
|
||||
drawTIA();
|
||||
myOSystem.menu().draw(true);
|
||||
if(isDoubleBuffered())
|
||||
{
|
||||
postFrameUpdate();
|
||||
invalidate();
|
||||
drawTIA();
|
||||
myOSystem.menu().draw(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case EventHandler::S_CMDMENU:
|
||||
invalidate();
|
||||
drawTIA();
|
||||
myOSystem.commandMenu().draw(true);
|
||||
if(isDoubleBuffered())
|
||||
{
|
||||
postFrameUpdate();
|
||||
invalidate();
|
||||
drawTIA();
|
||||
myOSystem.commandMenu().draw(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case EventHandler::S_LAUNCHER:
|
||||
invalidate();
|
||||
myOSystem.launcher().draw(true);
|
||||
if(isDoubleBuffered())
|
||||
{
|
||||
postFrameUpdate();
|
||||
invalidate();
|
||||
myOSystem.launcher().draw(true);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
case EventHandler::S_DEBUGGER:
|
||||
invalidate();
|
||||
myOSystem.debugger().draw(true);
|
||||
if(isDoubleBuffered())
|
||||
{
|
||||
postFrameUpdate();
|
||||
invalidate();
|
||||
myOSystem.debugger().draw(true);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
shared_ptr<FBSurface> FrameBuffer::allocateSurface(int w, int h, const uInt32* data)
|
||||
{
|
||||
|
@ -623,7 +544,6 @@ void FrameBuffer::setFullscreen(bool enable)
|
|||
myOSystem.settings().setValue("fullscreen", fullScreen());
|
||||
resetSurfaces();
|
||||
setCursorState();
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,7 +584,6 @@ bool FrameBuffer::changeWindowedVidMode(int direction)
|
|||
resetSurfaces();
|
||||
showMessage(mode.description);
|
||||
myOSystem.settings().setValue("tia.zoom", mode.zoom);
|
||||
refresh();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -252,12 +252,6 @@ class FrameBuffer
|
|||
*/
|
||||
TIASurface& tiaSurface() const { return *myTIASurface; }
|
||||
|
||||
/**
|
||||
Refresh display according to the current state, taking single vs.
|
||||
double-buffered modes into account, and redrawing accordingly.
|
||||
*/
|
||||
void refresh();
|
||||
|
||||
/**
|
||||
Enables/disables fullscreen mode.
|
||||
*/
|
||||
|
@ -336,11 +330,6 @@ class FrameBuffer
|
|||
*/
|
||||
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) const = 0;
|
||||
|
||||
/**
|
||||
This method is called to query the buffering type of the FrameBuffer.
|
||||
*/
|
||||
virtual bool isDoubleBuffered() const = 0;
|
||||
|
||||
/**
|
||||
This method is called to get the specified ARGB data from the viewable
|
||||
FrameBuffer area. Note that this isn't the same as any internal
|
||||
|
|
|
@ -418,7 +418,6 @@ bool OSystem::createLauncher(const string& startdir)
|
|||
{
|
||||
myLauncher->reStack();
|
||||
myFrameBuffer->setCursorState();
|
||||
myFrameBuffer->refresh();
|
||||
|
||||
setFramerate(60);
|
||||
resetLoopTiming();
|
||||
|
|
|
@ -162,7 +162,6 @@ void CommandDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
|
||||
case kSnapshotCmd:
|
||||
instance().eventHandler().leaveMenuMode();
|
||||
instance().frameBuffer().refresh();
|
||||
instance().eventHandler().handleEvent(Event::TakeSnapshot, 1);
|
||||
break;
|
||||
|
||||
|
@ -195,10 +194,7 @@ void CommandDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
instance().console().switches().update();
|
||||
instance().console().tia().update();
|
||||
instance().eventHandler().handleEvent(event, 0);
|
||||
instance().frameBuffer().refresh();
|
||||
}
|
||||
else if(stateCmd)
|
||||
{
|
||||
instance().eventHandler().handleEvent(event, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,9 +82,6 @@ void Dialog::open(bool refresh)
|
|||
buildCurrentFocusList();
|
||||
|
||||
_visible = true;
|
||||
|
||||
if(refresh)
|
||||
instance().frameBuffer().refresh();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -101,9 +98,6 @@ void Dialog::close(bool refresh)
|
|||
_visible = false;
|
||||
|
||||
parent().removeDialog();
|
||||
|
||||
if(refresh)
|
||||
instance().frameBuffer().refresh();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -131,8 +131,6 @@ void DialogContainer::reStack()
|
|||
|
||||
myBaseDialog->open(false); // don't force a refresh
|
||||
|
||||
myOSystem.frameBuffer().refresh();
|
||||
|
||||
// Reset all continuous events
|
||||
reset();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef EDITABLE_WIDGET_HXX
|
||||
#define EDITABLE_WIDGET_HXX
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "Widget.hxx"
|
||||
#include "Rect.hxx"
|
||||
|
||||
|
|
Loading…
Reference in New Issue