From 4610aa7ae3db6cf561e156ba011de3c7b516876d Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 24 Feb 2021 15:04:41 +0100 Subject: [PATCH] Remove: [Video] no longer draw in a thread Drawing in a thread is a bit odd, and often leads to surprising issues. For example, OpenGL would only allow it if you move the full context to the thread. Which is not always easily done on all OSes. In general, the advise is to handle system events and drawing from the main thread, and do everything else in other threads. So, let's be more like other games. Additionally, putting the drawing routine in a thread was only done for a few targets. Upcoming commit will move the GameLoop in a thread, which will work for all targets. --- src/video/allegro_v.cpp | 4 +- src/video/cocoa/cocoa_v.mm | 4 +- src/video/sdl2_default_v.cpp | 16 ----- src/video/sdl2_default_v.h | 1 - src/video/sdl2_opengl_v.cpp | 1 - src/video/sdl2_opengl_v.h | 2 - src/video/sdl2_v.cpp | 113 +++------------------------------- src/video/sdl2_v.h | 12 ---- src/video/sdl_v.cpp | 115 +---------------------------------- src/video/sdl_v.h | 11 ---- src/video/video_driver.cpp | 8 +-- src/video/video_driver.hpp | 12 ++-- src/video/win32_v.cpp | 110 +-------------------------------- src/video/win32_v.h | 19 +----- 14 files changed, 20 insertions(+), 408 deletions(-) diff --git a/src/video/allegro_v.cpp b/src/video/allegro_v.cpp index a01a9a5e7c..8ff1cc634c 100644 --- a/src/video/allegro_v.cpp +++ b/src/video/allegro_v.cpp @@ -478,9 +478,7 @@ void VideoDriver_Allegro::MainLoop() for (;;) { if (_exit_game) return; - if (this->Tick()) { - this->Paint(); - } + this->Tick(); this->SleepTillNextTick(); } } diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index 1a75017dfe..56d559f0dc 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -443,9 +443,7 @@ void VideoDriver_Cocoa::MainLoopReal() break; } - if (this->Tick()) { - this->Paint(); - } + this->Tick(); this->SleepTillNextTick(); } } diff --git a/src/video/sdl2_default_v.cpp b/src/video/sdl2_default_v.cpp index b8e769ede0..e61405ff83 100644 --- a/src/video/sdl2_default_v.cpp +++ b/src/video/sdl2_default_v.cpp @@ -136,22 +136,6 @@ void VideoDriver_SDL_Default::Paint() this->dirty_rect = {}; } -void VideoDriver_SDL_Default::PaintThread() -{ - /* First tell the main thread we're started */ - std::unique_lock lock(*this->draw_mutex); - this->draw_signal->notify_one(); - - /* Now wait for the first thing to draw! */ - this->draw_signal->wait(*this->draw_mutex); - - while (this->draw_continue) { - /* Then just draw and wait till we stop */ - this->Paint(); - this->draw_signal->wait(lock); - } -} - bool VideoDriver_SDL_Default::AllocateBackingStore(int w, int h, bool force) { int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); diff --git a/src/video/sdl2_default_v.h b/src/video/sdl2_default_v.h index 1b67be5d39..3e1e3b894c 100644 --- a/src/video/sdl2_default_v.h +++ b/src/video/sdl2_default_v.h @@ -21,7 +21,6 @@ protected: bool AllocateBackingStore(int w, int h, bool force = false) override; void *GetVideoPointer() override; void Paint() override; - void PaintThread() override; void ReleaseVideoPointer() override {} diff --git a/src/video/sdl2_opengl_v.cpp b/src/video/sdl2_opengl_v.cpp index 87a8bb9b36..4bd66a9949 100644 --- a/src/video/sdl2_opengl_v.cpp +++ b/src/video/sdl2_opengl_v.cpp @@ -71,7 +71,6 @@ const char *VideoDriver_SDL_OpenGL::Start(const StringList ¶m) this->ClientSizeChanged(w, h, true); SDL_GL_SetSwapInterval(GetDriverParamBool(param, "vsync") ? 1 : 0); - this->draw_threaded = false; return nullptr; } diff --git a/src/video/sdl2_opengl_v.h b/src/video/sdl2_opengl_v.h index 71bc4373a2..55697b43bb 100644 --- a/src/video/sdl2_opengl_v.h +++ b/src/video/sdl2_opengl_v.h @@ -36,8 +36,6 @@ protected: void Paint() override; bool CreateMainWindow(uint w, uint h, uint flags) override; - void PaintThread() override {} - private: void *gl_context; ///< OpenGL context. uint8 *anim_buffer; ///< Animation buffer from OpenGL back-end. diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp index a1f8960503..c1925c7da5 100644 --- a/src/video/sdl2_v.cpp +++ b/src/video/sdl2_v.cpp @@ -23,7 +23,6 @@ #include "../window_func.h" #include "sdl2_v.h" #include -#include #ifdef __EMSCRIPTEN__ # include # include @@ -50,11 +49,6 @@ void VideoDriver_SDL_Base::CheckPaletteAnim() 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(const StringList &parm) 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(*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 lock; - if (this->draw_mutex != nullptr) lock = std::unique_lock(*this->draw_mutex); - return CreateMainSurface(w, h, true); } bool VideoDriver_SDL_Base::ToggleFullscreen(bool fullscreen) { - std::unique_lock lock; - if (this->draw_mutex != nullptr) lock = std::unique_lock(*this->draw_mutex); - int w, h; /* Remember current window size */ @@ -773,16 +687,6 @@ bool VideoDriver_SDL_Base::AfterBlitterChange() 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::LockVideoBuffer() 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::UnlockVideoBuffer() _screen.dst_ptr = nullptr; } - if (this->draw_threaded) this->draw_lock.unlock(); this->buffer_locked = false; } diff --git a/src/video/sdl2_v.h b/src/video/sdl2_v.h index 48515251a2..b1a64dd9c8 100644 --- a/src/video/sdl2_v.h +++ b/src/video/sdl2_v.h @@ -33,10 +33,6 @@ public: bool AfterBlitterChange() override; - void AcquireBlitterLock() override; - - void ReleaseBlitterLock() override; - bool ClaimMousePointer() override; void EditBoxGainedFocus() override; @@ -48,10 +44,6 @@ public: protected: struct SDL_Window *sdl_window; ///< Main SDL window. Palette local_palette; ///< Copy of _cur_palette. - bool draw_threaded; ///< Whether the drawing is/may be done in a separate thread. - std::recursive_mutex *draw_mutex = nullptr; ///< Mutex to keep the access to the shared memory controlled. - std::condition_variable_any *draw_signal = nullptr; ///< Signal to draw the next frame. - volatile bool draw_continue; ///< Should we keep continue drawing? bool buffer_locked; ///< Video buffer was locked by the main thread. Rect dirty_rect; ///< Rectangle encompassing the dirty area of the video buffer. @@ -91,10 +83,6 @@ private: bool edit_box_focused; int startup_display; - std::thread draw_thread; - std::unique_lock draw_lock; - - static void PaintThreadThunk(VideoDriver_SDL_Base *drv); }; #endif /* VIDEO_SDL_H */ diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp index 8f7c26b898..2ecb9510c0 100644 --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.cpp @@ -23,8 +23,6 @@ #include "../window_func.h" #include "sdl_v.h" #include -#include -#include #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 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 StringList &parm) 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(*_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 lock; - if (_draw_mutex != nullptr) lock = std::unique_lock(*_draw_mutex); - return CreateMainSurface(w, h); } bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen) { - std::unique_lock lock; - if (_draw_mutex != nullptr) lock = std::unique_lock(*_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 */ diff --git a/src/video/sdl_v.h b/src/video/sdl_v.h index 7df29a2ea3..2b37cbdb6a 100644 --- a/src/video/sdl_v.h +++ b/src/video/sdl_v.h @@ -29,30 +29,19 @@ public: bool AfterBlitterChange() override; - void AcquireBlitterLock() override; - - void ReleaseBlitterLock() override; - bool ClaimMousePointer() override; const char *GetName() const override { return "sdl"; } protected: void InputLoop() override; - bool LockVideoBuffer() override; - void UnlockVideoBuffer() override; void Paint() override; - void PaintThread() override; void CheckPaletteAnim() override; bool PollEvent() override; private: - std::unique_lock draw_lock; - bool CreateMainSurface(uint w, uint h); void SetupKeyboard(); - - static void PaintThreadThunk(VideoDriver_SDL *drv); }; /** Factory for the SDL video driver. */ diff --git a/src/video/video_driver.cpp b/src/video/video_driver.cpp index cb81f857d8..49337c03a8 100644 --- a/src/video/video_driver.cpp +++ b/src/video/video_driver.cpp @@ -19,7 +19,7 @@ bool _video_hw_accel; ///< Whether to consider hardware accelerated video drivers. -bool VideoDriver::Tick() +void VideoDriver::Tick() { auto cur_ticks = std::chrono::steady_clock::now(); @@ -66,12 +66,10 @@ bool VideoDriver::Tick() ::InputLoop(); UpdateWindows(); - this->CheckPaletteAnim(); - return true; + this->CheckPaletteAnim(); + this->Paint(); } - - return false; } void VideoDriver::SleepTillNextTick() diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp index 58802efab1..9a3ec6a36b 100644 --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.hpp @@ -241,11 +241,6 @@ protected: */ virtual void Paint() {} - /** - * Thread function for threaded drawing. - */ - virtual void PaintThread() {} - /** * Process any pending palette animation. */ @@ -258,10 +253,11 @@ protected: virtual bool PollEvent() { return false; }; /** - * Run the game for a single tick, processing boththe game-tick and draw-tick. - * @returns True if the driver should redraw the screen. + * Give the video-driver a tick. + * It will process any potential game-tick and/or draw-tick, and/or any + * other video-driver related event. */ - bool Tick(); + void Tick(); /** * Sleep till the next tick is about to happen. diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 30729ead6d..d8841671a1 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -225,11 +225,6 @@ bool VideoDriver_Win32Base::MakeWindow(bool full_screen) return true; } -/* static */ void VideoDriver_Win32Base::PaintThreadThunk(VideoDriver_Win32Base *drv) -{ - drv->PaintThread(); -} - /** Forward key presses to the window system. */ static LRESULT HandleCharMsg(uint keycode, WChar charcode) { @@ -868,70 +863,12 @@ bool VideoDriver_Win32Base::PollEvent() void VideoDriver_Win32Base::MainLoop() { - std::thread draw_thread; - - if (this->draw_threaded) { - /* Initialise the mutex first, because that's the thing we *need* - * directly in the newly created thread. */ - try { - this->draw_signal = new std::condition_variable_any(); - this->draw_mutex = new std::recursive_mutex(); - } catch (...) { - this->draw_threaded = false; - } - - if (this->draw_threaded) { - this->draw_lock = std::unique_lock(*this->draw_mutex); - - this->draw_continue = true; - this->draw_threaded = StartNewThread(&draw_thread, "ottd:draw-win32", &VideoDriver_Win32Base::PaintThreadThunk, this); - - /* Free the mutex if we won't be able to use it. */ - if (!this->draw_threaded) { - this->draw_lock.unlock(); - this->draw_lock.release(); - delete this->draw_mutex; - delete this->draw_signal; - this->draw_mutex = nullptr; - this->draw_signal = nullptr; - } else { - DEBUG(driver, 1, "Threaded drawing enabled"); - /* Wait till the draw thread has started itself. */ - this->draw_signal->wait(*this->draw_mutex); - } - } - } - for (;;) { if (_exit_game) break; - /* Flush GDI buffer to ensure we don't conflict with the drawing thread. */ - GdiFlush(); - - if (this->Tick()) { - if (this->draw_mutex != nullptr && !HasModalProgress()) { - this->draw_signal->notify_one(); - } else { - this->Paint(); - } - } + this->Tick(); this->SleepTillNextTick(); } - - if (this->draw_threaded) { - this->draw_continue = false; - /* Sending signal if there is no thread blocked - * is very valid and results in noop */ - this->draw_signal->notify_all(); - if (this->draw_lock.owns_lock()) this->draw_lock.unlock(); - this->draw_lock.release(); - draw_thread.join(); - - delete this->draw_mutex; - delete this->draw_signal; - - this->draw_mutex = nullptr; - } } void VideoDriver_Win32Base::ClientSizeChanged(int w, int h, bool force) @@ -951,9 +888,6 @@ void VideoDriver_Win32Base::ClientSizeChanged(int w, int h, bool force) bool VideoDriver_Win32Base::ChangeResolution(int w, int h) { - std::unique_lock lock; - if (this->draw_mutex != nullptr) lock = std::unique_lock(*this->draw_mutex); - if (_window_maximize) ShowWindow(this->main_wnd, SW_SHOWNORMAL); this->width = this->width_org = w; @@ -964,30 +898,14 @@ bool VideoDriver_Win32Base::ChangeResolution(int w, int h) bool VideoDriver_Win32Base::ToggleFullscreen(bool full_screen) { - std::unique_lock lock; - if (this->draw_mutex != nullptr) lock = std::unique_lock(*this->draw_mutex); - bool res = this->MakeWindow(full_screen); InvalidateWindowClassesData(WC_GAME_OPTIONS, 3); return res; } -void VideoDriver_Win32Base::AcquireBlitterLock() -{ - if (this->draw_mutex != nullptr) this->draw_mutex->lock(); -} - -void VideoDriver_Win32Base::ReleaseBlitterLock() -{ - if (this->draw_mutex != nullptr) this->draw_mutex->unlock(); -} - void VideoDriver_Win32Base::EditBoxLostFocus() { - std::unique_lock lock; - if (this->draw_mutex != nullptr) lock = std::unique_lock(*this->draw_mutex); - CancelIMEComposition(this->main_wnd); SetCompositionPos(this->main_wnd); SetCandidatePos(this->main_wnd); @@ -1043,8 +961,6 @@ bool VideoDriver_Win32Base::LockVideoBuffer() 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); @@ -1060,7 +976,6 @@ void VideoDriver_Win32Base::UnlockVideoBuffer() _screen.dst_ptr = nullptr; } - if (this->draw_threaded) this->draw_lock.unlock(); this->buffer_locked = false; } @@ -1079,8 +994,6 @@ const char *VideoDriver_Win32GDI::Start(const StringList ¶m) MarkWholeScreenDirty(); - this->draw_threaded = !GetDriverParam(param, "no_threads") && !GetDriverParam(param, "no_thread") && std::thread::hardware_concurrency() > 1; - return nullptr; } @@ -1230,26 +1143,6 @@ void VideoDriver_Win32GDI::Paint() this->dirty_rect = {}; } -void VideoDriver_Win32GDI::PaintThread() -{ - /* First tell the main thread we're started */ - std::unique_lock lock(*this->draw_mutex); - this->draw_signal->notify_one(); - - /* Now wait for the first thing to draw! */ - this->draw_signal->wait(*this->draw_mutex); - - while (this->draw_continue) { - this->Paint(); - - /* Flush GDI buffer to ensure drawing here doesn't conflict with any GDI usage in the main WndProc. */ - GdiFlush(); - - this->draw_signal->wait(*this->draw_mutex); - } -} - - #ifdef _DEBUG /* Keep this function here.. * It allows you to redraw the screen from within the MSVC debugger */ @@ -1395,7 +1288,6 @@ const char *VideoDriver_Win32OpenGL::Start(const StringList ¶m) this->ClientSizeChanged(this->width, this->height, true); - this->draw_threaded = false; MarkWholeScreenDirty(); return nullptr; diff --git a/src/video/win32_v.h b/src/video/win32_v.h index 6dec59300f..03733d0228 100644 --- a/src/video/win32_v.h +++ b/src/video/win32_v.h @@ -17,7 +17,7 @@ /** Base class for Windows video drivers. */ class VideoDriver_Win32Base : public VideoDriver { public: - VideoDriver_Win32Base() : main_wnd(nullptr), fullscreen(false), draw_mutex(nullptr), draw_signal(nullptr) {} + VideoDriver_Win32Base() : main_wnd(nullptr), fullscreen(false) {} void Stop() override; @@ -29,10 +29,6 @@ public: bool ToggleFullscreen(bool fullscreen) override; - void AcquireBlitterLock() override; - - void ReleaseBlitterLock() override; - bool ClaimMousePointer() override; void EditBoxLostFocus() override; @@ -47,12 +43,7 @@ protected: int width_org = 0; ///< Original monitor resolution width, before we changed it. int height_org = 0; ///< Original monitor resolution height, before we changed it. - bool draw_threaded; ///< Whether the drawing is/may be done in a separate thread. - bool buffer_locked; ///< Video buffer was locked by the main thread. - volatile bool draw_continue; ///< Should we keep continue drawing? - - std::recursive_mutex *draw_mutex; ///< Mutex to keep the access to the shared memory controlled. - std::condition_variable_any *draw_signal; ///< Signal to draw the next frame. + bool buffer_locked; ///< Video buffer was locked by the main thread. Dimension GetScreenSize() const override; float GetDPIScale() override; @@ -78,10 +69,6 @@ protected: virtual void PaletteChanged(HWND hWnd) = 0; private: - std::unique_lock draw_lock; - - static void PaintThreadThunk(VideoDriver_Win32Base *drv); - friend LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); }; /** The GDI video driver for windows. */ @@ -104,7 +91,6 @@ protected: void Paint() override; void *GetVideoPointer() override { return this->buffer_bits; } - void PaintThread() override; bool AllocateBackingStore(int w, int h, bool force = false) override; void PaletteChanged(HWND hWnd) override; @@ -159,7 +145,6 @@ protected: uint8 GetFullscreenBpp() override { return 32; } // OpenGL is always 32 bpp. void Paint() override; - void PaintThread() override {} bool AllocateBackingStore(int w, int h, bool force = false) override; void *GetVideoPointer() override;