From 50334e62f4c3a555118a3a8c0d0f4ca7a4215e11 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 8 Jul 2020 14:19:52 +0200 Subject: [PATCH] Turn framebuffer drivers into capture clients Issue genodelabs/genode#3813 --- .../drivers.config | 22 +- .../drivers_interactive-panda/drivers.config | 20 +- recipes/src/arndale_drivers/used_apis | 2 +- recipes/src/panda_drivers/used_apis | 2 +- run/entropy_view.run | 12 +- run/flif.run | 15 +- run/gui_app.inc | 15 +- run/log_fader.run | 26 ++- run/scrcpy.run | 13 +- run/sdl.run | 2 +- run/sdl2.run | 2 +- run/sdl_opengl.inc | 35 ++- .../framebuffer/spec/exynos5/driver.cc | 2 +- src/drivers/framebuffer/spec/exynos5/main.cc | 130 ++++------- .../framebuffer/spec/exynos5/target.mk | 3 +- src/drivers/framebuffer/spec/omap4/main.cc | 202 +++++------------- 16 files changed, 186 insertions(+), 317 deletions(-) diff --git a/recipes/raw/drivers_interactive-arndale/drivers.config b/recipes/raw/drivers_interactive-arndale/drivers.config index 552920c..085fce5 100644 --- a/recipes/raw/drivers_interactive-arndale/drivers.config +++ b/recipes/raw/drivers_interactive-arndale/drivers.config @@ -8,13 +8,11 @@ + - - - @@ -29,17 +27,17 @@ - - + - - - - - - - + + + + + + + + diff --git a/recipes/raw/drivers_interactive-panda/drivers.config b/recipes/raw/drivers_interactive-panda/drivers.config index c2882d6..6967e6f 100644 --- a/recipes/raw/drivers_interactive-panda/drivers.config +++ b/recipes/raw/drivers_interactive-panda/drivers.config @@ -8,29 +8,27 @@ + - - - - - - - - - - - + + + + + + + + diff --git a/recipes/src/arndale_drivers/used_apis b/recipes/src/arndale_drivers/used_apis index 5d7bf97..d2b68d3 100644 --- a/recipes/src/arndale_drivers/used_apis +++ b/recipes/src/arndale_drivers/used_apis @@ -1,7 +1,7 @@ base os blit -framebuffer_session +capture_session input_session gpio_session timer_session diff --git a/recipes/src/panda_drivers/used_apis b/recipes/src/panda_drivers/used_apis index 5d7bf97..d2b68d3 100644 --- a/recipes/src/panda_drivers/used_apis +++ b/recipes/src/panda_drivers/used_apis @@ -1,7 +1,7 @@ base os blit -framebuffer_session +capture_session input_session gpio_session timer_session diff --git a/run/entropy_view.run b/run/entropy_view.run index 0fbcd97..c042931 100644 --- a/run/entropy_view.run +++ b/run/entropy_view.run @@ -37,18 +37,18 @@ append config { - + + - - - + - - + + + diff --git a/run/flif.run b/run/flif.run index e98ae14..00b2015 100644 --- a/run/flif.run +++ b/run/flif.run @@ -42,20 +42,21 @@ install_config { - + + - - - + - - + + + - + diff --git a/run/gui_app.inc b/run/gui_app.inc index a9b07e4..3104b6d 100644 --- a/run/gui_app.inc +++ b/run/gui_app.inc @@ -53,12 +53,11 @@ install_config { - + + - - - + @@ -69,10 +68,12 @@ install_config { - - + + + + - + diff --git a/run/log_fader.run b/run/log_fader.run index 0be9bd2..eaf4f66 100644 --- a/run/log_fader.run +++ b/run/log_fader.run @@ -26,6 +26,7 @@ set build_components { server/nitpicker server/rom_filter server/terminal_log + server/input_event_bridge test/nitpicker } @@ -63,15 +64,22 @@ append config { - - - - + - - + + + + + + + + + + + + @@ -99,7 +107,9 @@ append config { + + @@ -138,10 +148,9 @@ append config { - + - @@ -301,6 +310,7 @@ set boot_modules { testnit timer global_keys_handler + input_event_bridge } build_boot_image $boot_modules diff --git a/run/scrcpy.run b/run/scrcpy.run index 82010be..c28cec8 100644 --- a/run/scrcpy.run +++ b/run/scrcpy.run @@ -235,11 +235,12 @@ append_if $use_interactive_pkg config { - + + - + } @@ -250,7 +251,6 @@ if { !$use_interactive_pkg } { append_if [have_spec x86] config { - @@ -342,12 +342,13 @@ append config { - - + + + - + diff --git a/run/sdl.run b/run/sdl.run index 13837a7..192bdba 100644 --- a/run/sdl.run +++ b/run/sdl.run @@ -2,7 +2,7 @@ set build_components { test/sdl } set app_config { - + diff --git a/run/sdl2.run b/run/sdl2.run index b584023..974c019 100644 --- a/run/sdl2.run +++ b/run/sdl2.run @@ -2,7 +2,7 @@ set build_components { test/sdl2 } set app_config { - + diff --git a/run/sdl_opengl.inc b/run/sdl_opengl.inc index 4e5a776..1a52630 100644 --- a/run/sdl_opengl.inc +++ b/run/sdl_opengl.inc @@ -18,6 +18,7 @@ set build_components { drivers/gpu/intel server/liquid_framebuffer server/nitpicker + server/input_event_bridge lib/mesa/swrast app/launchpad app/pointer @@ -55,20 +56,26 @@ set config { append_if [have_spec linux] config { + + + + + - - } + + + + + + } append_platform_drv_config append_if [expr ![have_spec linux]] config { - - - } @@ -76,7 +83,8 @@ append_if [have_spec ps2] config { - } + + } append config { @@ -85,14 +93,18 @@ append config { - - + + + - + + + + @@ -120,7 +132,7 @@ set launchpad_config { - + @@ -178,8 +190,9 @@ install_config $config set boot_modules { core init ld.lib.so timer nitpicker pointer liquid_fb launchpad + input_event_bridge - libc.lib.so vfs.lib.so libm.lib.so pthread.lib.so + libc.lib.so vfs.lib.so libm.lib.so egl.lib.so mesa.lib.so stdcxx.lib.so expat.lib.so glapi.lib.so sdl.lib.so diff --git a/src/drivers/framebuffer/spec/exynos5/driver.cc b/src/drivers/framebuffer/spec/exynos5/driver.cc index 62fba90..307ed19 100644 --- a/src/drivers/framebuffer/spec/exynos5/driver.cc +++ b/src/drivers/framebuffer/spec/exynos5/driver.cc @@ -49,7 +49,7 @@ class Timer_delayer : public Mmio::Delayer, public Timer::Connection Timer_delayer(Genode::Env &env) : Timer::Connection(env) { } - void usleep(uint64_t us) { Timer::Connection::usleep(us); } + void usleep(uint64_t us) override { Timer::Connection::usleep(us); } }; diff --git a/src/drivers/framebuffer/spec/exynos5/main.cc b/src/drivers/framebuffer/spec/exynos5/main.cc index 6175ed9..8612c01 100644 --- a/src/drivers/framebuffer/spec/exynos5/main.cc +++ b/src/drivers/framebuffer/spec/exynos5/main.cc @@ -1,11 +1,12 @@ /* * \brief Framebuffer driver for Exynos5 HDMI * \author Martin Stein + * \author Norman Feske * \date 2013-08-09 */ /* - * Copyright (C) 2013-2017 Genode Labs GmbH + * Copyright (C) 2013-2020 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -13,122 +14,67 @@ /* Genode includes */ #include +#include #include -#include #include -#include +#include #include -#include -#include /* local includes */ #include -namespace Framebuffer -{ +namespace Framebuffer { using namespace Genode; - - /** - * Framebuffer session backend - */ - class Session_component; struct Main; }; -class Framebuffer::Session_component -: - public Genode::Rpc_object + +struct Framebuffer::Main { - private: + using Area = Capture::Area; + using Pixel = Capture::Pixel; - Genode::Env &_env; + Env &_env; - unsigned _width; - unsigned _height; - size_t _size; - Dataspace_capability _ds; - addr_t _phys_base; - Timer::Connection _timer { _env }; + Attached_rom_dataspace _config { _env, "config" }; - public: + Driver _driver { _env }; - /** - * Constructor - * - * \param driver driver backend that communicates with hardware - * \param width width of framebuffer in pixel - * \param height height of framebuffer in pixel - * \param output targeted output device - */ - Session_component(Genode::Env &env, Driver &driver, - unsigned width, unsigned height) - : - _env(env), - _width(width), - _height(height), - _size(driver.buffer_size(width, height)), - _ds(_env.ram().alloc(_size, WRITE_COMBINED)), - _phys_base(Dataspace_client(_ds).phys_addr()) - { - if (driver.init(width, height, _phys_base)) { - error("could not initialize display"); - struct Could_not_initialize_display : Exception { }; - throw Could_not_initialize_display(); - } - } + Area const _size { _config.xml().attribute_value("width", 1920u), + _config.xml().attribute_value("height", 1080u) }; - /************************************ - ** Framebuffer::Session interface ** - ************************************/ + Attached_ram_dataspace _fb_ds { _env.ram(), _env.rm(), + _driver.buffer_size(_size.w(), _size.h()), + WRITE_COMBINED }; - Dataspace_capability dataspace() override { return _ds; } + addr_t const _fb_phys = Dataspace_client(_fb_ds.cap()).phys_addr(); - Mode mode() const override - { - return Mode { .area = { _width, _height } }; - } + Capture::Connection _capture { _env }; - void mode_sigh(Genode::Signal_context_capability) override { } + Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size }; - void sync_sigh(Genode::Signal_context_capability sigh) override - { - _timer.sigh(sigh); - _timer.trigger_periodic(10*1000); - } + Timer::Connection _timer { _env }; - void refresh(int, int, int, int) override { } -}; + Signal_handler
_timer_handler { _env.ep(), *this, &Main::_handle_timer }; - -static unsigned config_dimension(Genode::Xml_node node, char const *attr, - unsigned default_value) -{ - return node.attribute_value(attr, default_value); -} - - -struct Main -{ - Genode::Env &_env; - Genode::Entrypoint &_ep; - - Genode::Attached_rom_dataspace _config { _env, "config" }; - - Framebuffer::Driver _driver { _env }; - - Framebuffer::Session_component _fb_session { _env, _driver, - config_dimension(_config.xml(), "width", 1920), - config_dimension(_config.xml(), "height", 1080) - }; - - Genode::Static_root _fb_root { _ep.manage(_fb_session) }; - - Main(Genode::Env &env) : _env(env), _ep(_env.ep()) + void _handle_timer() { - /* announce service and relax */ - _env.parent().announce(_ep.manage(_fb_root)); + Surface surface(_fb_ds.local_addr(), _size); + + _captured_screen.apply_to_surface(surface); + } + + Main(Env &env) : _env(env) + { + if (_driver.init(_size.w(), _size.h(), _fb_phys)) { + error("could not initialize display"); + throw Exception(); + } + + _timer.sigh(_timer_handler); + _timer.trigger_periodic(10*1000); } }; -void Component::construct(Genode::Env &env) { static Main main(env); } +void Component::construct(Genode::Env &env) { static Framebuffer::Main main(env); } diff --git a/src/drivers/framebuffer/spec/exynos5/target.mk b/src/drivers/framebuffer/spec/exynos5/target.mk index b9ee1ae..e3298f0 100644 --- a/src/drivers/framebuffer/spec/exynos5/target.mk +++ b/src/drivers/framebuffer/spec/exynos5/target.mk @@ -1,8 +1,7 @@ TARGET = exynos5_fb_drv REQUIRES = arm_v7 SRC_CC += main.cc driver.cc -LIBS += base +LIBS += base blit INC_DIR += $(PRG_DIR) INC_DIR += $(call select_from_repositories,include/spec/exynos5) -CC_CXX_WARN_STRICT := diff --git a/src/drivers/framebuffer/spec/omap4/main.cc b/src/drivers/framebuffer/spec/omap4/main.cc index 1f16dec..00de658 100644 --- a/src/drivers/framebuffer/spec/omap4/main.cc +++ b/src/drivers/framebuffer/spec/omap4/main.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2017 Genode Labs GmbH + * Copyright (C) 2012-2020 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -13,176 +13,78 @@ /* Genode includes */ #include +#include #include #include -#include #include -#include -#include #include +#include /* local includes */ #include - namespace Framebuffer { using namespace Genode; - class Session_component; + class Main; }; -class Framebuffer::Session_component : public Genode::Rpc_object +struct Framebuffer::Main { - private: + using Area = Capture::Area; + using Pixel = Capture::Pixel; - /* - * Noncopyable - */ - Session_component(Session_component const &); - Session_component &operator = (Session_component const &); + Env &_env; - size_t _width; - size_t _height; - bool _buffered; - Mode _mode { }; - size_t _size; - - /* dataspace uses a back buffer (if '_buffered' is true) */ - Genode::Dataspace_capability _bb_ds; - void *_bb_addr; - - /* dataspace of physical frame buffer */ - Genode::Dataspace_capability _fb_ds; - void *_fb_addr; - - Signal_context_capability _sync_sigh { }; - - Timer::Connection _timer; - - void _refresh_buffered(int x, int y, int w, int h) - { - Mode _mode = mode(); - - /* clip specified coordinates against screen boundaries */ - int x2 = min(x + w - 1, (int)_mode.area.w() - 1), - y2 = min(y + h - 1, (int)_mode.area.h() - 1); - int x1 = max(x, 0), - y1 = max(y, 0); - if (x1 > x2 || y1 > y2) return; - - int bypp = _mode.bytes_per_pixel(); - - /* copy pixels from back buffer to physical frame buffer */ - char *src = (char *)_bb_addr + bypp*(_mode.area.w()*y1 + x1), - *dst = (char *)_fb_addr + bypp*(_mode.area.w()*y1 + x1); - - blit(src, bypp*_mode.area.w(), dst, bypp*_mode.area.h(), - bypp*(x2 - x1 + 1), y2 - y1 + 1); - } - - public: - - Session_component(Genode::Env &env, Driver &driver, size_t width, size_t height, - Driver::Output output, bool buffered) - : _width(width), - _height(height), - _buffered(buffered), - _size(driver.buffer_size(width, height)), - _bb_ds(buffered ? env.ram().alloc(_size) - : Genode::Ram_dataspace_capability()), - _bb_addr(buffered ? (void*)env.rm().attach(_bb_ds) : 0), - _fb_ds(env.ram().alloc(_size, WRITE_COMBINED)), - _fb_addr((void*)env.rm().attach(_fb_ds)), - _timer(env) - { - if (!driver.init(width, height, output, - Dataspace_client(_fb_ds).phys_addr())) { - error("Could not initialize display"); - struct Could_not_initialize_display : Exception { }; - throw Could_not_initialize_display(); - } - - Genode::log("using ", width, "x", height, - output == Driver::OUTPUT_HDMI ? " HDMI" : " LCD"); - } - - /************************************ - ** Framebuffer::Session interface ** - ************************************/ - - Dataspace_capability dataspace() override - { - return _buffered ? _bb_ds : _fb_ds; - } - - Mode mode() const override - { - return Mode { .area = { _width, _height } }; - } - - void mode_sigh(Genode::Signal_context_capability) override { } - - void sync_sigh(Genode::Signal_context_capability sigh) override - { - _sync_sigh = sigh; - - _timer.sigh(_sync_sigh); - _timer.trigger_periodic(10*1000); - } - - void refresh(int x, int y, int w, int h) override - { - if (_buffered) - _refresh_buffered(x, y, w, h); - - if (_sync_sigh.valid()) - Signal_transmitter(_sync_sigh).submit(); - } -}; - - -template -static T config_attribute(Genode::Xml_node node, char const *attr_name, T const &default_value) -{ - return node.attribute_value(attr_name, default_value); -} - -static Framebuffer::Driver::Output config_output(Genode::Xml_node node, - Framebuffer::Driver::Output default_value) -{ - Framebuffer::Driver::Output value = default_value; - - if (node.attribute_value("output", Genode::String<8>()) == "LDC") - value = Framebuffer::Driver::OUTPUT_LCD; - - return value; -} - - -struct Main -{ - Genode::Env &_env; - Genode::Entrypoint &_ep; - - Genode::Attached_rom_dataspace _config { _env, "config" }; + Attached_rom_dataspace _config { _env, "config" }; Framebuffer::Driver _driver { _env }; - Framebuffer::Session_component _fb_session { _env, _driver, - config_attribute(_config.xml(), "width", 1024u), - config_attribute(_config.xml(), "height", 768u), - config_output(_config.xml(), Framebuffer::Driver::OUTPUT_HDMI), - config_attribute(_config.xml(), "buffered", false), - }; - - Genode::Static_root _fb_root { _ep.manage(_fb_session) }; - - Main(Genode::Env &env) : _env(env), _ep(_env.ep()) + Driver::Output _configured_output() const { - /* announce service */ - _env.parent().announce(_ep.manage(_fb_root)); + Driver::Output value = Driver::OUTPUT_HDMI; + + if (_config.xml().attribute_value("output", String<8>()) == "LDC") + value = Driver::OUTPUT_LCD; + + return value; + } + + Area const _size { _config.xml().attribute_value("width", 1024u), + _config.xml().attribute_value("height", 768u) }; + + Attached_ram_dataspace _fb_ds { _env.ram(), _env.rm(), + _driver.buffer_size(_size.w(), _size.h()), + WRITE_COMBINED }; + + addr_t const _fb_phys = Dataspace_client(_fb_ds.cap()).phys_addr(); + + Capture::Connection _capture { _env }; + + Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size }; + + Timer::Connection _timer { _env }; + + Signal_handler
_timer_handler { _env.ep(), *this, &Main::_handle_timer }; + + void _handle_timer() + { + Surface surface(_fb_ds.local_addr(), _size); + + _captured_screen.apply_to_surface(surface); + } + + Main(Env &env) : _env(env) + { + if (!_driver.init(_size.w(), _size.h(), _configured_output(), _fb_phys)) { + error("Could not initialize display"); + throw Exception(); + } + + _timer.sigh(_timer_handler); + _timer.trigger_periodic(10*1000); } }; -void Component::construct(Genode::Env &env) { static Main main(env); } +void Component::construct(Genode::Env &env) { static Framebuffer::Main main(env); }