From 61f6f59b120d656696c5bd5638b141d58f6f53ae Mon Sep 17 00:00:00 2001 From: Alayan <25536748+Alayan-stk-2@users.noreply.github.com> Date: Sun, 19 May 2024 16:12:47 +0200 Subject: [PATCH] Fix #5075 A basic restart of the screen does not reinitialize what's needed to properly update anisotropic filtering. Therefore, ensure a full restart is done, but avoid showing the user a resolution confirmation dialog afterwards. Also use a new applySettings function to avoid having two places to update when changing the code that manages applying updated graphics settings. --- src/graphics/irr_driver.cpp | 3 +- src/graphics/irr_driver.hpp | 5 +- .../options/options_screen_display.cpp | 1 - .../options/options_screen_video.cpp | 61 +++++++++++-------- .../options/options_screen_video.hpp | 2 + 5 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index d05d54385..c99fabdc5 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1028,8 +1028,7 @@ bool IrrDriver::moveWindow(int x, int y) } //----------------------------------------------------------------------------- -void IrrDriver::changeResolution(const int w, const int h, - const bool fullscreen) +void IrrDriver::changeResolution(const int w, const int h, const bool fullscreen) { // update user config values UserConfigParams::m_prev_real_width = UserConfigParams::m_real_width; diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 0382430fa..543a6b600 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -119,7 +119,7 @@ private: * Same indicates a change of the resolution (back to the original * one), but no confirmation dialog. */ enum {RES_CHANGE_NONE, RES_CHANGE_YES, RES_CHANGE_CANCEL, - RES_CHANGE_SAME, RES_CHANGE_YES_WARN} m_resolution_changing; + RES_CHANGE_SAME, RES_CHANGE_YES_WARN, RES_CHANGE_SAME_FULL} m_resolution_changing; public: @@ -531,6 +531,9 @@ public: void uploadLightingData(); void sameRestart() { m_resolution_changing = RES_CHANGE_SAME; } + /** Used when we don't want a changed resolution prompt but need to reinit things + * that sameRestart doesn't affect */ + void fullRestart() { m_resolution_changing = RES_CHANGE_SAME_FULL; } // ------------------------------------------------------------------------ u32 getDefaultFramebuffer() const; // ------------------------------------------------------------------------ diff --git a/src/states_screens/options/options_screen_display.cpp b/src/states_screens/options/options_screen_display.cpp index 3225dd6cc..acdae0a7a 100644 --- a/src/states_screens/options/options_screen_display.cpp +++ b/src/states_screens/options/options_screen_display.cpp @@ -376,7 +376,6 @@ void OptionsScreenDisplay::eventCallback(Widget* widget, const std::string& name CheckBoxWidget* w2 = getWidget("fullscreen"); assert(w2 != NULL); - irr_driver->changeResolution(w, h, w2->getState()); } else if (name == "rememberWinpos") diff --git a/src/states_screens/options/options_screen_video.cpp b/src/states_screens/options/options_screen_video.cpp index 2f22cccca..6354e8ef5 100644 --- a/src/states_screens/options/options_screen_video.cpp +++ b/src/states_screens/options/options_screen_video.cpp @@ -131,6 +131,8 @@ void OptionsScreenVideo::initPresets() // -------------------------------------------------------------------------------------------- int OptionsScreenVideo::getImageQuality() { + // applySettings assumes that only the first image quality preset has a different + // level of anisotropic filtering from others if (UserConfigParams::m_anisotropic == 4 && (UserConfigParams::m_high_definition_textures & 0x01) == 0x00 && UserConfigParams::m_hq_mipmap == false) @@ -672,25 +674,13 @@ void OptionsScreenVideo::eventCallback(Widget* widget, const std::string& name, if (!result) Log::fatal("OptionsScreenVideo", "Can't open replay for benchmark!"); - // Avoid crashing, when switching between advanced lighting and the old renderer - // before starting a performance test, ensure the image quality setting is applied - if (m_prev_adv_pipline != UserConfigParams::m_dynamic_lights && - CVS->isGLSL()) - { - irr_driver->sameRestart(); - // We cannot start the benchmark immediately, in case we just restarted the graphics engine - RaceManager::get()->scheduleBenchmark(); - } - else if (m_prev_img_quality != getImageQuality()) - { - // TODO - check if this is enough for the setting to be properly applied - irr_driver->setMaxTextureSize(); + // To avoid crashes and ensure the proper settings are used during the benchmark, + // we apply the settings. If this doesn't require restarting the screen, we start + // the benchmark immediately, otherwise we schedule it to start after the restart. + if (applySettings() == 0) startBenchmark(); - } else - { - startBenchmark(); - } + RaceManager::get()->scheduleBenchmark(); #endif } // benchmarkCurrent else if (name == "benchmarkRecommend") @@ -722,21 +712,40 @@ void OptionsScreenVideo::startBenchmark() void OptionsScreenVideo::tearDown() { #ifndef SERVER_ONLY - if (m_prev_adv_pipline != UserConfigParams::m_dynamic_lights && - CVS->isGLSL()) - { - irr_driver->sameRestart(); - } - else if (m_prev_img_quality != getImageQuality()) - { - irr_driver->setMaxTextureSize(); - } + applySettings(); Screen::tearDown(); // save changes when leaving screen user_config->saveConfig(); #endif } // tearDown +// -------------------------------------------------------------------------------------------- +/* Returns 1 or 2 if a restart will be done, 0 otherwise */ +int OptionsScreenVideo::applySettings() +{ + int restart = 0; +#ifndef SERVER_ONLY + if (m_prev_adv_pipline != UserConfigParams::m_dynamic_lights && CVS->isGLSL()) + restart = 1; + + if (m_prev_img_quality != getImageQuality()) + { + irr_driver->setMaxTextureSize(); + // A full restart is needed to properly apply anisotropic filtering if it was changed + // We assume that all ImageQuality settings >= 1 use the same x16 setting. + if ((m_prev_img_quality == 0 && getImageQuality() != 0) || + (m_prev_img_quality != 0 && getImageQuality() == 0)) + restart = 2; + } + + if (restart == 1) + irr_driver->sameRestart(); + else if (restart == 2) + irr_driver->fullRestart(); +#endif + return restart; +} // applySettings + // -------------------------------------------------------------------------------------------- bool OptionsScreenVideo::onEscapePressed() diff --git a/src/states_screens/options/options_screen_video.hpp b/src/states_screens/options/options_screen_video.hpp index 3b8da5c3d..d3fa413eb 100644 --- a/src/states_screens/options/options_screen_video.hpp +++ b/src/states_screens/options/options_screen_video.hpp @@ -74,6 +74,8 @@ private: void initPresets(); void startBenchmark(); static void onScrollResolutionsList(void* data); + /* Returns 1 or 2 if a restart will be done, 0 otherwise */ + int applySettings(); public: friend class GUIEngine::ScreenSingleton;