mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
framebuffer_session: alpha as Mode attribute
Propagate the want of an alpha channel as attribute of Framebuffer::Mode instead of passing this property as a separate bool argument. This clears the way for adding useful accessors for pixel/alpha/input surfaces to the Mode type as a subsequent step. Issue #5351
This commit is contained in:
parent
336d481726
commit
e738162bde
@ -45,9 +45,7 @@ class Scout::Graphics_backend_impl : public Graphics_backend
|
||||
|
||||
Genode::Dataspace_capability _init_fb_ds(Area max_size)
|
||||
{
|
||||
Framebuffer::Mode const mode { .area = { max_size.w, max_size.h*2 }};
|
||||
|
||||
_gui.buffer(mode, false);
|
||||
_gui.buffer({ .area = { max_size.w, max_size.h*2 }, .alpha = false });
|
||||
|
||||
return _gui.framebuffer.dataspace();
|
||||
}
|
||||
|
@ -239,10 +239,10 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
||||
|
||||
public:
|
||||
|
||||
Session_component(Genode::Env &env, Window_content &window_content)
|
||||
Session_component(Env &env, Window_content &window_content)
|
||||
: _timer(env), _window_content(window_content) { }
|
||||
|
||||
Genode::Dataspace_capability dataspace() override
|
||||
Dataspace_capability dataspace() override
|
||||
{
|
||||
_window_content.realloc_framebuffer();
|
||||
return _window_content.fb_ds_cap();
|
||||
@ -250,13 +250,15 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
||||
|
||||
Mode mode() const override
|
||||
{
|
||||
return Mode { .area = _window_content.mode_size() };
|
||||
return { .area = _window_content.mode_size(), .alpha = false };
|
||||
}
|
||||
|
||||
void mode_sigh(Genode::Signal_context_capability sigh) override {
|
||||
_window_content.mode_sigh(sigh); }
|
||||
void mode_sigh(Signal_context_capability sigh) override
|
||||
{
|
||||
_window_content.mode_sigh(sigh);
|
||||
}
|
||||
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||
void sync_sigh(Signal_context_capability sigh) override
|
||||
{
|
||||
_timer.sigh(sigh);
|
||||
_timer.trigger_periodic(10*1000);
|
||||
|
@ -366,7 +366,7 @@ struct Nitlog::Main
|
||||
|
||||
void _init_gui_buffer()
|
||||
{
|
||||
_gui.buffer(Framebuffer::Mode { .area = { _win_w, _win_h } }, false);
|
||||
_gui.buffer({ .area = { _win_w, _win_h }, .alpha = false });
|
||||
}
|
||||
|
||||
bool const _gui_buffer_initialized = (_init_gui_buffer(), true);
|
||||
|
@ -45,8 +45,6 @@ struct Gui_buffer : Genode::Noncopyable
|
||||
|
||||
Framebuffer::Mode const mode;
|
||||
|
||||
bool const use_alpha;
|
||||
|
||||
Pixel_rgb888 const reset_color;
|
||||
|
||||
/**
|
||||
@ -58,7 +56,8 @@ struct Gui_buffer : Genode::Noncopyable
|
||||
* Setup virtual framebuffer, the upper part containing the front
|
||||
* buffer, the lower part containing the back buffer.
|
||||
*/
|
||||
gui.buffer({ .area = { mode.area.w, mode.area.h*2 } }, use_alpha);
|
||||
gui.buffer({ .area = { mode.area.w, mode.area.h*2 },
|
||||
.alpha = mode.alpha });
|
||||
|
||||
return gui.framebuffer.dataspace();
|
||||
}
|
||||
@ -66,8 +65,8 @@ struct Gui_buffer : Genode::Noncopyable
|
||||
Genode::Attached_dataspace _fb_ds { rm, _ds_cap(gui) };
|
||||
|
||||
size_t _pixel_num_bytes() const { return size().count()*sizeof(Pixel_rgb888); }
|
||||
size_t _alpha_num_bytes() const { return use_alpha ? size().count() : 0; }
|
||||
size_t _input_num_bytes() const { return use_alpha ? size().count() : 0; }
|
||||
size_t _alpha_num_bytes() const { return mode.alpha ? size().count() : 0; }
|
||||
size_t _input_num_bytes() const { return mode.alpha ? size().count() : 0; }
|
||||
|
||||
void _with_pixel_ptr(auto const &fn)
|
||||
{
|
||||
@ -78,7 +77,7 @@ struct Gui_buffer : Genode::Noncopyable
|
||||
|
||||
void _with_alpha_ptr(auto const &fn)
|
||||
{
|
||||
if (!use_alpha)
|
||||
if (!mode.alpha)
|
||||
return;
|
||||
|
||||
/* skip pixel front buffer, pixel back buffer, and alpha front buffer */
|
||||
@ -89,7 +88,7 @@ struct Gui_buffer : Genode::Noncopyable
|
||||
|
||||
void _with_input_ptr(auto const &fn)
|
||||
{
|
||||
if (!use_alpha)
|
||||
if (!mode.alpha)
|
||||
return;
|
||||
|
||||
/* skip pixel buffers, alpha buffers, and input front buffer */
|
||||
@ -120,8 +119,8 @@ struct Gui_buffer : Genode::Noncopyable
|
||||
:
|
||||
ram(ram), rm(rm), gui(gui),
|
||||
mode({ .area = { Genode::max(1U, size.w),
|
||||
Genode::max(1U, size.h) } }),
|
||||
use_alpha(alpha == Alpha::ALPHA),
|
||||
Genode::max(1U, size.h) },
|
||||
.alpha = (alpha == Alpha::ALPHA) }),
|
||||
reset_color(reset_color.r, reset_color.g, reset_color.b, reset_color.a)
|
||||
{
|
||||
reset_surface();
|
||||
|
@ -86,10 +86,9 @@ class Nano3d::Scene
|
||||
* visible view because it contains the visible buffer, the
|
||||
* front buffer, and the back buffer.
|
||||
*/
|
||||
bool const use_alpha = true;
|
||||
unsigned const height = size.h*NUM_BUFFERS;
|
||||
gui.buffer(Framebuffer::Mode { .area = { size.w, height } },
|
||||
use_alpha);
|
||||
gui.buffer({ .area = { .w = size.w,
|
||||
.h = size.h*NUM_BUFFERS },
|
||||
.alpha = true });
|
||||
|
||||
return gui.framebuffer;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ struct Backdrop::Main
|
||||
Dataspace_capability _ds_cap(Gui::Connection &gui)
|
||||
{
|
||||
/* setup virtual framebuffer mode */
|
||||
gui.buffer(mode, false);
|
||||
gui.buffer(mode);
|
||||
|
||||
return gui.framebuffer.dataspace();
|
||||
}
|
||||
@ -314,9 +314,11 @@ void Backdrop::Main::_handle_config()
|
||||
_config.update();
|
||||
|
||||
Framebuffer::Mode const phys_mode = _gui.mode();
|
||||
Framebuffer::Mode const
|
||||
mode { .area = { _config.xml().attribute_value("width", phys_mode.area.w),
|
||||
_config.xml().attribute_value("height", phys_mode.area.h) } };
|
||||
Framebuffer::Mode const mode {
|
||||
.area = { _config.xml().attribute_value("width", phys_mode.area.w),
|
||||
_config.xml().attribute_value("height", phys_mode.area.h) },
|
||||
.alpha = false
|
||||
};
|
||||
|
||||
_buffer.construct(_env, _gui, mode);
|
||||
|
||||
|
@ -66,9 +66,10 @@ struct Decorator::Main : Window_factory_base
|
||||
* whereas the lower part contains the back buffer targeted by
|
||||
* the Decorator::Canvas.
|
||||
*/
|
||||
Framebuffer::Mode _mode_doubled() const
|
||||
static Framebuffer::Mode _doubled(Framebuffer::Mode const mode)
|
||||
{
|
||||
return { { .w = mode.area.w, .h = mode.area.h*2 } };
|
||||
return { .area = { .w = mode.area.w, .h = mode.area.h*2 },
|
||||
.alpha = mode.alpha };
|
||||
}
|
||||
|
||||
Pixel_rgb888 *_canvas_pixels_ptr()
|
||||
@ -80,7 +81,7 @@ struct Decorator::Main : Window_factory_base
|
||||
:
|
||||
mode(gui.mode()),
|
||||
fb_ds(env.rm(),
|
||||
(gui.buffer(_mode_doubled(), false), gui.framebuffer.dataspace())),
|
||||
(gui.buffer(_doubled(mode)), gui.framebuffer.dataspace())),
|
||||
canvas(_canvas_pixels_ptr(), mode.area, env.ram(), env.rm())
|
||||
{ }
|
||||
};
|
||||
|
@ -151,8 +151,8 @@ struct Gui::Session_component : Rpc_object<Gui::Session>
|
||||
void mode_sigh(Signal_context_capability sigh) override {
|
||||
_gui_session.mode_sigh(sigh); }
|
||||
|
||||
Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override {
|
||||
return _gui_session.buffer(mode, use_alpha); }
|
||||
Buffer_result buffer(Framebuffer::Mode mode) override {
|
||||
return _gui_session.buffer(mode); }
|
||||
|
||||
void focus(Capability<Gui::Session> session) override {
|
||||
_gui_session.focus(session); }
|
||||
|
@ -300,17 +300,15 @@ class Decorator::Window : public Window_base, public Animator::Item
|
||||
|
||||
void _reallocate_gui_buffers()
|
||||
{
|
||||
bool const use_alpha = true;
|
||||
|
||||
Area const size_top_bottom = _visible_top_bottom_area(geometry().area);
|
||||
|
||||
if (size_top_bottom.w > _size_top_bottom.w
|
||||
|| size_top_bottom.h > _size_top_bottom.h
|
||||
|| !_buffer_top_bottom.constructed()) {
|
||||
|
||||
_gui_top_bottom.buffer(Framebuffer::Mode { .area = { size_top_bottom.w,
|
||||
size_top_bottom.h } },
|
||||
use_alpha);
|
||||
_gui_top_bottom.buffer({ .area = { size_top_bottom.w,
|
||||
size_top_bottom.h },
|
||||
.alpha = true });
|
||||
|
||||
_buffer_top_bottom.construct(_gui_top_bottom, size_top_bottom,
|
||||
_env.ram(), _env.rm());
|
||||
@ -324,9 +322,9 @@ class Decorator::Window : public Window_base, public Animator::Item
|
||||
|| size_left_right.h > _size_left_right.h
|
||||
|| !_buffer_left_right.constructed()) {
|
||||
|
||||
_gui_left_right.buffer(Framebuffer::Mode { .area = { size_left_right.w,
|
||||
size_left_right.h } },
|
||||
use_alpha);
|
||||
_gui_left_right.buffer({ .area = { size_left_right.w,
|
||||
size_left_right.h },
|
||||
.alpha = true });
|
||||
|
||||
_buffer_left_right.construct(_gui_left_right, size_left_right,
|
||||
_env.ram(), _env.rm());
|
||||
|
@ -156,8 +156,8 @@ struct Sandboxed_runtime::Gui_session : Session_object<Gui::Session>
|
||||
void mode_sigh(Signal_context_capability sigh) override {
|
||||
_gui_session.mode_sigh(sigh); }
|
||||
|
||||
Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override {
|
||||
return _gui_session.buffer(mode, use_alpha); }
|
||||
Buffer_result buffer(Framebuffer::Mode mode) override {
|
||||
return _gui_session.buffer(mode); }
|
||||
|
||||
void focus(Capability<Gui::Session> session) override {
|
||||
_gui_session.focus(session); }
|
||||
|
@ -43,6 +43,7 @@ namespace Gui_fader {
|
||||
using Rect = Genode::Surface_base::Rect;
|
||||
|
||||
using Genode::size_t;
|
||||
using Genode::uint8_t;
|
||||
using Genode::Xml_node;
|
||||
using Genode::Dataspace_capability;
|
||||
using Genode::Attached_ram_dataspace;
|
||||
@ -65,7 +66,6 @@ class Gui_fader::Src_buffer
|
||||
|
||||
using Pixel = Pixel_rgb888;
|
||||
|
||||
bool const _use_alpha;
|
||||
Attached_ram_dataspace _ds;
|
||||
Texture<Pixel> _texture;
|
||||
bool _warned_once = false;
|
||||
@ -84,27 +84,24 @@ class Gui_fader::Src_buffer
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Src_buffer(Genode::Env &env, Area size, bool use_alpha)
|
||||
Src_buffer(Genode::Env &env, Framebuffer::Mode mode)
|
||||
:
|
||||
_use_alpha(use_alpha),
|
||||
_ds(env.ram(), env.rm(), _needed_bytes(size)),
|
||||
_ds(env.ram(), env.rm(), _needed_bytes(mode.area)),
|
||||
_texture(_ds.local_addr<Pixel>(),
|
||||
_ds.local_addr<unsigned char>() + size.count()*sizeof(Pixel),
|
||||
size)
|
||||
mode.alpha ? _ds.local_addr<uint8_t>() + mode.area.count()*sizeof(Pixel)
|
||||
: nullptr,
|
||||
mode.area)
|
||||
{ }
|
||||
|
||||
Dataspace_capability dataspace() { return _ds.cap(); }
|
||||
|
||||
Texture<Pixel> const &texture() const { return _texture; }
|
||||
|
||||
bool use_alpha() const { return _use_alpha; }
|
||||
bool use_alpha() const { return _texture.alpha(); }
|
||||
|
||||
void blit(Rect from, Point to)
|
||||
{
|
||||
if (_use_alpha && !_warned_once) {
|
||||
if (_texture.alpha() && !_warned_once) {
|
||||
Genode::warning("Framebuffer::Session::blit does not support alpha blending");
|
||||
_warned_once = true;
|
||||
}
|
||||
@ -267,7 +264,8 @@ class Gui_fader::Framebuffer_session_component
|
||||
|
||||
Blit_result blit(Framebuffer::Blit_batch const &batch) override
|
||||
{
|
||||
Framebuffer::Mode const mode { .area = _src_buffer.texture().size() };
|
||||
Framebuffer::Mode const mode { .area = _src_buffer.texture().size(),
|
||||
.alpha = false };
|
||||
for (Framebuffer::Transfer const &transfer : batch.transfer) {
|
||||
if (transfer.valid(mode)) {
|
||||
_src_buffer.blit(transfer.from, transfer.to);
|
||||
@ -306,7 +304,8 @@ class Gui_fader::Gui_session_component
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
Reconstructible<Src_buffer> _src_buffer { _env, Area(1, 1), false };
|
||||
Reconstructible<Src_buffer> _src_buffer {
|
||||
_env, Framebuffer::Mode { .area = { 1, 1 }, .alpha = false } };
|
||||
|
||||
Gui::Connection _gui { _env };
|
||||
|
||||
@ -464,15 +463,13 @@ class Gui_fader::Gui_session_component
|
||||
_gui.mode_sigh(sigh);
|
||||
}
|
||||
|
||||
Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override
|
||||
Buffer_result buffer(Framebuffer::Mode mode) override
|
||||
{
|
||||
Area const size = mode.area;
|
||||
_src_buffer.construct(_env, mode);
|
||||
|
||||
_src_buffer.construct(_env, size, use_alpha);
|
||||
_gui.buffer({ .area = mode.area, .alpha = true });
|
||||
|
||||
_gui.buffer(mode, true);
|
||||
|
||||
_fb_session.dst_buffer(_gui.framebuffer.dataspace(), size);
|
||||
_fb_session.dst_buffer(_gui.framebuffer.dataspace(), mode.area);
|
||||
return Buffer_result::OK;
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ struct Terminal::Main : Character_consumer
|
||||
_gui.input.sigh(_input_handler);
|
||||
_gui.mode_sigh(_mode_change_handler);
|
||||
|
||||
_fb_mode = _gui.mode();
|
||||
_fb_mode = { .area = _gui.mode().area, .alpha = false };
|
||||
|
||||
/* apply initial size from config, if provided */
|
||||
_config.xml().with_optional_sub_node("initial", [&] (Xml_node const &initial) {
|
||||
@ -259,7 +259,7 @@ void Terminal::Main::_handle_config()
|
||||
/*
|
||||
* Adapt terminal to font or framebuffer mode changes
|
||||
*/
|
||||
_gui.buffer(_fb_mode, false);
|
||||
_gui.buffer(_fb_mode);
|
||||
|
||||
if (_fb_mode.area.count() > 0)
|
||||
_fb_ds.construct(_env.rm(), _gui.framebuffer.dataspace());
|
||||
|
@ -331,9 +331,9 @@ struct Wm::Decorator_gui_session : Session_object<Gui::Session>,
|
||||
_real_gui.session.mode_sigh(sigh);
|
||||
}
|
||||
|
||||
Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override
|
||||
Buffer_result buffer(Framebuffer::Mode mode) override
|
||||
{
|
||||
return _real_gui.session.buffer(mode, use_alpha);
|
||||
return _real_gui.session.buffer(mode);
|
||||
}
|
||||
|
||||
void focus(Capability<Gui::Session>) override { }
|
||||
|
@ -114,9 +114,9 @@ class Wm::Direct_gui_session : public Session_object<Gui::Session>
|
||||
_session.mode_sigh(sigh);
|
||||
}
|
||||
|
||||
Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override
|
||||
Buffer_result buffer(Framebuffer::Mode mode) override
|
||||
{
|
||||
return _session.buffer(mode, use_alpha);
|
||||
return _session.buffer(mode);
|
||||
}
|
||||
|
||||
void focus(Capability<Gui::Session> session) override
|
||||
|
@ -1170,7 +1170,8 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
|
||||
* mode
|
||||
*/
|
||||
if (_resize_requested)
|
||||
return Framebuffer::Mode { .area = _requested_size };
|
||||
return Framebuffer::Mode { .area = _requested_size,
|
||||
.alpha = real_mode.alpha };
|
||||
|
||||
/*
|
||||
* If the first top-level view has a defined size, use it
|
||||
@ -1178,7 +1179,8 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
|
||||
*/
|
||||
if (Top_level_view const *v = _top_level_views.first())
|
||||
if (v->size().valid())
|
||||
return Framebuffer::Mode { .area = v->size() };
|
||||
return Framebuffer::Mode { .area = v->size(),
|
||||
.alpha = real_mode.alpha};
|
||||
|
||||
/*
|
||||
* If top-level view has yet been defined, return the real mode.
|
||||
@ -1200,7 +1202,7 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
|
||||
v->resizeable(resizeable);
|
||||
}
|
||||
|
||||
Buffer_result buffer(Framebuffer::Mode mode, bool has_alpha) override
|
||||
Buffer_result buffer(Framebuffer::Mode mode) override
|
||||
{
|
||||
/*
|
||||
* We must not perform the 'buffer' operation on the connection
|
||||
@ -1211,9 +1213,9 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
|
||||
* wrapped GUI session. Otherwise, we would perform session
|
||||
* upgrades initiated by the wm client's buffer operation twice.
|
||||
*/
|
||||
_has_alpha = has_alpha;
|
||||
_has_alpha = mode.alpha;
|
||||
|
||||
Buffer_result const result = _real_gui.session.buffer(mode, has_alpha);
|
||||
Buffer_result const result = _real_gui.session.buffer(mode);
|
||||
|
||||
_window_registry.flush();
|
||||
return result;
|
||||
|
@ -107,7 +107,7 @@ struct Wm::Layouter_gui_session : Session_object<Gui::Session>
|
||||
_mode_sigh_gui.mode_sigh(sigh);
|
||||
}
|
||||
|
||||
Buffer_result buffer(Framebuffer::Mode, bool) override { return Buffer_result::OK; }
|
||||
Buffer_result buffer(Framebuffer::Mode) override { return Buffer_result::OK; }
|
||||
|
||||
void focus(Capability<Gui::Session>) override { }
|
||||
};
|
||||
|
@ -87,8 +87,6 @@ class Pdf_view
|
||||
|
||||
private:
|
||||
|
||||
enum { NO_ALPHA = false };
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
Gui::Connection _gui { _env };
|
||||
@ -118,8 +116,8 @@ class Pdf_view
|
||||
unsigned max_y = Genode::max(_nit_mode.area.h, _fb_mode.area.h);
|
||||
|
||||
if (max_x > _fb_mode.area.w || max_y > _fb_mode.area.h) {
|
||||
_fb_mode = Mode { .area = { max_x, max_y } };
|
||||
_gui.buffer(_fb_mode, NO_ALPHA);
|
||||
_fb_mode = Mode { .area = { max_x, max_y }, .alpha = false };
|
||||
_gui.buffer(_fb_mode);
|
||||
if (_fb_ds.constructed())
|
||||
_fb_ds.destruct();
|
||||
_fb_ds.construct(_env.rm(), _gui.framebuffer.dataspace());
|
||||
|
@ -61,7 +61,7 @@ class Viewer
|
||||
_env { env },
|
||||
_mode { mode }
|
||||
{
|
||||
_gui.buffer(mode, false);
|
||||
_gui.buffer(mode);
|
||||
|
||||
_fb_ds.construct(_env.rm(), _gui.framebuffer.dataspace());
|
||||
_framebuffer = _fb_ds->local_addr<uint8_t>();
|
||||
@ -275,10 +275,10 @@ class Main
|
||||
if (_webcam.constructed())
|
||||
_webcam.destruct();
|
||||
|
||||
Framebuffer::Mode mode { .area = { width, height }, .alpha = false };
|
||||
if (enabled) {
|
||||
try {
|
||||
_webcam.construct(_env, Framebuffer::Mode {
|
||||
.area = { width, height } }, frame_format, fps);
|
||||
_webcam.construct(_env, mode, frame_format, fps);
|
||||
} catch (...) { }
|
||||
}
|
||||
}
|
||||
|
@ -57,13 +57,13 @@ struct Window : Genode_egl_window
|
||||
|
||||
Window(Genode::Env &env, int w, int h)
|
||||
:
|
||||
env(env), mode { .area = Gui::Area(w, h) }
|
||||
env(env), mode { .area = Gui::Area(w, h), .alpha = false }
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
type = WINDOW;
|
||||
|
||||
gui.buffer(mode, false);
|
||||
gui.buffer(mode);
|
||||
|
||||
mode_change();
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ namespace Framebuffer {
|
||||
struct Mode
|
||||
{
|
||||
Area area;
|
||||
bool alpha;
|
||||
|
||||
size_t bytes_per_pixel() const { return 4; }
|
||||
|
||||
|
@ -59,8 +59,8 @@ struct Gui::Session_client : Rpc_client<Session>
|
||||
void mode_sigh(Signal_context_capability sigh) override {
|
||||
call<Rpc_mode_sigh>(sigh); }
|
||||
|
||||
[[nodiscard]] Buffer_result buffer(Framebuffer::Mode mode, bool alpha) override {
|
||||
return call<Rpc_buffer>(mode, alpha); }
|
||||
[[nodiscard]] Buffer_result buffer(Framebuffer::Mode mode) override {
|
||||
return call<Rpc_buffer>(mode); }
|
||||
|
||||
void focus(Gui::Session_capability session) override {
|
||||
call<Rpc_focus>(session); }
|
||||
|
@ -154,9 +154,9 @@ class Gui::Connection : private Genode::Connection<Session>
|
||||
}
|
||||
}
|
||||
|
||||
void buffer(Framebuffer::Mode mode, bool use_alpha)
|
||||
void buffer(Framebuffer::Mode mode)
|
||||
{
|
||||
size_t const needed = Session_client::ram_quota(mode, use_alpha);
|
||||
size_t const needed = Session_client::ram_quota(mode);
|
||||
size_t const upgrade = needed > _ram_quota.value
|
||||
? needed - _ram_quota.value : 0u;
|
||||
if (upgrade > 0) {
|
||||
@ -166,7 +166,7 @@ class Gui::Connection : private Genode::Connection<Session>
|
||||
|
||||
for (bool retry = false; ; ) {
|
||||
using Result = Session_client::Buffer_result;
|
||||
auto const result = _client.buffer(mode, use_alpha);
|
||||
auto const result = _client.buffer(mode);
|
||||
if (result == Result::OUT_OF_RAM) { upgrade_ram(8*1024); retry = true; }
|
||||
if (result == Result::OUT_OF_CAPS) { upgrade_caps(2); retry = true; }
|
||||
if (!retry)
|
||||
|
@ -248,7 +248,7 @@ struct Gui::Session : Genode::Session
|
||||
/**
|
||||
* Define dimensions of virtual framebuffer
|
||||
*/
|
||||
virtual Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) = 0;
|
||||
virtual Buffer_result buffer(Framebuffer::Mode mode) = 0;
|
||||
|
||||
/**
|
||||
* Set focused session
|
||||
@ -268,13 +268,13 @@ struct Gui::Session : Genode::Session
|
||||
/**
|
||||
* Return number of bytes needed for virtual framebuffer of specified size
|
||||
*/
|
||||
static size_t ram_quota(Framebuffer::Mode mode, bool use_alpha)
|
||||
static size_t ram_quota(Framebuffer::Mode mode)
|
||||
{
|
||||
/*
|
||||
* If alpha blending is used, each pixel requires an additional byte
|
||||
* for the alpha value and a byte holding the input mask.
|
||||
*/
|
||||
return (mode.bytes_per_pixel() + 2*use_alpha)*mode.area.count();
|
||||
return (mode.bytes_per_pixel() + 2*mode.alpha)*mode.area.count();
|
||||
}
|
||||
|
||||
|
||||
@ -296,7 +296,7 @@ struct Gui::Session : Genode::Session
|
||||
GENODE_RPC(Rpc_mode, Framebuffer::Mode, mode);
|
||||
GENODE_RPC(Rpc_mode_sigh, void, mode_sigh, Signal_context_capability);
|
||||
GENODE_RPC(Rpc_focus, void, focus, Capability<Session>);
|
||||
GENODE_RPC(Rpc_buffer, Buffer_result, buffer, Framebuffer::Mode, bool);
|
||||
GENODE_RPC(Rpc_buffer, Buffer_result, buffer, Framebuffer::Mode);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_framebuffer, Rpc_input,
|
||||
Rpc_view, Rpc_child_view, Rpc_destroy_view, Rpc_associate,
|
||||
|
@ -133,9 +133,7 @@ void Pointer::Main::_resize_gui_buffer_if_needed(Gui::Area pointer_size)
|
||||
if (pointer_size == _current_pointer_size)
|
||||
return;
|
||||
|
||||
Framebuffer::Mode const mode { .area = pointer_size };
|
||||
|
||||
_gui.buffer(mode, true /* use alpha */);
|
||||
_gui.buffer({ .area = pointer_size, .alpha = true });
|
||||
|
||||
_pointer_ds = _gui.framebuffer.dataspace();
|
||||
|
||||
@ -333,9 +331,9 @@ Pointer::Main::Main(Genode::Env &env) : _env(env)
|
||||
* pointer size to let the user know right from the start if the
|
||||
* RAM quota is too low.
|
||||
*/
|
||||
Framebuffer::Mode const mode { .area = { Pointer::MAX_WIDTH, Pointer::MAX_HEIGHT } };
|
||||
|
||||
_gui.buffer(mode, true /* use alpha */);
|
||||
_gui.buffer({ .area = { Pointer::MAX_WIDTH, Pointer::MAX_HEIGHT },
|
||||
.alpha = true });
|
||||
|
||||
if (_shapes_enabled) {
|
||||
try {
|
||||
|
@ -51,11 +51,12 @@ struct Status_bar::Buffer
|
||||
* The status bar is as wide as nitpicker's screen and has a fixed
|
||||
* height.
|
||||
*/
|
||||
Framebuffer::Mode const _mode { .area = { _nit_mode.area.w, HEIGHT } };
|
||||
Framebuffer::Mode const _mode { .area = { _nit_mode.area.w, HEIGHT },
|
||||
.alpha = false };
|
||||
|
||||
Dataspace_capability _init_buffer()
|
||||
{
|
||||
_gui.buffer(_mode, false);
|
||||
_gui.buffer(_mode);
|
||||
return _gui.framebuffer.dataspace();
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
||||
{
|
||||
/* calculation in bytes */
|
||||
size_t const used = _buffer_num_bytes,
|
||||
needed = Gui::Session::ram_quota(mode, false),
|
||||
needed = Gui::Session::ram_quota(mode),
|
||||
usable = _pd.avail_ram().value,
|
||||
preserved = 64*1024;
|
||||
|
||||
@ -157,7 +157,7 @@ struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
||||
if (Gui::Area(_next_mode.area.w, _next_mode.area.h) == size)
|
||||
return;
|
||||
|
||||
Framebuffer::Mode const mode { .area = size };
|
||||
Framebuffer::Mode const mode { .area = size, .alpha = false };
|
||||
|
||||
if (!_ram_suffices_for_mode(mode)) {
|
||||
warning("insufficient RAM for mode ", mode);
|
||||
@ -182,10 +182,10 @@ struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
||||
|
||||
Dataspace_capability dataspace() override
|
||||
{
|
||||
_gui.buffer(_active_mode, false);
|
||||
_gui.buffer(_active_mode);
|
||||
|
||||
_buffer_num_bytes =
|
||||
max(_buffer_num_bytes, Gui::Session::ram_quota(_active_mode, false));
|
||||
max(_buffer_num_bytes, Gui::Session::ram_quota(_active_mode));
|
||||
|
||||
/*
|
||||
* We defer the update of the view until the client calls refresh the
|
||||
@ -294,8 +294,11 @@ struct Gui_fb::Main : View_updater
|
||||
|
||||
Framebuffer::Mode _initial_mode()
|
||||
{
|
||||
return Framebuffer::Mode { .area = { _initial_size.width (_gui.mode()),
|
||||
_initial_size.height(_gui.mode()) } };
|
||||
return {
|
||||
.area = { _initial_size.width (_gui.mode()),
|
||||
_initial_size.height(_gui.mode()) },
|
||||
.alpha = false
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -61,11 +61,11 @@ namespace Nitpicker { struct Buffer_provider; }
|
||||
/**
|
||||
* Interface for triggering the re-allocation of a virtual framebuffer
|
||||
*
|
||||
* Used by 'Framebuffer::Session_component', * implemented by 'Gui_session'
|
||||
* Used by 'Framebuffer::Session_component', implemented by 'Gui_session'
|
||||
*/
|
||||
struct Nitpicker::Buffer_provider : Interface
|
||||
{
|
||||
virtual Dataspace_capability realloc_buffer(Framebuffer::Mode, bool use_alpha) = 0;
|
||||
virtual Dataspace_capability realloc_buffer(Framebuffer::Mode) = 0;
|
||||
|
||||
virtual void blit(Rect from, Point to) = 0;
|
||||
|
||||
|
@ -33,12 +33,13 @@ class Nitpicker::Chunky_texture : public Buffer, public Texture<PT>
|
||||
/**
|
||||
* Return base address of alpha channel or 0 if no alpha channel exists
|
||||
*/
|
||||
unsigned char *_alpha_base(Area size, bool use_alpha)
|
||||
unsigned char *_alpha_base(Framebuffer::Mode mode)
|
||||
{
|
||||
if (!use_alpha) return 0;
|
||||
if (!mode.alpha) return nullptr;
|
||||
|
||||
/* alpha values come right after the pixel values */
|
||||
return (unsigned char *)local_addr() + calc_num_bytes(size, false);
|
||||
return (unsigned char *)local_addr()
|
||||
+ calc_num_bytes({ .area = mode.area, .alpha = false });
|
||||
}
|
||||
|
||||
Area _area() const { return Texture<PT>::size(); }
|
||||
@ -104,13 +105,13 @@ class Nitpicker::Chunky_texture : public Buffer, public Texture<PT>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Chunky_texture(Ram_allocator &ram, Region_map &rm, Area size, bool use_alpha)
|
||||
Chunky_texture(Ram_allocator &ram, Region_map &rm, Framebuffer::Mode mode)
|
||||
:
|
||||
Buffer(ram, rm, size, calc_num_bytes(size, use_alpha)),
|
||||
Texture<PT>((PT *)local_addr(),
|
||||
_alpha_base(size, use_alpha), size) { }
|
||||
Buffer(ram, rm, mode.area, calc_num_bytes(mode)),
|
||||
Texture<PT>((PT *)local_addr(), _alpha_base(mode), mode.area)
|
||||
{ }
|
||||
|
||||
static size_t calc_num_bytes(Area size, bool use_alpha)
|
||||
static size_t calc_num_bytes(Framebuffer::Mode mode)
|
||||
{
|
||||
/*
|
||||
* If using an alpha channel, the alpha buffer follows the
|
||||
@ -118,19 +119,17 @@ class Nitpicker::Chunky_texture : public Buffer, public Texture<PT>
|
||||
* mask buffer. Hence, we have to account one byte per
|
||||
* alpha value and one byte for the input mask value.
|
||||
*/
|
||||
size_t bytes_per_pixel = sizeof(PT) + (use_alpha ? 2 : 0);
|
||||
return bytes_per_pixel*size.count();
|
||||
size_t bytes_per_pixel = sizeof(PT) + (mode.alpha ? 2 : 0);
|
||||
return bytes_per_pixel*mode.area.count();
|
||||
}
|
||||
|
||||
unsigned char const *input_mask_buffer() const
|
||||
uint8_t const *input_mask_buffer() const
|
||||
{
|
||||
if (!Texture<PT>::alpha()) return 0;
|
||||
|
||||
Area const size = Texture<PT>::size();
|
||||
|
||||
/* input-mask values come right after the alpha values */
|
||||
return (unsigned char const *)local_addr() + calc_num_bytes(size, false)
|
||||
+ size.count();
|
||||
Framebuffer::Mode const mode { .area = _area(), .alpha = false };
|
||||
return (uint8_t const *)local_addr() + calc_num_bytes(mode) + _area().count();
|
||||
}
|
||||
|
||||
void blit(Rect from, Point to)
|
||||
|
@ -45,7 +45,6 @@ class Framebuffer::Session_component : public Rpc_object<Session>
|
||||
Signal_context_capability _mode_sigh { };
|
||||
Signal_context_capability _sync_sigh { };
|
||||
Framebuffer::Mode _mode { };
|
||||
bool _alpha = false;
|
||||
|
||||
public:
|
||||
|
||||
@ -78,10 +77,9 @@ class Framebuffer::Session_component : public Rpc_object<Session>
|
||||
* client calls 'dataspace' the next time, the new mode becomes
|
||||
* effective.
|
||||
*/
|
||||
void notify_mode_change(Framebuffer::Mode mode, bool alpha)
|
||||
void notify_mode_change(Framebuffer::Mode mode)
|
||||
{
|
||||
_mode = mode;
|
||||
_alpha = alpha;
|
||||
_mode = mode;
|
||||
|
||||
if (_mode_sigh.valid())
|
||||
Signal_transmitter(_mode_sigh).submit();
|
||||
@ -100,7 +98,7 @@ class Framebuffer::Session_component : public Rpc_object<Session>
|
||||
|
||||
Dataspace_capability dataspace() override
|
||||
{
|
||||
return _buffer_provider.realloc_buffer(_mode, _alpha);
|
||||
return _buffer_provider.realloc_buffer(_mode);
|
||||
}
|
||||
|
||||
Mode mode() const override { return _mode; }
|
||||
|
@ -384,21 +384,22 @@ Framebuffer::Mode Gui_session::mode()
|
||||
* the special case of 0x0, which can happen at boot time before the
|
||||
* framebuffer driver is running.
|
||||
*/
|
||||
return { .area = { max(screen.w, 1u), max(screen.h, 1u) } };
|
||||
return { .area = { max(screen.w, 1u), max(screen.h, 1u) },
|
||||
.alpha = uses_alpha() };
|
||||
}
|
||||
|
||||
|
||||
Gui_session::Buffer_result Gui_session::buffer(Framebuffer::Mode mode, bool use_alpha)
|
||||
Gui_session::Buffer_result Gui_session::buffer(Framebuffer::Mode mode)
|
||||
{
|
||||
/* check if the session quota suffices for the specified mode */
|
||||
if (_buffer_size + _ram_quota_guard().avail().value < ram_quota(mode, use_alpha))
|
||||
if (_buffer_size + _ram_quota_guard().avail().value < ram_quota(mode))
|
||||
return Buffer_result::OUT_OF_RAM;
|
||||
|
||||
/* buffer re-allocation may consume new dataspace capability if buffer is new */
|
||||
if (_cap_quota_guard().avail().value < 1)
|
||||
throw Buffer_result::OUT_OF_CAPS;
|
||||
|
||||
_framebuffer_session_component.notify_mode_change(mode, use_alpha);
|
||||
_framebuffer_session_component.notify_mode_change(mode);
|
||||
return Buffer_result::OK;
|
||||
}
|
||||
|
||||
@ -418,9 +419,9 @@ void Gui_session::focus(Capability<Gui::Session> session_cap)
|
||||
}
|
||||
|
||||
|
||||
Dataspace_capability Gui_session::realloc_buffer(Framebuffer::Mode mode, bool use_alpha)
|
||||
Dataspace_capability Gui_session::realloc_buffer(Framebuffer::Mode mode)
|
||||
{
|
||||
Ram_quota const next_buffer_size { Chunky_texture<Pixel>::calc_num_bytes(mode.area, use_alpha) };
|
||||
Ram_quota const next_buffer_size { Chunky_texture<Pixel>::calc_num_bytes(mode) };
|
||||
Ram_quota const orig_buffer_size { _buffer_size };
|
||||
|
||||
/*
|
||||
@ -439,7 +440,6 @@ Dataspace_capability Gui_session::realloc_buffer(Framebuffer::Mode mode, bool us
|
||||
}
|
||||
|
||||
_buffer_size = 0;
|
||||
_uses_alpha = false;
|
||||
_input_mask = nullptr;
|
||||
|
||||
Ram_quota const temporary_ram_upgrade = _texture.valid()
|
||||
@ -447,7 +447,7 @@ Dataspace_capability Gui_session::realloc_buffer(Framebuffer::Mode mode, bool us
|
||||
|
||||
_ram_quota_guard().upgrade(temporary_ram_upgrade);
|
||||
|
||||
if (!_texture.try_construct_next(_env.ram(), _env.rm(), mode.area, use_alpha)) {
|
||||
if (!_texture.try_construct_next(_env.ram(), _env.rm(), mode)) {
|
||||
_texture.release_current();
|
||||
replenish(orig_buffer_size);
|
||||
_ram_quota_guard().try_downgrade(temporary_ram_upgrade);
|
||||
@ -470,7 +470,6 @@ Dataspace_capability Gui_session::realloc_buffer(Framebuffer::Mode mode, bool us
|
||||
}
|
||||
|
||||
_buffer_size = next_buffer_size.value;
|
||||
_uses_alpha = use_alpha;
|
||||
_input_mask = _texture.input_mask_buffer();
|
||||
|
||||
return _texture.dataspace();
|
||||
|
@ -105,8 +105,7 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
*/
|
||||
unsigned char const *_input_mask = nullptr;
|
||||
|
||||
bool _uses_alpha = false;
|
||||
bool _visible = true;
|
||||
bool _visible = true;
|
||||
|
||||
Sliced_heap _session_alloc;
|
||||
|
||||
@ -284,7 +283,7 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
|
||||
View const *background() const override { return _background; }
|
||||
|
||||
bool uses_alpha() const override { return _texture.valid() && _uses_alpha; }
|
||||
bool uses_alpha() const override { return _texture.alpha(); }
|
||||
|
||||
unsigned layer() const override { return _domain ? _domain->layer() : ~0U; }
|
||||
|
||||
@ -407,7 +406,7 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
|
||||
void mode_sigh(Signal_context_capability sigh) override { _mode_sigh = sigh; }
|
||||
|
||||
Buffer_result buffer(Framebuffer::Mode, bool) override;
|
||||
Buffer_result buffer(Framebuffer::Mode) override;
|
||||
|
||||
void focus(Capability<Gui::Session>) override;
|
||||
|
||||
@ -416,7 +415,7 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
** Buffer_provider interface **
|
||||
*******************************/
|
||||
|
||||
Dataspace_capability realloc_buffer(Framebuffer::Mode mode, bool use_alpha) override;
|
||||
Dataspace_capability realloc_buffer(Framebuffer::Mode mode) override;
|
||||
|
||||
void blit(Rect from, Point to) override { _texture.blit(from, to); }
|
||||
|
||||
|
@ -47,14 +47,15 @@ class Nitpicker::Resizeable_texture
|
||||
: Area { };
|
||||
}
|
||||
|
||||
bool alpha() const { return valid() && _textures[_current]->alpha(); }
|
||||
|
||||
void release_current() { _textures[_current].destruct(); }
|
||||
|
||||
bool try_construct_next(Ram_allocator &ram, Region_map &rm,
|
||||
Area size, bool use_alpha)
|
||||
bool try_construct_next(Ram_allocator &ram, Region_map &rm, Framebuffer::Mode mode)
|
||||
{
|
||||
try {
|
||||
unsigned const next = !_current;
|
||||
_textures[next].construct(ram, rm, size, use_alpha);
|
||||
_textures[next].construct(ram, rm, mode);
|
||||
return true;
|
||||
} catch (...) { }
|
||||
return false;
|
||||
|
@ -459,7 +459,7 @@ class Vmm::Virtio_gpu_device : public Virtio_device<Virtio_gpu_queue, 2>
|
||||
_fb_ds.destruct();
|
||||
|
||||
_fb_mode = _gui.mode();
|
||||
_gui.buffer(_fb_mode, false);
|
||||
_gui.buffer(_fb_mode);
|
||||
|
||||
if (_fb_mode.area.count() > 0)
|
||||
_fb_ds.construct(_env.rm(), _gui.framebuffer.dataspace());
|
||||
|
@ -66,7 +66,7 @@ struct Test::Main
|
||||
}
|
||||
}
|
||||
|
||||
bool _gui_buffer_init = ( _validate_mode(), _gui.buffer(_mode, false), true );
|
||||
bool _gui_buffer_init = ( _validate_mode(), _gui.buffer(_mode), true );
|
||||
|
||||
Attached_dataspace _fb_ds { _env.rm(), _gui.framebuffer.dataspace() };
|
||||
|
||||
@ -75,7 +75,7 @@ struct Test::Main
|
||||
Output(Env &env, Allocator &alloc, Xml_node const &config)
|
||||
:
|
||||
_env(env), _alloc(alloc),
|
||||
_mode({ .area = _area_from_xml(config, Area { }) })
|
||||
_mode({ .area = _area_from_xml(config, Area { }), .alpha = false })
|
||||
{
|
||||
auto view_rect = [&] (Xml_node node)
|
||||
{
|
||||
|
@ -236,11 +236,11 @@ Test::Main::Main(Genode::Env &env) : _env(env)
|
||||
|
||||
Gui::Area const size { 256, 256 };
|
||||
|
||||
Framebuffer::Mode const mode { .area = size };
|
||||
Framebuffer::Mode const mode { .area = size, .alpha = _config.alpha };
|
||||
|
||||
log("screen is ", mode);
|
||||
|
||||
_gui.buffer(mode, _config.alpha);
|
||||
_gui.buffer(mode);
|
||||
|
||||
_fb_ds.construct(_env.rm(), _gui.framebuffer.dataspace());
|
||||
|
||||
|
@ -70,7 +70,7 @@ struct Test::Main
|
||||
}
|
||||
}
|
||||
|
||||
bool _gui_buffer_init = ( _validate_mode(), _gui.buffer(_mode, false), true );
|
||||
bool _gui_buffer_init = ( _validate_mode(), _gui.buffer(_mode), true );
|
||||
|
||||
Attached_dataspace _fb_ds { _env.rm(), _gui.framebuffer.dataspace() };
|
||||
|
||||
@ -79,7 +79,7 @@ struct Test::Main
|
||||
Output(Env &env, Allocator &alloc, Xml_node const &config)
|
||||
:
|
||||
_env(env), _alloc(alloc),
|
||||
_mode({ .area = _area_from_xml(config, Area { }) })
|
||||
_mode({ .area = _area_from_xml(config, Area { }), .alpha = false })
|
||||
{
|
||||
auto view_rect = [&] (Xml_node node)
|
||||
{
|
||||
|
@ -66,13 +66,13 @@ class Genodefb :
|
||||
|
||||
size_t const max_h = Genode::min(_fb_mode.area.h, _virtual_fb_mode.area.h);
|
||||
size_t const num_pixels = _fb_mode.area.w * max_h;
|
||||
memset(_fb_base, 0, num_pixels * _fb_mode.bytes_per_pixel());
|
||||
memset(_fb_base, 0, num_pixels * sizeof(Genode::Pixel_rgb888));
|
||||
_gui.framebuffer.refresh({ { 0, 0 }, _virtual_fb_mode.area });
|
||||
}
|
||||
|
||||
void _adjust_buffer()
|
||||
{
|
||||
_gui.buffer(_fb_mode, false);
|
||||
_gui.buffer(_fb_mode);
|
||||
_view.area(_fb_mode.area);
|
||||
}
|
||||
|
||||
|
@ -64,13 +64,13 @@ class Genodefb :
|
||||
|
||||
size_t const max_h = Genode::min(_fb_mode.area.h, _virtual_fb_mode.area.h);
|
||||
size_t const num_pixels = _fb_mode.area.w * max_h;
|
||||
memset(_fb_base, 0, num_pixels * _fb_mode.bytes_per_pixel());
|
||||
memset(_fb_base, 0, num_pixels * sizeof(Genode::Pixel_rgb888));
|
||||
_gui.framebuffer.refresh({ { 0, 0 }, _virtual_fb_mode.area });
|
||||
}
|
||||
|
||||
void _adjust_buffer()
|
||||
{
|
||||
_gui.buffer(_fb_mode, false);
|
||||
_gui.buffer(_fb_mode);
|
||||
_view.area(_fb_mode.area);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user