diff --git a/repos/libports/src/driver/framebuffer/vesa/main.cc b/repos/libports/src/driver/framebuffer/vesa/main.cc index e4dabc3f1a..cc6bf700f0 100644 --- a/repos/libports/src/driver/framebuffer/vesa/main.cc +++ b/repos/libports/src/driver/framebuffer/vesa/main.cc @@ -150,7 +150,11 @@ void Vesa_driver::Main::_handle_config() /* enable pixel capturing */ _fb_ds.construct(_env.rm(), Framebuffer::hw_framebuffer()); - _captured_screen.construct(_capture, _env.rm(), _size); + + using Attr = Capture::Connection::Screen::Attr; + _captured_screen.construct(_capture, _env.rm(), Attr { + .px = _size, + .mm = { } }); 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 8e07b37b7c..a557e28cf3 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(_area); + _capture->buffer({ .px = _area, .mm = { } }); _ds.construct(_env.rm(), _capture->dataspace()); } else { _ds.destruct(); diff --git a/repos/os/include/capture_session/capture_session.h b/repos/os/include/capture_session/capture_session.h index dc1fe698ea..79d309e957 100644 --- a/repos/os/include/capture_session/capture_session.h +++ b/repos/os/include/capture_session/capture_session.h @@ -68,18 +68,21 @@ struct Capture::Session : Genode::Session */ virtual void screen_size_sigh(Signal_context_capability) = 0; + enum class Buffer_result { OK, OUT_OF_RAM, OUT_OF_CAPS }; + + struct Buffer_attr + { + Area px; /* buffer area in pixels */ + Area mm; /* physical size in millimeters */ + }; + /** * Define dimensions of the shared pixel buffer * * The 'size' controls the server-side allocation of the shared pixel - * buffer and may affect the screen size of the GUI server. The screen - * size is bounding box of the pixel buffers of all capture clients. - * - * \throw Out_of_ram session quota does not suffice for specified - * buffer dimensions - * \throw Out_of_caps + * buffer and may affect the screen size of the GUI server. */ - virtual void buffer(Area size) = 0; + virtual Buffer_result buffer(Buffer_attr) = 0; /** * Request dataspace of the shared pixel buffer defined via 'buffer' @@ -121,8 +124,7 @@ struct Capture::Session : Genode::Session GENODE_RPC(Rpc_screen_size, Area, screen_size); GENODE_RPC(Rpc_screen_size_sigh, void, screen_size_sigh, Signal_context_capability); - GENODE_RPC_THROW(Rpc_buffer, void, buffer, - GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), Area); + GENODE_RPC(Rpc_buffer, Buffer_result, buffer, Buffer_attr); GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace); GENODE_RPC(Rpc_capture_at, Affected_rects, capture_at, Point); diff --git a/repos/os/include/capture_session/client.h b/repos/os/include/capture_session/client.h deleted file mode 100644 index bf032d8d9f..0000000000 --- a/repos/os/include/capture_session/client.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * \brief Client-side capture session interface - * \author Norman Feske - * \date 2020-06-26 - */ - -/* - * Copyright (C) 2020 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _INCLUDE__CAPTURE_SESSION__CLIENT_H_ -#define _INCLUDE__CAPTURE_SESSION__CLIENT_H_ - -#include -#include - -namespace Capture { struct Session_client; } - - -struct Capture::Session_client : public Genode::Rpc_client -{ - /** - * Constructor - */ - Session_client(Capability session) : Rpc_client(session) { } - - Area screen_size() const override { return call(); } - - void screen_size_sigh(Signal_context_capability sigh) override - { - call(sigh); - } - - void buffer(Area size) override { call(size); } - - Dataspace_capability dataspace() override { return call(); } - - Affected_rects capture_at(Point pos) override - { - return call(pos); - } -}; - -#endif /* _INCLUDE__CAPTURE_SESSION__CLIENT_H_ */ diff --git a/repos/os/include/capture_session/connection.h b/repos/os/include/capture_session/connection.h index 35393a7737..2ae0463fb7 100644 --- a/repos/os/include/capture_session/connection.h +++ b/repos/os/include/capture_session/connection.h @@ -14,7 +14,7 @@ #ifndef _INCLUDE__CAPTURE_SESSION__CONNECTION_H_ #define _INCLUDE__CAPTURE_SESSION__CONNECTION_H_ -#include +#include #include #include #include @@ -23,8 +23,7 @@ namespace Capture { class Connection; } -class Capture::Connection : public Genode::Connection, - public Session_client +class Capture::Connection : private Genode::Connection { private: @@ -32,19 +31,20 @@ class Capture::Connection : public Genode::Connection, public: + using Label = Genode::Session_label; + /** * Constructor */ Connection(Genode::Env &env, Label const &label = Label()) : Genode::Connection(env, label, - Ram_quota { 36*1024 }, Args()), - Session_client(cap()) + Ram_quota { 36*1024 }, Args()) { } - void buffer(Area size) override + void buffer(Session::Buffer_attr attr) { - size_t const needed = buffer_bytes(size); + size_t const needed = Session::buffer_bytes(attr.px); size_t const upgrade = needed > _session_quota ? needed - _session_quota : 0; @@ -53,10 +53,35 @@ class Capture::Connection : public Genode::Connection, _session_quota += upgrade; } - Session_client::buffer(size); + for (;;) { + using Result = Session::Buffer_result; + switch (cap().call(attr)) { + case Result::OUT_OF_RAM: upgrade_ram(8*1024); break; + case Result::OUT_OF_CAPS: upgrade_caps(2); break; + case Result::OK: + return; + } + } } struct Screen; + + Area screen_size() const { return cap().call(); } + + void screen_size_sigh(Signal_context_capability sigh) + { + cap().call(sigh); + } + + Genode::Dataspace_capability dataspace() + { + return cap().call(); + } + + Session::Affected_rects capture_at(Point pos) + { + return cap().call(pos); + } }; @@ -64,29 +89,38 @@ class Capture::Connection::Screen { public: - Area const size; + struct Attr + { + Area px; /* buffer area in pixels */ + Area mm; /* physical size in millimeters */ + }; + + Attr const attr; private: Capture::Connection &_connection; - bool const _buffer_initialized = ( _connection.buffer(size), true ); + bool const _buffer_initialized = ( + _connection.buffer({ .px = attr.px, .mm = attr.mm }), true ); Attached_dataspace _ds; - Texture const _texture { _ds.local_addr(), nullptr, size }; + Texture const _texture { _ds.local_addr(), nullptr, attr.px }; public: - Screen(Capture::Connection &connection, Region_map &rm, Area size) + Screen(Capture::Connection &connection, Region_map &rm, Attr attr) : - size(size), _connection(connection), _ds(rm, _connection.dataspace()) + attr(attr), _connection(connection), _ds(rm, _connection.dataspace()) { } void with_texture(auto const &fn) const { fn(_texture); } void apply_to_surface(Surface &surface) { + using Affected_rects = Session::Affected_rects; + Affected_rects const affected = _connection.capture_at(Capture::Point(0, 0)); with_texture([&] (Texture const &texture) { diff --git a/repos/os/src/driver/framebuffer/boot/main.cc b/repos/os/src/driver/framebuffer/boot/main.cc index 02f3511e3b..d257fd39f8 100644 --- a/repos/os/src/driver/framebuffer/boot/main.cc +++ b/repos/os/src/driver/framebuffer/boot/main.cc @@ -87,8 +87,9 @@ struct Framebuffer::Main Capture::Connection _capture { _env }; - Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _info.size }; - + Capture::Connection::Screen _captured_screen { _capture, _env.rm(), { + .px = _info.size, + .mm = { } } }; 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 dd6bbfd349..54611e4ccb 100644 --- a/repos/os/src/driver/framebuffer/pl11x/main.cc +++ b/repos/os/src/driver/framebuffer/pl11x/main.cc @@ -59,7 +59,9 @@ struct Pl11x_driver::Main Capture::Connection _capture { _env }; - Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size }; + Capture::Connection::Screen _captured_screen { _capture, _env.rm(), { + .px = _size, + .mm = { } } }; /* diff --git a/repos/os/src/driver/framebuffer/ram/main.cc b/repos/os/src/driver/framebuffer/ram/main.cc index 8d4d0c2425..38d099c2a9 100644 --- a/repos/os/src/driver/framebuffer/ram/main.cc +++ b/repos/os/src/driver/framebuffer/ram/main.cc @@ -65,8 +65,9 @@ class Main Capture::Area const _size { SCR_WIDTH, SCR_HEIGHT }; Capture::Connection _capture { _env }; - Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size }; - + Capture::Connection::Screen _captured_screen { _capture, _env.rm(), { + .px = _size, + .mm = { } } }; 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 7376dcf44e..9f8450f2a7 100644 --- a/repos/os/src/driver/framebuffer/sdl/main.cc +++ b/repos/os/src/driver/framebuffer/sdl/main.cc @@ -223,7 +223,12 @@ struct Fb_sdl::Main void _resize(Area size) { _sdl_screen.construct(size, _sdl_window->renderer()); - _captured_screen.construct(_capture, _env.rm(), size); + + using Attr = Capture::Connection::Screen::Attr; + _captured_screen.construct(_capture, _env.rm(), Attr { + .px = size, + .mm = { } }); + _update_sdl_screen_from_capture(); } diff --git a/repos/os/src/driver/framebuffer/virtio/component.h b/repos/os/src/driver/framebuffer/virtio/component.h index 1ffd81c03b..1294c7daf2 100644 --- a/repos/os/src/driver/framebuffer/virtio/component.h +++ b/repos/os/src/driver/framebuffer/virtio/component.h @@ -355,7 +355,10 @@ class Virtio_fb::Driver throw Display_init_failed(); } - _captured_screen.construct(_capture, _env.rm(), _display_area); + using Attr = Capture::Connection::Screen::Attr; + _captured_screen.construct(_capture, _env.rm(), Attr { + .px = _display_area, + .mm = { } }); } void _shutdown_display() diff --git a/repos/os/src/lib/vfs/capture/plugin.cc b/repos/os/src/lib/vfs/capture/plugin.cc index f4bb061438..abe27cf2bd 100644 --- a/repos/os/src/lib/vfs/capture/plugin.cc +++ b/repos/os/src/lib/vfs/capture/plugin.cc @@ -121,7 +121,7 @@ class Vfs_capture::Data_file_system : public Single_file_system } catch (Genode::Service_denied) { return OPEN_ERR_UNACCESSIBLE; } - _capture->buffer(_capture_area); + _capture->buffer({ .px = _capture_area, .mm = { } }); _capture_ds.construct(_env.rm(), _capture->dataspace()); } diff --git a/repos/os/src/server/black_hole/capture.h b/repos/os/src/server/black_hole/capture.h index 601c9f6333..11c5cf7fc5 100644 --- a/repos/os/src/server/black_hole/capture.h +++ b/repos/os/src/server/black_hole/capture.h @@ -67,14 +67,19 @@ class Capture::Session_component : public Session_object void screen_size_sigh(Signal_context_capability) override { } - void buffer(Area size) override + Buffer_result buffer(Buffer_attr attr) override { - if (size.count() == 0) { + if (attr.px.count() == 0) { _buffer.destruct(); - return; + return Buffer_result::OK; } - _buffer.construct(_ram, _env.rm(), buffer_bytes(size)); + try { + _buffer.construct(_ram, _env.rm(), buffer_bytes(attr.px)); + } + catch (Out_of_ram) { return Buffer_result::OUT_OF_RAM; } + catch (Out_of_caps) { return Buffer_result::OUT_OF_CAPS; } + return Buffer_result::OK; } Dataspace_capability dataspace() override diff --git a/repos/os/src/server/nitpicker/capture_session.h b/repos/os/src/server/nitpicker/capture_session.h index 66490249c6..cab23f1ec0 100644 --- a/repos/os/src/server/nitpicker/capture_session.h +++ b/repos/os/src/server/nitpicker/capture_session.h @@ -44,7 +44,7 @@ class Nitpicker::Capture_session : public Session_object View_stack const &_view_stack; - Area _buffer_size { }; + Buffer_attr _buffer_attr { }; Constructible _buffer { }; @@ -79,7 +79,7 @@ class Nitpicker::Capture_session : public Session_object ** Interface used by 'Nitpicker::Main' ** *****************************************/ - Area buffer_size() const { return _buffer_size; } + Area buffer_size() const { return _buffer_attr.px; } void mark_as_damaged(Rect rect) { @@ -104,23 +104,26 @@ class Nitpicker::Capture_session : public Session_object _screen_size_sigh = sigh; } - void buffer(Area size) override + Buffer_result buffer(Buffer_attr const attr) override { - _buffer_size = Area { }; + Buffer_result result = Buffer_result::OK; - if (size.count() == 0) { + _buffer_attr = { }; + + if (attr.px.count() == 0) { _buffer.destruct(); - return; + return result; } try { - _buffer.construct(_ram, _env.rm(), buffer_bytes(size)); - _buffer_size = size; - _handler.capture_buffer_size_changed(); - } catch (...) { - _handler.capture_buffer_size_changed(); - throw; + _buffer.construct(_ram, _env.rm(), buffer_bytes(attr.px)); + _buffer_attr = attr; } + catch (Out_of_ram) { result = Buffer_result::OUT_OF_RAM; } + catch (Out_of_caps) { result = Buffer_result::OUT_OF_CAPS; } + + _handler.capture_buffer_size_changed(); + return result; } Dataspace_capability dataspace() override @@ -138,9 +141,9 @@ class Nitpicker::Capture_session : public Session_object using Pixel = Pixel_rgb888; - Canvas canvas = { _buffer->local_addr(), pos, _buffer_size }; + Canvas canvas = { _buffer->local_addr(), pos, _buffer_attr.px }; - Rect const buffer_rect(Point(0, 0), _buffer_size); + Rect const buffer_rect(Point(0, 0), _buffer_attr.px); Affected_rects affected { }; unsigned i = 0; diff --git a/repos/os/src/test/black_hole/main.cc b/repos/os/src/test/black_hole/main.cc index 7aff1e7afb..1a14e083ec 100644 --- a/repos/os/src/test/black_hole/main.cc +++ b/repos/os/src/test/black_hole/main.cc @@ -261,7 +261,9 @@ class Black_hole_test::Capture_test Capture::Area _screen_size { 1, 1 }; Capture::Pixel _pixels[1]; Surface _surface { _pixels, _screen_size }; - Capture::Connection::Screen _screen { _connection, _env.rm(), _screen_size }; + Capture::Connection::Screen _screen { _connection, _env.rm(), + { .px = _screen_size, + .mm = { } } }; bool _finished { false }; public: diff --git a/repos/os/src/test/capture/main.cc b/repos/os/src/test/capture/main.cc index 915e248168..347b13a6b2 100644 --- a/repos/os/src/test/capture/main.cc +++ b/repos/os/src/test/capture/main.cc @@ -113,7 +113,7 @@ struct Test::Main Capture::Connection _capture { _env, "" }; - bool _capture_buffer_init = ( _capture.buffer(_area), true ); + bool _capture_buffer_init = ( _capture.buffer({ .px = _area, .mm = { }}), true ); Attached_dataspace _capture_ds { _env.rm(), _capture.dataspace() }; diff --git a/repos/os/src/test/framebuffer/main.cc b/repos/os/src/test/framebuffer/main.cc index f924dd5585..628490395a 100644 --- a/repos/os/src/test/framebuffer/main.cc +++ b/repos/os/src/test/framebuffer/main.cc @@ -72,11 +72,17 @@ struct Test::Capture_session : Rpc_object void screen_size_sigh(Signal_context_capability) override { } - void buffer(Area size) override + Buffer_result buffer(Buffer_attr attr) override { - _ds.construct(_env.ram(), _env.rm(), buffer_bytes(size)); - _size = size; + try { + _ds.construct(_env.ram(), _env.rm(), buffer_bytes(attr.px)); + } + catch (Out_of_ram) { return Buffer_result::OUT_OF_RAM; } + catch (Out_of_caps) { return Buffer_result::OUT_OF_CAPS; } + + _size = attr.px; _draw(); + return Buffer_result::OK; } Dataspace_capability dataspace() override diff --git a/repos/pc/src/driver/framebuffer/intel/pc/main.cc b/repos/pc/src/driver/framebuffer/intel/pc/main.cc index aca7b0fbba..45a7364118 100644 --- a/repos/pc/src/driver/framebuffer/intel/pc/main.cc +++ b/repos/pc/src/driver/framebuffer/intel/pc/main.cc @@ -110,7 +110,7 @@ struct Framebuffer::Driver _capture(env), _size(size), _size_phys(size_phys), - _captured_screen(_capture, env.rm(), _size), + _captured_screen(_capture, env.rm(), { .px = _size, .mm = { } }), _base(base) {} bool same_setup(void * base, Capture::Area &size,