summaryrefslogtreecommitdiff
path: root/src/openttd.cpp
diff options
context:
space:
mode:
authorPatric Stout <truebrain@openttd.org>2021-03-09 14:53:51 +0100
committerPatric Stout <github@truebrain.nl>2021-03-10 13:41:18 +0100
commit970fedd78cef3f5ef7a26fcaf4fd9db0f6abbe4b (patch)
treeb894a4b222a74f9d8e80832e36bd21d9a16f4f9e /src/openttd.cpp
parent098d5b22395e123e4990b73a2ad7bf703adf068b (diff)
downloadopenttd-970fedd78cef3f5ef7a26fcaf4fd9db0f6abbe4b.tar.xz
Add: make modal windows update more smooth
Basically, modal windows had their own thread-locking for what drawing was possible. This is a bit nonsense now we have a game-thread. And it makes much more sense to do things like NewGRFScan and GenerateWorld in the game-thread, and not in a thread next to the game-thread. This commit changes that: it removes the threads for NewGRFScan and GenerateWorld, and just runs the code in the game-thread. On regular intervals it allows the draw-thread to do a tick, which gives a much smoother look and feel. It does slow down NewGRFScan and GenerateWorld ever so slightly as it spends more time on drawing. But the slowdown is not measureable on my machines (with 700+ NewGRFs / 4kx4k map and a Debug build). Running without a game-thread means NewGRFScan and GenerateWorld are now blocking.
Diffstat (limited to 'src/openttd.cpp')
-rw-r--r--src/openttd.cpp40
1 files changed, 22 insertions, 18 deletions
diff --git a/src/openttd.cpp b/src/openttd.cpp
index 3397e4f0e..2d37c8e3a 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -91,6 +91,8 @@ extern void ShowOSErrorBox(const char *buf, bool system);
extern std::string _config_file;
bool _save_config = false;
+bool _request_newgrf_scan = false;
+NewGRFScanCallback *_request_newgrf_scan_callback = nullptr;
/**
* Error handling for fatal user errors.
@@ -345,7 +347,6 @@ static void LoadIntroGame(bool load_newgrfs = true)
/* Load the default opening screen savegame */
if (SaveOrLoad("opntitle.dat", SLO_LOAD, DFT_GAME_FILE, BASESET_DIR) != SL_OK) {
GenerateWorld(GWM_EMPTY, 64, 64); // if failed loading, make empty world.
- WaitTillGeneratedWorld();
SetLocalCompany(COMPANY_SPECTATOR);
} else {
SetLocalCompany(COMPANY_FIRST);
@@ -559,9 +560,6 @@ int openttd_main(int argc, char *argv[])
extern bool _dedicated_forks;
_dedicated_forks = false;
- std::unique_lock<std::mutex> modal_work_lock(_modal_progress_work_mutex, std::defer_lock);
- std::unique_lock<std::mutex> modal_paint_lock(_modal_progress_paint_mutex, std::defer_lock);
-
_game_mode = GM_MENU;
_switch_mode = SM_MENU;
@@ -828,30 +826,17 @@ int openttd_main(int argc, char *argv[])
if (musicdriver.empty() && !_ini_musicdriver.empty()) musicdriver = _ini_musicdriver;
DriverFactoryBase::SelectDriver(musicdriver, Driver::DT_MUSIC);
- /* Take our initial lock on whatever we might want to do! */
- try {
- modal_work_lock.lock();
- modal_paint_lock.lock();
- } catch (const std::system_error&) {
- /* If there is some error we assume that threads aren't usable on the system we run. */
- extern bool _use_threaded_modal_progress; // From progress.cpp
- _use_threaded_modal_progress = false;
- }
-
GenerateWorld(GWM_EMPTY, 64, 64); // Make the viewport initialization happy
- WaitTillGeneratedWorld();
-
LoadIntroGame(false);
CheckForMissingGlyphs();
/* ScanNewGRFFiles now has control over the scanner. */
- ScanNewGRFFiles(scanner.release());
+ RequestNewGRFScan(scanner.release());
VideoDriver::GetInstance()->MainLoop();
WaitTillSaved();
- WaitTillGeneratedWorld(); // Make sure any generate world threads have been joined.
/* only save config if we have to */
if (_save_config) {
@@ -1460,6 +1445,19 @@ static void DoAutosave()
}
}
+/**
+ * Request a new NewGRF scan. This will be executed on the next game-tick.
+ * This is mostly needed to ensure NewGRF scans (which are blocking) are
+ * done in the game-thread, and not in the draw-thread (which most often
+ * triggers this request).
+ * @param callback Optional callback to call when NewGRF scan is completed.
+ */
+void RequestNewGRFScan(NewGRFScanCallback *callback)
+{
+ _request_newgrf_scan = true;
+ _request_newgrf_scan_callback = callback;
+}
+
void GameLoop()
{
if (_game_mode == GM_BOOTSTRAP) {
@@ -1468,6 +1466,12 @@ void GameLoop()
return;
}
+ if (_request_newgrf_scan) {
+ ScanNewGRFFiles(_request_newgrf_scan_callback);
+ _request_newgrf_scan = false;
+ _request_newgrf_scan_callback = nullptr;
+ }
+
ProcessAsyncSaveFinish();
/* autosave game? */