File diff r25010:cc3b6b985580 → r25011:61d28a13bb41
src/video/sdl2_v.cpp
Show inline comments
 
@@ -23,7 +23,6 @@
 
#include "../window_func.h"
 
#include "sdl2_v.h"
 
#include <SDL.h>
 
#include <mutex>
 
#ifdef __EMSCRIPTEN__
 
#	include <emscripten.h>
 
#	include <emscripten/html5.h>
 
@@ -50,11 +49,6 @@ void VideoDriver_SDL_Base::CheckPaletteA
 
	this->MakeDirty(0, 0, _screen.width, _screen.height);
 
}
 

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

	
 
static const Dimension default_resolutions[] = {
 
	{  640,  480 },
 
	{  800,  600 },
 
@@ -565,19 +559,6 @@ const char *VideoDriver_SDL_Base::Start(
 

	
 
	MarkWholeScreenDirty();
 

	
 
	this->draw_threaded = !GetDriverParamBool(parm, "no_threads") && !GetDriverParamBool(parm, "no_thread");
 
	/* Wayland SDL video driver uses EGL to render the game. SDL created the
 
	 * EGL context from the main-thread, and with EGL you are not allowed to
 
	 * draw in another thread than the context was created. The function of
 
	 * draw_threaded is to do exactly this: draw in another thread than the
 
	 * window was created, and as such, this fails on Wayland SDL video
 
	 * driver. So, we disable threading by default if Wayland SDL video
 
	 * driver is detected.
 
	 */
 
	if (strcmp(dname, "wayland") == 0) {
 
		this->draw_threaded = false;
 
	}
 

	
 
	SDL_StopTextInput();
 
	this->edit_box_focused = false;
 

	
 
@@ -631,18 +612,17 @@ void VideoDriver_SDL_Base::LoopOnce()
 
		 * After that, Emscripten just halts, and the HTML shows a nice
 
		 * "bye, see you next time" message. */
 
		emscripten_cancel_main_loop();
 
		MainLoopCleanup();
 
		emscripten_exit_pointerlock();
 
		/* In effect, the game ends here. As emscripten_set_main_loop() caused
 
		 * the stack to be unwound, the code after MainLoop() in
 
		 * openttd_main() is never executed. */
 
		EM_ASM(if (window["openttd_syncfs"]) openttd_syncfs());
 
		EM_ASM(if (window["openttd_exit"]) openttd_exit());
 
#endif
 
		return;
 
	}
 

	
 
	if (VideoDriver::Tick()) {
 
		if (this->draw_mutex != nullptr && !HasModalProgress()) {
 
			this->draw_signal->notify_one();
 
		} else {
 
			this->Paint();
 
		}
 
	}
 
	this->Tick();
 

	
 
/* Emscripten is running an event-based mainloop; there is already some
 
 * downtime between each iteration, so no need to sleep. */
 
@@ -653,36 +633,6 @@ void VideoDriver_SDL_Base::LoopOnce()
 

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

	
 
			this->draw_threaded = StartNewThread(&draw_thread, "ottd:draw-sdl", &VideoDriver_SDL_Base::PaintThreadThunk, this);
 

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

	
 
	DEBUG(driver, 1, "SDL2: using %sthreads", this->draw_threaded ? "" : "no ");
 

	
 
#ifdef __EMSCRIPTEN__
 
	/* Run the main loop event-driven, based on RequestAnimationFrame. */
 
	emscripten_set_main_loop_arg(&this->EmscriptenLoop, this, 0, 1);
 
@@ -690,52 +640,16 @@ void VideoDriver_SDL_Base::MainLoop()
 
	while (!_exit_game) {
 
		LoopOnce();
 
	}
 

	
 
	MainLoopCleanup();
 
#endif
 
}
 

	
 
void VideoDriver_SDL_Base::MainLoopCleanup()
 
{
 
	if (this->draw_mutex != nullptr) {
 
		this->draw_continue = false;
 
		/* Sending signal if there is no thread blocked
 
		 * is very valid and results in noop */
 
		this->draw_signal->notify_one();
 
		if (draw_lock.owns_lock()) draw_lock.unlock();
 
		draw_lock.release();
 
		draw_thread.join();
 

	
 
		delete this->draw_mutex;
 
		delete this->draw_signal;
 

	
 
		this->draw_mutex = nullptr;
 
		this->draw_signal = nullptr;
 
	}
 

	
 
#ifdef __EMSCRIPTEN__
 
	emscripten_exit_pointerlock();
 
	/* In effect, the game ends here. As emscripten_set_main_loop() caused
 
	 * the stack to be unwound, the code after MainLoop() in
 
	 * openttd_main() is never executed. */
 
	EM_ASM(if (window["openttd_syncfs"]) openttd_syncfs());
 
	EM_ASM(if (window["openttd_exit"]) openttd_exit());
 
#endif
 
}
 

	
 
bool VideoDriver_SDL_Base::ChangeResolution(int w, int h)
 
{
 
	std::unique_lock<std::recursive_mutex> lock;
 
	if (this->draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*this->draw_mutex);
 

	
 
	return CreateMainSurface(w, h, true);
 
}
 

	
 
bool VideoDriver_SDL_Base::ToggleFullscreen(bool fullscreen)
 
{
 
	std::unique_lock<std::recursive_mutex> lock;
 
	if (this->draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*this->draw_mutex);
 

	
 
	int w, h;
 

	
 
	/* Remember current window size */
 
@@ -773,16 +687,6 @@ bool VideoDriver_SDL_Base::AfterBlitterC
 
	return CreateMainSurface(w, h, false);
 
}
 

	
 
void VideoDriver_SDL_Base::AcquireBlitterLock()
 
{
 
	if (this->draw_mutex != nullptr) this->draw_mutex->lock();
 
}
 

	
 
void VideoDriver_SDL_Base::ReleaseBlitterLock()
 
{
 
	if (this->draw_mutex != nullptr) this->draw_mutex->unlock();
 
}
 

	
 
Dimension VideoDriver_SDL_Base::GetScreenSize() const
 
{
 
	SDL_DisplayMode mode;
 
@@ -796,8 +700,6 @@ bool VideoDriver_SDL_Base::LockVideoBuff
 
	if (this->buffer_locked) return false;
 
	this->buffer_locked = true;
 

	
 
	if (this->draw_threaded) this->draw_lock.lock();
 

	
 
	_screen.dst_ptr = this->GetVideoPointer();
 
	assert(_screen.dst_ptr != nullptr);
 

	
 
@@ -812,6 +714,5 @@ void VideoDriver_SDL_Base::UnlockVideoBu
 
		_screen.dst_ptr = nullptr;
 
	}
 

	
 
	if (this->draw_threaded) this->draw_lock.unlock();
 
	this->buffer_locked = false;
 
}