From 2305b5004fb5d02e4c0d535025b059ab7562c83f Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 20 Jan 2025 16:51:00 +0100 Subject: [PATCH] Capture::Connection::Screen: use Blit::back2front Issue #5428 --- .../src/driver/framebuffer/vesa/main.cc | 6 ++- repos/libports/src/lib/qemu-usb/webcam.cc | 2 +- repos/os/include/capture_session/connection.h | 52 +++++++++++++------ repos/os/src/driver/framebuffer/boot/main.cc | 6 ++- repos/os/src/driver/framebuffer/pl11x/main.cc | 6 ++- repos/os/src/driver/framebuffer/ram/main.cc | 6 ++- repos/os/src/driver/framebuffer/sdl/main.cc | 6 ++- .../src/driver/framebuffer/virtio/component.h | 7 ++- repos/os/src/test/black_hole/main.cc | 6 ++- .../src/driver/framebuffer/intel/pc/main.cc | 6 ++- 10 files changed, 71 insertions(+), 32 deletions(-) diff --git a/repos/libports/src/driver/framebuffer/vesa/main.cc b/repos/libports/src/driver/framebuffer/vesa/main.cc index cc6bf700f0a..6f165555b91 100644 --- a/repos/libports/src/driver/framebuffer/vesa/main.cc +++ b/repos/libports/src/driver/framebuffer/vesa/main.cc @@ -153,8 +153,10 @@ void Vesa_driver::Main::_handle_config() using Attr = Capture::Connection::Screen::Attr; _captured_screen.construct(_capture, _env.rm(), Attr { - .px = _size, - .mm = { } }); + .px = _size, + .mm = { }, + .rotate = { }, + .flip = { } }); unsigned long const period_ms = config.attribute_value("period_ms", 20U); _timer.trigger_periodic(period_ms*1000); diff --git a/repos/libports/src/lib/qemu-usb/webcam.cc b/repos/libports/src/lib/qemu-usb/webcam.cc index a557e28cf3e..3d1b7eb5989 100644 --- a/repos/libports/src/lib/qemu-usb/webcam.cc +++ b/repos/libports/src/lib/qemu-usb/webcam.cc @@ -130,7 +130,7 @@ struct Capture_webcam /* construct/destruct capture connection and dataspace */ if (on) { _capture.construct(_env, "webcam"); - _capture->buffer({ .px = _area, .mm = { } }); + _capture->buffer({ .px = _area, .mm = { }, .rotate = { }, .flip = { } }); _ds.construct(_env.rm(), _capture->dataspace()); } else { _ds.destruct(); diff --git a/repos/os/include/capture_session/connection.h b/repos/os/include/capture_session/connection.h index f152057df02..2866feba45d 100644 --- a/repos/os/include/capture_session/connection.h +++ b/repos/os/include/capture_session/connection.h @@ -31,7 +31,18 @@ class Capture::Connection : private Genode::Connection public: - using Label = Genode::Session_label; + using Label = Genode::Session_label; + using Rotate = Blit::Rotate; + using Flip = Blit::Flip; + + static Rotate rotate_from_xml(Xml_node const &node) + { + unsigned const v = node.attribute_value("rotate", 0u); + return (v == 90) ? Rotate::R90 : + (v == 180) ? Rotate::R180 : + (v == 270) ? Rotate::R270 : + Rotate::R0; + } /** * Constructor @@ -98,8 +109,13 @@ class Capture::Connection::Screen struct Attr { - Area px; /* buffer area in pixels */ - Area mm; /* physical size in millimeters */ + Area px; /* buffer area in pixels */ + Area mm; /* physical size in millimeters */ + Rotate rotate; + Flip flip; + + Area padded_px() const { return { .w = align_addr(px.w, 4), + .h = align_addr(px.h, 4) }; } }; Attr const attr; @@ -113,7 +129,8 @@ class Capture::Connection::Screen Attached_dataspace _ds; - Texture const _texture { _ds.local_addr(), nullptr, attr.px }; + Texture const _texture { _ds.local_addr(), nullptr, + attr.padded_px() }; public: @@ -126,26 +143,31 @@ class Capture::Connection::Screen Rect apply_to_surface(Surface &surface) { - Rect bounding_box { }; + /* record information about pixels affected by 'back2front' */ + struct Flusher : Surface_base::Flusher + { + Rect bounding_box { }; + void flush_pixels(Rect rect) override + { + bounding_box = bounding_box.area.count() + ? Rect::compound(bounding_box, rect) + : rect; + }; + } flusher { }; + + surface.flusher(&flusher); using Affected_rects = Session::Affected_rects; Affected_rects const affected = _connection.capture_at(Capture::Point(0, 0)); with_texture([&] (Texture const &texture) { - affected.for_each_rect([&] (Capture::Rect const rect) { - - surface.clip(rect); - - Blit_painter::paint(surface, texture, Capture::Point(0, 0)); - - bounding_box = bounding_box.area.count() - ? Rect::compound(bounding_box, rect) - : rect; + Blit::back2front(surface, texture, rect, attr.rotate, attr.flip); }); }); - return bounding_box; + surface.flusher(nullptr); + return flusher.bounding_box; } }; diff --git a/repos/os/src/driver/framebuffer/boot/main.cc b/repos/os/src/driver/framebuffer/boot/main.cc index d257fd39f8f..1e579fba627 100644 --- a/repos/os/src/driver/framebuffer/boot/main.cc +++ b/repos/os/src/driver/framebuffer/boot/main.cc @@ -88,8 +88,10 @@ struct Framebuffer::Main Capture::Connection _capture { _env }; Capture::Connection::Screen _captured_screen { _capture, _env.rm(), { - .px = _info.size, - .mm = { } } }; + .px = _info.size, + .mm = { }, + .rotate = { }, + .flip = { } } }; Timer::Connection _timer { _env }; Signal_handler
_timer_handler { _env.ep(), *this, &Main::_handle_timer }; diff --git a/repos/os/src/driver/framebuffer/pl11x/main.cc b/repos/os/src/driver/framebuffer/pl11x/main.cc index 54611e4ccb2..555549463d0 100644 --- a/repos/os/src/driver/framebuffer/pl11x/main.cc +++ b/repos/os/src/driver/framebuffer/pl11x/main.cc @@ -60,8 +60,10 @@ struct Pl11x_driver::Main Capture::Connection _capture { _env }; Capture::Connection::Screen _captured_screen { _capture, _env.rm(), { - .px = _size, - .mm = { } } }; + .px = _size, + .mm = { }, + .rotate = { }, + .flip = { } } }; /* diff --git a/repos/os/src/driver/framebuffer/ram/main.cc b/repos/os/src/driver/framebuffer/ram/main.cc index 38d099c2a95..3a6fe88d455 100644 --- a/repos/os/src/driver/framebuffer/ram/main.cc +++ b/repos/os/src/driver/framebuffer/ram/main.cc @@ -66,8 +66,10 @@ class Main Capture::Area const _size { SCR_WIDTH, SCR_HEIGHT }; Capture::Connection _capture { _env }; Capture::Connection::Screen _captured_screen { _capture, _env.rm(), { - .px = _size, - .mm = { } } }; + .px = _size, + .mm = { }, + .rotate = { }, + .flip = { } } }; Timer::Connection _timer { _env }; Signal_handler
_timer_handler { _env.ep(), *this, &Main::_handle_timer }; diff --git a/repos/os/src/driver/framebuffer/sdl/main.cc b/repos/os/src/driver/framebuffer/sdl/main.cc index d88cf5c8f6d..4d6d496200d 100644 --- a/repos/os/src/driver/framebuffer/sdl/main.cc +++ b/repos/os/src/driver/framebuffer/sdl/main.cc @@ -270,8 +270,10 @@ struct Fb_sdl::Sdl : Noncopyable using Attr = Capture::Connection::Screen::Attr; _captured_screen.construct(_capture, _rm, Attr { - .px = size, - .mm = { } }); + .px = size, + .mm = { }, + .rotate = { }, + .flip = { }}); _update_screen_from_capture(); _schedule_next_frame(); diff --git a/repos/os/src/driver/framebuffer/virtio/component.h b/repos/os/src/driver/framebuffer/virtio/component.h index 1294c7daf23..121e501adb7 100644 --- a/repos/os/src/driver/framebuffer/virtio/component.h +++ b/repos/os/src/driver/framebuffer/virtio/component.h @@ -22,6 +22,7 @@ namespace Virtio_fb { using namespace Genode; class Driver; + using uint64_t = Genode::uint64_t; } /* @@ -357,8 +358,10 @@ class Virtio_fb::Driver using Attr = Capture::Connection::Screen::Attr; _captured_screen.construct(_capture, _env.rm(), Attr { - .px = _display_area, - .mm = { } }); + .px = _display_area, + .mm = { }, + .rotate = { }, + .flip = { } }); } void _shutdown_display() diff --git a/repos/os/src/test/black_hole/main.cc b/repos/os/src/test/black_hole/main.cc index 1a14e083ecb..4681d1db412 100644 --- a/repos/os/src/test/black_hole/main.cc +++ b/repos/os/src/test/black_hole/main.cc @@ -262,8 +262,10 @@ class Black_hole_test::Capture_test Capture::Pixel _pixels[1]; Surface _surface { _pixels, _screen_size }; Capture::Connection::Screen _screen { _connection, _env.rm(), - { .px = _screen_size, - .mm = { } } }; + { .px = _screen_size, + .mm = { }, + .rotate = { }, + .flip = { } } }; bool _finished { false }; public: diff --git a/repos/pc/src/driver/framebuffer/intel/pc/main.cc b/repos/pc/src/driver/framebuffer/intel/pc/main.cc index f0171074758..731de05576b 100644 --- a/repos/pc/src/driver/framebuffer/intel/pc/main.cc +++ b/repos/pc/src/driver/framebuffer/intel/pc/main.cc @@ -224,8 +224,10 @@ struct Framebuffer::Driver if (!conn.size.valid()) return same; - Capture::Connection::Screen::Attr attr = { .px = conn.size, - .mm = conn.size_mm }; + Capture::Connection::Screen::Attr attr = { .px = conn.size, + .mm = conn.size_mm, + .rotate = { }, + .flip = { } }; conn.capture.construct(env, label); conn.screen .construct(*conn.capture, env.rm(), attr);