mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-21 03:55:04 +00:00
parent
49e907e5f6
commit
3d1d1b439d
134
repos/os/include/capture_session/capture_session.h
Normal file
134
repos/os/include/capture_session/capture_session.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* \brief 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__CAPTURE_SESSION_H_
|
||||
#define _INCLUDE__CAPTURE_SESSION__CAPTURE_SESSION_H_
|
||||
|
||||
#include <base/signal.h>
|
||||
#include <session/session.h>
|
||||
#include <os/surface.h>
|
||||
#include <os/pixel_rgb888.h>
|
||||
#include <dataspace/capability.h>
|
||||
|
||||
namespace Capture {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Session_client;
|
||||
struct Session;
|
||||
|
||||
using Rect = Surface_base::Rect;
|
||||
using Point = Surface_base::Point;
|
||||
using Area = Surface_base::Area;
|
||||
using Pixel = Pixel_rgb888;
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct Capture::Session : Genode::Session
|
||||
{
|
||||
/**
|
||||
* \noapi
|
||||
*/
|
||||
static const char *service_name() { return "Capture"; }
|
||||
|
||||
/*
|
||||
* A capture session consumes a dataspace capability for the server's
|
||||
* session-object allocation, a session capability, and a dataspace
|
||||
* capability for the pixel buffer.
|
||||
*/
|
||||
enum { CAP_QUOTA = 3 };
|
||||
|
||||
/**
|
||||
* Return number of bytes needed for pixel buffer of specified size
|
||||
*/
|
||||
static size_t buffer_bytes(Area size)
|
||||
{
|
||||
size_t const bytes_per_pixel = 4;
|
||||
return bytes_per_pixel*size.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Request current screen size
|
||||
*/
|
||||
virtual Area screen_size() const = 0;
|
||||
|
||||
/**
|
||||
* Register signal handler to be notified whenever the screen size changes
|
||||
*/
|
||||
virtual void screen_size_sigh(Signal_context_capability) = 0;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
virtual void buffer(Area size) = 0;
|
||||
|
||||
/**
|
||||
* Request dataspace of the shared pixel buffer defined via 'buffer'
|
||||
*/
|
||||
virtual Dataspace_capability dataspace() = 0;
|
||||
|
||||
/**
|
||||
* Result type of 'capture_at'
|
||||
*
|
||||
* The geometry information are relative to the viewport specified for the
|
||||
* 'capture_at' call.
|
||||
*/
|
||||
struct Affected_rects
|
||||
{
|
||||
enum { NUM_RECTS = 3U };
|
||||
|
||||
Rect rects[NUM_RECTS];
|
||||
|
||||
template <typename FN>
|
||||
void for_each_rect(FN const &fn) const
|
||||
{
|
||||
for (unsigned i = 0; i < NUM_RECTS; i++)
|
||||
if (rects[i].valid())
|
||||
fn(rects[i]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the pixel-buffer with content at the specified screen position
|
||||
*
|
||||
* \return geometry information about the content that changed since the
|
||||
* previous call of 'capture_at'
|
||||
*/
|
||||
virtual Affected_rects capture_at(Point) = 0;
|
||||
|
||||
|
||||
/*********************
|
||||
** RPC declaration **
|
||||
*********************/
|
||||
|
||||
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_dataspace, Dataspace_capability, dataspace);
|
||||
GENODE_RPC(Rpc_capture_at, Affected_rects, capture_at, Point);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_screen_size, Rpc_screen_size_sigh, Rpc_buffer,
|
||||
Rpc_dataspace, Rpc_capture_at);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__CAPTURE_SESSION__CAPTURE_SESSION_H_ */
|
47
repos/os/include/capture_session/client.h
Normal file
47
repos/os/include/capture_session/client.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* \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_ */
|
114
repos/os/include/capture_session/connection.h
Normal file
114
repos/os/include/capture_session/connection.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* \brief Connection to capture service
|
||||
* \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__CONNECTION_H_
|
||||
#define _INCLUDE__CAPTURE_SESSION__CONNECTION_H_
|
||||
|
||||
#include <capture_session/client.h>
|
||||
#include <base/connection.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <os/texture.h>
|
||||
#include <blit/painter.h>
|
||||
|
||||
namespace Capture { class Connection; }
|
||||
|
||||
|
||||
class Capture::Connection : public Genode::Connection<Session>,
|
||||
public Session_client
|
||||
{
|
||||
public:
|
||||
|
||||
enum { RAM_QUOTA = 36*1024UL };
|
||||
|
||||
private:
|
||||
|
||||
size_t _session_quota = 0;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Connection(Genode::Env &env, char const *label = "")
|
||||
:
|
||||
Genode::Connection<Capture::Session>(
|
||||
env, session(env.parent(),
|
||||
"ram_quota=%u, cap_quota=%u, label=\"%s\"",
|
||||
RAM_QUOTA, CAP_QUOTA, label)),
|
||||
Session_client(cap())
|
||||
{ }
|
||||
|
||||
void buffer(Area size) override
|
||||
{
|
||||
size_t const needed = buffer_bytes(size);
|
||||
size_t const upgrade = needed > _session_quota
|
||||
? needed - _session_quota
|
||||
: 0;
|
||||
if (upgrade > 0) {
|
||||
this->upgrade_ram(upgrade);
|
||||
_session_quota += upgrade;
|
||||
}
|
||||
|
||||
Session_client::buffer(size);
|
||||
}
|
||||
|
||||
struct Screen;
|
||||
};
|
||||
|
||||
|
||||
class Capture::Connection::Screen
|
||||
{
|
||||
public:
|
||||
|
||||
Area const size;
|
||||
|
||||
private:
|
||||
|
||||
Capture::Connection &_connection;
|
||||
|
||||
bool const _buffer_initialized = ( _connection.buffer(size), true );
|
||||
|
||||
Attached_dataspace _ds;
|
||||
|
||||
Texture<Pixel> const _texture { _ds.local_addr<Pixel>(), nullptr, size };
|
||||
|
||||
public:
|
||||
|
||||
Screen(Capture::Connection &connection, Region_map &rm, Area size)
|
||||
:
|
||||
size(size), _connection(connection), _ds(rm, _connection.dataspace())
|
||||
{ }
|
||||
|
||||
template <typename FN>
|
||||
void with_texture(FN const &fn) const
|
||||
{
|
||||
fn(_texture);
|
||||
}
|
||||
|
||||
void apply_to_surface(Surface<Pixel> &surface)
|
||||
{
|
||||
Affected_rects const affected = _connection.capture_at(Capture::Point(0, 0));
|
||||
|
||||
with_texture([&] (Texture<Pixel> const &texture) {
|
||||
|
||||
affected.for_each_rect([&] (Capture::Rect const rect) {
|
||||
|
||||
surface.clip(rect);
|
||||
|
||||
Blit_painter::paint(surface, texture, Capture::Point(0, 0));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__CAPTURE_SESSION__CONNECTION_H_ */
|
2
repos/os/recipes/api/capture_session/content.mk
Normal file
2
repos/os/recipes/api/capture_session/content.mk
Normal file
@ -0,0 +1,2 @@
|
||||
MIRRORED_FROM_REP_DIR := include/capture_session
|
||||
include $(REP_DIR)/recipes/api/session.inc
|
1
repos/os/recipes/api/capture_session/hash
Normal file
1
repos/os/recipes/api/capture_session/hash
Normal file
@ -0,0 +1 @@
|
||||
2020-07-01 0d69d596b5fa9020478a318eb6751f5f25aebedb
|
Loading…
Reference in New Issue
Block a user