Changeset - r28750:2657250b24e9
[Not reviewed]
master
0 8 0
Patric Stout - 10 months ago 2024-02-12 21:39:23
truebrain@openttd.org
Fix #10079: don't render at 1000fps if HW acceleration + vsync is requested but not active (#12067)
8 files changed with 14 insertions and 11 deletions:
0 comments (0 inline, 0 general)
src/video/cocoa/cocoa_ogl.h
Show inline comments
 
@@ -14,25 +14,25 @@
 

	
 
@class OTTD_OpenGLView;
 

	
 
class VideoDriver_CocoaOpenGL : public VideoDriver_Cocoa {
 
	CGLContextObj gl_context;
 

	
 
	uint8_t *anim_buffer; ///< Animation buffer from OpenGL back-end.
 
	std::string driver_info; ///< Information string about selected driver.
 

	
 
	const char *AllocateContext(bool allow_software);
 

	
 
public:
 
	VideoDriver_CocoaOpenGL() : gl_context(nullptr), anim_buffer(nullptr), driver_info(this->GetName()) {}
 
	VideoDriver_CocoaOpenGL() : VideoDriver_Cocoa(true), gl_context(nullptr), anim_buffer(nullptr), driver_info(this->GetName()) {}
 

	
 
	const char *Start(const StringList &param) override;
 
	void Stop() override;
 

	
 
	bool HasEfficient8Bpp() const override { return true; }
 

	
 
	bool UseSystemCursor() override { return true; }
 

	
 
	void ClearSystemSprites() override;
 

	
 
	void PopulateSystemSprites() override;
 

	
src/video/cocoa/cocoa_v.h
Show inline comments
 
@@ -26,25 +26,25 @@ private:
 
	bool refresh_sys_sprites; ///< System sprites need refreshing.
 

	
 
public:
 
	bool setup; ///< Window is currently being created.
 

	
 
	OTTD_CocoaWindow *window;    ///< Pointer to window object
 
	OTTD_CocoaView *cocoaview;   ///< Pointer to view object
 
	CGColorSpaceRef color_space; ///< Window color space
 

	
 
	OTTD_CocoaWindowDelegate *delegate; //!< Window delegate object
 

	
 
public:
 
	VideoDriver_Cocoa();
 
	VideoDriver_Cocoa(bool uses_hardware_acceleration = false);
 

	
 
	void Stop() override;
 
	void MainLoop() override;
 

	
 
	void MakeDirty(int left, int top, int width, int height) override;
 
	bool AfterBlitterChange() override;
 

	
 
	bool ChangeResolution(int w, int h) override;
 
	bool ToggleFullscreen(bool fullscreen) override;
 

	
 
	void ClearSystemSprites() override;
 
	void PopulateSystemSprites() override;
src/video/cocoa/cocoa_v.mm
Show inline comments
 
@@ -78,25 +78,26 @@ static const Dimension _default_resoluti
 
	{ 1152,  864 },
 
	{ 1280,  800 },
 
	{ 1280,  960 },
 
	{ 1280, 1024 },
 
	{ 1400, 1050 },
 
	{ 1600, 1200 },
 
	{ 1680, 1050 },
 
	{ 1920, 1200 },
 
	{ 2560, 1440 }
 
};
 

	
 

	
 
VideoDriver_Cocoa::VideoDriver_Cocoa()
 
VideoDriver_Cocoa::VideoDriver_Cocoa(bool uses_hardware_acceleration)
 
	: VideoDriver(uses_hardware_acceleration)
 
{
 
	this->setup         = false;
 
	this->buffer_locked = false;
 

	
 
	this->refresh_sys_sprites = true;
 

	
 
	this->window    = nil;
 
	this->cocoaview = nil;
 
	this->delegate  = nil;
 

	
 
	this->color_space = nullptr;
 

	
src/video/sdl2_opengl_v.h
Show inline comments
 
@@ -3,25 +3,25 @@
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file sdl2_opengl_v.h OpenGL backend of the SDL2 video driver. */
 

	
 
#include "sdl2_v.h"
 

	
 
/** The OpenGL video driver for windows. */
 
class VideoDriver_SDL_OpenGL : public VideoDriver_SDL_Base {
 
public:
 
	VideoDriver_SDL_OpenGL() : gl_context(nullptr), anim_buffer(nullptr) {}
 
	VideoDriver_SDL_OpenGL() : VideoDriver_SDL_Base(true), gl_context(nullptr), anim_buffer(nullptr) {}
 

	
 
	const char *Start(const StringList &param) override;
 

	
 
	void Stop() override;
 

	
 
	bool HasEfficient8Bpp() const override { return true; }
 

	
 
	bool UseSystemCursor() override { return true; }
 

	
 
	void ClearSystemSprites() override;
 

	
 
	void PopulateSystemSprites() override;
src/video/sdl2_v.h
Show inline comments
 
@@ -8,25 +8,25 @@
 
/** @file sdl2_v.h Base of the SDL2 video driver. */
 

	
 
#ifndef VIDEO_SDL_H
 
#define VIDEO_SDL_H
 

	
 
#include <condition_variable>
 

	
 
#include "video_driver.hpp"
 

	
 
/** The SDL video driver. */
 
class VideoDriver_SDL_Base : public VideoDriver {
 
public:
 
	VideoDriver_SDL_Base() : sdl_window(nullptr), buffer_locked(false) {}
 
	VideoDriver_SDL_Base(bool uses_hardware_acceleration = false) : VideoDriver(uses_hardware_acceleration), sdl_window(nullptr), buffer_locked(false) {}
 

	
 
	const char *Start(const StringList &param) override;
 

	
 
	void Stop() override;
 

	
 
	void MakeDirty(int left, int top, int width, int height) override;
 

	
 
	void MainLoop() override;
 

	
 
	bool ChangeResolution(int w, int h) override;
 

	
 
	bool ToggleFullscreen(bool fullscreen) override;
src/video/video_driver.cpp
Show inline comments
 
@@ -13,26 +13,26 @@
 
#include "../blitter/factory.hpp"
 
#include "../debug.h"
 
#include "../driver.h"
 
#include "../fontcache.h"
 
#include "../gfx_func.h"
 
#include "../gfxinit.h"
 
#include "../progress.h"
 
#include "../rev.h"
 
#include "../thread.h"
 
#include "../window_func.h"
 
#include "video_driver.hpp"
 

	
 
bool _video_hw_accel; ///< Whether to consider hardware accelerated video drivers.
 
bool _video_vsync; ///< Whether we should use vsync (only if _video_hw_accel is enabled).
 
bool _video_hw_accel; ///< Whether to consider hardware accelerated video drivers on startup.
 
bool _video_vsync; ///< Whether we should use vsync (only if active video driver supports HW acceleration).
 

	
 
void VideoDriver::GameLoop()
 
{
 
	this->next_game_tick += this->GetGameInterval();
 

	
 
	/* Avoid next_game_tick getting behind more and more if it cannot keep up. */
 
	auto now = std::chrono::steady_clock::now();
 
	if (this->next_game_tick < now - ALLOWED_DRIFT * this->GetGameInterval()) this->next_game_tick = now;
 

	
 
	{
 
		std::lock_guard<std::mutex> lock(this->game_state_mutex);
 

	
src/video/video_driver.hpp
Show inline comments
 
@@ -26,25 +26,25 @@ extern std::string _ini_videodriver;
 
extern std::vector<Dimension> _resolutions;
 
extern Dimension _cur_resolution;
 
extern bool _rightclick_emulate;
 
extern bool _video_hw_accel;
 
extern bool _video_vsync;
 

	
 
/** The base of all video drivers. */
 
class VideoDriver : public Driver {
 
	const uint DEFAULT_WINDOW_WIDTH = 640u;  ///< Default window width.
 
	const uint DEFAULT_WINDOW_HEIGHT = 480u; ///< Default window height.
 

	
 
public:
 
	VideoDriver() : fast_forward_key_pressed(false), fast_forward_via_key(false), is_game_threaded(true) {}
 
	VideoDriver(bool uses_hardware_acceleration = false) : fast_forward_key_pressed(false), fast_forward_via_key(false), is_game_threaded(true), uses_hardware_acceleration(uses_hardware_acceleration) {}
 

	
 
	/**
 
	 * Mark a particular area dirty.
 
	 * @param left   The left most line of the dirty area.
 
	 * @param top    The top most line of the dirty area.
 
	 * @param width  The width of the dirty area.
 
	 * @param height The height of the dirty area.
 
	 */
 
	virtual void MakeDirty(int left, int top, int width, int height) = 0;
 

	
 
	/**
 
	 * Perform the actual drawing.
 
@@ -313,25 +313,25 @@ protected:
 
	{
 
		/* If we are paused, run on normal speed. */
 
		if (_pause_mode) return std::chrono::milliseconds(MILLISECONDS_PER_TICK);
 
		/* Infinite speed, as quickly as you can. */
 
		if (_game_speed == 0) return std::chrono::microseconds(0);
 

	
 
		return std::chrono::microseconds(MILLISECONDS_PER_TICK * 1000 * 100 / _game_speed);
 
	}
 

	
 
	std::chrono::steady_clock::duration GetDrawInterval()
 
	{
 
		/* If vsync, draw interval is decided by the display driver */
 
		if (_video_vsync && _video_hw_accel) return std::chrono::microseconds(0);
 
		if (_video_vsync && this->uses_hardware_acceleration) return std::chrono::microseconds(0);
 
		return std::chrono::microseconds(1000000 / _settings_client.gui.refresh_rate);
 
	}
 

	
 
	/** Execute all queued commands. */
 
	void DrainCommandQueue()
 
	{
 
		std::vector<std::function<void()>> cmds{};
 

	
 
		{
 
			/* Exchange queue with an empty one to limit the time we
 
			 * hold the mutex. This also ensures that queued functions can
 
			 * add new functions to the queue without everything blocking. */
 
@@ -346,23 +346,25 @@ protected:
 

	
 
	std::chrono::steady_clock::time_point next_game_tick;
 
	std::chrono::steady_clock::time_point next_draw_tick;
 

	
 
	bool fast_forward_key_pressed; ///< The fast-forward key is being pressed.
 
	bool fast_forward_via_key; ///< The fast-forward was enabled by key press.
 

	
 
	bool is_game_threaded;
 
	std::thread game_thread;
 
	std::mutex game_state_mutex;
 
	std::mutex game_thread_wait_mutex;
 

	
 
	bool uses_hardware_acceleration;
 

	
 
	static void GameThreadThunk(VideoDriver *drv);
 

	
 
private:
 
	std::mutex cmd_queue_mutex;
 
	std::vector<std::function<void()>> cmd_queue;
 

	
 
	void GameLoop();
 
	void GameThread();
 
};
 

	
 
#endif /* VIDEO_VIDEO_DRIVER_HPP */
src/video/win32_v.h
Show inline comments
 
@@ -9,25 +9,25 @@
 

	
 
#ifndef VIDEO_WIN32_H
 
#define VIDEO_WIN32_H
 

	
 
#include "video_driver.hpp"
 
#include <mutex>
 
#include <condition_variable>
 
#include <windows.h>
 

	
 
/** Base class for Windows video drivers. */
 
class VideoDriver_Win32Base : public VideoDriver {
 
public:
 
	VideoDriver_Win32Base() : main_wnd(nullptr), fullscreen(false), buffer_locked(false) {}
 
	VideoDriver_Win32Base(bool uses_hardware_acceleration = false) : VideoDriver(uses_hardware_acceleration), main_wnd(nullptr), fullscreen(false), buffer_locked(false) {}
 

	
 
	void Stop() override;
 

	
 
	void MakeDirty(int left, int top, int width, int height) override;
 

	
 
	void MainLoop() override;
 

	
 
	bool ChangeResolution(int w, int h) override;
 

	
 
	bool ToggleFullscreen(bool fullscreen) override;
 

	
 
	bool ClaimMousePointer() override;
 
@@ -109,25 +109,25 @@ public:
 
/** The factory for Windows' video driver. */
 
class FVideoDriver_Win32GDI : public DriverFactoryBase {
 
public:
 
	FVideoDriver_Win32GDI() : DriverFactoryBase(Driver::DT_VIDEO, 9, "win32", "Win32 GDI Video Driver") {}
 
	Driver *CreateInstance() const override { return new VideoDriver_Win32GDI(); }
 
};
 

	
 
#ifdef WITH_OPENGL
 

	
 
/** The OpenGL video driver for windows. */
 
class VideoDriver_Win32OpenGL : public VideoDriver_Win32Base {
 
public:
 
	VideoDriver_Win32OpenGL() : dc(nullptr), gl_rc(nullptr), anim_buffer(nullptr), driver_info(this->GetName()) {}
 
	VideoDriver_Win32OpenGL() : VideoDriver_Win32Base(true), dc(nullptr), gl_rc(nullptr), anim_buffer(nullptr), driver_info(this->GetName()) {}
 

	
 
	const char *Start(const StringList &param) override;
 

	
 
	void Stop() override;
 

	
 
	bool ToggleFullscreen(bool fullscreen) override;
 

	
 
	bool AfterBlitterChange() override;
 

	
 
	bool HasEfficient8Bpp() const override { return true; }
 

	
 
	bool UseSystemCursor() override { return true; }
0 comments (0 inline, 0 general)