Changeset - r22568:df7ef8916103
[Not reviewed]
master
0 6 0
frosch - 7 years ago 2017-03-11 13:05:54
frosch@openttd.org
(svn r27775) -Fix [FS#6510]: Insufficient thread synchronisation when switching blitters. (JGR)
6 files changed with 47 insertions and 5 deletions:
0 comments (0 inline, 0 general)
src/gfxinit.cpp
Show inline comments
 
@@ -287,21 +287,26 @@ static bool SwitchNewGRFBlitter()
 
		{ "32bpp-anim",      1,  8, 32,  8, 32 },
 
	};
 

	
 
	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;
 

	
 
		if (!IsInsideMM(depth_wanted_by_base, replacement_blitters[i].min_base_depth, replacement_blitters[i].max_base_depth + 1)) continue;
 
		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);
 
		Blitter *new_blitter = BlitterFactory::SelectBlitter(repl_blitter);
 
		if (new_blitter == NULL) NOT_REACHED();
 
		DEBUG(misc, 1, "Successfully switched to %s.", repl_blitter);
 
@@ -310,12 +315,14 @@ static bool SwitchNewGRFBlitter()
 

	
 
	if (!VideoDriver::GetInstance()->AfterBlitterChange()) {
 
		/* Failed to switch blitter, let's hope we can return to the old one. */
 
		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;
 
}
 

	
 
/** Check whether we still use the right blitter, or use another (better) one. */
 
void CheckBlitter()
 
{
src/video/sdl_v.cpp
Show inline comments
 
@@ -815,13 +815,20 @@ bool VideoDriver_SDL::ToggleFullscreen(b
 
	if (_draw_mutex != NULL) _draw_mutex->EndCritical(true);
 
	return ret;
 
}
 

	
 
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 */
src/video/sdl_v.h
Show inline comments
 
@@ -28,12 +28,16 @@ public:
 
	/* virtual */ bool ChangeResolution(int w, int h);
 

	
 
	/* virtual */ bool ToggleFullscreen(bool fullscreen);
 

	
 
	/* virtual */ bool AfterBlitterChange();
 

	
 
	/* virtual */ void AcquireBlitterLock();
 

	
 
	/* virtual */ void ReleaseBlitterLock();
 

	
 
	/* virtual */ bool ClaimMousePointer();
 

	
 
	/* virtual */ const char *GetName() const { return "sdl"; }
 
private:
 
	int PollEvent();
 
	bool CreateMainSurface(uint w, uint h);
src/video/video_driver.hpp
Show inline comments
 
@@ -46,19 +46,32 @@ public:
 
	 * @return True if the change succeeded.
 
	 */
 
	virtual bool ToggleFullscreen(bool fullscreen) = 0;
 

	
 
	/**
 
	 * Callback invoked after the blitter was changed.
 
	 * This may only be called between AcquireBlitterLock and ReleaseBlitterLock.
 
	 * @return True if no error.
 
	 */
 
	virtual bool AfterBlitterChange()
 
	{
 
		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;
 
	}
 

	
 
	/**
src/video/win32_v.cpp
Show inline comments
 
@@ -1331,16 +1331,23 @@ bool VideoDriver_Win32::ToggleFullscreen
 
	if (_draw_mutex != NULL) _draw_mutex->EndCritical(true);
 
	return ret;
 
}
 

	
 
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()
 
{
 
	if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true);
 
	CancelIMEComposition(_wnd.main_wnd);
src/video/win32_v.h
Show inline comments
 
@@ -28,12 +28,16 @@ public:
 
	/* virtual */ bool ChangeResolution(int w, int h);
 

	
 
	/* virtual */ bool ToggleFullscreen(bool fullscreen);
 

	
 
	/* virtual */ bool AfterBlitterChange();
 

	
 
	/* virtual */ void AcquireBlitterLock();
 

	
 
	/* virtual */ void ReleaseBlitterLock();
 

	
 
	/* virtual */ bool ClaimMousePointer();
 

	
 
	/* virtual */ void EditBoxLostFocus();
 

	
 
	/* virtual */ const char *GetName() const { return "win32"; }
 

	
0 comments (0 inline, 0 general)