genode/repos/os/src/server/nitpicker/session_component.h
Norman Feske 9d67f9fc8e Remove Allocator_guard
This patch removes old 'Allocator_guard' utility and replaces its use
with the modern 'Constrained_ram_allocator'.

The adjustment of core in this respect has the side effect of a more
accurate capability accounting in core's CPU, TRACE, and RM services.
In particular, the dataspace capabilities needed for core-internal
allocations via the 'Sliced_heap' are accounted to the client now.
The same goes for nitpicker and nic_dump as other former users of the
allocator guard. Hence, the patch also touches code at the client and
server sides related to these services.

The only remaining user of the 'Allocator_guard' is the Intel GPU
driver. As the adaptation of this component would be too invasive
without testing, this patch leaves this component unchanged by keeping a
copy of the 'allocator_guard.h' locally at the component.

Fixes #3750
2020-05-18 10:16:12 +02:00

406 lines
11 KiB
C++

/*
* \brief Nitpicker session component
* \author Norman Feske
* \date 2017-11-16
*/
/*
* Copyright (C) 2006-2017 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 _SESSION_COMPONENT_H_
#define _SESSION_COMPONENT_H_
/* Genode includes */
#include <util/list.h>
#include <base/session_object.h>
#include <base/heap.h>
#include <os/session_policy.h>
#include <os/reporter.h>
#include <os/pixel_rgb565.h>
#include <nitpicker_session/nitpicker_session.h>
/* local includes */
#include "canvas.h"
#include "domain_registry.h"
#include "framebuffer_session.h"
#include "input_session.h"
#include "focus.h"
#include "chunky_texture.h"
#include "view_component.h"
namespace Nitpicker {
class Visibility_controller;
class Session_component;
class View_component;
typedef List<Session_component> Session_list;
}
struct Nitpicker::Visibility_controller : Interface
{
typedef Session::Label Suffix;
virtual void hide_matching_sessions(Session_label const &, Suffix const &) = 0;
virtual void show_matching_sessions(Session_label const &, Suffix const &) = 0;
};
class Nitpicker::Session_component : public Session_object<Nitpicker::Session>,
public View_owner,
public Buffer_provider,
private Session_list::Element
{
private:
friend class List<Session_component>;
using Nitpicker::Session::Label;
/*
* Noncopyable
*/
Session_component(Session_component const &);
Session_component &operator = (Session_component const &);
Env &_env;
Constrained_ram_allocator _ram;
Domain_registry::Entry const *_domain = nullptr;
Texture_base const *_texture = nullptr;
View_component *_background = nullptr;
/*
* The input mask buffer containing a byte value per texture pixel,
* which describes the policy of handling user input referring to the
* pixel. If set to zero, the input is passed through the view such
* that it can be handled by one of the subsequent views in the view
* stack. If set to one, the input is consumed by the view. If
* 'input_mask' is a null pointer, user input is unconditionally
* consumed by the view.
*/
unsigned char const *_input_mask = nullptr;
bool _uses_alpha = false;
bool _visible = true;
Sliced_heap _session_alloc;
Framebuffer::Session &_framebuffer;
Framebuffer::Session_component _framebuffer_session_component;
bool const _input_session_accounted = (
withdraw(Ram_quota{Input::Session_component::ev_ds_size()}), true );
Input::Session_component _input_session_component { _env };
View_stack &_view_stack;
Font const &_font;
Focus_updater &_focus_updater;
Signal_context_capability _mode_sigh { };
View_component &_pointer_origin;
View_component &_builtin_background;
List<Session_view_list_elem> _view_list { };
Tslab<View_component, 4000> _view_alloc { &_session_alloc };
/* capabilities for sub sessions */
Framebuffer::Session_capability _framebuffer_session_cap;
Input::Session_capability _input_session_cap;
bool const _provides_default_bg;
/* size of currently allocated virtual framebuffer, in bytes */
size_t _buffer_size = 0;
Attached_ram_dataspace _command_ds { _env.ram(), _env.rm(),
sizeof(Command_buffer) };
bool const _command_buffer_accounted = (
withdraw(Ram_quota{align_addr(sizeof(Session::Command_buffer), 12)}), true );
Command_buffer &_command_buffer = *_command_ds.local_addr<Command_buffer>();
typedef Handle_registry<View_handle, View_component> View_handle_registry;
View_handle_registry _view_handle_registry;
Reporter &_focus_reporter;
Visibility_controller &_visibility_controller;
Session_component *_forwarded_focus = nullptr;
/**
* Calculate session-local coordinate to physical screen position
*
* \param pos coordinate in session-local coordinate system
* \param screen_area session-local screen size
*/
Point _phys_pos(Point pos, Area screen_area) const
{
return _domain ? _domain->phys_pos(pos, screen_area) : Point(0, 0);
}
void _release_buffer();
/**
* Helper for performing sanity checks in OP_TO_FRONT and OP_TO_BACK
*
* We have to check for the equality of both the specified view and
* neighbor. If both arguments refer to the same view, the creation of
* locked pointers for both views would result in a deadlock.
*/
bool _views_are_equal(View_handle, View_handle);
void _execute_command(Command const &);
void _destroy_view(View_component &);
public:
Session_component(Env &env,
Resources const &resources,
Label const &label,
Diag const &diag,
View_stack &view_stack,
Font const &font,
Focus_updater &focus_updater,
View_component &pointer_origin,
View_component &builtin_background,
Framebuffer::Session &framebuffer,
bool provides_default_bg,
Reporter &focus_reporter,
Visibility_controller &visibility_controller)
:
Session_object(env.ep(), resources, label, diag),
_env(env),
_ram(env.ram(), _ram_quota_guard(), _cap_quota_guard()),
_session_alloc(_ram, env.rm()),
_framebuffer(framebuffer),
_framebuffer_session_component(view_stack, *this, framebuffer, *this),
_view_stack(view_stack), _font(font), _focus_updater(focus_updater),
_pointer_origin(pointer_origin),
_builtin_background(builtin_background),
_framebuffer_session_cap(_env.ep().manage(_framebuffer_session_component)),
_input_session_cap(_env.ep().manage(_input_session_component)),
_provides_default_bg(provides_default_bg),
_view_handle_registry(_session_alloc),
_focus_reporter(focus_reporter),
_visibility_controller(visibility_controller)
{ }
~Session_component()
{
_env.ep().dissolve(_framebuffer_session_component);
_env.ep().dissolve(_input_session_component);
destroy_all_views();
_release_buffer();
}
using Session_list::Element::next;
/**************************
** View_owner interface **
**************************/
Session::Label label() const override { return _label; }
/**
* Return true if session label starts with specified 'selector'
*/
bool matches_session_label(Session::Label const &selector) const override
{
/*
* Append label separator to match selectors with a trailing
* separator.
*/
String<Session_label::capacity() + 4> const label(_label, " ->");
return strcmp(label.string(), selector.string(),
strlen(selector.string())) == 0;
}
bool visible() const override { return _visible; }
bool label_visible() const override
{
return !_domain || _domain->label_visible();
}
bool has_same_domain(View_owner const *owner) const override
{
if (!owner) return false;
return static_cast<Session_component const &>(*owner)._domain == _domain;
}
bool has_focusable_domain() const override
{
return _domain && (_domain->focus_click() || _domain->focus_transient());
}
bool has_transient_focusable_domain() const override
{
return _domain && _domain->focus_transient();
}
Color color() const override { return _domain ? _domain->color() : white(); }
bool content_client() const override { return _domain && _domain->content_client(); }
bool hover_always() const override { return _domain && _domain->hover_always(); }
View const *background() const override { return _background; }
Texture_base const *texture() const override { return _texture; }
bool uses_alpha() const override { return _texture && _uses_alpha; }
unsigned layer() const override { return _domain ? _domain->layer() : ~0UL; }
bool origin_pointer() const override { return _domain && _domain->origin_pointer(); }
/**
* Return input mask value at specified buffer position
*/
unsigned char input_mask_at(Point p) const override
{
if (!_input_mask || !_texture) return 0;
/* check boundaries */
if ((unsigned)p.x() >= _texture->size().w()
|| (unsigned)p.y() >= _texture->size().h())
return 0;
return _input_mask[p.y()*_texture->size().w() + p.x()];
}
void submit_input_event(Input::Event e) override;
void report(Xml_generator &xml) const override
{
xml.attribute("label", _label);
xml.attribute("color", String<32>(color()));
if (_domain)
xml.attribute("domain", _domain->name());
}
View_owner &forwarded_focus() override;
/****************************************
** Interface used by the main program **
****************************************/
/**
* Set the visibility of the views owned by the session
*/
void visible(bool visible) { _visible = visible; }
/**
* Return session-local screen area
*
* \param phys_pos size of physical screen
*/
Area screen_area(Area phys_area) const
{
return _domain ? _domain->screen_area(phys_area) : Area(0, 0);
}
void reset_domain() { _domain = nullptr; }
/**
* Set session domain according to the list of configured policies
*
* Select the policy that matches the label. If multiple policies
* match, select the one with the largest number of characters.
*/
void apply_session_policy(Xml_node config, Domain_registry const &);
void destroy_all_views();
/**
* Deliver mode-change signal to client
*/
void notify_mode_change()
{
if (_mode_sigh.valid())
Signal_transmitter(_mode_sigh).submit();
}
/**
* Deliver sync signal to the client's virtual frame buffer
*/
void submit_sync()
{
_framebuffer_session_component.submit_sync();
}
void forget(Session_component &session)
{
if (_forwarded_focus == &session)
_forwarded_focus = nullptr;
}
/*********************************
** Nitpicker session interface **
*********************************/
Framebuffer::Session_capability framebuffer_session() override {
return _framebuffer_session_cap; }
Input::Session_capability input_session() override {
return _input_session_cap; }
View_handle create_view(View_handle parent_handle) override;
void destroy_view(View_handle handle) override;
View_handle view_handle(View_capability view_cap, View_handle handle) override;
View_capability view_capability(View_handle handle) override;
void release_view_handle(View_handle handle) override;
Dataspace_capability command_dataspace() override { return _command_ds.cap(); }
void execute() override;
Framebuffer::Mode mode() override;
void mode_sigh(Signal_context_capability sigh) override { _mode_sigh = sigh; }
void buffer(Framebuffer::Mode mode, bool use_alpha) override;
void focus(Capability<Nitpicker::Session> session_cap) override;
void session_control(Label suffix, Session_control control) override;
/*******************************
** Buffer_provider interface **
*******************************/
Buffer *realloc_buffer(Framebuffer::Mode mode, bool use_alpha) override;
};
#endif /* _SESSION_COMPONENT_H_ */