mirror of https://github.com/OpenTTD/OpenTTD.git
Fix: ensure switching blitter happens in the main thread
This because video-drivers might need to make changes to their context, which for most video-drivers has to be done in the same thread as the window was created; main thread in our case.
This commit is contained in:
parent
e56d2c63c3
commit
8946b41d20
|
@ -308,18 +308,11 @@ static bool SwitchNewGRFBlitter()
|
|||
}
|
||||
if (BlitterFactory::GetBlitterFactory(repl_blitter) == nullptr) continue;
|
||||
|
||||
DEBUG(misc, 1, "Switching blitter from '%s' to '%s'... ", cur_blitter, repl_blitter);
|
||||
Blitter *new_blitter = BlitterFactory::SelectBlitter(repl_blitter);
|
||||
if (new_blitter == nullptr) NOT_REACHED();
|
||||
DEBUG(misc, 1, "Successfully switched to %s.", repl_blitter);
|
||||
/* Inform the video driver we want to switch blitter as soon as possible. */
|
||||
VideoDriver::GetInstance()->ChangeBlitter(repl_blitter);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!VideoDriver::GetInstance()->AfterBlitterChange()) {
|
||||
/* Failed to switch blitter, let's hope we can return to the old one. */
|
||||
if (BlitterFactory::SelectBlitter(cur_blitter) == nullptr || !VideoDriver::GetInstance()->AfterBlitterChange()) usererror("Failed to reinitialize video driver. Specify a fixed blitter in the config");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,11 @@
|
|||
#include "../stdafx.h"
|
||||
#include "../core/random_func.hpp"
|
||||
#include "../network/network.h"
|
||||
#include "../blitter/factory.hpp"
|
||||
#include "../debug.h"
|
||||
#include "../fontcache.h"
|
||||
#include "../gfx_func.h"
|
||||
#include "../gfxinit.h"
|
||||
#include "../progress.h"
|
||||
#include "../thread.h"
|
||||
#include "../window_func.h"
|
||||
|
@ -74,6 +77,27 @@ void VideoDriver::StopGameThread()
|
|||
this->game_thread.join();
|
||||
}
|
||||
|
||||
void VideoDriver::RealChangeBlitter(const char *repl_blitter)
|
||||
{
|
||||
const char *cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName();
|
||||
|
||||
DEBUG(driver, 1, "Switching blitter from '%s' to '%s'... ", cur_blitter, repl_blitter);
|
||||
Blitter *new_blitter = BlitterFactory::SelectBlitter(repl_blitter);
|
||||
if (new_blitter == nullptr) NOT_REACHED();
|
||||
DEBUG(driver, 1, "Successfully switched to %s.", repl_blitter);
|
||||
|
||||
if (!this->AfterBlitterChange()) {
|
||||
/* Failed to switch blitter, let's hope we can return to the old one. */
|
||||
if (BlitterFactory::SelectBlitter(cur_blitter) == nullptr || !this->AfterBlitterChange()) usererror("Failed to reinitialize video driver. Specify a fixed blitter in the config");
|
||||
}
|
||||
|
||||
/* Clear caches that might have sprites for another blitter. */
|
||||
this->ClearSystemSprites();
|
||||
ClearFontCache();
|
||||
GfxClearSpriteCache();
|
||||
ReInitAllWindows();
|
||||
}
|
||||
|
||||
void VideoDriver::Tick()
|
||||
{
|
||||
if (!this->is_game_threaded && std::chrono::steady_clock::now() >= this->next_game_tick) {
|
||||
|
@ -115,6 +139,11 @@ void VideoDriver::Tick()
|
|||
|
||||
this->LockVideoBuffer();
|
||||
|
||||
if (this->change_blitter != nullptr) {
|
||||
this->RealChangeBlitter(this->change_blitter);
|
||||
this->change_blitter = nullptr;
|
||||
}
|
||||
|
||||
while (this->PollEvent()) {}
|
||||
::InputLoop();
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class VideoDriver : public Driver {
|
|||
const uint DEFAULT_WINDOW_HEIGHT = 480u; ///< Default window height.
|
||||
|
||||
public:
|
||||
VideoDriver() : is_game_threaded(true) {}
|
||||
VideoDriver() : is_game_threaded(true), change_blitter(nullptr) {}
|
||||
|
||||
/**
|
||||
* Mark a particular area dirty.
|
||||
|
@ -161,6 +161,15 @@ public:
|
|||
return ZOOM_LVL_OUT_4X;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a request to change the blitter. This is not executed immediately,
|
||||
* but instead on the next draw-tick.
|
||||
*/
|
||||
void ChangeBlitter(const char *new_blitter)
|
||||
{
|
||||
this->change_blitter = new_blitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently active instance of the video driver.
|
||||
*/
|
||||
|
@ -303,6 +312,9 @@ protected:
|
|||
private:
|
||||
void GameLoop();
|
||||
void GameThread();
|
||||
void RealChangeBlitter(const char *repl_blitter);
|
||||
|
||||
const char *change_blitter; ///< Request to change the blitter. nullptr if no pending request.
|
||||
};
|
||||
|
||||
#endif /* VIDEO_VIDEO_DRIVER_HPP */
|
||||
|
|
Loading…
Reference in New Issue