From c6ce1c800296d5a0f18bc101d34c25dc638a6714 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Wed, 12 Oct 2016 22:36:16 +0100 Subject: OPENGL: Add support for filtering feature This replaces the two graphics modes "OpenGL (No filtering)" and "OpenGL". Now there is a single "OpenGL" mode and filtering is controlled by the kFeatureFilteringMode. --- backends/graphics/opengl/opengl-graphics.cpp | 43 +++++++++++++++++----------- backends/graphics/opengl/opengl-graphics.h | 9 +++--- 2 files changed, 32 insertions(+), 20 deletions(-) (limited to 'backends') diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index 41f35e29eb..a0882347b5 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -82,6 +82,7 @@ bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) { switch (f) { case OSystem::kFeatureAspectRatioCorrection: case OSystem::kFeatureCursorPalette: + case OSystem::kFeatureFilteringMode: return true; case OSystem::kFeatureOverlaySupportsAlpha: @@ -99,6 +100,20 @@ void OpenGLGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) { _currentState.aspectRatioCorrection = enable; break; + case OSystem::kFeatureFilteringMode: + assert(_transactionMode != kTransactionNone); + _currentState.filtering = enable; + + if (_gameScreen) { + _gameScreen->enableLinearFiltering(enable); + } + + if (_cursor) { + _cursor->enableLinearFiltering(enable); + } + + break; + case OSystem::kFeatureCursorPalette: _cursorPaletteEnabled = enable; updateCursorPalette(); @@ -114,6 +129,9 @@ bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) { case OSystem::kFeatureAspectRatioCorrection: return _currentState.aspectRatioCorrection; + case OSystem::kFeatureFilteringMode: + return _currentState.filtering; + case OSystem::kFeatureCursorPalette: return _cursorPaletteEnabled; @@ -125,8 +143,7 @@ bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) { namespace { const OSystem::GraphicsMode glGraphicsModes[] = { - { "opengl_linear", _s("OpenGL"), GFX_LINEAR }, - { "opengl_nearest", _s("OpenGL (No filtering)"), GFX_NEAREST }, + { "opengl", _s("OpenGL"), GFX_OPENGL }, { nullptr, nullptr, 0 } }; @@ -137,25 +154,15 @@ const OSystem::GraphicsMode *OpenGLGraphicsManager::getSupportedGraphicsModes() } int OpenGLGraphicsManager::getDefaultGraphicsMode() const { - return GFX_LINEAR; + return GFX_OPENGL; } bool OpenGLGraphicsManager::setGraphicsMode(int mode) { assert(_transactionMode != kTransactionNone); switch (mode) { - case GFX_LINEAR: - case GFX_NEAREST: + case GFX_OPENGL: _currentState.graphicsMode = mode; - - if (_gameScreen) { - _gameScreen->enableLinearFiltering(mode == GFX_LINEAR); - } - - if (_cursor) { - _cursor->enableLinearFiltering(mode == GFX_LINEAR); - } - return true; default: @@ -250,6 +257,10 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() { transactionError |= OSystem::kTransactionModeSwitchFailed; } + if (_oldState.filtering != _currentState.filtering) { + transactionError |= OSystem::kTransactionFilteringFailed; + } + // Roll back to the old state. _currentState = _oldState; _transactionMode = kTransactionRollback; @@ -286,7 +297,7 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() { } _gameScreen->allocate(_currentState.gameWidth, _currentState.gameHeight); - _gameScreen->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR); + _gameScreen->enableLinearFiltering(_currentState.filtering); // We fill the screen to all black or index 0 for CLUT8. #ifdef USE_RGB_COLOR if (_currentState.gameFormat.bytesPerPixel == 1) { @@ -660,7 +671,7 @@ void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int } _cursor = createSurface(textureFormat, true); assert(_cursor); - _cursor->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR); + _cursor->enableLinearFiltering(_currentState.filtering); } _cursorKeyColor = keycolor; diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h index 7900f06fb7..01672f4f5c 100644 --- a/backends/graphics/opengl/opengl-graphics.h +++ b/backends/graphics/opengl/opengl-graphics.h @@ -50,8 +50,7 @@ class Shader; #endif enum { - GFX_LINEAR = 0, - GFX_NEAREST = 1 + GFX_OPENGL = 0 }; class OpenGLGraphicsManager : virtual public GraphicsManager { @@ -213,7 +212,7 @@ private: #ifdef USE_RGB_COLOR gameFormat(), #endif - aspectRatioCorrection(false), graphicsMode(GFX_LINEAR) { + aspectRatioCorrection(false), graphicsMode(GFX_OPENGL), filtering(true) { } bool valid; @@ -224,6 +223,7 @@ private: #endif bool aspectRatioCorrection; int graphicsMode; + bool filtering; bool operator==(const VideoState &right) { return gameWidth == right.gameWidth && gameHeight == right.gameHeight @@ -231,7 +231,8 @@ private: && gameFormat == right.gameFormat #endif && aspectRatioCorrection == right.aspectRatioCorrection - && graphicsMode == right.graphicsMode; + && graphicsMode == right.graphicsMode + && filtering == right.filtering; } bool operator!=(const VideoState &right) { -- cgit v1.2.3 From 3a69898729b5d08aabcb53e6382284d1df818c9b Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Wed, 12 Oct 2016 22:38:07 +0100 Subject: SURFACESDL: Add support for filtering feature when using SDL2 This implements the request from ticket #9573: SDL1/2: Different rendering/filtering? --- .../graphics/surfacesdl/surfacesdl-graphics.cpp | 41 ++++++++++++++++++++++ backends/graphics/surfacesdl/surfacesdl-graphics.h | 7 ++++ 2 files changed, 48 insertions(+) (limited to 'backends') diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index 46e243c945..cc1d8dbafa 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -190,6 +190,10 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou #else _videoMode.fullscreen = true; #endif + +#if SDL_VERSION_ATLEAST(2, 0, 0) + _videoMode.filtering = ConfMan.getBool("filtering"); +#endif } SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() { @@ -227,6 +231,9 @@ bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) { return (f == OSystem::kFeatureFullscreenMode) || (f == OSystem::kFeatureAspectRatioCorrection) || +#if SDL_VERSION_ATLEAST(2, 0, 0) + (f == OSystem::kFeatureFilteringMode) || +#endif (f == OSystem::kFeatureCursorPalette) || (f == OSystem::kFeatureIconifyWindow); } @@ -239,6 +246,11 @@ void SurfaceSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) case OSystem::kFeatureAspectRatioCorrection: setAspectRatioCorrection(enable); break; +#if SDL_VERSION_ATLEAST(2, 0, 0) + case OSystem::kFeatureFilteringMode: + setFilteringMode(enable); + break; +#endif case OSystem::kFeatureCursorPalette: _cursorPaletteDisabled = !enable; blitCursor(); @@ -263,6 +275,10 @@ bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) { return _videoMode.fullscreen; case OSystem::kFeatureAspectRatioCorrection: return _videoMode.aspectRatioCorrection; +#if SDL_VERSION_ATLEAST(2, 0, 0) + case OSystem::kFeatureFilteringMode: + return _videoMode.filtering; +#endif case OSystem::kFeatureCursorPalette: return !_cursorPaletteDisabled; default: @@ -323,6 +339,12 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() { _videoMode.mode = _oldVideoMode.mode; _videoMode.scaleFactor = _oldVideoMode.scaleFactor; +#if SDL_VERSION_ATLEAST(2, 0, 0) + } else if (_videoMode.filtering != _oldVideoMode.filtering) { + errors |= OSystem::kTransactionFilteringFailed; + + _videoMode.filtering = _oldVideoMode.filtering; +#endif #ifdef USE_RGB_COLOR } else if (_videoMode.format != _oldVideoMode.format) { errors |= OSystem::kTransactionFormatNotSupported; @@ -342,6 +364,9 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() { if (_videoMode.fullscreen == _oldVideoMode.fullscreen && _videoMode.aspectRatioCorrection == _oldVideoMode.aspectRatioCorrection && _videoMode.mode == _oldVideoMode.mode && +#if SDL_VERSION_ATLEAST(2, 0, 0) + _videoMode.filtering == _oldVideoMode.filtering && +#endif _videoMode.screenWidth == _oldVideoMode.screenWidth && _videoMode.screenHeight == _oldVideoMode.screenHeight) { @@ -1267,6 +1292,20 @@ void SurfaceSdlGraphicsManager::setAspectRatioCorrection(bool enable) { } } +#if SDL_VERSION_ATLEAST(2, 0, 0) +void SurfaceSdlGraphicsManager::setFilteringMode(bool enable) { + Common::StackLock lock(_graphicsMutex); + + if (_oldVideoMode.setup && _oldVideoMode.filtering == enable) + return; + + if (_transactionMode == kTransactionActive) { + _videoMode.filtering = enable; + _transactionDetails.needHotswap = true; + } +} +#endif + void SurfaceSdlGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) { assert(_transactionMode == kTransactionNone); assert(buf); @@ -2542,6 +2581,8 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height, SDL_GetWindowSize(_window->getSDLWindow(), &_windowWidth, &_windowHeight); setWindowResolution(_windowWidth, _windowHeight); + + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, _videoMode.filtering ? "linear" : "nearest"); _screenTexture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); if (!_screenTexture) { diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h index 82f4a33d8e..bc2edc964c 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.h +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h @@ -250,6 +250,10 @@ protected: bool aspectRatioCorrection; AspectRatio desiredAspectRatio; +#if SDL_VERSION_ATLEAST(2, 0, 0) + bool filtering; +#endif + int mode; int scaleFactor; @@ -383,6 +387,9 @@ protected: virtual void setFullscreenMode(bool enable); virtual void setAspectRatioCorrection(bool enable); +#if SDL_VERSION_ATLEAST(2, 0, 0) + virtual void setFilteringMode(bool enable); +#endif virtual int effectiveScreenHeight() const; -- cgit v1.2.3 From 529a7ca26c61cfe10339ee9c7a1fa75ccaf4b562 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Wed, 12 Oct 2016 23:33:12 +0100 Subject: OPENGLSDL: Add hotkey to enable/disable filtering Crtl-Alt-f now enables/disables filtering instead of changing the graphics mode. Since there is only one graphics mode now, a hotkey to change it is a bit useless. --- backends/graphics/openglsdl/openglsdl-graphics.cpp | 40 +++++----------------- 1 file changed, 9 insertions(+), 31 deletions(-) (limited to 'backends') diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index f6ae25c4ee..042cd49099 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -735,38 +735,13 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) { return true; } else if (event.kbd.keycode == Common::KEYCODE_f) { - // Ctrl+Alt+f toggles the graphics modes. - - // We are crazy we will allow the OpenGL base class to - // introduce new graphics modes like shaders for special - // filtering. If some other OpenGL subclass needs this, - // we can think of refactoring this. - int mode = getGraphicsMode(); - const OSystem::GraphicsMode *supportedModes = getSupportedGraphicsModes(); - const OSystem::GraphicsMode *modeDesc = nullptr; - - // Search the current mode. - for (; supportedModes->name; ++supportedModes) { - if (supportedModes->id == mode) { - modeDesc = supportedModes; - break; - } - } - assert(modeDesc); - - // Try to use the next mode in the list. - ++modeDesc; - if (!modeDesc->name) { - modeDesc = getSupportedGraphicsModes(); - } - - // Never ever try to resize the window when we simply want to - // switch the graphics mode. This assures that the window size - // does not change. + // Never ever try to resize the window when we simply want to enable or disable filtering. + // This assures that the window size does not change. _ignoreLoadVideoMode = true; + // Ctrl+Alt+f toggles filtering on/off beginGFXTransaction(); - setGraphicsMode(modeDesc->id); + setFeatureState(OSystem::kFeatureFilteringMode, !getFeatureState(OSystem::kFeatureFilteringMode)); endGFXTransaction(); // Make sure we do not ignore the next resize. This @@ -774,8 +749,11 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) { assert(!_ignoreLoadVideoMode); #ifdef USE_OSD - const Common::String osdMsg = Common::String::format(_("Graphics mode: %s"), _(modeDesc->description)); - displayMessageOnOSD(osdMsg.c_str()); + if (getFeatureState(OSystem::kFeatureFilteringMode)) { + displayMessageOnOSD(_("Filtering enabled")); + } else { + displayMessageOnOSD(_("Filtering disabled")); + } #endif return true; -- cgit v1.2.3 From fd77916f865a7dded2a14aa67d038ef3370a52f7 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Wed, 12 Oct 2016 23:33:28 +0100 Subject: SURFACESDL: Add hotkey to enable/disable filtering --- .../graphics/surfacesdl/surfacesdl-graphics.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'backends') diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index cc1d8dbafa..2b62cc2c6e 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -2341,6 +2341,24 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) { internUpdateScreen(); return true; } + +#if SDL_VERSION_ATLEAST(2, 0, 0) + // Ctrl-Alt-f toggles filtering + if (key == 'f') { + beginGFXTransaction(); + setFeatureState(OSystem::kFeatureFilteringMode, !_videoMode.filtering); + endGFXTransaction(); +#ifdef USE_OSD + if (getFeatureState(OSystem::kFeatureFilteringMode)) { + displayMessageOnOSD(_("Filtering enabled")); + } else { + displayMessageOnOSD(_("Filtering disabled")); + } +#endif + internUpdateScreen(); + return true; + } +#endif int newMode = -1; int factor = _videoMode.scaleFactor - 1; @@ -2414,6 +2432,10 @@ bool SurfaceSdlGraphicsManager::isScalerHotkey(const Common::Event &event) { if (keyValue >= ARRAYSIZE(s_gfxModeSwitchTable)) return false; } +#if SDL_VERSION_ATLEAST(2, 0, 0) + if (event.kbd.keycode == 'f') + return true; +#endif return (isScaleKey || event.kbd.keycode == 'a'); } return false; -- cgit v1.2.3 From aa39a6ce4b2285d1308eb4607bdd53d317304661 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Thu, 13 Oct 2016 00:19:15 +0100 Subject: SURFACESDL: Improve toggling filtering on/off We don't need to recreate the window when turning filtering on or off. Only the texture needs to be recreated. --- .../graphics/surfacesdl/surfacesdl-graphics.cpp | 26 +++++++++++++++++++++- backends/graphics/surfacesdl/surfacesdl-graphics.h | 4 ++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index 2b62cc2c6e..90d079d151 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -313,6 +313,9 @@ void SurfaceSdlGraphicsManager::beginGFXTransaction() { _transactionDetails.needUpdatescreen = false; _transactionDetails.normal1xScaler = false; +#if SDL_VERSION_ATLEAST(2, 0, 0) + _transactionDetails.needTextureUpdate = false; +#endif #ifdef USE_RGB_COLOR _transactionDetails.formatChanged = false; #endif @@ -420,6 +423,12 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() { if (_transactionDetails.needUpdatescreen) internUpdateScreen(); } +#if SDL_VERSION_ATLEAST(2, 0, 0) + } else if (_transactionDetails.needTextureUpdate) { + setGraphicsModeIntern(); + recreateScreenTexture(); + internUpdateScreen(); +#endif } else if (_transactionDetails.needUpdatescreen) { setGraphicsModeIntern(); internUpdateScreen(); @@ -1301,7 +1310,7 @@ void SurfaceSdlGraphicsManager::setFilteringMode(bool enable) { if (_transactionMode == kTransactionActive) { _videoMode.filtering = enable; - _transactionDetails.needHotswap = true; + _transactionDetails.needTextureUpdate = true; } } #endif @@ -2355,6 +2364,7 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) { displayMessageOnOSD(_("Filtering disabled")); } #endif + _forceFull = true; internUpdateScreen(); return true; } @@ -2580,6 +2590,20 @@ void SurfaceSdlGraphicsManager::setWindowResolution(int width, int height) { _forceFull = true; } +void SurfaceSdlGraphicsManager::recreateScreenTexture() { + if (!_renderer) + return; + + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, _videoMode.filtering ? "linear" : "nearest"); + + SDL_Texture *oldTexture = _screenTexture; + _screenTexture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, _videoMode.hardwareWidth, _videoMode.hardwareHeight); + if (_screenTexture) + SDL_DestroyTexture(oldTexture); + else + _screenTexture = oldTexture; +} + SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) { deinitializeRenderer(); diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h index bc2edc964c..975cbfe27b 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.h +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h @@ -198,6 +198,7 @@ protected: int _windowWidth, _windowHeight; void deinitializeRenderer(); void setWindowResolution(int width, int height); + void recreateScreenTexture(); SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags); void SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects); @@ -237,6 +238,9 @@ protected: bool needHotswap; bool needUpdatescreen; bool normal1xScaler; +#if SDL_VERSION_ATLEAST(2, 0, 0) + bool needTextureUpdate; +#endif #ifdef USE_RGB_COLOR bool formatChanged; #endif -- cgit v1.2.3