From 73991e62ec70167172665285bc1e487fc01161e2 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 22 Oct 2024 11:20:55 +0200 Subject: [PATCH] nitpicker: clear capture buffer on policy change This patch resets the pixel buffer shared with the capture client whenever the capture policy is modified and reports the whole buffer as affected rectangle on the next client call of 'capture_at'. It also clips the dirty rectangles tracked via 'mark_as_dirty' against the bounding box of the capture session to avoid the interference of out-of-view parts of the panorama with a capture client. Fixes #5368 --- .../os/src/server/nitpicker/capture_session.h | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/repos/os/src/server/nitpicker/capture_session.h b/repos/os/src/server/nitpicker/capture_session.h index ea6cc6765e..722073fc90 100644 --- a/repos/os/src/server/nitpicker/capture_session.h +++ b/repos/os/src/server/nitpicker/capture_session.h @@ -98,6 +98,8 @@ class Nitpicker::Capture_session : public Session_object Policy _policy = Policy::blocked(); + bool _policy_changed = false; + Buffer_attr _buffer_attr { }; Constructible _buffer { }; @@ -164,7 +166,7 @@ class Nitpicker::Capture_session : public Session_object void mark_as_damaged(Rect rect) { - _dirty_rect.mark_as_dirty(rect); + _dirty_rect.mark_as_dirty(Rect::intersect(rect, bounding_box())); } void process_damage() { _wakeup_if_needed(); } @@ -175,7 +177,11 @@ class Nitpicker::Capture_session : public Session_object Signal_transmitter(_screen_size_sigh).submit(); } - void apply_policy(Policy const &policy) { _policy = policy; } + void apply_policy(Policy const &policy) + { + _policy = policy; + _policy_changed = true; + } void gen_capture_attr(Xml_generator &xml) const { @@ -252,8 +258,16 @@ class Nitpicker::Capture_session : public Session_object if (!_buffer.constructed()) return Affected_rects { }; + Point const anchor = _anchor_point() + pos; + Canvas canvas { _buffer->local_addr(), - _anchor_point() + pos, _buffer_attr.px }; + anchor, _buffer_attr.px }; + + if (_policy_changed) { + canvas.draw_box({ anchor, canvas.size() }, Color::rgb(0, 0, 0)); + _dirty_rect.mark_as_dirty({ anchor, canvas.size() }); + _policy_changed = false; + } canvas.clip(Rect::intersect(bounding_box(), _view_stack.bounding_box())); @@ -266,7 +280,7 @@ class Nitpicker::Capture_session : public Session_object _view_stack.draw(canvas, rect); if (i < Affected_rects::NUM_RECTS) { - Rect const translated(rect.p1() - _anchor_point() - pos, rect.area); + Rect const translated(rect.p1() - anchor, rect.area); Rect const clipped = Rect::intersect(translated, buffer_rect); affected.rects[i++] = clipped; }