Merge tag '1.11.0-beta2' into jgrpp

# Conflicts:
#	.github/workflows/ci-build.yml
#	.github/workflows/release.yml
#	CMakeLists.txt
#	src/blitter/32bpp_optimized.cpp
#	src/debug.cpp
#	src/gfx.cpp
#	src/gfx_func.h
#	src/lang/czech.txt
#	src/lang/english.txt
#	src/lang/italian.txt
#	src/lang/swedish.txt
#	src/lang/ukrainian.txt
#	src/network/network_server.cpp
#	src/os/windows/crashlog_win.cpp
#	src/os/windows/win32.cpp
#	src/pathfinder/follow_track.hpp
#	src/screenshot.cpp
#	src/settings_type.h
#	src/spritecache.cpp
#	src/vehicle_gui.cpp
#	src/video/sdl2_v.cpp
#	src/video/video_driver.cpp
#	src/video/video_driver.hpp
#	src/video/win32_v.cpp
This commit is contained in:
Jonathan G Rennison
2021-03-02 11:59:03 +00:00
148 changed files with 19670 additions and 1452 deletions

View File

@@ -23,12 +23,10 @@
#include "../scope.h"
#include "sdl2_v.h"
#include <SDL.h>
#include <mutex>
#include <condition_variable>
#include <algorithm>
#include <mutex>
#if defined(__MINGW32__)
#include "../3rdparty/mingw-std-threads/mingw.mutex.h"
#include "../3rdparty/mingw-std-threads/mingw.condition_variable.h"
#endif
#ifdef __EMSCRIPTEN__
# include <emscripten.h>
@@ -47,31 +45,11 @@
#include "../safeguards.h"
static FVideoDriver_SDL iFVideoDriver_SDL;
static SDL_Window *_sdl_window;
static SDL_Surface *_sdl_surface;
static SDL_Surface *_sdl_rgb_surface;
static SDL_Surface *_sdl_real_surface;
/** 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;
static SDL_Palette *_sdl_palette;
#ifdef __EMSCRIPTEN__
/** Whether we just had a window-enter event. */
static bool _cursor_new_in_window = false;
#endif
static Rect _dirty_rect;
static std::string _editing_text;
static void SetTextInputRect();
@@ -83,6 +61,7 @@ bool EditBoxInGlobalFocus();
void InputLoop();
#if defined(WITH_FCITX)
static SDL_Window *_fcitx_sdl_window;
static bool _fcitx_mode = false;
static char _fcitx_service_name[64];
static char _fcitx_ic_name[64];
@@ -271,126 +250,21 @@ const static bool _fcitx_mode = false;
const static bool _suppress_text_event = false;
#endif
void VideoDriver_SDL::MakeDirty(int left, int top, int width, int height)
void VideoDriver_SDL_Base::MakeDirty(int left, int top, int width, int height)
{
Rect r = {left, top, left + width, top + height};
_dirty_rect = BoundingRect(_dirty_rect, r);
this->dirty_rect = BoundingRect(this->dirty_rect, r);
}
static void UpdatePalette()
{
SDL_Color pal[256];
for (int i = 0; i != _local_palette.count_dirty; i++) {
pal[i].r = _local_palette.palette[_local_palette.first_dirty + i].r;
pal[i].g = _local_palette.palette[_local_palette.first_dirty + i].g;
pal[i].b = _local_palette.palette[_local_palette.first_dirty + i].b;
pal[i].a = 0;
}
SDL_SetPaletteColors(_sdl_palette, pal, _local_palette.first_dirty, _local_palette.count_dirty);
SDL_SetSurfacePalette(_sdl_surface, _sdl_palette);
}
static void MakePalette()
{
if (_sdl_palette == nullptr) {
_sdl_palette = SDL_AllocPalette(256);
if (_sdl_palette == nullptr) usererror("SDL2: Couldn't allocate palette: %s", SDL_GetError());
}
_cur_palette.first_dirty = 0;
_cur_palette.count_dirty = 256;
_local_palette = _cur_palette;
UpdatePalette();
if (_sdl_surface != _sdl_real_surface) {
/* When using a shadow surface, also set our palette on the real screen. This lets SDL
* allocate as many colors (or approximations) as
* possible, instead of using only the default SDL
* palette. This allows us to get more colors exactly
* right and might allow using better approximations for
* other colors.
*
* Note that colors allocations are tried in-order, so
* this favors colors further up into the palette. Also
* note that if two colors from the same animation
* sequence are approximated using the same color, that
* animation will stop working.
*
* Since changing the system palette causes the colours
* to change right away, and allocations might
* drastically change, we can't use this for animation,
* since that could cause weird coloring between the
* palette change and the blitting below, so we only set
* the real palette during initialisation.
*/
SDL_SetSurfacePalette(_sdl_real_surface, _sdl_palette);
}
}
void VideoDriver_SDL::CheckPaletteAnim()
void VideoDriver_SDL_Base::CheckPaletteAnim()
{
if (_cur_palette.count_dirty == 0) return;
_local_palette = _cur_palette;
this->local_palette = _cur_palette;
this->MakeDirty(0, 0, _screen.width, _screen.height);
}
void VideoDriver_SDL::Paint()
{
PerformanceMeasurer framerate(PFE_VIDEO);
if (IsEmptyRect(_dirty_rect) && _cur_palette.count_dirty == 0) return;
if (_cur_palette.count_dirty != 0) {
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
switch (blitter->UsePaletteAnimation()) {
case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND:
UpdatePalette();
break;
case Blitter::PALETTE_ANIMATION_BLITTER:
blitter->PaletteAnimate(_local_palette);
break;
case Blitter::PALETTE_ANIMATION_NONE:
break;
default:
NOT_REACHED();
}
_cur_palette.count_dirty = 0;
}
SDL_Rect r = { _dirty_rect.left, _dirty_rect.top, _dirty_rect.right - _dirty_rect.left, _dirty_rect.bottom - _dirty_rect.top };
if (_sdl_surface != _sdl_real_surface) {
SDL_BlitSurface(_sdl_surface, &r, _sdl_real_surface, &r);
}
SDL_UpdateWindowSurfaceRects(_sdl_window, &r, 1);
_dirty_rect = {};
}
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)
/* static */ void VideoDriver_SDL_Base::PaintThreadThunk(VideoDriver_SDL_Base *drv)
{
drv->PaintThread();
}
@@ -473,11 +347,26 @@ static uint FindStartupDisplay(uint startup_display)
return 0;
}
bool VideoDriver_SDL::CreateMainWindow(uint w, uint h)
void VideoDriver_SDL_Base::ClientSizeChanged(int w, int h, bool force)
{
if (_sdl_window != nullptr) return true;
/* Allocate backing store of the new size. */
if (this->AllocateBackingStore(w, h, force)) {
/* Mark all palette colours dirty. */
_cur_palette.first_dirty = 0;
_cur_palette.count_dirty = 256;
this->local_palette = _cur_palette;
Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
BlitterFactory::GetCurrentBlitter()->PostResize();
GameSizeChanged();
}
}
bool VideoDriver_SDL_Base::CreateMainWindow(uint w, uint h, uint flags)
{
if (this->sdl_window != nullptr) return true;
flags |= SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
if (_fullscreen) {
flags |= SDL_WINDOW_FULLSCREEN;
@@ -492,13 +381,16 @@ bool VideoDriver_SDL::CreateMainWindow(uint w, uint h)
char caption[50];
seprintf(caption, lastof(caption), "OpenTTD %s", _openttd_revision);
_sdl_window = SDL_CreateWindow(
this->sdl_window = SDL_CreateWindow(
caption,
x, y,
w, h,
flags);
#if defined(WITH_FCITX)
_fcitx_sdl_window = this->sdl_window;
#endif
if (_sdl_window == nullptr) {
if (this->sdl_window == nullptr) {
DEBUG(driver, 0, "SDL2: Couldn't allocate a window to draw on: %s", SDL_GetError());
return false;
}
@@ -512,7 +404,7 @@ bool VideoDriver_SDL::CreateMainWindow(uint w, uint h)
uint32 rgbmap = SDL_MapRGB(icon->format, 255, 0, 255);
SDL_SetColorKey(icon, SDL_TRUE, rgbmap);
SDL_SetWindowIcon(_sdl_window, icon);
SDL_SetWindowIcon(this->sdl_window, icon);
SDL_FreeSurface(icon);
}
}
@@ -520,67 +412,24 @@ bool VideoDriver_SDL::CreateMainWindow(uint w, uint h)
return true;
}
bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize)
bool VideoDriver_SDL_Base::CreateMainSurface(uint w, uint h, bool resize)
{
int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
GetAvailableVideoMode(&w, &h);
DEBUG(driver, 1, "SDL2: using mode %ux%ux%d", w, h, bpp);
DEBUG(driver, 1, "SDL2: using mode %ux%u", w, h);
if (!this->CreateMainWindow(w, h)) return false;
if (resize) SDL_SetWindowSize(_sdl_window, w, h);
_sdl_real_surface = SDL_GetWindowSurface(_sdl_window);
if (_sdl_real_surface == nullptr) {
DEBUG(driver, 0, "SDL2: Couldn't get window surface: %s", SDL_GetError());
return false;
}
/* Free any previously allocated rgb surface. */
if (_sdl_rgb_surface != nullptr) {
SDL_FreeSurface(_sdl_rgb_surface);
_sdl_rgb_surface = nullptr;
}
if (bpp == 8) {
_sdl_rgb_surface = SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0);
if (_sdl_rgb_surface == nullptr) {
DEBUG(driver, 0, "SDL2: Couldn't allocate shadow surface: %s", SDL_GetError());
return false;
}
_sdl_surface = _sdl_rgb_surface;
} else {
_sdl_surface = _sdl_real_surface;
}
/* X11 doesn't appreciate it if we invalidate areas outside the window
* if shared memory is enabled (read: it crashes). So, as we might have
* gotten smaller, reset our dirty rects. GameSizeChanged() a bit lower
* will mark the whole screen dirty again anyway, but this time with the
* new dimensions. */
_dirty_rect = {};
_screen.width = _sdl_surface->w;
_screen.height = _sdl_surface->h;
_screen.pitch = _sdl_surface->pitch / (bpp / 8);
_screen.dst_ptr = _sdl_surface->pixels;
MakePalette();
if (resize) SDL_SetWindowSize(this->sdl_window, w, h);
this->ClientSizeChanged(w, h, true);
/* When in full screen, we will always have the mouse cursor
* within the window, even though SDL does not give us the
* appropriate event to know this. */
if (_fullscreen) _cursor.in_window = true;
BlitterFactory::GetCurrentBlitter()->PostResize();
GameSizeChanged();
return true;
}
bool VideoDriver_SDL::ClaimMousePointer()
bool VideoDriver_SDL_Base::ClaimMousePointer()
{
SDL_ShowCursor(0);
#ifdef __EMSCRIPTEN__
@@ -603,7 +452,7 @@ static void SetTextInputRect()
if (_fcitx_mode) {
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (!SDL_GetWindowWMInfo(_sdl_window, &info)) {
if (!SDL_GetWindowWMInfo(_fcitx_sdl_window, &info)) {
return;
}
int x = 0;
@@ -616,7 +465,7 @@ static void SetTextInputRect()
Window unused;
XTranslateCoordinates(x_disp, x_win, attrib.root, 0, 0, &x, &y, &unused);
} else {
SDL_GetWindowPosition(_sdl_window, &x, &y);
SDL_GetWindowPosition(_fcitx_sdl_window, &x, &y);
}
x += winrect.x;
y += winrect.y;
@@ -639,7 +488,7 @@ static void SetTextInputRect()
/**
* This is called to indicate that an edit box has gained focus, text input mode should be enabled.
*/
void VideoDriver_SDL::EditBoxGainedFocus()
void VideoDriver_SDL_Base::EditBoxGainedFocus()
{
if (!this->edit_box_focused) {
SDL_StartTextInput();
@@ -651,7 +500,7 @@ void VideoDriver_SDL::EditBoxGainedFocus()
/**
* This is called to indicate that an edit box has lost focus, text input mode should be disabled.
*/
void VideoDriver_SDL::EditBoxLostFocus()
void VideoDriver_SDL_Base::EditBoxLostFocus()
{
if (this->edit_box_focused) {
if (_fcitx_mode) {
@@ -793,14 +642,14 @@ static uint ConvertSdlKeycodeIntoMy(SDL_Keycode kc)
return key;
}
int VideoDriver_SDL::PollEvent()
bool VideoDriver_SDL_Base::PollEvent()
{
#if defined(WITH_FCITX)
if (_fcitx_mode) FcitxPoll();
#endif
SDL_Event ev;
if (!SDL_PollEvent(&ev)) return -2;
if (!SDL_PollEvent(&ev)) return false;
switch (ev.type) {
case SDL_MOUSEMOTION:
@@ -822,7 +671,7 @@ int VideoDriver_SDL::PollEvent()
}
#else
if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) {
SDL_WarpMouseInWindow(_sdl_window, _cursor.pos.x, _cursor.pos.y);
SDL_WarpMouseInWindow(this->sdl_window, _cursor.pos.x, _cursor.pos.y);
}
#endif
HandleMouseEvents();
@@ -988,13 +837,12 @@ int VideoDriver_SDL::PollEvent()
#endif
}
}
return -1;
return true;
}
const char *VideoDriver_SDL::Start(const StringList &parm)
static const char *InitializeSDL()
{
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
#if defined(WITH_FCITX)
FcitxInit();
#endif
@@ -1005,18 +853,32 @@ const char *VideoDriver_SDL::Start(const StringList &parm)
SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION, "0");
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1");
/* Just on the offchance the audio subsystem started before the video system,
* check whether any part of SDL has been initialised before getting here.
* Slightly duplicated with sound/sdl_s.cpp */
int ret_code = 0;
if (SDL_WasInit(SDL_INIT_VIDEO) == 0) {
ret_code = SDL_InitSubSystem(SDL_INIT_VIDEO);
}
if (ret_code < 0) return SDL_GetError();
/* Check if the video-driver is already initialized. */
if (SDL_WasInit(SDL_INIT_VIDEO) != 0) return nullptr;
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) return SDL_GetError();
return nullptr;
}
const char *VideoDriver_SDL_Base::Initialize()
{
this->UpdateAutoResolution();
const char *error = InitializeSDL();
if (error != nullptr) return error;
FindResolutions();
DEBUG(driver, 2, "Resolution for display: %ux%u", _cur_resolution.width, _cur_resolution.height);
return nullptr;
}
const char *VideoDriver_SDL_Base::Start(const StringList &parm)
{
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
const char *error = this->Initialize();
if (error != nullptr) return error;
this->startup_display = FindStartupDisplay(GetDriverParamInt(parm, "display", -1));
@@ -1029,17 +891,17 @@ const char *VideoDriver_SDL::Start(const StringList &parm)
MarkWholeScreenDirty();
_draw_threaded = !GetDriverParamBool(parm, "no_threads") && !GetDriverParamBool(parm, "no_thread");
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
* 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) {
_draw_threaded = false;
this->draw_threaded = false;
}
SDL_StopTextInput();
@@ -1052,7 +914,7 @@ const char *VideoDriver_SDL::Start(const StringList &parm)
return nullptr;
}
void VideoDriver_SDL::Stop()
void VideoDriver_SDL_Base::Stop()
{
#if defined(WITH_FCITX)
FcitxDeinit();
@@ -1063,7 +925,7 @@ void VideoDriver_SDL::Stop()
}
}
void VideoDriver_SDL::InputLoop()
void VideoDriver_SDL_Base::InputLoop()
{
uint32 mod = SDL_GetModState();
const Uint8 *keys = SDL_GetKeyboardState(NULL);
@@ -1093,11 +955,8 @@ void VideoDriver_SDL::InputLoop()
if (old_shift_pressed != _shift_pressed) HandleShiftChanged();
}
void VideoDriver_SDL::LoopOnce()
void VideoDriver_SDL_Base::LoopOnce()
{
InteractiveRandom(); // randomness
while (PollEvent() == -1) {}
if (_exit_game) {
#ifdef __EMSCRIPTEN__
/* Emscripten is event-driven, and as such the main loop is inside
@@ -1113,8 +972,8 @@ void VideoDriver_SDL::LoopOnce()
}
if (VideoDriver::Tick()) {
if (_draw_mutex != nullptr && !HasModalProgress()) {
_draw_signal->notify_one();
if (this->draw_mutex != nullptr && !HasModalProgress()) {
this->draw_signal->notify_one();
} else {
this->Paint();
}
@@ -1127,37 +986,37 @@ void VideoDriver_SDL::LoopOnce()
#endif
}
void VideoDriver_SDL::MainLoop()
void VideoDriver_SDL_Base::MainLoop()
{
if (_draw_threaded) {
if (this->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;
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>(*_draw_mutex);
_draw_signal = new std::condition_variable_any();
_draw_continue = true;
draw_lock = std::unique_lock<std::recursive_mutex>(*this->draw_mutex);
this->draw_signal = new std::condition_variable_any();
this->draw_continue = true;
_draw_threaded = StartNewThread(&draw_thread, "ottd:draw-sdl", &VideoDriver_SDL::PaintThreadThunk, this);
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 (!_draw_threaded) {
if (!this->draw_threaded) {
draw_lock.unlock();
draw_lock.release();
delete _draw_mutex;
delete _draw_signal;
_draw_mutex = nullptr;
_draw_signal = nullptr;
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. */
_draw_signal->wait(*_draw_mutex);
this->draw_signal->wait(*this->draw_mutex);
}
}
}
DEBUG(driver, 1, "SDL2: using %sthreads", _draw_threaded ? "" : "no ");
DEBUG(driver, 1, "SDL2: using %sthreads", this->draw_threaded ? "" : "no ");
#ifdef __EMSCRIPTEN__
/* Run the main loop event-driven, based on RequestAnimationFrame. */
@@ -1171,22 +1030,22 @@ void VideoDriver_SDL::MainLoop()
#endif
}
void VideoDriver_SDL::MainLoopCleanup()
void VideoDriver_SDL_Base::MainLoopCleanup()
{
if (_draw_mutex != nullptr) {
_draw_continue = false;
if (this->draw_mutex != nullptr) {
this->draw_continue = false;
/* Sending signal if there is no thread blocked
* is very valid and results in noop */
_draw_signal->notify_one();
this->draw_signal->notify_one();
if (draw_lock.owns_lock()) draw_lock.unlock();
draw_lock.release();
draw_thread.join();
delete _draw_mutex;
delete _draw_signal;
delete this->draw_mutex;
delete this->draw_signal;
_draw_mutex = nullptr;
_draw_signal = nullptr;
this->draw_mutex = nullptr;
this->draw_signal = nullptr;
}
#ifdef __EMSCRIPTEN__
@@ -1199,40 +1058,40 @@ void VideoDriver_SDL::MainLoopCleanup()
#endif
}
bool VideoDriver_SDL::ChangeResolution(int w, int h)
bool VideoDriver_SDL_Base::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);
if (this->draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*this->draw_mutex);
return CreateMainSurface(w, h, true);
}
bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen)
bool VideoDriver_SDL_Base::ToggleFullscreen(bool fullscreen)
{
std::unique_lock<std::recursive_mutex> lock;
if (_draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*_draw_mutex);
if (this->draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*this->draw_mutex);
int w, h;
/* Remember current window size */
if (fullscreen) {
SDL_GetWindowSize(_sdl_window, &w, &h);
SDL_GetWindowSize(this->sdl_window, &w, &h);
/* Find fullscreen window size */
SDL_DisplayMode dm;
if (SDL_GetCurrentDisplayMode(0, &dm) < 0) {
DEBUG(driver, 0, "SDL_GetCurrentDisplayMode() failed: %s", SDL_GetError());
} else {
SDL_SetWindowSize(_sdl_window, dm.w, dm.h);
SDL_SetWindowSize(this->sdl_window, dm.w, dm.h);
}
}
DEBUG(driver, 1, "SDL2: Setting %s", fullscreen ? "fullscreen" : "windowed");
int ret = SDL_SetWindowFullscreen(_sdl_window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
int ret = SDL_SetWindowFullscreen(this->sdl_window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
if (ret == 0) {
/* Switching resolution succeeded, set fullscreen value of window. */
_fullscreen = fullscreen;
if (!fullscreen) SDL_SetWindowSize(_sdl_window, w, h);
if (!fullscreen) SDL_SetWindowSize(this->sdl_window, w, h);
} else {
DEBUG(driver, 0, "SDL_SetWindowFullscreen() failed: %s", SDL_GetError());
}
@@ -1240,25 +1099,25 @@ bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen)
return ret == 0;
}
bool VideoDriver_SDL::AfterBlitterChange()
bool VideoDriver_SDL_Base::AfterBlitterChange()
{
assert(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 0);
int w, h;
SDL_GetWindowSize(_sdl_window, &w, &h);
SDL_GetWindowSize(this->sdl_window, &w, &h);
return CreateMainSurface(w, h, false);
}
void VideoDriver_SDL::AcquireBlitterLock()
void VideoDriver_SDL_Base::AcquireBlitterLock()
{
if (_draw_mutex != nullptr) _draw_mutex->lock();
if (this->draw_mutex != nullptr) this->draw_mutex->lock();
}
void VideoDriver_SDL::ReleaseBlitterLock()
void VideoDriver_SDL_Base::ReleaseBlitterLock()
{
if (_draw_mutex != nullptr) _draw_mutex->unlock();
if (this->draw_mutex != nullptr) this->draw_mutex->unlock();
}
Dimension VideoDriver_SDL::GetScreenSize() const
Dimension VideoDriver_SDL_Base::GetScreenSize() const
{
SDL_DisplayMode mode;
if (SDL_GetCurrentDisplayMode(this->startup_display, &mode) != 0) return VideoDriver::GetScreenSize();
@@ -1266,13 +1125,27 @@ Dimension VideoDriver_SDL::GetScreenSize() const
return { static_cast<uint>(mode.w), static_cast<uint>(mode.h) };
}
bool VideoDriver_SDL::LockVideoBuffer()
bool VideoDriver_SDL_Base::LockVideoBuffer()
{
if (_draw_threaded) this->draw_lock.lock();
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);
return true;
}
void VideoDriver_SDL::UnlockVideoBuffer()
void VideoDriver_SDL_Base::UnlockVideoBuffer()
{
if (_draw_threaded) this->draw_lock.unlock();
if (_screen.dst_ptr != nullptr) {
/* Hand video buffer back to the drawing backend. */
this->ReleaseVideoPointer();
_screen.dst_ptr = nullptr;
}
if (this->draw_threaded) this->draw_lock.unlock();
this->buffer_locked = false;
}