mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 13:26:27 +00:00
capture_session: propagate physical size in mm
This patch adds the physical screen size as argument to the Capture::Session::buffer RPC function, which allows drivers to propagate DPI information to the GUI server. While changing the the interface, the patch replaces the former use of C++ exceptions by a result type. The 'Buffer_result' is handled transparently by the Capture::Connection. The client.h code is now integrated in connection.h. Issue #5344
This commit is contained in:
parent
6d79a44c46
commit
6d68d3297d
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 <capture_session/capture_session.h>
|
||||
#include <base/rpc_client.h>
|
||||
|
||||
namespace Capture { struct Session_client; }
|
||||
|
||||
|
||||
struct Capture::Session_client : public Genode::Rpc_client<Session>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_client(Capability<Session> session) : Rpc_client<Session>(session) { }
|
||||
|
||||
Area screen_size() const override { return call<Rpc_screen_size>(); }
|
||||
|
||||
void screen_size_sigh(Signal_context_capability sigh) override
|
||||
{
|
||||
call<Rpc_screen_size_sigh>(sigh);
|
||||
}
|
||||
|
||||
void buffer(Area size) override { call<Rpc_buffer>(size); }
|
||||
|
||||
Dataspace_capability dataspace() override { return call<Rpc_dataspace>(); }
|
||||
|
||||
Affected_rects capture_at(Point pos) override
|
||||
{
|
||||
return call<Rpc_capture_at>(pos);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__CAPTURE_SESSION__CLIENT_H_ */
|
@ -14,7 +14,7 @@
|
||||
#ifndef _INCLUDE__CAPTURE_SESSION__CONNECTION_H_
|
||||
#define _INCLUDE__CAPTURE_SESSION__CONNECTION_H_
|
||||
|
||||
#include <capture_session/client.h>
|
||||
#include <capture_session/capture_session.h>
|
||||
#include <base/connection.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <os/texture.h>
|
||||
@ -23,8 +23,7 @@
|
||||
namespace Capture { class Connection; }
|
||||
|
||||
|
||||
class Capture::Connection : public Genode::Connection<Session>,
|
||||
public Session_client
|
||||
class Capture::Connection : private Genode::Connection<Session>
|
||||
{
|
||||
private:
|
||||
|
||||
@ -32,19 +31,20 @@ class Capture::Connection : public Genode::Connection<Session>,
|
||||
|
||||
public:
|
||||
|
||||
using Label = Genode::Session_label;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Connection(Genode::Env &env, Label const &label = Label())
|
||||
:
|
||||
Genode::Connection<Capture::Session>(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>,
|
||||
_session_quota += upgrade;
|
||||
}
|
||||
|
||||
Session_client::buffer(size);
|
||||
for (;;) {
|
||||
using Result = Session::Buffer_result;
|
||||
switch (cap().call<Session::Rpc_buffer>(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<Session::Rpc_screen_size>(); }
|
||||
|
||||
void screen_size_sigh(Signal_context_capability sigh)
|
||||
{
|
||||
cap().call<Session::Rpc_screen_size_sigh>(sigh);
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability dataspace()
|
||||
{
|
||||
return cap().call<Session::Rpc_dataspace>();
|
||||
}
|
||||
|
||||
Session::Affected_rects capture_at(Point pos)
|
||||
{
|
||||
return cap().call<Session::Rpc_capture_at>(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<Pixel> const _texture { _ds.local_addr<Pixel>(), nullptr, size };
|
||||
Texture<Pixel> const _texture { _ds.local_addr<Pixel>(), 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<Pixel> &surface)
|
||||
{
|
||||
using Affected_rects = Session::Affected_rects;
|
||||
|
||||
Affected_rects const affected = _connection.capture_at(Capture::Point(0, 0));
|
||||
|
||||
with_texture([&] (Texture<Pixel> const &texture) {
|
||||
|
@ -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<Main> _timer_handler { _env.ep(), *this, &Main::_handle_timer };
|
||||
|
@ -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 = { } } };
|
||||
|
||||
|
||||
/*
|
||||
|
@ -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<Main> _timer_handler { _env.ep(), *this, &Main::_handle_timer };
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -67,14 +67,19 @@ class Capture::Session_component : public Session_object<Capture::Session>
|
||||
|
||||
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
|
||||
|
@ -44,7 +44,7 @@ class Nitpicker::Capture_session : public Session_object<Capture::Session>
|
||||
|
||||
View_stack const &_view_stack;
|
||||
|
||||
Area _buffer_size { };
|
||||
Buffer_attr _buffer_attr { };
|
||||
|
||||
Constructible<Attached_ram_dataspace> _buffer { };
|
||||
|
||||
@ -79,7 +79,7 @@ class Nitpicker::Capture_session : public Session_object<Capture::Session>
|
||||
** 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<Capture::Session>
|
||||
_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<Capture::Session>
|
||||
|
||||
using Pixel = Pixel_rgb888;
|
||||
|
||||
Canvas<Pixel> canvas = { _buffer->local_addr<Pixel>(), pos, _buffer_size };
|
||||
Canvas<Pixel> canvas = { _buffer->local_addr<Pixel>(), 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;
|
||||
|
@ -261,7 +261,9 @@ class Black_hole_test::Capture_test
|
||||
Capture::Area _screen_size { 1, 1 };
|
||||
Capture::Pixel _pixels[1];
|
||||
Surface<Capture::Pixel> _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:
|
||||
|
@ -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() };
|
||||
|
||||
|
@ -72,11 +72,17 @@ struct Test::Capture_session : Rpc_object<Capture::Session>
|
||||
|
||||
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
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user