Revert to old way of handling framebuffer surfaces.

Still TODO is fix crash when FileListWidget is used (BrowserDialog).
This commit is contained in:
Stephen Anthony 2021-05-28 22:12:12 -02:30
parent ac26a6f361
commit ae527a7f5e
20 changed files with 69 additions and 127 deletions

View File

@ -71,6 +71,8 @@ FBBackendSDL2::~FBBackendSDL2()
myWindow = nullptr; myWindow = nullptr;
} }
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER); SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER);
cerr << "~FBBackendSDL2()" << endl;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -40,6 +40,8 @@ namespace {
} }
} }
static int REF_COUNT = 0;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurfaceSDL2::FBSurfaceSDL2(FBBackendSDL2& backend, FBSurfaceSDL2::FBSurfaceSDL2(FBBackendSDL2& backend,
uInt32 width, uInt32 height, uInt32 width, uInt32 height,
@ -48,6 +50,7 @@ FBSurfaceSDL2::FBSurfaceSDL2(FBBackendSDL2& backend,
: myBackend{backend}, : myBackend{backend},
myInterpolationMode{inter} myInterpolationMode{inter}
{ {
REF_COUNT++;
createSurface(width, height, staticData); createSurface(width, height, staticData);
} }
@ -58,6 +61,8 @@ FBSurfaceSDL2::~FBSurfaceSDL2()
if(mySurface) if(mySurface)
{ {
REF_COUNT--;
cerr << " ~FBSurfaceSDL2(): " << this << " " << REF_COUNT << endl;
SDL_FreeSurface(mySurface); SDL_FreeSurface(mySurface);
mySurface = nullptr; mySurface = nullptr;
} }

View File

@ -67,6 +67,7 @@ FrameBuffer::FrameBuffer(OSystem& osystem)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBuffer::~FrameBuffer() FrameBuffer::~FrameBuffer()
{ {
cerr << "~FrameBuffer()\n";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -885,63 +886,28 @@ void FrameBuffer::setPauseDelay()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unique_ptr<FBSurface> FrameBuffer::allocateSurface( shared_ptr<FBSurface> FrameBuffer::allocateSurface(
int w, int h, ScalingInterpolation inter, const uInt32* data) int w, int h, ScalingInterpolation inter, const uInt32* data)
{ {
return myBackend->createSurface(w, h, inter, data); mySurfaceList.push_back(myBackend->createSurface(w, h, inter, data));
return mySurfaceList.back();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::deallocateSurface(shared_ptr<FBSurface> surface)
{
if(surface)
{
cerr << "deallocateSurface: " << surface << endl;
mySurfaceList.remove(surface);
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::resetSurfaces() void FrameBuffer::resetSurfaces()
{ {
switch(myOSystem.eventHandler().state()) for(auto& surface: mySurfaceList)
{ surface->reload();
case EventHandlerState::NONE:
case EventHandlerState::EMULATION:
case EventHandlerState::PAUSE:
case EventHandlerState::PLAYBACK:
#ifdef GUI_SUPPORT
myMsg.surface->reload();
myStatsMsg.surface->reload();
#endif
myTIASurface->resetSurfaces();
break;
#ifdef GUI_SUPPORT
case EventHandlerState::OPTIONSMENU:
myOSystem.menu().resetSurfaces();
break;
case EventHandlerState::CMDMENU:
myOSystem.commandMenu().resetSurfaces();
break;
case EventHandlerState::HIGHSCORESMENU:
myOSystem.highscoresMenu().resetSurfaces();
break;
case EventHandlerState::MESSAGEMENU:
myOSystem.messageMenu().resetSurfaces();
break;
case EventHandlerState::TIMEMACHINE:
myOSystem.timeMachine().resetSurfaces();
break;
case EventHandlerState::LAUNCHER:
myOSystem.launcher().resetSurfaces();
break;
#endif
#ifdef DEBUGGER_SUPPORT
case EventHandlerState::DEBUGGER:
myOSystem.debugger().resetSurfaces();
break;
#endif
default:
break;
}
update(UpdateMode::REDRAW); // force full update update(UpdateMode::REDRAW); // force full update
} }

View File

@ -18,7 +18,7 @@
#ifndef FRAMEBUFFER_HXX #ifndef FRAMEBUFFER_HXX
#define FRAMEBUFFER_HXX #define FRAMEBUFFER_HXX
#include <map> #include <list>
class OSystem; class OSystem;
class Console; class Console;
@ -158,13 +158,21 @@ class FrameBuffer
@return A pointer to a valid surface object, or nullptr @return A pointer to a valid surface object, or nullptr
*/ */
unique_ptr<FBSurface> allocateSurface( shared_ptr<FBSurface> allocateSurface(
int w, int w,
int h, int h,
ScalingInterpolation inter = ScalingInterpolation::none, ScalingInterpolation inter = ScalingInterpolation::none,
const uInt32* data = nullptr const uInt32* data = nullptr
); );
/**
Deallocate a previously allocated surface. If no such surface exists,
this method does nothing.
@param surface The surface to remove/deallocate
*/
void deallocateSurface(shared_ptr<FBSurface> surface);
/** /**
Set up the TIA/emulation palette. Due to the way the palette is stored, Set up the TIA/emulation palette. Due to the way the palette is stored,
a call to this method implicitly calls setUIPalette() too. a call to this method implicitly calls setUIPalette() too.
@ -521,7 +529,7 @@ class FrameBuffer
int x{0}, y{0}, w{0}, h{0}; int x{0}, y{0}, w{0}, h{0};
MessagePosition position{MessagePosition::BottomCenter}; MessagePosition position{MessagePosition::BottomCenter};
ColorId color{kNone}; ColorId color{kNone};
unique_ptr<FBSurface> surface; shared_ptr<FBSurface> surface;
bool enabled{false}; bool enabled{false};
bool dirty{false}; bool dirty{false};
bool showGauge{false}; bool showGauge{false};
@ -540,6 +548,9 @@ class FrameBuffer
// Minimum TIA zoom level that can be used for this framebuffer // Minimum TIA zoom level that can be used for this framebuffer
float myTIAMinZoom{2.F}; float myTIAMinZoom{2.F};
// Holds a reference to all the surfaces that have been created
std::list<shared_ptr<FBSurface>> mySurfaceList;
// Maximum message width [chars] // Maximum message width [chars]
static constexpr int MESSAGE_WIDTH = 56; static constexpr int MESSAGE_WIDTH = 56;
// Maximum gauge bar width [chars] // Maximum gauge bar width [chars]

View File

@ -110,6 +110,7 @@ OSystem::OSystem()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSystem::~OSystem() OSystem::~OSystem()
{ {
cerr << "~OSystem()\n";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -103,6 +103,7 @@ class OSystem
@return The frame buffer @return The frame buffer
*/ */
FrameBuffer& frameBuffer() const { return *myFrameBuffer; } FrameBuffer& frameBuffer() const { return *myFrameBuffer; }
bool hasFrameBuffer() const { return myFrameBuffer.get() != nullptr; }
/** /**
Get the sound object of the system. Get the sound object of the system.

View File

@ -541,12 +541,3 @@ bool TIASurface::correctAspect() const
{ {
return myOSystem.settings().getBool("tia.correct_aspect"); return myOSystem.settings().getBool("tia.correct_aspect");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::resetSurfaces()
{
myTiaSurface->reload();
mySLineSurface->reload();
myBaseTiaSurface->reload();
myShadeSurface->reload();
}

View File

@ -49,7 +49,7 @@ class TIASurface
Creates a new TIASurface object Creates a new TIASurface object
*/ */
explicit TIASurface(OSystem& system); explicit TIASurface(OSystem& system);
virtual ~TIASurface(); ~TIASurface();
/** /**
Set the TIA object, which is needed for actually rendering the TIA image. Set the TIA object, which is needed for actually rendering the TIA image.
@ -183,11 +183,6 @@ class TIASurface
*/ */
void updateSurfaceSettings(); void updateSurfaceSettings();
/**
Issue a 'reload' to each surface.
*/
void resetSurfaces();
private: private:
/** /**
Average current calculated buffer's pixel with previous calculated buffer's pixel (50:50). Average current calculated buffer's pixel with previous calculated buffer's pixel (50:50).
@ -213,7 +208,8 @@ class TIASurface
FrameBuffer& myFB; FrameBuffer& myFB;
TIA* myTIA{nullptr}; TIA* myTIA{nullptr};
unique_ptr<FBSurface> myTiaSurface, mySLineSurface, myBaseTiaSurface, myShadeSurface; shared_ptr<FBSurface> myTiaSurface, mySLineSurface,
myBaseTiaSurface, myShadeSurface;
// NTSC object to use in TIA rendering mode // NTSC object to use in TIA rendering mode
NTSCFilter myNTSCFilter; NTSCFilter myNTSCFilter;

View File

@ -70,6 +70,14 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Dialog::~Dialog() Dialog::~Dialog()
{ {
if(instance().hasFrameBuffer())
{
instance().frameBuffer().deallocateSurface(_surface);
instance().frameBuffer().deallocateSurface(_shadeSurface);
}
else
cerr << "!!! framebuffer not available\n";
_myFocus.list.clear(); _myFocus.list.clear();
_myTabList.clear(); _myTabList.clear();
@ -251,12 +259,6 @@ void Dialog::setDirtyChain()
_dirtyChain = true; _dirtyChain = true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::resetSurfaces()
{
_surface->reload();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::tick() void Dialog::tick()
{ {

View File

@ -63,8 +63,6 @@ class Dialog : public GuiObject
virtual void saveConfig() { } virtual void saveConfig() { }
virtual void setDefaults() { } virtual void setDefaults() { }
virtual void resetSurfaces();
void setDirty() override; void setDirty() override;
void setDirtyChain() override; void setDirtyChain() override;
void redraw(bool force = false); void redraw(bool force = false);
@ -263,8 +261,8 @@ class Dialog : public GuiObject
TabFocusList _myTabList; // focus for each tab (if any) TabFocusList _myTabList; // focus for each tab (if any)
WidgetArray _buttonGroup; WidgetArray _buttonGroup;
unique_ptr<FBSurface> _surface; shared_ptr<FBSurface> _surface;
unique_ptr<FBSurface> _shadeSurface; shared_ptr<FBSurface> _shadeSurface;
int _tabID{0}; int _tabID{0};
uInt32 _max_w{0}; // maximum wanted width uInt32 _max_w{0}; // maximum wanted width

View File

@ -163,7 +163,6 @@ int DialogContainer::addDialog(Dialog* d)
myDialogStack.top()->tooltip().hide(); myDialogStack.top()->tooltip().hide();
d->setDirty(); d->setDirty();
d->resetSurfaces();
myDialogStack.push(d); myDialogStack.push(d);
} }
return myDialogStack.size(); return myDialogStack.size();
@ -200,14 +199,6 @@ void DialogContainer::reStack()
reset(); reset();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DialogContainer::resetSurfaces()
{
myDialogStack.applyAll([&](Dialog*& d) {
d->resetSurfaces();
});
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DialogContainer::handleTextEvent(char text) void DialogContainer::handleTextEvent(char text)
{ {

View File

@ -150,13 +150,6 @@ class DialogContainer
*/ */
void reStack(); void reStack();
/**
Issue a 'reload' event to each dialog surface in the stack. This
is typically used when interpolation or attributes for a dialog
have changed.
*/
void resetSurfaces();
/** /**
Inform the container that it should resize according to the current Inform the container that it should resize according to the current
screen dimensions. We make this virtual, since the container may or screen dimensions. We make this virtual, since the container may or

View File

@ -75,7 +75,7 @@ void FileListWidget::setLocation(const FilesystemNode& node,
{ {
progress().resetProgress(); progress().resetProgress();
progress().open(); progress().open();
FilesystemNode::CancelCheck isCancelled = []() { FilesystemNode::CancelCheck isCancelled = [this]() {
return myProgressDialog->isCancelled(); return myProgressDialog->isCancelled();
}; };
@ -154,6 +154,7 @@ ProgressDialog& FileListWidget::progress()
return *myProgressDialog; return *myProgressDialog;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FileListWidget::incProgress() void FileListWidget::incProgress()
{ {
if(_includeSubDirs) if(_includeSubDirs)
@ -269,5 +270,3 @@ string FileListWidget::getToolTip(const Common::Point& pos) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt64 FileListWidget::_QUICK_SELECT_DELAY = 300; uInt64 FileListWidget::_QUICK_SELECT_DELAY = 300;
unique_ptr<ProgressDialog> FileListWidget::myProgressDialog{nullptr};

View File

@ -94,9 +94,6 @@ class FileListWidget : public StringListWidget
ProgressDialog& progress(); ProgressDialog& progress();
void incProgress(); void incProgress();
protected:
static unique_ptr<ProgressDialog> myProgressDialog;
private: private:
/** Very similar to setDirectory(), but also updates the history */ /** Very similar to setDirectory(), but also updates the history */
void setLocation(const FilesystemNode& node, const string& select); void setLocation(const FilesystemNode& node, const string& select);
@ -124,6 +121,8 @@ class FileListWidget : public StringListWidget
uInt64 _quickSelectTime{0}; uInt64 _quickSelectTime{0};
static uInt64 _QUICK_SELECT_DELAY; static uInt64 _QUICK_SELECT_DELAY;
unique_ptr<ProgressDialog> myProgressDialog;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported
FileListWidget() = delete; FileListWidget() = delete;

View File

@ -353,15 +353,6 @@ void LauncherDialog::reload()
myPendingReload = false; myPendingReload = false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::resetSurfaces()
{
if(myRomInfoWidget)
myRomInfoWidget->resetSurfaces();
Dialog::resetSurfaces();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::tick() void LauncherDialog::tick()
{ {

View File

@ -108,7 +108,6 @@ class LauncherDialog : public Dialog
void loadConfig() override; void loadConfig() override;
void saveConfig() override; void saveConfig() override;
void resetSurfaces() override;
void updateUI(); void updateUI();
/** /**

View File

@ -184,13 +184,6 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node)
setDirty(); setDirty();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomInfoWidget::resetSurfaces()
{
if(mySurface)
mySurface->reload();
}
#ifdef PNG_SUPPORT #ifdef PNG_SUPPORT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RomInfoWidget::loadPng(const string& filename) bool RomInfoWidget::loadPng(const string& filename)

View File

@ -44,8 +44,6 @@ class RomInfoWidget : public Widget, public CommandSender
void clearProperties(); void clearProperties();
void reloadProperties(const FilesystemNode& node); void reloadProperties(const FilesystemNode& node);
void resetSurfaces();
const string& getUrl() const { return myUrl; } const string& getUrl() const { return myUrl; }
protected: protected:
@ -60,7 +58,7 @@ class RomInfoWidget : public Widget, public CommandSender
private: private:
// Surface pointer holding the PNG image // Surface pointer holding the PNG image
unique_ptr<FBSurface> mySurface; shared_ptr<FBSurface> mySurface;
// Whether the surface should be redrawn by drawWidget() // Whether the surface should be redrawn by drawWidget()
bool mySurfaceIsValid{false}; bool mySurfaceIsValid{false};

View File

@ -34,6 +34,12 @@ ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font)
setFont(font); setFont(font);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ToolTip::~ToolTip()
{
myDialog.instance().frameBuffer().deallocateSurface(mySurface);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ToolTip::setFont(const GUI::Font& font) void ToolTip::setFont(const GUI::Font& font)
{ {
@ -48,12 +54,12 @@ void ToolTip::setFont(const GUI::Font& font)
myHeight = fontHeight * MAX_ROWS + myTextYOfs * 2; myHeight = fontHeight * MAX_ROWS + myTextYOfs * 2;
// unallocate // unallocate
if(mySurface != nullptr) myDialog.instance().frameBuffer().deallocateSurface(mySurface);
mySurface.reset(); mySurface = nullptr;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const unique_ptr<FBSurface>& ToolTip::surface() const shared_ptr<FBSurface>& ToolTip::surface()
{ {
if(mySurface == nullptr) if(mySurface == nullptr)
mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight); mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight);

View File

@ -42,7 +42,7 @@ class ToolTip
static constexpr uInt32 MAX_LEN = MAX_COLUMNS * MAX_ROWS; static constexpr uInt32 MAX_LEN = MAX_COLUMNS * MAX_ROWS;
ToolTip(Dialog& dialog, const GUI::Font& font); ToolTip(Dialog& dialog, const GUI::Font& font);
~ToolTip() = default; ~ToolTip();
void setFont(const GUI::Font& font); void setFont(const GUI::Font& font);
@ -76,7 +76,7 @@ class ToolTip
/** /**
Allocate surface if required and return it Allocate surface if required and return it
*/ */
const unique_ptr<FBSurface>& surface(); const shared_ptr<FBSurface>& surface();
void show(const string& tip); void show(const string& tip);
@ -100,7 +100,7 @@ class ToolTip
uInt32 myTextYOfs{0}; uInt32 myTextYOfs{0};
bool myTipShown{false}; bool myTipShown{false};
uInt32 myScale{1}; uInt32 myScale{1};
unique_ptr<FBSurface> mySurface; shared_ptr<FBSurface> mySurface;
}; };
#endif #endif