Changeset - r24831:5af48bd7a880
[Not reviewed]
master
0 7 0
Patric Stout - 4 years ago 2021-02-17 13:46:19
truebrain@openttd.org
Codechange: switch all video drivers to std::chrono for keeping time

On all OSes we tested the std::chrono::steady_clock is of a high
enough resolution to do millisecond measurements, which is all we
need.

By accident, this fixes a Win32 driver bug, where we would never
hit our targets, as the resolution of the clock was too low to
do accurate millisecond measurements with (it was ~16ms resolution
instead).
7 files changed with 44 insertions and 101 deletions:
0 comments (0 inline, 0 general)
src/video/allegro_v.cpp
Show inline comments
 
@@ -445,34 +445,15 @@ void VideoDriver_Allegro::Stop()
 
	if (--_allegro_instance_count == 0) allegro_exit();
 
}
 

	
 
#if defined(UNIX) || defined(__OS2__)
 
# include <sys/time.h> /* gettimeofday */
 

	
 
static uint32 GetTime()
 
{
 
	struct timeval tim;
 

	
 
	gettimeofday(&tim, nullptr);
 
	return tim.tv_usec / 1000 + tim.tv_sec * 1000;
 
}
 
#else
 
static uint32 GetTime()
 
{
 
	return GetTickCount();
 
}
 
#endif
 

	
 

	
 
void VideoDriver_Allegro::MainLoop()
 
{
 
	uint32 cur_ticks = GetTime();
 
	uint32 last_cur_ticks = cur_ticks;
 
	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
	auto cur_ticks = std::chrono::steady_clock::now();
 
	auto last_cur_ticks = cur_ticks;
 
	auto next_tick = cur_ticks;
 

	
 
	CheckPaletteAnim();
 

	
 
	for (;;) {
 
		uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
 
		InteractiveRandom(); // randomness
 

	
 
		PollEvent();
 
@@ -491,11 +472,11 @@ void VideoDriver_Allegro::MainLoop()
 
			_fast_forward = 0;
 
		}
 

	
 
		cur_ticks = GetTime();
 
		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
 
			_realtime_tick += cur_ticks - last_cur_ticks;
 
		cur_ticks = std::chrono::steady_clock::now();
 
		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode)) {
 
			_realtime_tick += std::chrono::duration_cast<std::chrono::milliseconds>(cur_ticks - last_cur_ticks).count();
 
			last_cur_ticks = cur_ticks;
 
			next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
			next_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
 

	
 
			bool old_ctrl_pressed = _ctrl_pressed;
 

	
src/video/cocoa/cocoa_v.mm
Show inline comments
 
@@ -634,19 +634,13 @@ bool VideoDriver_Cocoa::PollEvent()
 
/** Main game loop. */
 
void VideoDriver_Cocoa::GameLoop()
 
{
 
	uint32 cur_ticks = GetTick();
 
	uint32 last_cur_ticks = cur_ticks;
 
	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 

	
 
#ifdef _DEBUG
 
	uint32 et0 = GetTick();
 
	uint32 st = 0;
 
#endif
 
	auto cur_ticks = std::chrono::steady_clock::now();
 
	auto last_cur_ticks = cur_ticks;
 
	auto next_tick = cur_ticks;
 

	
 
	for (;;) {
 
		@autoreleasepool {
 

	
 
			uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
 
			InteractiveRandom(); // randomness
 

	
 
			while (this->PollEvent()) {}
 
@@ -669,11 +663,11 @@ void VideoDriver_Cocoa::GameLoop()
 
				_fast_forward = 0;
 
			}
 

	
 
			cur_ticks = GetTick();
 
			if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
 
				_realtime_tick += cur_ticks - last_cur_ticks;
 
			cur_ticks = std::chrono::steady_clock::now();
 
			if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode)) {
 
				_realtime_tick += std::chrono::duration_cast<std::chrono::milliseconds>(cur_ticks - last_cur_ticks).count();
 
				last_cur_ticks = cur_ticks;
 
				next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
				next_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
 

	
 
				bool old_ctrl_pressed = _ctrl_pressed;
 

	
 
@@ -688,28 +682,13 @@ void VideoDriver_Cocoa::GameLoop()
 
				this->CheckPaletteAnim();
 
				this->Draw();
 
			} else {
 
#ifdef _DEBUG
 
				uint32 st0 = GetTick();
 
#endif
 
				CSleep(1);
 
#ifdef _DEBUG
 
				st += GetTick() - st0;
 
#endif
 
				NetworkDrawChatMessage();
 
				DrawMouseCursor();
 
				this->Draw();
 
			}
 
		}
 
	}
 

	
 
#ifdef _DEBUG
 
	uint32 et = GetTick();
 

	
 
	DEBUG(driver, 1, "cocoa_v: nextEventMatchingMask took %i ms total", _tEvent);
 
	DEBUG(driver, 1, "cocoa_v: game loop took %i ms total (%i ms without sleep)", et - et0, et - et0 - st);
 
	DEBUG(driver, 1, "cocoa_v: (nextEventMatchingMask total)/(game loop total) is %f%%", (double)_tEvent / (double)(et - et0) * 100);
 
	DEBUG(driver, 1, "cocoa_v: (nextEventMatchingMask total)/(game loop without sleep total) is %f%%", (double)_tEvent / (double)(et - et0 - st) * 100);
 
#endif
 
}
 

	
 

	
src/video/dedicated_v.cpp
Show inline comments
 
@@ -195,14 +195,6 @@ static bool InputWaiting()
 
	return select(STDIN + 1, &readfds, nullptr, nullptr, &tv) > 0;
 
}
 

	
 
static uint32 GetTime()
 
{
 
	struct timeval tim;
 

	
 
	gettimeofday(&tim, nullptr);
 
	return tim.tv_usec / 1000 + tim.tv_sec * 1000;
 
}
 

	
 
#else
 

	
 
static bool InputWaiting()
 
@@ -210,11 +202,6 @@ static bool InputWaiting()
 
	return WaitForSingleObject(_hInputReady, 1) == WAIT_OBJECT_0;
 
}
 

	
 
static uint32 GetTime()
 
{
 
	return GetTickCount();
 
}
 

	
 
#endif
 

	
 
static void DedicatedHandleKeyInput()
 
@@ -248,8 +235,9 @@ static void DedicatedHandleKeyInput()
 

	
 
void VideoDriver_Dedicated::MainLoop()
 
{
 
	uint32 cur_ticks = GetTime();
 
	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
	auto cur_ticks = std::chrono::steady_clock::now();
 
	auto last_cur_ticks = cur_ticks;
 
	auto next_tick = cur_ticks;
 

	
 
	/* Signal handlers */
 
#if defined(UNIX)
 
@@ -290,15 +278,14 @@ void VideoDriver_Dedicated::MainLoop()
 
	}
 

	
 
	while (!_exit_game) {
 
		uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
 
		InteractiveRandom(); // randomness
 

	
 
		if (!_dedicated_forks) DedicatedHandleKeyInput();
 

	
 
		cur_ticks = GetTime();
 
		_realtime_tick += cur_ticks - prev_cur_ticks;
 
		if (cur_ticks >= next_tick || cur_ticks < prev_cur_ticks || _ddc_fastforward) {
 
			next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
		cur_ticks = std::chrono::steady_clock::now();
 
		_realtime_tick += std::chrono::duration_cast<std::chrono::milliseconds>(cur_ticks - last_cur_ticks).count();
 
		if (cur_ticks >= next_tick || _ddc_fastforward) {
 
			next_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
 

	
 
			GameLoop();
 
			UpdateWindows();
src/video/sdl2_v.cpp
Show inline comments
 
@@ -734,7 +734,6 @@ void VideoDriver_SDL::LoopOnce()
 
	uint32 mod;
 
	int numkeys;
 
	const Uint8 *keys;
 
	uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
 
	InteractiveRandom(); // randomness
 

	
 
	while (PollEvent() == -1) {}
 
@@ -768,11 +767,11 @@ void VideoDriver_SDL::LoopOnce()
 
		_fast_forward = 0;
 
	}
 

	
 
	cur_ticks = SDL_GetTicks();
 
	if (SDL_TICKS_PASSED(cur_ticks, next_tick) || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
 
		_realtime_tick += cur_ticks - last_cur_ticks;
 
	cur_ticks = std::chrono::steady_clock::now();
 
	if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode)) {
 
		_realtime_tick += std::chrono::duration_cast<std::chrono::milliseconds>(cur_ticks - last_cur_ticks).count();
 
		last_cur_ticks = cur_ticks;
 
		next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
		next_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
 

	
 
		bool old_ctrl_pressed = _ctrl_pressed;
 

	
 
@@ -826,9 +825,9 @@ void VideoDriver_SDL::LoopOnce()
 

	
 
void VideoDriver_SDL::MainLoop()
 
{
 
	cur_ticks = SDL_GetTicks();
 
	cur_ticks = std::chrono::steady_clock::now();
 
	last_cur_ticks = cur_ticks;
 
	next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
	next_tick = cur_ticks;
 

	
 
	this->CheckPaletteAnim();
 

	
src/video/sdl2_v.h
Show inline comments
 
@@ -62,9 +62,9 @@ private:
 
	 */
 
	bool edit_box_focused;
 

	
 
	uint32 cur_ticks;
 
	uint32 last_cur_ticks;
 
	uint32 next_tick;
 
	std::chrono::steady_clock::time_point cur_ticks;
 
	std::chrono::steady_clock::time_point last_cur_ticks;
 
	std::chrono::steady_clock::time_point next_tick;
 

	
 
	int startup_display;
 
	std::thread draw_thread;
src/video/sdl_v.cpp
Show inline comments
 
@@ -648,9 +648,9 @@ void VideoDriver_SDL::Stop()
 

	
 
void VideoDriver_SDL::MainLoop()
 
{
 
	uint32 cur_ticks = SDL_GetTicks();
 
	uint32 last_cur_ticks = cur_ticks;
 
	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
	auto cur_ticks = std::chrono::steady_clock::now();
 
	auto last_cur_ticks = cur_ticks;
 
	auto next_tick = cur_ticks;
 
	uint32 mod;
 
	int numkeys;
 
	Uint8 *keys;
 
@@ -690,7 +690,6 @@ void VideoDriver_SDL::MainLoop()
 
	DEBUG(driver, 1, "SDL: using %sthreads", _draw_threaded ? "" : "no ");
 

	
 
	for (;;) {
 
		uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
 
		InteractiveRandom(); // randomness
 

	
 
		while (PollEvent() == -1) {}
 
@@ -719,11 +718,11 @@ void VideoDriver_SDL::MainLoop()
 
			_fast_forward = 0;
 
		}
 

	
 
		cur_ticks = SDL_GetTicks();
 
		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
 
			_realtime_tick += cur_ticks - last_cur_ticks;
 
		cur_ticks = std::chrono::steady_clock::now();
 
		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode)) {
 
			_realtime_tick += std::chrono::duration_cast<std::chrono::milliseconds>(cur_ticks - last_cur_ticks).count();
 
			last_cur_ticks = cur_ticks;
 
			next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
			next_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
 

	
 
			bool old_ctrl_pressed = _ctrl_pressed;
 

	
src/video/win32_v.cpp
Show inline comments
 
@@ -1133,9 +1133,9 @@ static void CheckPaletteAnim()
 
void VideoDriver_Win32::MainLoop()
 
{
 
	MSG mesg;
 
	uint32 cur_ticks = GetTickCount();
 
	uint32 last_cur_ticks = cur_ticks;
 
	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
	auto cur_ticks = std::chrono::steady_clock::now();
 
	auto last_cur_ticks = cur_ticks;
 
	auto next_tick = cur_ticks;
 

	
 
	std::thread draw_thread;
 
	std::unique_lock<std::recursive_mutex> draw_lock;
 
@@ -1176,8 +1176,6 @@ void VideoDriver_Win32::MainLoop()
 

	
 
	CheckPaletteAnim();
 
	for (;;) {
 
		uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
 

	
 
		while (PeekMessage(&mesg, nullptr, 0, 0, PM_REMOVE)) {
 
			InteractiveRandom(); // randomness
 
			/* Convert key messages to char messages if we want text input. */
 
@@ -1198,11 +1196,11 @@ void VideoDriver_Win32::MainLoop()
 
			_fast_forward = 0;
 
		}
 

	
 
		cur_ticks = GetTickCount();
 
		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
 
			_realtime_tick += cur_ticks - last_cur_ticks;
 
		cur_ticks = std::chrono::steady_clock::now();
 
		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode)) {
 
			_realtime_tick += std::chrono::duration_cast<std::chrono::milliseconds>(cur_ticks - last_cur_ticks).count();
 
			last_cur_ticks = cur_ticks;
 
			next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 
			next_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
 

	
 
			bool old_ctrl_pressed = _ctrl_pressed;
 

	
0 comments (0 inline, 0 general)