File diff r25010:cc3b6b985580 → r25011:61d28a13bb41
src/video/sdl_v.cpp
Show inline comments
 
@@ -23,8 +23,6 @@
 
#include "../window_func.h"
 
#include "sdl_v.h"
 
#include <SDL.h>
 
#include <mutex>
 
#include <condition_variable>
 

	
 
#include "../safeguards.h"
 

	
 
@@ -34,14 +32,6 @@ static SDL_Surface *_sdl_surface;
 
static SDL_Surface *_sdl_realscreen;
 
static bool _all_modes;
 

	
 
/** Whether the drawing is/may be done in a separate thread. */
 
static bool _draw_threaded;
 
/** Mutex to keep the access to the shared memory controlled. */
 
static std::recursive_mutex *_draw_mutex = nullptr;
 
/** Signal to draw the next frame. */
 
static std::condition_variable_any *_draw_signal = nullptr;
 
/** Should we keep continue drawing? */
 
static volatile bool _draw_continue;
 
static Palette _local_palette;
 

	
 
#define MAX_DIRTY_RECTS 100
 
@@ -174,27 +164,6 @@ void VideoDriver_SDL::Paint()
 
	}
 
}
 

	
 
void VideoDriver_SDL::PaintThread()
 
{
 
	/* First tell the main thread we're started */
 
	std::unique_lock<std::recursive_mutex> lock(*_draw_mutex);
 
	_draw_signal->notify_one();
 

	
 
	/* Now wait for the first thing to draw! */
 
	_draw_signal->wait(*_draw_mutex);
 

	
 
	while (_draw_continue) {
 
		/* Then just draw and wait till we stop */
 
		this->Paint();
 
		_draw_signal->wait(lock);
 
	}
 
}
 

	
 
/* static */ void VideoDriver_SDL::PaintThreadThunk(VideoDriver_SDL *drv)
 
{
 
	drv->PaintThread();
 
}
 

	
 
static const Dimension _default_resolutions[] = {
 
	{ 640,  480},
 
	{ 800,  600},
 
@@ -630,8 +599,6 @@ const char *VideoDriver_SDL::Start(const
 
	MarkWholeScreenDirty();
 
	SetupKeyboard();
 

	
 
	_draw_threaded = !GetDriverParamBool(parm, "no_threads") && !GetDriverParamBool(parm, "no_thread");
 

	
 
	return nullptr;
 
}
 

	
 
@@ -680,80 +647,21 @@ void VideoDriver_SDL::InputLoop()
 

	
 
void VideoDriver_SDL::MainLoop()
 
{
 
	std::thread draw_thread;
 
	if (_draw_threaded) {
 
		/* Initialise the mutex first, because that's the thing we *need*
 
		 * directly in the newly created thread. */
 
		_draw_mutex = new std::recursive_mutex();
 
		if (_draw_mutex == nullptr) {
 
			_draw_threaded = false;
 
		} else {
 
			this->draw_lock = std::unique_lock<std::recursive_mutex>(*_draw_mutex);
 
			_draw_signal = new std::condition_variable_any();
 
			_draw_continue = true;
 

	
 
			_draw_threaded = StartNewThread(&draw_thread, "ottd:draw-sdl", &VideoDriver_SDL::PaintThreadThunk, this);
 

	
 
			/* Free the mutex if we won't be able to use it. */
 
			if (!_draw_threaded) {
 
				this->draw_lock.unlock();
 
				this->draw_lock.release();
 
				delete _draw_mutex;
 
				delete _draw_signal;
 
				_draw_mutex = nullptr;
 
				_draw_signal = nullptr;
 
			} else {
 
				/* Wait till the draw mutex has started itself. */
 
				_draw_signal->wait(*_draw_mutex);
 
			}
 
		}
 
	}
 

	
 
	DEBUG(driver, 1, "SDL: using %sthreads", _draw_threaded ? "" : "no ");
 

	
 
	for (;;) {
 
		if (_exit_game) break;
 

	
 
		if (this->Tick()) {
 
			if (_draw_mutex != nullptr && !HasModalProgress()) {
 
				_draw_signal->notify_one();
 
			} else {
 
				this->Paint();
 
			}
 
		}
 
		this->Tick();
 
		this->SleepTillNextTick();
 
	}
 

	
 
	if (_draw_mutex != nullptr) {
 
		_draw_continue = false;
 
		/* Sending signal if there is no thread blocked
 
		 * is very valid and results in noop */
 
		_draw_signal->notify_one();
 
		if (this->draw_lock.owns_lock()) this->draw_lock.unlock();
 
		this->draw_lock.release();
 
		draw_thread.join();
 

	
 
		delete _draw_mutex;
 
		delete _draw_signal;
 

	
 
		_draw_mutex = nullptr;
 
		_draw_signal = nullptr;
 
	}
 
}
 

	
 
bool VideoDriver_SDL::ChangeResolution(int w, int h)
 
{
 
	std::unique_lock<std::recursive_mutex> lock;
 
	if (_draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*_draw_mutex);
 

	
 
	return CreateMainSurface(w, h);
 
}
 

	
 
bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen)
 
{
 
	std::unique_lock<std::recursive_mutex> lock;
 
	if (_draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*_draw_mutex);
 

	
 
	_fullscreen = fullscreen;
 
	GetVideoModes(); // get the list of available video modes
 
	bool ret = !_resolutions.empty() && CreateMainSurface(_cur_resolution.width, _cur_resolution.height);
 
@@ -772,25 +680,4 @@ bool VideoDriver_SDL::AfterBlitterChange
 
	return CreateMainSurface(_screen.width, _screen.height);
 
}
 

	
 
void VideoDriver_SDL::AcquireBlitterLock()
 
{
 
	if (_draw_mutex != nullptr) _draw_mutex->lock();
 
}
 

	
 
void VideoDriver_SDL::ReleaseBlitterLock()
 
{
 
	if (_draw_mutex != nullptr) _draw_mutex->unlock();
 
}
 

	
 
bool VideoDriver_SDL::LockVideoBuffer()
 
{
 
	if (_draw_threaded) this->draw_lock.lock();
 
	return true;
 
}
 

	
 
void VideoDriver_SDL::UnlockVideoBuffer()
 
{
 
	if (_draw_threaded) this->draw_lock.unlock();
 
}
 

	
 
#endif /* WITH_SDL */