mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 06:57:51 +00:00
nit_fb: prevent enlarging mode when out of RAM
This patch adds a safety check to nit_fb to ensures that nit_fb never runs out of RAM. Should the available RAM not suffice for resizing the virtual framebuffer to a new mode, it keeps the current mode.
This commit is contained in:
parent
013eb506a8
commit
69ac68ca98
@ -27,6 +27,7 @@ namespace Nit_fb {
|
|||||||
using Genode::Static_root;
|
using Genode::Static_root;
|
||||||
using Genode::Signal_handler;
|
using Genode::Signal_handler;
|
||||||
using Genode::Xml_node;
|
using Genode::Xml_node;
|
||||||
|
using Genode::size_t;
|
||||||
|
|
||||||
typedef Genode::Surface_base::Point Point;
|
typedef Genode::Surface_base::Point Point;
|
||||||
typedef Genode::Surface_base::Area Area;
|
typedef Genode::Surface_base::Area Area;
|
||||||
@ -95,6 +96,8 @@ namespace Framebuffer { struct Session_component; }
|
|||||||
|
|
||||||
struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
||||||
{
|
{
|
||||||
|
Genode::Pd_session const &_pd;
|
||||||
|
|
||||||
Nitpicker::Connection &_nitpicker;
|
Nitpicker::Connection &_nitpicker;
|
||||||
|
|
||||||
Framebuffer::Session &_nit_fb = *_nitpicker.framebuffer();
|
Framebuffer::Session &_nit_fb = *_nitpicker.framebuffer();
|
||||||
@ -113,6 +116,14 @@ struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
|||||||
*/
|
*/
|
||||||
Framebuffer::Mode _next_mode;
|
Framebuffer::Mode _next_mode;
|
||||||
|
|
||||||
|
typedef Genode::size_t size_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of bytes used for backing the current virtual framebuffer at
|
||||||
|
* nitpicker.
|
||||||
|
*/
|
||||||
|
size_t _buffer_num_bytes = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mode that was returned to the client at the last call of
|
* Mode that was returned to the client at the last call of
|
||||||
* 'Framebuffer:mode'. The virtual framebuffer must correspond to this
|
* 'Framebuffer:mode'. The virtual framebuffer must correspond to this
|
||||||
@ -123,15 +134,27 @@ struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
|||||||
|
|
||||||
bool _dataspace_is_new = true;
|
bool _dataspace_is_new = true;
|
||||||
|
|
||||||
|
bool _ram_suffices_for_mode(Framebuffer::Mode mode) const
|
||||||
|
{
|
||||||
|
/* calculation in bytes */
|
||||||
|
size_t const used = _buffer_num_bytes,
|
||||||
|
needed = Nitpicker::Session::ram_quota(mode, false),
|
||||||
|
usable = _pd.avail_ram().value,
|
||||||
|
preserved = 64*1024;
|
||||||
|
|
||||||
|
return used + usable > needed + preserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Session_component(Nitpicker::Connection &nitpicker,
|
Session_component(Genode::Pd_session const &pd,
|
||||||
|
Nitpicker::Connection &nitpicker,
|
||||||
View_updater &view_updater,
|
View_updater &view_updater,
|
||||||
Framebuffer::Mode initial_mode)
|
Framebuffer::Mode initial_mode)
|
||||||
:
|
:
|
||||||
_nitpicker(nitpicker), _view_updater(view_updater),
|
_pd(pd), _nitpicker(nitpicker), _view_updater(view_updater),
|
||||||
_next_mode(initial_mode)
|
_next_mode(initial_mode)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -141,7 +164,14 @@ struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
|||||||
if (Nitpicker::Area(_next_mode.width(), _next_mode.height()) == size)
|
if (Nitpicker::Area(_next_mode.width(), _next_mode.height()) == size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_next_mode = Framebuffer::Mode(size.w(), size.h(), _next_mode.format());
|
Framebuffer::Mode const mode(size.w(), size.h(), _next_mode.format());
|
||||||
|
|
||||||
|
if (!_ram_suffices_for_mode(mode)) {
|
||||||
|
Genode::warning("insufficient RAM for mode ", mode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_next_mode = mode;
|
||||||
|
|
||||||
if (_mode_sigh.valid())
|
if (_mode_sigh.valid())
|
||||||
Genode::Signal_transmitter(_mode_sigh).submit();
|
Genode::Signal_transmitter(_mode_sigh).submit();
|
||||||
@ -161,6 +191,10 @@ struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
|||||||
{
|
{
|
||||||
_nitpicker.buffer(_active_mode, false);
|
_nitpicker.buffer(_active_mode, false);
|
||||||
|
|
||||||
|
_buffer_num_bytes =
|
||||||
|
Genode::max(_buffer_num_bytes,
|
||||||
|
Nitpicker::Session::ram_quota(_active_mode, false));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We defer the update of the view until the client calls refresh the
|
* We defer the update of the view until the client calls refresh the
|
||||||
* next time. This avoid showing the empty buffer as an intermediate
|
* next time. This avoid showing the empty buffer as an intermediate
|
||||||
@ -271,7 +305,7 @@ struct Nit_fb::Main : View_updater
|
|||||||
* Input and framebuffer sessions provided to our client
|
* Input and framebuffer sessions provided to our client
|
||||||
*/
|
*/
|
||||||
Input::Session_component input_session { env, env.ram() };
|
Input::Session_component input_session { env, env.ram() };
|
||||||
Framebuffer::Session_component fb_session { nitpicker, *this, _initial_mode() };
|
Framebuffer::Session_component fb_session { env.pd(), nitpicker, *this, _initial_mode() };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attach root interfaces to the entry point
|
* Attach root interfaces to the entry point
|
||||||
|
Loading…
Reference in New Issue
Block a user