mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r27775) -Fix [FS#6510]: Insufficient thread synchronisation when switching blitters. (JGR)
This commit is contained in:
parent
d5f82bf55b
commit
b1fe837b8e
|
@ -290,6 +290,8 @@ static bool SwitchNewGRFBlitter()
|
|||
const bool animation_wanted = HasBit(_display_opt, DO_FULL_ANIMATION);
|
||||
const char *cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName();
|
||||
|
||||
VideoDriver::GetInstance()->AcquireBlitterLock();
|
||||
|
||||
for (uint i = 0; i < lengthof(replacement_blitters); i++) {
|
||||
if (animation_wanted && (replacement_blitters[i].animation == 0)) continue;
|
||||
if (!animation_wanted && (replacement_blitters[i].animation == 1)) continue;
|
||||
|
@ -298,7 +300,10 @@ static bool SwitchNewGRFBlitter()
|
|||
if (!IsInsideMM(depth_wanted_by_grf, replacement_blitters[i].min_grf_depth, replacement_blitters[i].max_grf_depth + 1)) continue;
|
||||
const char *repl_blitter = replacement_blitters[i].name;
|
||||
|
||||
if (strcmp(repl_blitter, cur_blitter) == 0) return false;
|
||||
if (strcmp(repl_blitter, cur_blitter) == 0) {
|
||||
VideoDriver::GetInstance()->ReleaseBlitterLock();
|
||||
return false;
|
||||
}
|
||||
if (BlitterFactory::GetBlitterFactory(repl_blitter) == NULL) continue;
|
||||
|
||||
DEBUG(misc, 1, "Switching blitter from '%s' to '%s'... ", cur_blitter, repl_blitter);
|
||||
|
@ -313,6 +318,8 @@ static bool SwitchNewGRFBlitter()
|
|||
if (BlitterFactory::SelectBlitter(cur_blitter) == NULL || !VideoDriver::GetInstance()->AfterBlitterChange()) usererror("Failed to reinitialize video driver. Specify a fixed blitter in the config");
|
||||
}
|
||||
|
||||
VideoDriver::GetInstance()->ReleaseBlitterLock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -817,11 +817,18 @@ bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen)
|
|||
}
|
||||
|
||||
bool VideoDriver_SDL::AfterBlitterChange()
|
||||
{
|
||||
return CreateMainSurface(_screen.width, _screen.height);
|
||||
}
|
||||
|
||||
void VideoDriver_SDL::AcquireBlitterLock()
|
||||
{
|
||||
if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true);
|
||||
bool ret = CreateMainSurface(_screen.width, _screen.height);
|
||||
}
|
||||
|
||||
void VideoDriver_SDL::ReleaseBlitterLock()
|
||||
{
|
||||
if (_draw_mutex != NULL) _draw_mutex->EndCritical(true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WITH_SDL */
|
||||
|
|
|
@ -31,6 +31,10 @@ public:
|
|||
|
||||
/* virtual */ bool AfterBlitterChange();
|
||||
|
||||
/* virtual */ void AcquireBlitterLock();
|
||||
|
||||
/* virtual */ void ReleaseBlitterLock();
|
||||
|
||||
/* virtual */ bool ClaimMousePointer();
|
||||
|
||||
/* virtual */ const char *GetName() const { return "sdl"; }
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
|
||||
/**
|
||||
* Callback invoked after the blitter was changed.
|
||||
* This may only be called between AcquireBlitterLock and ReleaseBlitterLock.
|
||||
* @return True if no error.
|
||||
*/
|
||||
virtual bool AfterBlitterChange()
|
||||
|
@ -56,6 +57,18 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire any lock(s) required to be held when changing blitters.
|
||||
* These lock(s) may not be acquired recursively.
|
||||
*/
|
||||
virtual void AcquireBlitterLock() { }
|
||||
|
||||
/**
|
||||
* Release any lock(s) required to be held when changing blitters.
|
||||
* These lock(s) may not be acquired recursively.
|
||||
*/
|
||||
virtual void ReleaseBlitterLock() { }
|
||||
|
||||
virtual bool ClaimMousePointer()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -1333,11 +1333,18 @@ bool VideoDriver_Win32::ToggleFullscreen(bool full_screen)
|
|||
}
|
||||
|
||||
bool VideoDriver_Win32::AfterBlitterChange()
|
||||
{
|
||||
return AllocateDibSection(_screen.width, _screen.height, true) && this->MakeWindow(_fullscreen);
|
||||
}
|
||||
|
||||
void VideoDriver_Win32::AcquireBlitterLock()
|
||||
{
|
||||
if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true);
|
||||
bool ret = AllocateDibSection(_screen.width, _screen.height, true) && this->MakeWindow(_fullscreen);
|
||||
}
|
||||
|
||||
void VideoDriver_Win32::ReleaseBlitterLock()
|
||||
{
|
||||
if (_draw_mutex != NULL) _draw_mutex->EndCritical(true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VideoDriver_Win32::EditBoxLostFocus()
|
||||
|
|
|
@ -31,6 +31,10 @@ public:
|
|||
|
||||
/* virtual */ bool AfterBlitterChange();
|
||||
|
||||
/* virtual */ void AcquireBlitterLock();
|
||||
|
||||
/* virtual */ void ReleaseBlitterLock();
|
||||
|
||||
/* virtual */ bool ClaimMousePointer();
|
||||
|
||||
/* virtual */ void EditBoxLostFocus();
|
||||
|
|
Loading…
Reference in New Issue