From ebe6c40a6abb2789349c2b6471eef24ac270ab94 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Sun, 27 Aug 2017 22:21:05 -0500 Subject: SDL: Do not reset window size when engines update rendering surface This change allows: * Engines to update their target rendering surface/size and pixel format with the backend multiple times during gameplay; * Users to resize the ScummVM window without having it reset size/position every time an engine updates its target surface format; * Conversions/scaling to continue to run efficiently in hardware, instead of requiring engines to pick their maximum possible output format once and upscale inefficiently in software; * The window to reset size once when an engine calls to set its initial output size, and to reset again once ScummVM returns to the launcher. This is relevant for at least SCI32 and DreamWeb engines, which perform graphics mode switches during games. --- backends/graphics/openglsdl/openglsdl-graphics.cpp | 12 ++------- backends/graphics/sdl/sdl-graphics.cpp | 30 ++++++++++++++++++++-- backends/graphics/sdl/sdl-graphics.h | 11 ++++++++ .../graphics/surfacesdl/surfacesdl-graphics.cpp | 9 +++++-- backends/platform/sdl/sdl.cpp | 12 +++++++-- backends/platform/sdl/sdl.h | 2 -- 6 files changed, 58 insertions(+), 18 deletions(-) (limited to 'backends') diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index f664314862..efc10a0d2c 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -509,16 +509,8 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, _glContextMajor); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, _glContextMinor); - if (!_window->createOrUpdateWindow(width, height, flags)) { - // We treat fullscreen requests as a "hint" for now. This means in - // case it is not available we simply ignore it. - if (_wantsFullScreen) { - _window->createOrUpdateWindow(width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); - } - - if (!_window->getSDLWindow()) { - return false; - } + if (!createOrUpdateWindow(width, height, flags)) { + return false; } _glContext = SDL_GL_CreateContext(_window->getSDLWindow()); diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index a13ca45477..aa6087beae 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -21,13 +21,16 @@ */ #include "backends/graphics/sdl/sdl-graphics.h" - #include "backends/platform/sdl/sdl-sys.h" #include "backends/events/sdl/sdl-events.h" #include "common/textconsole.h" SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window) - : _eventSource(source), _window(window) { + : _eventSource(source), _window(window) +#if SDL_VERSION_ATLEAST(2, 0, 0) + , _allowWindowSizeReset(false), _lastFlags(0) +#endif + { } SdlGraphicsManager::~SdlGraphicsManager() { @@ -73,3 +76,26 @@ bool SdlGraphicsManager::setState(const State &state) { } } +#if SDL_VERSION_ATLEAST(2, 0, 0) +bool SdlGraphicsManager::createOrUpdateWindow(const int width, const int height, const Uint32 flags) { + if (!_window) { + return false; + } + + // We only update the actual window when flags change (which usually means + // fullscreen mode is entered/exited) or when updates are forced so that we + // do not reset the window size whenever a game makes a call to change the + // size or pixel format of the internal game surface (since a user may have + // resized the game window) + if (!_window->getSDLWindow() || _lastFlags != flags || _allowWindowSizeReset) { + if (!_window->createOrUpdateWindow(width, height, flags)) { + return false; + } + + _lastFlags = flags; + _allowWindowSizeReset = false; + } + + return true; +} +#endif diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h index 7f8790a9b4..937beef9b4 100644 --- a/backends/graphics/sdl/sdl-graphics.h +++ b/backends/graphics/sdl/sdl-graphics.h @@ -123,6 +123,17 @@ public: SdlWindow *getWindow() const { return _window; } protected: +#if SDL_VERSION_ATLEAST(2, 0, 0) +public: + void unlockWindowSize() { _allowWindowSizeReset = true; } + +protected: + Uint32 _lastFlags; + bool _allowWindowSizeReset; + + bool createOrUpdateWindow(const int width, const int height, const Uint32 flags); +#endif + SdlEventSource *_eventSource; SdlWindow *_window; }; diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index 983b71ab28..cd7e11b32d 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -784,9 +784,14 @@ void SurfaceSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFo } #endif - // Avoid redundant res changes +#if !SDL_VERSION_ATLEAST(2, 0, 0) + // Avoid redundant res changes, only in SDL1. In SDL2, redundancies may not + // actually be redundant if ScummVM is switching between game engines and + // the screen dimensions are being reinitialized, since window resizing is + // supposed to reset when this happens if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight) return; +#endif _videoMode.screenWidth = w; _videoMode.screenHeight = h; @@ -2797,7 +2802,7 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height, createWindowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } - if (!_window->createOrUpdateWindow(width, height, createWindowFlags)) { + if (!createOrUpdateWindow(width, height, createWindowFlags)) { return nullptr; } diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index bbd5c89f80..f44d87666a 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -297,20 +297,28 @@ void OSystem_SDL::initBackend() { dynamic_cast(_graphicsManager)->activateManager(); } -#if defined(USE_TASKBAR) void OSystem_SDL::engineInit() { +#if SDL_VERSION_ATLEAST(2, 0, 0) + dynamic_cast(_graphicsManager)->unlockWindowSize(); +#endif +#ifdef USE_TASKBAR // Add the started engine to the list of recent tasks _taskbarManager->addRecent(ConfMan.getActiveDomainName(), ConfMan.get("description")); // Set the overlay icon the current running engine _taskbarManager->setOverlayIcon(ConfMan.getActiveDomainName(), ConfMan.get("description")); +#endif } void OSystem_SDL::engineDone() { +#if SDL_VERSION_ATLEAST(2, 0, 0) + dynamic_cast(_graphicsManager)->unlockWindowSize(); +#endif +#ifdef USE_TASKBAR // Remove overlay icon _taskbarManager->setOverlayIcon("", ""); -} #endif +} void OSystem_SDL::initSDL() { // Check if SDL has not been initialized diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index bc4292be0b..61513fa65f 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -59,10 +59,8 @@ public: // Override functions from ModularBackend and OSystem virtual void initBackend(); -#if defined(USE_TASKBAR) virtual void engineInit(); virtual void engineDone(); -#endif virtual void quit(); virtual void fatalError(); -- cgit v1.2.3