From e738162bdea61345517cad664c5dd32d8513da25 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 25 Sep 2024 11:34:39 +0200 Subject: [PATCH] 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 --- .../include/scout/graphics_backend_impl.h | 4 +-- .../src/server/liquid_framebuffer/services.cc | 14 ++++---- repos/demo/src/server/nitlog/main.cc | 2 +- repos/gems/include/gems/gui_buffer.h | 17 +++++---- repos/gems/include/nano3d/scene.h | 7 ++-- repos/gems/src/app/backdrop/main.cc | 10 +++--- repos/gems/src/app/decorator/main.cc | 7 ++-- repos/gems/src/app/sculpt_manager/gui.cc | 4 +-- repos/gems/src/app/themed_decorator/window.h | 14 ++++---- .../gems/src/lib/dialog/sandboxed_runtime.cc | 4 +-- repos/gems/src/server/gui_fader/main.cc | 35 +++++++++---------- repos/gems/src/server/terminal/main.cc | 4 +-- repos/gems/src/server/wm/decorator_gui.h | 4 +-- repos/gems/src/server/wm/direct_gui.h | 4 +-- repos/gems/src/server/wm/gui.h | 12 ++++--- repos/gems/src/server/wm/layouter_gui.h | 2 +- repos/libports/src/app/pdf_view/main.cc | 6 ++-- repos/libports/src/app/usb_webcam/main.cc | 6 ++-- .../src/test/mesa_demo/eglut/eglut_genode.cc | 4 +-- .../framebuffer_session/framebuffer_session.h | 1 + repos/os/include/gui_session/client.h | 4 +-- repos/os/include/gui_session/connection.h | 6 ++-- repos/os/include/gui_session/gui_session.h | 8 ++--- repos/os/src/app/pointer/main.cc | 8 ++--- repos/os/src/app/status_bar/main.cc | 5 +-- repos/os/src/server/gui_fb/main.cc | 15 ++++---- repos/os/src/server/nitpicker/buffer.h | 4 +-- .../os/src/server/nitpicker/chunky_texture.h | 29 ++++++++------- .../server/nitpicker/framebuffer_session.h | 8 ++--- repos/os/src/server/nitpicker/gui_session.cc | 17 +++++---- repos/os/src/server/nitpicker/gui_session.h | 9 +++-- .../src/server/nitpicker/resizeable_texture.h | 7 ++-- repos/os/src/server/vmm/virtio_gpu.h | 2 +- repos/os/src/test/capture/main.cc | 4 +-- repos/os/src/test/nitpicker/main.cc | 4 +-- repos/os/src/test/vfs_capture/main.cc | 4 +-- repos/ports/src/virtualbox5/frontend/fb.h | 4 +-- repos/ports/src/virtualbox6/include/fb.h | 4 +-- 38 files changed, 149 insertions(+), 154 deletions(-) diff --git a/repos/demo/include/scout/graphics_backend_impl.h b/repos/demo/include/scout/graphics_backend_impl.h index 112848f2af..c8d49b561b 100644 --- a/repos/demo/include/scout/graphics_backend_impl.h +++ b/repos/demo/include/scout/graphics_backend_impl.h @@ -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(); } diff --git a/repos/demo/src/server/liquid_framebuffer/services.cc b/repos/demo/src/server/liquid_framebuffer/services.cc index ff95c10d4f..b2c1a3a203 100644 --- a/repos/demo/src/server/liquid_framebuffer/services.cc +++ b/repos/demo/src/server/liquid_framebuffer/services.cc @@ -239,10 +239,10 @@ class Framebuffer::Session_component : public Genode::Rpc_object 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 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); diff --git a/repos/demo/src/server/nitlog/main.cc b/repos/demo/src/server/nitlog/main.cc index d376d5dcbc..b2efdf9ad2 100644 --- a/repos/demo/src/server/nitlog/main.cc +++ b/repos/demo/src/server/nitlog/main.cc @@ -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); diff --git a/repos/gems/include/gems/gui_buffer.h b/repos/gems/include/gems/gui_buffer.h index efd12f2ecd..77bfab4348 100644 --- a/repos/gems/include/gems/gui_buffer.h +++ b/repos/gems/include/gems/gui_buffer.h @@ -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(); diff --git a/repos/gems/include/nano3d/scene.h b/repos/gems/include/nano3d/scene.h index 7728a8c20f..196f8788c5 100644 --- a/repos/gems/include/nano3d/scene.h +++ b/repos/gems/include/nano3d/scene.h @@ -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; } diff --git a/repos/gems/src/app/backdrop/main.cc b/repos/gems/src/app/backdrop/main.cc index 74af42cf0a..3fae2b405b 100644 --- a/repos/gems/src/app/backdrop/main.cc +++ b/repos/gems/src/app/backdrop/main.cc @@ -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); diff --git a/repos/gems/src/app/decorator/main.cc b/repos/gems/src/app/decorator/main.cc index 8e4ba83141..e23410579c 100644 --- a/repos/gems/src/app/decorator/main.cc +++ b/repos/gems/src/app/decorator/main.cc @@ -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()) { } }; diff --git a/repos/gems/src/app/sculpt_manager/gui.cc b/repos/gems/src/app/sculpt_manager/gui.cc index 0174dbb385..abc69b182c 100644 --- a/repos/gems/src/app/sculpt_manager/gui.cc +++ b/repos/gems/src/app/sculpt_manager/gui.cc @@ -151,8 +151,8 @@ struct Gui::Session_component : Rpc_object 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 session) override { _gui_session.focus(session); } diff --git a/repos/gems/src/app/themed_decorator/window.h b/repos/gems/src/app/themed_decorator/window.h index 9a228103a4..d3eba1e7a1 100644 --- a/repos/gems/src/app/themed_decorator/window.h +++ b/repos/gems/src/app/themed_decorator/window.h @@ -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()); diff --git a/repos/gems/src/lib/dialog/sandboxed_runtime.cc b/repos/gems/src/lib/dialog/sandboxed_runtime.cc index ff460a3ad8..9a3e737bc0 100644 --- a/repos/gems/src/lib/dialog/sandboxed_runtime.cc +++ b/repos/gems/src/lib/dialog/sandboxed_runtime.cc @@ -156,8 +156,8 @@ struct Sandboxed_runtime::Gui_session : Session_object 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 session) override { _gui_session.focus(session); } diff --git a/repos/gems/src/server/gui_fader/main.cc b/repos/gems/src/server/gui_fader/main.cc index 07499a89e8..f382d36c74 100644 --- a/repos/gems/src/server/gui_fader/main.cc +++ b/repos/gems/src/server/gui_fader/main.cc @@ -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 _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(), - _ds.local_addr() + size.count()*sizeof(Pixel), - size) + mode.alpha ? _ds.local_addr() + mode.area.count()*sizeof(Pixel) + : nullptr, + mode.area) { } Dataspace_capability dataspace() { return _ds.cap(); } Texture 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 { _env, Area(1, 1), false }; + Reconstructible _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; } diff --git a/repos/gems/src/server/terminal/main.cc b/repos/gems/src/server/terminal/main.cc index 2ed39bd81b..371c362059 100644 --- a/repos/gems/src/server/terminal/main.cc +++ b/repos/gems/src/server/terminal/main.cc @@ -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()); diff --git a/repos/gems/src/server/wm/decorator_gui.h b/repos/gems/src/server/wm/decorator_gui.h index 286e2175f2..7a53342f6a 100644 --- a/repos/gems/src/server/wm/decorator_gui.h +++ b/repos/gems/src/server/wm/decorator_gui.h @@ -331,9 +331,9 @@ struct Wm::Decorator_gui_session : Session_object, _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) override { } diff --git a/repos/gems/src/server/wm/direct_gui.h b/repos/gems/src/server/wm/direct_gui.h index b28248e2df..51d36f8668 100644 --- a/repos/gems/src/server/wm/direct_gui.h +++ b/repos/gems/src/server/wm/direct_gui.h @@ -114,9 +114,9 @@ class Wm::Direct_gui_session : public Session_object _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 session) override diff --git a/repos/gems/src/server/wm/gui.h b/repos/gems/src/server/wm/gui.h index 3c56da1a12..99cb8f8fc3 100644 --- a/repos/gems/src/server/wm/gui.h +++ b/repos/gems/src/server/wm/gui.h @@ -1170,7 +1170,8 @@ class Wm::Gui::Session_component : public Session_object, * 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, */ 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, 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, * 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; diff --git a/repos/gems/src/server/wm/layouter_gui.h b/repos/gems/src/server/wm/layouter_gui.h index 2c42d9bb33..9fa01ba370 100644 --- a/repos/gems/src/server/wm/layouter_gui.h +++ b/repos/gems/src/server/wm/layouter_gui.h @@ -107,7 +107,7 @@ struct Wm::Layouter_gui_session : Session_object _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) override { } }; diff --git a/repos/libports/src/app/pdf_view/main.cc b/repos/libports/src/app/pdf_view/main.cc index 0d775c12a5..1d2eaf1112 100644 --- a/repos/libports/src/app/pdf_view/main.cc +++ b/repos/libports/src/app/pdf_view/main.cc @@ -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()); diff --git a/repos/libports/src/app/usb_webcam/main.cc b/repos/libports/src/app/usb_webcam/main.cc index 29ff6b51a0..c5da5ae6c6 100644 --- a/repos/libports/src/app/usb_webcam/main.cc +++ b/repos/libports/src/app/usb_webcam/main.cc @@ -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(); @@ -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 (...) { } } } diff --git a/repos/libports/src/test/mesa_demo/eglut/eglut_genode.cc b/repos/libports/src/test/mesa_demo/eglut/eglut_genode.cc index 38ffed7fb9..1ed9c8054f 100644 --- a/repos/libports/src/test/mesa_demo/eglut/eglut_genode.cc +++ b/repos/libports/src/test/mesa_demo/eglut/eglut_genode.cc @@ -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(); } diff --git a/repos/os/include/framebuffer_session/framebuffer_session.h b/repos/os/include/framebuffer_session/framebuffer_session.h index cc979db90e..dae6a89fc1 100644 --- a/repos/os/include/framebuffer_session/framebuffer_session.h +++ b/repos/os/include/framebuffer_session/framebuffer_session.h @@ -34,6 +34,7 @@ namespace Framebuffer { struct Mode { Area area; + bool alpha; size_t bytes_per_pixel() const { return 4; } diff --git a/repos/os/include/gui_session/client.h b/repos/os/include/gui_session/client.h index d681e05879..02823c1665 100644 --- a/repos/os/include/gui_session/client.h +++ b/repos/os/include/gui_session/client.h @@ -59,8 +59,8 @@ struct Gui::Session_client : Rpc_client void mode_sigh(Signal_context_capability sigh) override { call(sigh); } - [[nodiscard]] Buffer_result buffer(Framebuffer::Mode mode, bool alpha) override { - return call(mode, alpha); } + [[nodiscard]] Buffer_result buffer(Framebuffer::Mode mode) override { + return call(mode); } void focus(Gui::Session_capability session) override { call(session); } diff --git a/repos/os/include/gui_session/connection.h b/repos/os/include/gui_session/connection.h index 5116568f34..739aa26e5e 100644 --- a/repos/os/include/gui_session/connection.h +++ b/repos/os/include/gui_session/connection.h @@ -154,9 +154,9 @@ class Gui::Connection : private Genode::Connection } } - 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 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) diff --git a/repos/os/include/gui_session/gui_session.h b/repos/os/include/gui_session/gui_session.h index 2e82d35582..ffae8ec999 100644 --- a/repos/os/include/gui_session/gui_session.h +++ b/repos/os/include/gui_session/gui_session.h @@ -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); - 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, diff --git a/repos/os/src/app/pointer/main.cc b/repos/os/src/app/pointer/main.cc index 1ee8bbcd78..cfdc39cb7f 100644 --- a/repos/os/src/app/pointer/main.cc +++ b/repos/os/src/app/pointer/main.cc @@ -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 { diff --git a/repos/os/src/app/status_bar/main.cc b/repos/os/src/app/status_bar/main.cc index 5ff1c9be91..4531ea8900 100644 --- a/repos/os/src/app/status_bar/main.cc +++ b/repos/os/src/app/status_bar/main.cc @@ -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(); } diff --git a/repos/os/src/server/gui_fb/main.cc b/repos/os/src/server/gui_fb/main.cc index 880af4af71..f598565e9f 100644 --- a/repos/os/src/server/gui_fb/main.cc +++ b/repos/os/src/server/gui_fb/main.cc @@ -124,7 +124,7 @@ struct Framebuffer::Session_component : Genode::Rpc_object { /* 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 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 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 + }; } /* diff --git a/repos/os/src/server/nitpicker/buffer.h b/repos/os/src/server/nitpicker/buffer.h index dfd89f28b6..5a792edc39 100644 --- a/repos/os/src/server/nitpicker/buffer.h +++ b/repos/os/src/server/nitpicker/buffer.h @@ -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; diff --git a/repos/os/src/server/nitpicker/chunky_texture.h b/repos/os/src/server/nitpicker/chunky_texture.h index 8d0ec42fa4..dcc6a949fd 100644 --- a/repos/os/src/server/nitpicker/chunky_texture.h +++ b/repos/os/src/server/nitpicker/chunky_texture.h @@ -33,12 +33,13 @@ class Nitpicker::Chunky_texture : public Buffer, public Texture /** * 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::size(); } @@ -104,13 +105,13 @@ class Nitpicker::Chunky_texture : public Buffer, public Texture /** * 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 *)local_addr(), - _alpha_base(size, use_alpha), size) { } + Buffer(ram, rm, mode.area, calc_num_bytes(mode)), + Texture((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 * 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::alpha()) return 0; - Area const size = Texture::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) diff --git a/repos/os/src/server/nitpicker/framebuffer_session.h b/repos/os/src/server/nitpicker/framebuffer_session.h index 1d0656e801..c38e7f9039 100644 --- a/repos/os/src/server/nitpicker/framebuffer_session.h +++ b/repos/os/src/server/nitpicker/framebuffer_session.h @@ -45,7 +45,6 @@ class Framebuffer::Session_component : public Rpc_object 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 * 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 Dataspace_capability dataspace() override { - return _buffer_provider.realloc_buffer(_mode, _alpha); + return _buffer_provider.realloc_buffer(_mode); } Mode mode() const override { return _mode; } diff --git a/repos/os/src/server/nitpicker/gui_session.cc b/repos/os/src/server/nitpicker/gui_session.cc index c45d9320e3..cddd083add 100644 --- a/repos/os/src/server/nitpicker/gui_session.cc +++ b/repos/os/src/server/nitpicker/gui_session.cc @@ -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 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::calc_num_bytes(mode.area, use_alpha) }; + Ram_quota const next_buffer_size { Chunky_texture::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(); diff --git a/repos/os/src/server/nitpicker/gui_session.h b/repos/os/src/server/nitpicker/gui_session.h index 66b90e8e47..3c057d7469 100644 --- a/repos/os/src/server/nitpicker/gui_session.h +++ b/repos/os/src/server/nitpicker/gui_session.h @@ -105,8 +105,7 @@ class Nitpicker::Gui_session : public Session_object, */ 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, 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, 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) override; @@ -416,7 +415,7 @@ class Nitpicker::Gui_session : public Session_object, ** 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); } diff --git a/repos/os/src/server/nitpicker/resizeable_texture.h b/repos/os/src/server/nitpicker/resizeable_texture.h index 6a9a3ebdc8..f616b40f14 100644 --- a/repos/os/src/server/nitpicker/resizeable_texture.h +++ b/repos/os/src/server/nitpicker/resizeable_texture.h @@ -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; diff --git a/repos/os/src/server/vmm/virtio_gpu.h b/repos/os/src/server/vmm/virtio_gpu.h index 59633d77bd..766a16a090 100644 --- a/repos/os/src/server/vmm/virtio_gpu.h +++ b/repos/os/src/server/vmm/virtio_gpu.h @@ -459,7 +459,7 @@ class Vmm::Virtio_gpu_device : public Virtio_device _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()); diff --git a/repos/os/src/test/capture/main.cc b/repos/os/src/test/capture/main.cc index 8724e42083..bb847c4728 100644 --- a/repos/os/src/test/capture/main.cc +++ b/repos/os/src/test/capture/main.cc @@ -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) { diff --git a/repos/os/src/test/nitpicker/main.cc b/repos/os/src/test/nitpicker/main.cc index ac7bece9ee..d3696ad954 100644 --- a/repos/os/src/test/nitpicker/main.cc +++ b/repos/os/src/test/nitpicker/main.cc @@ -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()); diff --git a/repos/os/src/test/vfs_capture/main.cc b/repos/os/src/test/vfs_capture/main.cc index 2781ea444b..ba3c017be5 100644 --- a/repos/os/src/test/vfs_capture/main.cc +++ b/repos/os/src/test/vfs_capture/main.cc @@ -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) { diff --git a/repos/ports/src/virtualbox5/frontend/fb.h b/repos/ports/src/virtualbox5/frontend/fb.h index 78505b1a3d..0197cfbcf8 100644 --- a/repos/ports/src/virtualbox5/frontend/fb.h +++ b/repos/ports/src/virtualbox5/frontend/fb.h @@ -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); } diff --git a/repos/ports/src/virtualbox6/include/fb.h b/repos/ports/src/virtualbox6/include/fb.h index 3e43eafa19..3d2e990134 100644 --- a/repos/ports/src/virtualbox6/include/fb.h +++ b/repos/ports/src/virtualbox6/include/fb.h @@ -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); }