From 7a64527db5b23c8b9d988f1d914fbd3555025830 Mon Sep 17 00:00:00 2001 From: cx384 Date: Sat, 15 Jun 2024 16:00:33 +0200 Subject: [PATCH 1/5] Fix connected_players on_shutdown (#14739) --- doc/lua_api.md | 2 + games/devtest/mods/unittests/init.lua | 1 + games/devtest/mods/unittests/on_shutdown.lua | 22 ++++++++++ src/server.cpp | 46 +++++++++----------- 4 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 games/devtest/mods/unittests/on_shutdown.lua diff --git a/doc/lua_api.md b/doc/lua_api.md index b1412ca85..c733fc0a3 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -5720,6 +5720,8 @@ Call these functions only at load time! aliases handled. * `minetest.register_on_shutdown(function())` * Called before server shutdown + * Players that were kicked by the shutdown procedure are still fully accessible + in `minetest.get_connected_players()`. * **Warning**: If the server terminates abnormally (i.e. crashes), the registered callbacks **will likely not be run**. Data should be saved at semi-frequent intervals as well as on server shutdown. diff --git a/games/devtest/mods/unittests/init.lua b/games/devtest/mods/unittests/init.lua index 47568d9fc..eae003a2a 100644 --- a/games/devtest/mods/unittests/init.lua +++ b/games/devtest/mods/unittests/init.lua @@ -186,6 +186,7 @@ dofile(modpath .. "/metadata.lua") dofile(modpath .. "/raycast.lua") dofile(modpath .. "/inventory.lua") dofile(modpath .. "/load_time.lua") +dofile(modpath .. "/on_shutdown.lua") -------------- diff --git a/games/devtest/mods/unittests/on_shutdown.lua b/games/devtest/mods/unittests/on_shutdown.lua new file mode 100644 index 000000000..6d5d88638 --- /dev/null +++ b/games/devtest/mods/unittests/on_shutdown.lua @@ -0,0 +1,22 @@ +-- Test whether players still exist on shutdown +local players = {} + +core.register_on_joinplayer(function(player) + players[player:get_player_name()] = true +end) + +core.register_on_leaveplayer(function(player) + local name = player:get_player_name(); + assert(players[name], "Unrecorded player join.") + players[name] = nil +end) + +core.register_on_shutdown(function() + for _, player in pairs(core.get_connected_players()) do + local name = player:get_player_name() + assert(players[name], "Unrecorded player join or left too early.") + players[name] = nil + end + + assert(not next(players), "Invalid connected players on shutdown.") +end) diff --git a/src/server.cpp b/src/server.cpp index 316f349b2..937cbe90a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -329,27 +329,6 @@ Server::~Server() SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE, L"*** Server shutting down")); - if (m_env) { - MutexAutoLock envlock(m_env_mutex); - - infostream << "Server: Saving players" << std::endl; - m_env->saveLoadedPlayers(); - - infostream << "Server: Kicking players" << std::endl; - std::string kick_msg; - bool reconnect = false; - if (isShutdownRequested()) { - reconnect = m_shutdown_state.should_reconnect; - kick_msg = m_shutdown_state.message; - } - if (kick_msg.empty()) { - kick_msg = g_settings->get("kick_msg_shutdown"); - } - m_env->saveLoadedPlayers(true); - kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN, - kick_msg, reconnect); - } - actionstream << "Server: Shutting down" << std::endl; // Stop server step from happening @@ -369,16 +348,33 @@ Server::~Server() if (m_env) { MutexAutoLock envlock(m_env_mutex); + infostream << "Server: Executing shutdown hooks" << std::endl; try { - // Empty out the environment, this can also invoke callbacks. - m_env->deactivateBlocksAndObjects(); + m_script->on_shutdown(); } catch (ModError &e) { addShutdownError(e); } - infostream << "Server: Executing shutdown hooks" << std::endl; + infostream << "Server: Saving players" << std::endl; + m_env->saveLoadedPlayers(); + + infostream << "Server: Kicking players" << std::endl; + std::string kick_msg; + bool reconnect = false; + if (isShutdownRequested()) { + reconnect = m_shutdown_state.should_reconnect; + kick_msg = m_shutdown_state.message; + } + if (kick_msg.empty()) { + kick_msg = g_settings->get("kick_msg_shutdown"); + } + m_env->saveLoadedPlayers(true); + kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN, + kick_msg, reconnect); + try { - m_script->on_shutdown(); + // Empty out the environment, this can also invoke callbacks. + m_env->deactivateBlocksAndObjects(); } catch (ModError &e) { addShutdownError(e); } From a9cca5e76ca73e6e7ca335f2a2ad247604b903ae Mon Sep 17 00:00:00 2001 From: grorp Date: Sun, 16 Jun 2024 17:49:42 +0200 Subject: [PATCH 2/5] SDL2: Support highdpi (#14703) and handle DPI changes at runtime --- builtin/settingtypes.txt | 3 -- irr/include/IEventReceiver.h | 3 ++ irr/src/CIrrDeviceSDL.cpp | 83 +++++++++++++++++++++------------- irr/src/CIrrDeviceSDL.h | 5 +- irr/src/CMakeLists.txt | 2 + misc/minetest.exe.manifest | 2 + src/client/clientlauncher.cpp | 2 + src/client/fontengine.cpp | 2 +- src/client/hud.cpp | 2 + src/client/inputhandler.cpp | 9 ++++ src/client/renderingengine.cpp | 16 +++---- src/defaultsettings.cpp | 2 +- 12 files changed, 84 insertions(+), 47 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index aca960590..bb7ba7f7f 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -2187,9 +2187,6 @@ curl_file_download_timeout (cURL file download timeout) int 300000 5000 21474836 [**Miscellaneous] -# Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens. -screen_dpi (DPI) int 72 1 - # Adjust the detected display density, used for scaling UI elements. display_density_factor (Display Density Scaling Factor) float 1 0.5 5.0 diff --git a/irr/include/IEventReceiver.h b/irr/include/IEventReceiver.h index cf7dee3ab..a484bfb84 100644 --- a/irr/include/IEventReceiver.h +++ b/irr/include/IEventReceiver.h @@ -205,6 +205,9 @@ enum EAPPLICATION_EVENT_TYPE //! The application received a memory warning. EAET_MEMORY_WARNING, + //! The display density changed (only works on SDL). + EAET_DPI_CHANGED, + //! No real event, but to get number of event types. EAET_COUNT }; diff --git a/irr/src/CIrrDeviceSDL.cpp b/irr/src/CIrrDeviceSDL.cpp index f5859372e..f8fb66da3 100644 --- a/irr/src/CIrrDeviceSDL.cpp +++ b/irr/src/CIrrDeviceSDL.cpp @@ -285,6 +285,11 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters ¶m) : SDL_SetHint(SDL_HINT_TV_REMOTE_AS_JOYSTICK, "0"); #endif +#if SDL_VERSION_ATLEAST(2, 24, 0) + // highdpi support on Windows + SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, "1"); +#endif + // Minetest has its own code to synthesize mouse events from touch events, // so we prevent SDL from doing it. SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); @@ -475,6 +480,7 @@ bool CIrrDeviceSDL::createWindow() bool CIrrDeviceSDL::createWindowWithContext() { u32 SDL_Flags = 0; + SDL_Flags |= SDL_WINDOW_ALLOW_HIGHDPI; SDL_Flags |= getFullscreenFlag(CreationParams.Fullscreen); if (Resizable) @@ -589,13 +595,16 @@ bool CIrrDeviceSDL::createWindowWithContext() return false; } - // Update Width and Height to match the actual window size. - // In fullscreen mode, the window size specified in SIrrlichtCreationParameters - // is ignored, so we cannot rely on it. - int w = 0, h = 0; - SDL_GetWindowSize(Window, &w, &h); - Width = w; - Height = h; + updateSizeAndScale(); + if (ScaleX != 1.0f || ScaleY != 1.0f) { + // The given window size is in pixels, not in screen coordinates. + // We can only do the conversion now since we didn't know the scale before. + SDL_SetWindowSize(Window, CreationParams.WindowSize.Width / ScaleX, + CreationParams.WindowSize.Height / ScaleY); + // Re-center, otherwise large, non-maximized windows go offscreen. + SDL_SetWindowPosition(Window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + updateSizeAndScale(); + } return true; #endif // !_IRR_EMSCRIPTEN_PLATFORM_ @@ -659,10 +668,10 @@ bool CIrrDeviceSDL::run() irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; - MouseX = irrevent.MouseInput.X = SDL_event.motion.x; - MouseY = irrevent.MouseInput.Y = SDL_event.motion.y; - MouseXRel = SDL_event.motion.xrel; - MouseYRel = SDL_event.motion.yrel; + MouseX = irrevent.MouseInput.X = SDL_event.motion.x * ScaleX; + MouseY = irrevent.MouseInput.Y = SDL_event.motion.y * ScaleY; + MouseXRel = SDL_event.motion.xrel * ScaleX; + MouseYRel = SDL_event.motion.yrel * ScaleY; irrevent.MouseInput.ButtonStates = MouseButtonStates; irrevent.MouseInput.Shift = (keymod & KMOD_SHIFT) != 0; irrevent.MouseInput.Control = (keymod & KMOD_CTRL) != 0; @@ -694,8 +703,8 @@ bool CIrrDeviceSDL::run() SDL_Keymod keymod = SDL_GetModState(); irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; - irrevent.MouseInput.X = SDL_event.button.x; - irrevent.MouseInput.Y = SDL_event.button.y; + irrevent.MouseInput.X = SDL_event.button.x * ScaleX; + irrevent.MouseInput.Y = SDL_event.button.y * ScaleY; irrevent.MouseInput.Shift = (keymod & KMOD_SHIFT) != 0; irrevent.MouseInput.Control = (keymod & KMOD_CTRL) != 0; @@ -827,14 +836,25 @@ bool CIrrDeviceSDL::run() case SDL_WINDOWEVENT: switch (SDL_event.window.event) { case SDL_WINDOWEVENT_RESIZED: - if ((SDL_event.window.data1 != (int)Width) || (SDL_event.window.data2 != (int)Height)) { - Width = SDL_event.window.data1; - Height = SDL_event.window.data2; + case SDL_WINDOWEVENT_SIZE_CHANGED: +#if SDL_VERSION_ATLEAST(2, 0, 18) + case SDL_WINDOWEVENT_DISPLAY_CHANGED: +#endif + u32 old_w = Width, old_h = Height; + f32 old_scale_x = ScaleX, old_scale_y = ScaleY; + updateSizeAndScale(); + if (old_w != Width || old_h != Height) { if (VideoDriver) VideoDriver->OnResize(core::dimension2d(Width, Height)); } + if (old_scale_x != ScaleX || old_scale_y != ScaleY) { + irrevent.EventType = EET_APPLICATION_EVENT; + irrevent.ApplicationEvent.EventType = EAET_DPI_CHANGED; + postEventFromUser(irrevent); + } break; } + break; case SDL_USEREVENT: irrevent.EventType = irr::EET_USER_EVENT; @@ -1030,25 +1050,26 @@ bool CIrrDeviceSDL::activateJoysticks(core::array &joystickInfo) return false; } +void CIrrDeviceSDL::updateSizeAndScale() +{ + int window_w, window_h; + SDL_GetWindowSize(Window, &window_w, &window_h); + + int drawable_w, drawable_h; + SDL_GL_GetDrawableSize(Window, &drawable_w, &drawable_h); + + ScaleX = (float)drawable_w / (float)window_w; + ScaleY = (float)drawable_h / (float)window_h; + + Width = drawable_w; + Height = drawable_h; +} + //! Get the display density in dots per inch. float CIrrDeviceSDL::getDisplayDensity() const { - if (!Window) - return 0.0f; - - int window_w; - int window_h; - SDL_GetWindowSize(Window, &window_w, &window_h); - - int drawable_w; - int drawable_h; - SDL_GL_GetDrawableSize(Window, &drawable_w, &drawable_h); - // assume 96 dpi - float dpi_w = (float)drawable_w / (float)window_w * 96.0f; - float dpi_h = (float)drawable_h / (float)window_h * 96.0f; - - return std::max(dpi_w, dpi_h); + return std::max(ScaleX * 96.0f, ScaleY * 96.0f); } void CIrrDeviceSDL::SwapWindow() diff --git a/irr/src/CIrrDeviceSDL.h b/irr/src/CIrrDeviceSDL.h index c536a8149..8c7c7c3e1 100644 --- a/irr/src/CIrrDeviceSDL.h +++ b/irr/src/CIrrDeviceSDL.h @@ -158,7 +158,8 @@ class CIrrDeviceSDL : public CIrrDeviceStub //! Sets the new position of the cursor. void setPosition(s32 x, s32 y) override { - SDL_WarpMouseInWindow(Device->Window, x, y); + SDL_WarpMouseInWindow(Device->Window, + x / Device->ScaleX, y / Device->ScaleY); if (SDL_GetRelativeMouseMode()) { // There won't be an event for this warp (details on libsdl-org/SDL/issues/6034) @@ -300,6 +301,8 @@ class CIrrDeviceSDL : public CIrrDeviceStub u32 MouseButtonStates; u32 Width, Height; + f32 ScaleX = 1.0f, ScaleY = 1.0f; + void updateSizeAndScale(); bool Resizable; diff --git a/irr/src/CMakeLists.txt b/irr/src/CMakeLists.txt index daff63bc2..d5e9d47e7 100644 --- a/irr/src/CMakeLists.txt +++ b/irr/src/CMakeLists.txt @@ -1,3 +1,5 @@ +# When enabling SDL2 by default on macOS, don't forget to change +# "NSHighResolutionCapable" to true in "Info.plist". if(NOT APPLE) set(DEFAULT_SDL2 ON) endif() diff --git a/misc/minetest.exe.manifest b/misc/minetest.exe.manifest index ff5469250..1b8c3ba7b 100644 --- a/misc/minetest.exe.manifest +++ b/misc/minetest.exe.manifest @@ -10,7 +10,9 @@ + true + PerMonitorV2 UTF-8 SegmentHeap diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index 6379fc141..f64d02844 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -69,6 +69,7 @@ static void dump_start_data(const GameStartData &data) ClientLauncher::~ClientLauncher() { delete input; + g_settings->deregisterChangedCallback("dpi_change_notifier", setting_changed_callback, this); g_settings->deregisterChangedCallback("gui_scaling", setting_changed_callback, this); delete g_fontengine; @@ -129,6 +130,7 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args) guienv = m_rendering_engine->get_gui_env(); config_guienv(); + g_settings->registerChangedCallback("dpi_change_notifier", setting_changed_callback, this); g_settings->registerChangedCallback("gui_scaling", setting_changed_callback, this); g_fontengine = new FontEngine(guienv); diff --git a/src/client/fontengine.cpp b/src/client/fontengine.cpp index 0b1b0928e..e0174e011 100644 --- a/src/client/fontengine.cpp +++ b/src/client/fontengine.cpp @@ -59,7 +59,7 @@ FontEngine::FontEngine(gui::IGUIEnvironment* env) : "mono_font_path", "mono_font_path_bold", "mono_font_path_italic", "mono_font_path_bold_italic", "fallback_font_path", - "screen_dpi", "gui_scaling", + "dpi_change_notifier", "gui_scaling", }; for (auto name : settings) diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 637a2f500..c5e71b853 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -60,6 +60,7 @@ Hud::Hud(Client *client, LocalPlayer *player, this->inventory = inventory; readScalingSetting(); + g_settings->registerChangedCallback("dpi_change_notifier", setting_changed_callback, this); g_settings->registerChangedCallback("hud_scaling", setting_changed_callback, this); for (auto &hbar_color : hbar_colors) @@ -153,6 +154,7 @@ void Hud::readScalingSetting() Hud::~Hud() { + g_settings->deregisterChangedCallback("dpi_change_notifier", setting_changed_callback, this); g_settings->deregisterChangedCallback("hud_scaling", setting_changed_callback, this); if (m_selection_mesh) diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index a30c818a7..4233916c2 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -113,6 +113,15 @@ bool MyEventReceiver::OnEvent(const SEvent &event) return true; } + if (event.EventType == EET_APPLICATION_EVENT && + event.ApplicationEvent.EventType == EAET_DPI_CHANGED) { + // This is a fake setting so that we can use (de)registerChangedCallback + // not only to listen for gui/hud_scaling changes, but also for DPI changes. + g_settings->setU16("dpi_change_notifier", + g_settings->getU16("dpi_change_notifier") + 1); + return true; + } + // This is separate from other keyboard handling so that it also works in menus. if (event.EventType == EET_KEY_INPUT_EVENT) { const KeyPress keyCode(event.KeyInput); diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp index e7ba333d2..18b9ff158 100644 --- a/src/client/renderingengine.cpp +++ b/src/client/renderingengine.cpp @@ -462,18 +462,14 @@ const VideoDriverInfo &RenderingEngine::getVideoDriverInfo(irr::video::E_DRIVER_ float RenderingEngine::getDisplayDensity() { + float user_factor = g_settings->getFloat("display_density_factor", 0.5f, 5.0f); #ifndef __ANDROID__ - static float cached_display_density = [&] { - float dpi = get_raw_device()->getDisplayDensity(); - // fall back to manually specified dpi - if (dpi == 0.0f) - dpi = g_settings->getFloat("screen_dpi"); - return dpi / 96.0f; - }(); - return std::max(cached_display_density * g_settings->getFloat("display_density_factor"), 0.5f); - + float dpi = get_raw_device()->getDisplayDensity(); + if (dpi == 0.0f) + dpi = 96.0f; + return std::max(dpi / 96.0f * user_factor, 0.5f); #else // __ANDROID__ - return porting::getDisplayDensity(); + return porting::getDisplayDensity() * user_factor; #endif // __ANDROID__ } diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index f16c56db4..1bb4dbe97 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -536,8 +536,8 @@ void set_default_settings() settings->setDefault("server_description", ""); settings->setDefault("enable_console", "false"); - settings->setDefault("screen_dpi", "72"); settings->setDefault("display_density_factor", "1"); + settings->setDefault("dpi_change_notifier", "0"); // Altered settings for macOS #if defined(__MACH__) && defined(__APPLE__) From d7f4ce6cff814cb93ca3d3ab4e0902e54cb4d932 Mon Sep 17 00:00:00 2001 From: grorp Date: Sun, 16 Jun 2024 17:50:02 +0200 Subject: [PATCH 3/5] Fix broken default sneak keybind on macOS with SDL (#14754) --- src/cmake_config.h.in | 1 + src/defaultsettings.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in index 2185600af..a8eb53edd 100644 --- a/src/cmake_config.h.in +++ b/src/cmake_config.h.in @@ -40,3 +40,4 @@ #cmakedefine01 CURSES_HAVE_NCURSESW_CURSES_H #cmakedefine01 BUILD_UNITTESTS #cmakedefine01 BUILD_BENCHMARKS +#cmakedefine01 USE_SDL2 diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 1bb4dbe97..13b323960 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -539,8 +539,8 @@ void set_default_settings() settings->setDefault("display_density_factor", "1"); settings->setDefault("dpi_change_notifier", "0"); - // Altered settings for macOS -#if defined(__MACH__) && defined(__APPLE__) + // Altered settings for CIrrDeviceOSX +#if !USE_SDL2 && defined(__MACH__) && defined(__APPLE__) settings->setDefault("keymap_sneak", "KEY_SHIFT"); #endif From fac9aac82129edd5d77c3aca3e9e6bbf39cc3220 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 17 Jun 2024 15:59:35 +0200 Subject: [PATCH 4/5] Move malloc_trim invocations to background thread (#14744) --- src/client/mesh_generator_thread.cpp | 15 +++++++++------ src/emerge.cpp | 2 ++ src/porting.cpp | 13 ++++++++++--- src/porting.h | 11 +++++++++-- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/client/mesh_generator_thread.cpp b/src/client/mesh_generator_thread.cpp index 32a01205d..21656aa6e 100644 --- a/src/client/mesh_generator_thread.cpp +++ b/src/client/mesh_generator_thread.cpp @@ -24,18 +24,20 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock.h" #include "map.h" #include "util/directiontables.h" +#include "porting.h" -static class BlockPlaceholder { -public: - MapNode data[MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE]; +// Data placeholder used for copying from non-existent blocks +static struct BlockPlaceholder { + MapNode data[MapBlock::nodecount]; BlockPlaceholder() { - for (std::size_t i = 0; i < MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE; i++) + for (std::size_t i = 0; i < MapBlock::nodecount; i++) data[i] = MapNode(CONTENT_IGNORE); } } block_placeholder; + /* QueuedMeshUpdate */ @@ -225,12 +227,13 @@ void MeshUpdateWorkerThread::doUpdate() while ((q = m_queue_in->pop())) { if (m_generation_interval) sleep_ms(m_generation_interval); + + porting::TriggerMemoryTrim(); + ScopeProfiler sp(g_profiler, "Client: Mesh making (sum)"); MapBlockMesh *mesh_new = new MapBlockMesh(m_client, q->data, *m_camera_offset); - - MeshUpdateResult r; r.p = q->p; r.mesh = mesh_new; diff --git a/src/emerge.cpp b/src/emerge.cpp index d6d6e630a..b53f298b3 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -662,6 +662,8 @@ void *EmergeThread::run() EmergeAction action; MapBlock *block = nullptr; + porting::TriggerMemoryTrim(); + if (!popBlockEmerge(&pos, &bedata)) { m_queue_event.wait(); continue; diff --git a/src/porting.cpp b/src/porting.cpp index 0763e92e1..a7601b101 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -920,22 +920,29 @@ double perf_freq = get_perf_freq(); * * As a workaround we track freed memory coarsely and call malloc_trim() once a * certain amount is reached. + * + * Because trimming can take more than 10ms and would cause jitter if done + * uncontrolled we have a separate function, which is called from background threads. */ static std::atomic memory_freed; -constexpr size_t MEMORY_TRIM_THRESHOLD = 128 * 1024 * 1024; +constexpr size_t MEMORY_TRIM_THRESHOLD = 256 * 1024 * 1024; void TrackFreedMemory(size_t amount) +{ + memory_freed.fetch_add(amount, std::memory_order_relaxed); +} + +void TriggerMemoryTrim() { constexpr auto MO = std::memory_order_relaxed; - memory_freed.fetch_add(amount, MO); if (memory_freed.load(MO) >= MEMORY_TRIM_THRESHOLD) { // Synchronize call if (memory_freed.exchange(0, MO) < MEMORY_TRIM_THRESHOLD) return; // Leave some headroom for future allocations - malloc_trim(1 * 1024 * 1024); + malloc_trim(8 * 1024 * 1024); } } diff --git a/src/porting.h b/src/porting.h index 27fabe7cd..b5e23c1f9 100644 --- a/src/porting.h +++ b/src/porting.h @@ -290,15 +290,22 @@ void osSpecificInit(); // This attaches to the parents process console, or creates a new one if it doesnt exist. void attachOrCreateConsole(); +#if HAVE_MALLOC_TRIM /** * Call this after freeing bigger blocks of memory. Used on some platforms to * properly give memory back to the OS. * @param amount Number of bytes freed */ -#if HAVE_MALLOC_TRIM void TrackFreedMemory(size_t amount); + +/** + * Call this regularly from background threads. This performs the actual trimming + * and is potentially slow. + */ +void TriggerMemoryTrim(); #else -inline void TrackFreedMemory(size_t amount) { (void)amount; } +static inline void TrackFreedMemory(size_t amount) { (void)amount; } +static inline void TriggerMemoryTrim() { (void)0; } #endif #ifdef _WIN32 From fe6da3a16bd2d284085d35e450f2896b460b252b Mon Sep 17 00:00:00 2001 From: l-koehler <134855488+l-koehler@users.noreply.github.com> Date: Mon, 17 Jun 2024 13:59:49 +0000 Subject: [PATCH 5/5] Disallow formspec debug if the player does not have the debug privilege (#14753) --- src/client/game.cpp | 4 ++++ src/gui/guiFormSpecMenu.cpp | 6 ++++-- src/gui/guiFormSpecMenu.h | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/client/game.cpp b/src/client/game.cpp index 2e27d6b0d..88892beb5 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1914,6 +1914,10 @@ void Game::updateDebugState() if (!has_debug) { draw_control->show_wireframe = false; m_flags.disable_camera_update = false; + auto formspec = m_game_ui->getFormspecGUI(); + if (formspec) { + formspec->setDebugView(false); + } } // noclip diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index ca9401091..98974c6f6 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -4184,8 +4184,10 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) m_client->makeScreenshot(); } - if (event.KeyInput.PressedDown && kp == getKeySetting("keymap_toggle_debug")) - m_show_debug = !m_show_debug; + if (event.KeyInput.PressedDown && kp == getKeySetting("keymap_toggle_debug")) { + if (!m_client || m_client->checkPrivilege("debug")) + m_show_debug = !m_show_debug; + } if (event.KeyInput.PressedDown && (event.KeyInput.Key==KEY_RETURN || diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h index 616971bc6..9ded4c7a8 100644 --- a/src/gui/guiFormSpecMenu.h +++ b/src/gui/guiFormSpecMenu.h @@ -223,6 +223,11 @@ class GUIFormSpecMenu : public GUIModalMenu m_allowclose = value; } + void setDebugView(bool value) + { + m_show_debug = value; + } + void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0)) { m_lock = lock;