From 2a0da78e080e575b50372e77f64682c18d4b28f5 Mon Sep 17 00:00:00 2001 From: El Date: Mon, 9 Feb 2026 11:19:20 +0000 Subject: [PATCH] VNC-151 Fix mode switch --- common/rfb/encoders/ScreenEncoderManager.cxx | 26 +++++++++++++------- common/rfb/encoders/ScreenEncoderManager.h | 1 + 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/common/rfb/encoders/ScreenEncoderManager.cxx b/common/rfb/encoders/ScreenEncoderManager.cxx index b612ba0..dcd870b 100644 --- a/common/rfb/encoders/ScreenEncoderManager.cxx +++ b/common/rfb/encoders/ScreenEncoderManager.cxx @@ -43,8 +43,7 @@ namespace rfb { template ScreenEncoderManager::~ScreenEncoderManager() { - for (uint8_t i = 0; i < get_screen_count(); ++i) - remove_screen(i); + clear_screens(); } template @@ -54,6 +53,7 @@ namespace rfb { available_encoders.clear(); dri_node = nullptr; screens_to_refresh.clear(); + clear_screens(); } template @@ -97,7 +97,6 @@ namespace rfb { screens[index] = {layout, encoder, true}; head = std::min(head, index); ++count; - rebuild_screens_to_refresh(); return true; } @@ -115,7 +114,6 @@ namespace rfb { mask &= ~(1 << index); --count; - rebuild_screens_to_refresh(); } screens[index] = {}; } @@ -134,6 +132,12 @@ namespace rfb { } } + template + void ScreenEncoderManager::clear_screens() { + for (uint8_t i = 0; i < get_screen_count(); ++i) + remove_screen(i); + } + template ScreenEncoderManager::stats_t ScreenEncoderManager::get_stats() const { return stats; @@ -143,6 +147,8 @@ namespace rfb { bool ScreenEncoderManager::sync_layout(const ScreenSet &layout, const Region ®ion) { const auto bounds = region.get_bounding_rect(); + const auto old_mask = mask; + for (uint8_t i = 0; i < static_cast(layout.num_screens()); ++i) { const auto &screen = layout.screens[i]; auto id = screen.id; @@ -155,13 +161,14 @@ namespace rfb { remove_screen(id); if (!add_screen(id, screen)) return false; - } - - if (screen.dimensions.overlaps(bounds)) { + } else if (screen.dimensions.overlaps(bounds)) { screens[id].dirty = true; } } + if (old_mask != mask || (mask > 0 && screens_to_refresh.empty())) + rebuild_screens_to_refresh(); + return true; } @@ -191,7 +198,7 @@ namespace rfb { return; } - const auto send_frame = [this, &bpp, out_conn, pb, &palette](const screen_t &screen) { + const auto send_frame = [this, &bpp, out_conn, pb, &palette](screen_t &screen) { ++stats.rects; const auto &rect = screen.layout.dimensions; const auto area = rect.area(); @@ -207,6 +214,8 @@ namespace rfb { encoder->writeRect(pb, palette); conn->writer()->endRect(); + screen.dirty = false; + const auto after = out_conn->length(); stats.bytes += after - before; }; @@ -223,7 +232,6 @@ namespace rfb { auto &screen = screens[index]; if (screen.dirty) { send_frame(screen); - screen.dirty = false; } } } else { diff --git a/common/rfb/encoders/ScreenEncoderManager.h b/common/rfb/encoders/ScreenEncoderManager.h index 1125e61..308d414 100644 --- a/common/rfb/encoders/ScreenEncoderManager.h +++ b/common/rfb/encoders/ScreenEncoderManager.h @@ -56,6 +56,7 @@ namespace rfb { [[nodiscard]] size_t get_screen_count() const; void remove_screen(uint8_t index); void rebuild_screens_to_refresh(); + void clear_screens(); public: struct stats_t {