From c81af531a3958b9dfef3595aecc2ca70a8cbdd34 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 1 Jul 2020 22:26:11 +0200 Subject: [PATCH] Turn framebuffer drivers into capture clients This patch replaces the use of the "Framebuffer" session interface by the new "Capture" session interface in all framebuffer drivers. Thanks to this change, those drivers have become mere clients of the nitpicker GUI server now, and are no longer critical for the liveliness of the GUI server. The patch touches the following areas: - The actual driver components. The new versions of all drivers have been tested on the respective hardware. Generally, the drivers have become simpler. - The drivers_interactive packages for various boards. The drivers subsystem no longer provides a "Framebuffer" service but needs a valid route to the "Capture" service provided by nitpicker. - The driver manager of Sculpt OS. - This patch changes the role of the test-framebuffer component from a framebuffer client to a capture server so that drivers (capture clients) can be directly connected to the test component without the nitpicker server. - Framebuffer driver no longer support the unbuffered mode. - The fb_bench.run script is no longer very meaningful because it interplays solely with nitpicker, not with the driver directly. - All run scripts for graphical scenarios and the related depot archives got adapted to the change. Fixes #3813 --- .../drivers.config | 6 +- .../drivers_interactive-rpi/drivers.config | 6 +- .../recipes/src/imx8_fb_drv/used_apis | 2 +- .../recipes/src/intel_fb_drv/used_apis | 2 +- repos/dde_linux/run/intel_fb.run | 3 +- .../framebuffer/imx8/include/component.h | 223 ------------- .../drivers/framebuffer/imx8/include/driver.h | 156 +++++++++ .../src/drivers/framebuffer/imx8/lx_emul.cc | 32 +- .../src/drivers/framebuffer/imx8/main.cc | 117 +++---- .../framebuffer/intel/include/component.h | 237 ------------- .../framebuffer/intel/include/driver.h | 168 ++++++++++ .../src/drivers/framebuffer/intel/lx_emul.cc | 30 +- .../src/drivers/framebuffer/intel/main.cc | 124 ++++--- .../raw/drivers_managed-pc/drivers.config | 5 +- .../gems/recipes/src/driver_manager/used_apis | 2 +- repos/gems/run/cpu_load_display.run | 13 +- repos/gems/run/decorator.run | 13 +- repos/gems/run/decorator_stress.run | 12 +- repos/gems/run/depot_deploy.run | 12 +- repos/gems/run/driver_manager.run | 24 +- repos/gems/run/gui_fader.run | 13 +- repos/gems/run/leitzentrale.run | 14 +- repos/gems/run/menu_view.run | 13 +- repos/gems/run/nano3d.run | 13 +- repos/gems/run/sculpt.run | 15 +- repos/gems/run/sculpt/nitpicker.config | 4 +- repos/gems/run/terminal_log.run | 15 +- repos/gems/run/text_area.run | 12 +- repos/gems/run/text_painter.run | 38 ++- repos/gems/run/wm.run | 13 +- repos/gems/src/app/driver_manager/main.cc | 9 +- repos/gems/src/test/driver_manager/main.cc | 16 +- repos/libports/recipes/src/vesa_drv/used_apis | 2 +- repos/libports/run/mesa.inc | 12 +- repos/libports/run/mupdf.run | 13 +- repos/libports/run/qt5_common.inc | 16 +- .../src/drivers/framebuffer/vesa/main.cc | 295 ++++++----------- .../pkg/drivers_interactive-linux/archives | 1 + .../drivers.config | 14 +- .../drivers_interactive-linux/drivers.config | 22 +- .../drivers_interactive-pbxa9/drivers.config | 20 +- .../raw/drivers_interactive-pc/drivers.config | 8 +- repos/os/recipes/src/boot_fb_drv/used_apis | 2 +- repos/os/recipes/src/fb_sdl/used_apis | 4 +- .../recipes/src/imx53_qsb_drivers/used_apis | 2 +- repos/os/recipes/src/pbxa9_drivers/used_apis | 2 +- repos/os/recipes/src/rpi_fb_drv/used_apis | 2 +- repos/os/run/demo.run | 13 +- repos/os/run/fb_bench.run | 38 ++- repos/os/run/framebuffer.run | 9 +- repos/os/run/loader.run | 12 +- repos/os/run/pointer.run | 37 ++- .../drivers/framebuffer/boot/framebuffer.cc | 97 ------ .../framebuffer/boot/include/framebuffer.h | 64 ---- repos/os/src/drivers/framebuffer/boot/main.cc | 110 ++++-- .../os/src/drivers/framebuffer/boot/target.mk | 3 +- .../os/src/drivers/framebuffer/pl11x/main.cc | 313 ++++++++---------- .../src/drivers/framebuffer/pl11x/target.mk | 2 +- .../drivers/framebuffer/spec/imx53/driver.h | 7 +- .../drivers/framebuffer/spec/imx53/main.cc | 154 +++------ .../src/drivers/framebuffer/spec/rpi/main.cc | 130 ++------ .../src/drivers/framebuffer/spec/sdl/main.cc | 300 +++++++---------- repos/os/src/test/framebuffer/main.cc | 205 +++++++----- repos/ports/run/bash.run | 39 ++- repos/ports/run/debug_nitpicker.run | 12 +- repos/ports/run/seoul.inc | 19 +- repos/ports/run/vbox5_genode_usb_hid.run | 9 +- repos/ports/run/vbox_share.inc | 6 +- repos/ports/run/vbox_win.inc | 9 +- repos/ports/run/vim.run | 17 +- repos/ports/run/virtualbox.run | 15 +- repos/ports/run/virtualbox_auto.inc | 3 +- 72 files changed, 1492 insertions(+), 1908 deletions(-) delete mode 100644 repos/dde_linux/src/drivers/framebuffer/imx8/include/component.h create mode 100644 repos/dde_linux/src/drivers/framebuffer/imx8/include/driver.h delete mode 100644 repos/dde_linux/src/drivers/framebuffer/intel/include/component.h create mode 100644 repos/dde_linux/src/drivers/framebuffer/intel/include/driver.h delete mode 100644 repos/os/src/drivers/framebuffer/boot/framebuffer.cc delete mode 100644 repos/os/src/drivers/framebuffer/boot/include/framebuffer.h diff --git a/repos/dde_linux/recipes/raw/drivers_interactive-imx8q_evk/drivers.config b/repos/dde_linux/recipes/raw/drivers_interactive-imx8q_evk/drivers.config index 9ad66bb853..91f5a12e41 100644 --- a/repos/dde_linux/recipes/raw/drivers_interactive-imx8q_evk/drivers.config +++ b/repos/dde_linux/recipes/raw/drivers_interactive-imx8q_evk/drivers.config @@ -9,13 +9,11 @@ + - - - @@ -57,7 +55,6 @@ - @@ -68,6 +65,7 @@ + diff --git a/repos/dde_linux/recipes/raw/drivers_interactive-rpi/drivers.config b/repos/dde_linux/recipes/raw/drivers_interactive-rpi/drivers.config index 5bfb97e50f..3496801946 100644 --- a/repos/dde_linux/recipes/raw/drivers_interactive-rpi/drivers.config +++ b/repos/dde_linux/recipes/raw/drivers_interactive-rpi/drivers.config @@ -9,13 +9,11 @@ + - - - @@ -39,7 +37,6 @@ - @@ -49,6 +46,7 @@ + diff --git a/repos/dde_linux/recipes/src/imx8_fb_drv/used_apis b/repos/dde_linux/recipes/src/imx8_fb_drv/used_apis index da546f3ebf..da1f92e6eb 100644 --- a/repos/dde_linux/recipes/src/imx8_fb_drv/used_apis +++ b/repos/dde_linux/recipes/src/imx8_fb_drv/used_apis @@ -4,4 +4,4 @@ blit platform_session timer_session report_session -framebuffer_session +capture_session diff --git a/repos/dde_linux/recipes/src/intel_fb_drv/used_apis b/repos/dde_linux/recipes/src/intel_fb_drv/used_apis index 41904bab86..b8846965eb 100644 --- a/repos/dde_linux/recipes/src/intel_fb_drv/used_apis +++ b/repos/dde_linux/recipes/src/intel_fb_drv/used_apis @@ -3,5 +3,5 @@ os platform_session timer_session report_session -framebuffer_session +capture_session blit diff --git a/repos/dde_linux/run/intel_fb.run b/repos/dde_linux/run/intel_fb.run index 5c5ac4f581..47662238b8 100644 --- a/repos/dde_linux/run/intel_fb.run +++ b/repos/dde_linux/run/intel_fb.run @@ -128,7 +128,6 @@ append config { - @@ -149,6 +148,8 @@ append config { + + diff --git a/repos/dde_linux/src/drivers/framebuffer/imx8/include/component.h b/repos/dde_linux/src/drivers/framebuffer/imx8/include/component.h deleted file mode 100644 index 2b915a7fba..0000000000 --- a/repos/dde_linux/src/drivers/framebuffer/imx8/include/component.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * \brief i.MX8 framebuffer driver session component - * \author Stefan Kalkowski - * \author Christian Prochaska - * \date 2015-10-16 - */ - -/* - * Copyright (C) 2015-2019 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -#ifndef __COMPONENT_H__ -#define __COMPONENT_H__ - -/* Genode includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace Framebuffer { - class Driver; - class Session_component; - class Root; -} - - -class Framebuffer::Driver -{ - private: - - struct Configuration - { - struct lx_c_fb_config _lx = { 16, 64, 64, 4, - nullptr, 0, nullptr }; - } _config; - - Session_component &_session; - Timer::Connection _timer; - Genode::Reporter _reporter; - - Genode::Signal_context_capability _config_sigh; - - drm_display_mode * _preferred_mode(drm_connector *connector, - unsigned &brightness); - - public: - - Driver(Genode::Env & env, Session_component &session) - : _session(session), _timer(env), - _reporter(env, "connectors") {} - - int width() const { return _config._lx.width; } - int height() const { return _config._lx.height; } - int bpp() const { return _config._lx.bpp; } - - void * fb_addr() const { return _config._lx.addr; } - unsigned pitch() const { return _config._lx.pitch; } - - void finish_initialization(); - - void update_mode(); - - void generate_report(); - - /** - * Register signal handler used for config updates - * - * The signal handler is artificially triggered as a side effect - * of connector changes. - */ - void config_sigh(Genode::Signal_context_capability sigh) - { - _config_sigh = sigh; - } - - void trigger_reconfiguration() - { - /* - * Trigger the reprocessing of the configuration following the - * same ontrol flow as used for external config changes. - */ - if (_config_sigh.valid()) - Genode::Signal_transmitter(_config_sigh).submit(); - else - Genode::warning("config signal handler unexpectedly undefined"); - } -}; - - -class Framebuffer::Session_component : public Genode::Rpc_object -{ - private: - - template using Lazy = Genode::Constructible; - - Driver _driver; - Genode::Attached_rom_dataspace &_config; - Genode::Signal_context_capability _mode_sigh; - Timer::Connection _timer; - Genode::Ram_allocator &_ram; - Genode::Attached_ram_dataspace _ds; - bool _in_mode_change = true; - - public: - - Session_component(Genode::Env &env, - Genode::Attached_rom_dataspace &config) - : _driver(env, *this), _config(config), _timer(env), - _ram(env.ram()), _ds(env.ram(), env.rm(), 0) {} - - Driver & driver() { return _driver; } - - void config_changed() - { - _config.update(); - if (!_config.valid()) return; - - _in_mode_change = true; - - _driver.update_mode(); - - if (_mode_sigh.valid()) - Genode::Signal_transmitter(_mode_sigh).submit(); - } - - Genode::Xml_node config() { return _config.xml(); } - - int force_width_from_config() - { - return _config.xml().attribute_value("force_width", 0); - } - - int force_height_from_config() - { - return _config.xml().attribute_value("force_height", 0); - } - - /*********************************** - ** Framebuffer session interface ** - ***********************************/ - - Genode::Dataspace_capability dataspace() override - { - _ds.realloc(&_ram, _driver.width() * _driver.height() * - mode().bytes_per_pixel()); - _in_mode_change = false; - return _ds.cap(); - } - - Mode mode() const override { - return Mode { .area = { _driver.width(), _driver.height() } }; } - - void mode_sigh(Genode::Signal_context_capability sigh) override { - _mode_sigh = sigh; } - - void sync_sigh(Genode::Signal_context_capability sigh) override - { - _timer.sigh(sigh); - _timer.trigger_periodic(10*1000); - } - - void refresh(int x, int y, int w, int h) override - { - using namespace Genode; - - if (!_driver.fb_addr() || !_ds.local_addr() || _in_mode_change) - return; - - int width = _driver.width(); - int height = _driver.height(); - unsigned bpp = 4; - unsigned pitch = _driver.width(); - - /* clip specified coordinates against screen boundaries */ - int x2 = min(x + w - 1, width - 1), - y2 = min(y + h - 1, height - 1); - int x1 = max(x, 0), - y1 = max(y, 0); - if (x1 > x2 || y1 > y2) return; - - /* copy pixels from back buffer to physical frame buffer */ - char *src = _ds.local_addr() + bpp*(width*y1 + x1), - *dst = (char*)_driver.fb_addr() + bpp*(pitch*y1 + x1); - - blit(src, bpp*width, dst, bpp*pitch, - bpp*(x2 - x1 + 1), y2 - y1 + 1); - } -}; - - -struct Framebuffer::Root -: Genode::Root_component -{ - Session_component session; /* single session */ - - Session_component *_create_session(const char *) override { - return &session; } - - void _destroy_session(Session_component *) override { } - - Root(Genode::Env &env, Genode::Allocator &alloc, - Genode::Attached_rom_dataspace &config) - : Genode::Root_component(env.ep(), alloc), - session(env, config) { } -}; - -#endif /* __COMPONENT_H__ */ diff --git a/repos/dde_linux/src/drivers/framebuffer/imx8/include/driver.h b/repos/dde_linux/src/drivers/framebuffer/imx8/include/driver.h new file mode 100644 index 0000000000..095d950ce4 --- /dev/null +++ b/repos/dde_linux/src/drivers/framebuffer/imx8/include/driver.h @@ -0,0 +1,156 @@ +/* + * \brief i.MX8 framebuffer driver + * \author Stefan Kalkowski + * \author Norman Feske + * \author Christian Prochaska + * \date 2015-10-16 + */ + +/* + * Copyright (C) 2015-2020 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef __DRIVER_H__ +#define __DRIVER_H__ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace Framebuffer { + + using namespace Genode; + class Driver; +} + + +class Framebuffer::Driver +{ + private: + + using Area = Capture::Area; + using Pixel = Capture::Pixel; + + struct Configuration + { + struct lx_c_fb_config _lx = { .height = 16, + .width = 64, + .pitch = 64, + .bpp = 4, + .addr = nullptr, + .size = 0, + .lx_fb = nullptr }; + } _lx_config; + + Env &_env; + + Attached_rom_dataspace &_config; + + Timer::Connection _timer { _env }; + + Reporter _reporter { _env, "connectors" }; + + Signal_context_capability _config_sigh; + + drm_display_mode * _preferred_mode(drm_connector *connector, + unsigned &brightness); + + /* + * Capture + */ + + Capture::Connection _capture { _env }; + + Constructible _captured_screen { }; + + Timer::Connection _capture_timer { _env }; + + Signal_handler _capture_timer_handler { + _env.ep(), *this, &Driver::_handle_capture_timer }; + + void _handle_capture_timer() + { + if (!_captured_screen.constructed()) + return; + + Area const phys_size { _lx_config._lx.pitch/sizeof(Pixel), + _lx_config._lx.height }; + + Capture::Surface surface((Pixel *)_lx_config._lx.addr, phys_size); + + _captured_screen->apply_to_surface(surface); + } + + int _force_width_from_config() + { + return _config.xml().attribute_value("force_width", 0); + } + + int _force_height_from_config() + { + return _config.xml().attribute_value("force_height", 0); + } + + public: + + Driver(Env &env, Attached_rom_dataspace &config) + : + _env(env), _config(config) + { + _capture_timer.sigh(_capture_timer_handler); + } + + void finish_initialization(); + void update_mode(); + void generate_report(); + + /** + * Register signal handler used for config updates + * + * The signal handler is artificially triggered as a side effect + * of connector changes. + */ + void config_sigh(Signal_context_capability sigh) + { + _config_sigh = sigh; + } + + void trigger_reconfiguration() + { + /* + * Trigger the reprocessing of the configuration following the + * same ontrol flow as used for external config changes. + */ + if (_config_sigh.valid()) + Signal_transmitter(_config_sigh).submit(); + else + warning("config signal handler unexpectedly undefined"); + } + + void config_changed() + { + _config.update(); + + update_mode(); + + Area const size { _lx_config._lx.width, _lx_config._lx.height }; + + _captured_screen.construct(_capture, _env.rm(), size); + + _capture_timer.trigger_periodic(10*1000); + } +}; + +#endif /* __DRIVER_H__ */ diff --git a/repos/dde_linux/src/drivers/framebuffer/imx8/lx_emul.cc b/repos/dde_linux/src/drivers/framebuffer/imx8/lx_emul.cc index b75e8136cd..f9facbde94 100644 --- a/repos/dde_linux/src/drivers/framebuffer/imx8/lx_emul.cc +++ b/repos/dde_linux/src/drivers/framebuffer/imx8/lx_emul.cc @@ -17,7 +17,7 @@ #include /* local includes */ -#include +#include #include #include @@ -1053,7 +1053,7 @@ Framebuffer::Driver::_preferred_mode(drm_connector *connector, /* try to read configuration for connector */ try { - Xml_node config = _session.config(); + Xml_node config = _config.xml(); Xml_node xn = config.sub_node(); for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) { if (!xn.has_type("connector")) @@ -1114,7 +1114,7 @@ void Framebuffer::Driver::finish_initialization() generate_report(); - _session.config_changed(); + config_changed(); } @@ -1122,21 +1122,21 @@ void Framebuffer::Driver::update_mode() { using namespace Genode; - Configuration old = _config; - _config = Configuration(); + Configuration old = _lx_config; + _lx_config = Configuration(); lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) { unsigned brightness; drm_display_mode * mode = _preferred_mode(c, brightness); if (!mode) return; - if (mode->hdisplay > _config._lx.width) _config._lx.width = mode->hdisplay; - if (mode->vdisplay > _config._lx.height) _config._lx.height = mode->vdisplay; + if (mode->hdisplay > _lx_config._lx.width) _lx_config._lx.width = mode->hdisplay; + if (mode->vdisplay > _lx_config._lx.height) _lx_config._lx.height = mode->vdisplay; }); - lx_c_allocate_framebuffer(lx_drm_device, &_config._lx); + lx_c_allocate_framebuffer(lx_drm_device, &_lx_config._lx); - if (!_config._lx.lx_fb) { + if (!_lx_config._lx.lx_fb) { Genode::error("updating framebuffer failed"); return; } @@ -1147,16 +1147,16 @@ void Framebuffer::Driver::update_mode() unsigned brightness = MAX_BRIGHTNESS + 1; /* set mode */ - lx_c_set_mode(lx_drm_device, c, _config._lx.lx_fb, + lx_c_set_mode(lx_drm_device, c, _lx_config._lx.lx_fb, _preferred_mode(c, brightness)); }); } /* force virtual framebuffer size if requested */ - if (int w = _session.force_width_from_config()) - _config._lx.width = min(_config._lx.width, w); - if (int h = _session.force_height_from_config()) - _config._lx.height = min(_config._lx.height, h); + if (int w = _force_width_from_config()) + _lx_config._lx.width = min(_lx_config._lx.width, w); + if (int h = _force_height_from_config()) + _lx_config._lx.height = min(_lx_config._lx.height, h); if (old._lx.lx_fb) { if (drm_framebuffer_read_refcount(old._lx.lx_fb) > 1) { @@ -1197,8 +1197,8 @@ void Framebuffer::Driver::generate_report() /* check for report configuration option */ try { - _reporter.enabled(_session.config().sub_node("report") - .attribute_value(_reporter.name().string(), false)); + _reporter.enabled(_config.xml().sub_node("report") + .attribute_value(_reporter.name().string(), false)); } catch (...) { _reporter.enabled(false); } diff --git a/repos/dde_linux/src/drivers/framebuffer/imx8/main.cc b/repos/dde_linux/src/drivers/framebuffer/imx8/main.cc index 1d4b8b15a3..690b67fa1b 100644 --- a/repos/dde_linux/src/drivers/framebuffer/imx8/main.cc +++ b/repos/dde_linux/src/drivers/framebuffer/imx8/main.cc @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2015-2019 Genode Labs GmbH + * Copyright (C) 2015-2020 Genode Labs GmbH * * This file is distributed under the terms of the GNU General Public License * version 2. @@ -19,8 +19,8 @@ #include #include -/* Server related local includes */ -#include +/* local includes */ +#include /* Linux emulation environment includes */ #include @@ -32,7 +32,7 @@ #include /* Linux module functions */ -extern "C" void radix_tree_init(); /* called by start_kernel(void) normally */ +extern "C" void radix_tree_init(); /* called by start_kernel(void) normally */ extern "C" void drm_connector_ida_init(); /* called by drm_core_init(void) normally */ extern "C" int module_irq_imx_irqsteer_init(); extern "C" int module_imx_drm_pdrv_init(); @@ -40,90 +40,79 @@ extern "C" int module_dcss_driver_init(); extern "C" int module_dcss_crtc_driver_init(); extern "C" int module_imx_hdp_imx_platform_driver_init(); - -static void run_linux(void * m); - unsigned long jiffies; +namespace Framebuffer { struct Main; } -struct Main + +struct Framebuffer::Main { - Genode::Env &env; - Genode::Entrypoint &ep { env.ep() }; - Genode::Attached_rom_dataspace config { env, "config" }; - Genode::Heap heap { env.ram(), env.rm() }; - Framebuffer::Root root { env, heap, config }; + void _run_linux(); + /** + * Entry for executing code in the Linux kernel context + */ + static void _run_linux_entry(void *m) + { + reinterpret_cast(m)->_run_linux(); + } + + Env &_env; + Entrypoint &_ep { _env.ep() }; + Attached_rom_dataspace _config { _env, "config" }; + Heap _heap { _env.ram(), _env.rm() }; + Driver _driver { _env, _config }; /* Linux task that handles the initialization */ - Genode::Constructible linux; + Constructible _linux; - Main(Genode::Env &env) : env(env) + Signal_handler
_policy_change_handler { + _env.ep(), *this, &Main::_handle_policy_change }; + + bool _policy_change_pending = false; + + void _handle_policy_change() { - Genode::log("--- i.MX8 framebuffer driver ---"); + _policy_change_pending = true; + _linux->unblock(); + Lx::scheduler().schedule(); + } - Lx_kit::construct_env(env); + Main(Env &env) : _env(env) + { + log("--- i.MX8 framebuffer driver ---"); + + Lx_kit::construct_env(_env); LX_MUTEX_INIT(bridge_lock); LX_MUTEX_INIT(core_lock); LX_MUTEX_INIT(component_mutex); /* init singleton Lx::Scheduler */ - Lx::scheduler(&env); + Lx::scheduler(&_env); - Lx::malloc_init(env, heap); + Lx::malloc_init(_env, _heap); /* init singleton Lx::Timer */ - Lx::timer(&env, &ep, &heap, &jiffies); + Lx::timer(&_env, &_ep, &_heap, &jiffies); /* init singleton Lx::Irq */ - Lx::Irq::irq(&ep, &heap); + Lx::Irq::irq(&_ep, &_heap); /* init singleton Lx::Work */ - Lx::Work::work_queue(&heap); + Lx::Work::work_queue(&_heap); - linux.construct(run_linux, reinterpret_cast(this), - "linux", Lx::Task::PRIORITY_0, Lx::scheduler()); + _linux.construct(_run_linux_entry, reinterpret_cast(this), + "linux", Lx::Task::PRIORITY_0, Lx::scheduler()); /* give all task a first kick before returning */ Lx::scheduler().schedule(); } - - void announce() { env.parent().announce(ep.manage(root)); } - - Lx::Task &linux_task() { return *linux; } }; -struct Policy_agent +void Framebuffer::Main::_run_linux() { - Main &main; - Genode::Signal_handler handler; - bool _pending = false; - - void handle() - { - _pending = true; - main.linux_task().unblock(); - Lx::scheduler().schedule(); - } - - bool pending() - { - bool ret = _pending; - _pending = false; - return ret; - } - - Policy_agent(Main &m) - : main(m), handler(main.ep, *this, &Policy_agent::handle) {} -}; - - -static void run_linux(void * m) -{ - Main * main = reinterpret_cast(m); - system_wq = alloc_workqueue("system_wq", 0, 0); radix_tree_init(); @@ -240,17 +229,17 @@ static void run_linux(void * m) platform_device_register(display_subsystem_pdev); - main->root.session.driver().finish_initialization(); - main->announce(); + _driver.finish_initialization(); + _driver.config_sigh(_policy_change_handler); - Policy_agent pa(*main); - main->root.session.driver().config_sigh(pa.handler); - main->config.sigh(pa.handler); + _config.sigh(_policy_change_handler); while (1) { Lx::scheduler().current()->block_and_schedule(); - while (pa.pending()) - main->root.session.config_changed(); + while (_policy_change_pending) { + _policy_change_pending = false; + _driver.config_changed(); + } } } @@ -260,5 +249,5 @@ void Component::construct(Genode::Env &env) /* XXX execute constructors of global statics */ env.exec_static_constructors(); - static Main m(env); + static Framebuffer::Main main(env); } diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h b/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h deleted file mode 100644 index dfa47e2a5c..0000000000 --- a/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * \brief Intel framebuffer driver session component - * \author Stefan Kalkowski - * \date 2015-10-16 - */ - -/* - * Copyright (C) 2015-2017 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -#ifndef __COMPONENT_H__ -#define __COMPONENT_H__ - -/* Genode includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace Framebuffer { - class Driver; - class Session_component; - class Root; -} - - -class Framebuffer::Driver -{ - private: - - struct Configuration - { - struct lx_c_fb_config _lx = { .height = 16, - .width = 64, - .pitch = 64, - .bpp = 4, - .addr = nullptr, - .size = 0, - .lx_fb = nullptr }; - } _config; - - Session_component &_session; - Timer::Connection _timer; - Genode::Reporter _reporter; - Genode::Signal_handler _poll_handler; - Genode::uint64_t _poll_ms = 0; - - Genode::Signal_context_capability _config_sigh; - - drm_display_mode * _preferred_mode(drm_connector *connector, - unsigned &brightness); - - void _poll(); - - public: - - Driver(Genode::Env & env, Session_component &session) - : _session(session), _timer(env), - _reporter(env, "connectors"), - _poll_handler(env.ep(), *this, &Driver::_poll) {} - - int width() const { return _config._lx.width; } - int height() const { return _config._lx.height; } - int bpp() const { return _config._lx.bpp; } - void * fb_addr() const { return _config._lx.addr; } - unsigned pitch() const { return _config._lx.pitch; } - - void finish_initialization(); - void set_polling(Genode::uint64_t poll); - void update_mode(); - void generate_report(); - - /** - * Register signal handler used for config updates - * - * The signal handler is artificially triggered as a side effect - * of connector changes. - */ - void config_sigh(Genode::Signal_context_capability sigh) - { - _config_sigh = sigh; - } - - void trigger_reconfiguration() - { - /* - * Trigger the reprocessing of the configuration following the - * same ontrol flow as used for external config changes. - */ - if (_config_sigh.valid()) - Genode::Signal_transmitter(_config_sigh).submit(); - else - Genode::warning("config signal handler unexpectedly undefined"); - } -}; - - -class Framebuffer::Session_component : public Genode::Rpc_object -{ - private: - - template using Lazy = Genode::Constructible; - - Driver _driver; - Genode::Attached_rom_dataspace &_config; - Genode::Signal_context_capability _mode_sigh; - Timer::Connection _timer; - Genode::Ram_allocator &_ram; - Genode::Attached_ram_dataspace _ds; - bool _in_mode_change = true; - - Genode::uint64_t _polling_from_config() { - return _config.xml().attribute_value("poll", 0); } - - public: - - Session_component(Genode::Env &env, - Genode::Attached_rom_dataspace &config) - : _driver(env, *this), _config(config), _timer(env), - _ram(env.ram()), _ds(env.ram(), env.rm(), 0) {} - - Driver & driver() { return _driver; } - - void config_changed() - { - _config.update(); - if (!_config.valid()) return; - - _driver.set_polling(_polling_from_config()); - - _in_mode_change = true; - - _driver.update_mode(); - - if (_mode_sigh.valid()) - Genode::Signal_transmitter(_mode_sigh).submit(); - } - - Genode::Xml_node config() { return _config.xml(); } - - int force_width_from_config() - { - return _config.xml().attribute_value("force_width", 0); - } - - int force_height_from_config() - { - return _config.xml().attribute_value("force_height", 0); - } - - - /*********************************** - ** Framebuffer session interface ** - ***********************************/ - - Genode::Dataspace_capability dataspace() override - { - _ds.realloc(&_ram, _driver.width()*_driver.height()*_driver.bpp()); - _in_mode_change = false; - return _ds.cap(); - } - - Mode mode() const override - { - return Mode { .area { _driver.width(), _driver.height() } }; - } - - void mode_sigh(Genode::Signal_context_capability sigh) override { - _mode_sigh = sigh; } - - void sync_sigh(Genode::Signal_context_capability sigh) override - { - _timer.sigh(sigh); - _timer.trigger_periodic(10*1000); - } - - void refresh(int x, int y, int w, int h) override - { - using namespace Genode; - - if (!_driver.fb_addr() || - !_ds.local_addr() || - _in_mode_change) return; - - int width = _driver.width(); - int height = _driver.height(); - unsigned bpp = _driver.bpp(); - unsigned pitch = _driver.pitch(); - - /* clip specified coordinates against screen boundaries */ - int x2 = min(x + w - 1, width - 1), - y2 = min(y + h - 1, height - 1); - int x1 = max(x, 0), - y1 = max(y, 0); - if (x1 > x2 || y1 > y2) return; - - /* copy pixels from back buffer to physical frame buffer */ - char *src = _ds.local_addr() + bpp*(width*y1 + x1), - *dst = (char*)_driver.fb_addr() + pitch*y1 + bpp*x1; - - blit(src, bpp*width, dst, pitch, - bpp*(x2 - x1 + 1), y2 - y1 + 1); - } -}; - - -struct Framebuffer::Root -: Genode::Root_component -{ - Session_component session; /* single session */ - - Session_component *_create_session(const char *) override { - return &session; } - - void _destroy_session(Session_component *) override { } - - Root(Genode::Env &env, Genode::Allocator &alloc, - Genode::Attached_rom_dataspace &config) - : Genode::Root_component(env.ep(), alloc), - session(env, config) { } -}; - -#endif /* __COMPONENT_H__ */ diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/include/driver.h b/repos/dde_linux/src/drivers/framebuffer/intel/include/driver.h new file mode 100644 index 0000000000..797877cc20 --- /dev/null +++ b/repos/dde_linux/src/drivers/framebuffer/intel/include/driver.h @@ -0,0 +1,168 @@ +/* + * \brief Intel framebuffer driver + * \author Stefan Kalkowski + * \author Norman Feske + * \date 2015-10-16 + */ + +/* + * Copyright (C) 2015-2020 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef __DRIVER_H__ +#define __DRIVER_H__ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace Framebuffer { + + using namespace Genode; + class Driver; +} + + +class Framebuffer::Driver +{ + private: + + using Area = Capture::Area; + using Pixel = Capture::Pixel; + + struct Configuration + { + struct lx_c_fb_config _lx = { .height = 16, + .width = 64, + .pitch = 64, + .bpp = 4, + .addr = nullptr, + .size = 0, + .lx_fb = nullptr }; + } _lx_config; + + Env &_env; + + Attached_rom_dataspace &_config; + + Timer::Connection _timer { _env }; + + Reporter _reporter { _env, "connectors" }; + + Signal_handler _poll_handler { _env.ep(), *this, &Driver::_poll }; + + uint64_t _poll_ms = 0; + + Signal_context_capability _config_sigh; + + drm_display_mode * _preferred_mode(drm_connector *connector, + unsigned &brightness); + + void _poll(); + + uint64_t _polling_from_config() { + return _config.xml().attribute_value("poll", 0); } + + + /* + * Capture + */ + + Capture::Connection _capture { _env }; + + Constructible _captured_screen { }; + + Timer::Connection _capture_timer { _env }; + + Signal_handler _capture_timer_handler { + _env.ep(), *this, &Driver::_handle_capture_timer }; + + void _handle_capture_timer() + { + if (!_captured_screen.constructed()) + return; + + Area const phys_size { _lx_config._lx.pitch/sizeof(Pixel), + _lx_config._lx.height }; + + Capture::Surface surface((Pixel *)_lx_config._lx.addr, phys_size); + + _captured_screen->apply_to_surface(surface); + } + + int _force_width_from_config() + { + return _config.xml().attribute_value("force_width", 0); + } + + int _force_height_from_config() + { + return _config.xml().attribute_value("force_height", 0); + } + + public: + + Driver(Env &env, Attached_rom_dataspace &config) + : + _env(env), _config(config) + { + _capture_timer.sigh(_capture_timer_handler); + } + + void finish_initialization(); + void set_polling(uint64_t poll); + void update_mode(); + void generate_report(); + + /** + * Register signal handler used for config updates + * + * The signal handler is artificially triggered as a side effect + * of connector changes. + */ + void config_sigh(Signal_context_capability sigh) + { + _config_sigh = sigh; + } + + void trigger_reconfiguration() + { + /* + * Trigger the reprocessing of the configuration following the + * same ontrol flow as used for external config changes. + */ + if (_config_sigh.valid()) + Signal_transmitter(_config_sigh).submit(); + else + warning("config signal handler unexpectedly undefined"); + } + + void config_changed() + { + _config.update(); + + set_polling(_polling_from_config()); + + update_mode(); + + Area const size { _lx_config._lx.width, _lx_config._lx.height }; + + _captured_screen.construct(_capture, _env.rm(), size); + + _capture_timer.trigger_periodic(10*1000); + } +}; + +#endif /* __DRIVER_H__ */ diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc index 50c3ae4484..823d9f44ab 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc +++ b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc @@ -19,7 +19,7 @@ #include /* local includes */ -#include +#include /* DRM-specific includes */ #include @@ -100,7 +100,7 @@ Framebuffer::Driver::_preferred_mode(drm_connector *connector, /* try to read configuration for connector */ try { - Xml_node config = _session.config(); + Xml_node config = _config.xml(); Xml_node xn = config.sub_node(); for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) { if (!xn.has_type("connector")) @@ -157,7 +157,7 @@ void Framebuffer::Driver::finish_initialization() lx_c_set_driver(lx_drm_device, (void*)this); generate_report(); - _session.config_changed(); + Driver::config_changed(); } @@ -189,20 +189,20 @@ void Framebuffer::Driver::update_mode() { using namespace Genode; - Configuration old = _config; - _config = Configuration(); + Configuration old = _lx_config; + _lx_config = Configuration(); lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) { unsigned brightness; drm_display_mode * mode = _preferred_mode(c, brightness); if (!mode) return; - if (mode->hdisplay > _config._lx.width) _config._lx.width = mode->hdisplay; - if (mode->vdisplay > _config._lx.height) _config._lx.height = mode->vdisplay; + if (mode->hdisplay > _lx_config._lx.width) _lx_config._lx.width = mode->hdisplay; + if (mode->vdisplay > _lx_config._lx.height) _lx_config._lx.height = mode->vdisplay; }); - lx_c_allocate_framebuffer(lx_drm_device, &_config._lx); + lx_c_allocate_framebuffer(lx_drm_device, &_lx_config._lx); - if (!_config._lx.lx_fb) { + if (!_lx_config._lx.lx_fb) { Genode::error("updating framebuffer failed"); return; } @@ -213,7 +213,7 @@ void Framebuffer::Driver::update_mode() unsigned brightness = MAX_BRIGHTNESS + 1; /* set mode */ - lx_c_set_mode(lx_drm_device, c, _config._lx.lx_fb, + lx_c_set_mode(lx_drm_device, c, _lx_config._lx.lx_fb, _preferred_mode(c, brightness)); /* set sane brightness, ignore unsane values and let as is */ @@ -223,10 +223,10 @@ void Framebuffer::Driver::update_mode() } /* force virtual framebuffer size if requested */ - if (int w = _session.force_width_from_config()) - _config._lx.width = min(_config._lx.width, w); - if (int h = _session.force_height_from_config()) - _config._lx.height = min(_config._lx.height, h); + if (int w = _force_width_from_config()) + _lx_config._lx.width = min(_lx_config._lx.width, w); + if (int h = _force_height_from_config()) + _lx_config._lx.height = min(_lx_config._lx.height, h); if (old._lx.addr) Lx::iounmap(old._lx.addr); if (old._lx.lx_fb) { @@ -268,7 +268,7 @@ void Framebuffer::Driver::generate_report() /* check for report configuration option */ try { - _reporter.enabled(_session.config().sub_node("report") + _reporter.enabled(_config.xml().sub_node("report") .attribute_value(_reporter.name().string(), false)); } catch (...) { _reporter.enabled(false); diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/main.cc b/repos/dde_linux/src/drivers/framebuffer/intel/main.cc index 352055d9ee..7d64d7ac62 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/main.cc +++ b/repos/dde_linux/src/drivers/framebuffer/intel/main.cc @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2015-2017 Genode Labs GmbH + * Copyright (C) 2015-2020 Genode Labs GmbH * * This file is distributed under the terms of the GNU General Public License * version 2. @@ -18,8 +18,8 @@ #include #include -/* Server related local includes */ -#include +/* local includes */ +#include /* Linux emulation environment includes */ #include @@ -33,110 +33,102 @@ #include /* Linux module functions */ -extern "C" void postcore_i2c_init(void); /* i2c-core-base.c */ -extern "C" int module_i915_init(); /* i915_drv.c */ -extern "C" void radix_tree_init(); /* called by start_kernel(void) normally */ +extern "C" void postcore_i2c_init(void); /* i2c-core-base.c */ +extern "C" int module_i915_init(); /* i915_drv.c */ +extern "C" void radix_tree_init(); /* called by start_kernel(void) normally */ extern "C" void drm_connector_ida_init(); /* called by drm_core_init(void) normally */ -static void run_linux(void * m); - unsigned long jiffies; +namespace Framebuffer { struct Main; } -struct Main + +struct Framebuffer::Main { - Genode::Env &env; - Genode::Entrypoint &ep { env.ep() }; - Genode::Attached_rom_dataspace config { env, "config" }; - Genode::Heap heap { env.ram(), env.rm() }; - Framebuffer::Root root { env, heap, config }; + void _run_linux(); + + /** + * Entry for executing code in the Linux kernel context + */ + static void _run_linux_entry(void *m) + { + reinterpret_cast(m)->_run_linux(); + } + + Env &_env; + Entrypoint &_ep { _env.ep() }; + Attached_rom_dataspace _config { _env, "config" }; + Heap _heap { _env.ram(), _env.rm() }; + Driver _driver { _env, _config }; /* Linux task that handles the initialization */ - Genode::Constructible linux; + Constructible _linux; - Main(Genode::Env &env) : env(env) + Signal_handler
_policy_change_handler { + _env.ep(), *this, &Main::_handle_policy_change }; + + bool _policy_change_pending = false; + + void _handle_policy_change() { - Genode::log("--- intel framebuffer driver ---"); + _policy_change_pending = true; + _linux->unblock(); + Lx::scheduler().schedule(); + } - Lx_kit::construct_env(env); + Main(Env &env) : _env(env) + { + log("--- intel framebuffer driver ---"); + + Lx_kit::construct_env(_env); LX_MUTEX_INIT(bridge_lock); LX_MUTEX_INIT(core_lock); /* init singleton Lx::Scheduler */ - Lx::scheduler(&env); + Lx::scheduler(&_env); - Lx::pci_init(env, env.ram(), heap); - Lx::malloc_init(env, heap); + Lx::pci_init(_env, _env.ram(), _heap); + Lx::malloc_init(_env, _heap); /* init singleton Lx::Timer */ - Lx::timer(&env, &ep, &heap, &jiffies); + Lx::timer(&_env, &_ep, &_heap, &jiffies); /* init singleton Lx::Irq */ - Lx::Irq::irq(&ep, &heap); + Lx::Irq::irq(&_ep, &_heap); /* init singleton Lx::Work */ - Lx::Work::work_queue(&heap); + Lx::Work::work_queue(&_heap); - linux.construct(run_linux, reinterpret_cast(this), - "linux", Lx::Task::PRIORITY_0, Lx::scheduler()); + _linux.construct(_run_linux_entry, reinterpret_cast(this), + "linux", Lx::Task::PRIORITY_0, Lx::scheduler()); /* give all task a first kick before returning */ Lx::scheduler().schedule(); } - - void announce() { env.parent().announce(ep.manage(root)); } - - Lx::Task &linux_task() { return *linux; } }; -struct Policy_agent +void Framebuffer::Main::_run_linux() { - Main &main; - Genode::Signal_handler handler; - bool _pending = false; - - void handle() - { - _pending = true; - main.linux_task().unblock(); - Lx::scheduler().schedule(); - } - - bool pending() - { - bool ret = _pending; - _pending = false; - return ret; - } - - Policy_agent(Main &m) - : main(m), handler(main.ep, *this, &Policy_agent::handle) {} -}; - - -static void run_linux(void * m) -{ - Main * main = reinterpret_cast(m); - system_wq = alloc_workqueue("system_wq", 0, 0); radix_tree_init(); drm_connector_ida_init(); postcore_i2c_init(); module_i915_init(); - main->root.session.driver().finish_initialization(); - main->announce(); - Policy_agent pa(*main); - main->root.session.driver().config_sigh(pa.handler); - main->config.sigh(pa.handler); + _driver.finish_initialization(); + _driver.config_sigh(_policy_change_handler); + + _config.sigh(_policy_change_handler); while (1) { Lx::scheduler().current()->block_and_schedule(); - while (pa.pending()) - main->root.session.config_changed(); + while (_policy_change_pending) { + _policy_change_pending = false; + _driver.config_changed(); + } } } @@ -146,5 +138,5 @@ void Component::construct(Genode::Env &env) /* XXX execute constructors of global statics */ env.exec_static_constructors(); - static Main m(env); + static Framebuffer::Main main(env); } diff --git a/repos/gems/recipes/raw/drivers_managed-pc/drivers.config b/repos/gems/recipes/raw/drivers_managed-pc/drivers.config index 8492f6f5fd..b1583d20f0 100644 --- a/repos/gems/recipes/raw/drivers_managed-pc/drivers.config +++ b/repos/gems/recipes/raw/drivers_managed-pc/drivers.config @@ -11,6 +11,7 @@ + @@ -19,9 +20,6 @@ - - - @@ -228,6 +226,7 @@ + diff --git a/repos/gems/recipes/src/driver_manager/used_apis b/repos/gems/recipes/src/driver_manager/used_apis index 285587958c..8f0c8889ba 100644 --- a/repos/gems/recipes/src/driver_manager/used_apis +++ b/repos/gems/recipes/src/driver_manager/used_apis @@ -3,6 +3,6 @@ os report_session block_session usb_session -framebuffer_session +capture_session timer_session platform_session diff --git a/repos/gems/run/cpu_load_display.run b/repos/gems/run/cpu_load_display.run index cfb9a166fe..08c9640abd 100644 --- a/repos/gems/run/cpu_load_display.run +++ b/repos/gems/run/cpu_load_display.run @@ -37,18 +37,19 @@ install_config { - + + - - - + - - + + + + diff --git a/repos/gems/run/decorator.run b/repos/gems/run/decorator.run index 61963ad91b..ac17cfcf08 100644 --- a/repos/gems/run/decorator.run +++ b/repos/gems/run/decorator.run @@ -39,12 +39,11 @@ install_config { - + + - - - + @@ -58,8 +57,9 @@ install_config { - - + + + @@ -168,6 +168,7 @@ install_config { + } diff --git a/repos/gems/run/decorator_stress.run b/repos/gems/run/decorator_stress.run index 3766c9b94b..b10ba7a333 100644 --- a/repos/gems/run/decorator_stress.run +++ b/repos/gems/run/decorator_stress.run @@ -41,18 +41,18 @@ install_config { - + + - - - + - - + + + diff --git a/repos/gems/run/depot_deploy.run b/repos/gems/run/depot_deploy.run index c6c1000820..d51a24b19f 100644 --- a/repos/gems/run/depot_deploy.run +++ b/repos/gems/run/depot_deploy.run @@ -50,18 +50,18 @@ install_config { - + + - - - + - - + + + diff --git a/repos/gems/run/driver_manager.run b/repos/gems/run/driver_manager.run index b7b7aa9275..e50c5ac062 100644 --- a/repos/gems/run/driver_manager.run +++ b/repos/gems/run/driver_manager.run @@ -11,6 +11,7 @@ import_from_depot [depot_user]/src/[base_src] \ [depot_user]/pkg/drivers_managed-pc \ [depot_user]/src/report_rom \ [depot_user]/src/dynamic_rom \ + [depot_user]/src/nitpicker \ [depot_user]/src/init install_config { @@ -41,6 +42,7 @@ install_config { + @@ -57,13 +59,13 @@ install_config { - - + + + - @@ -95,16 +97,30 @@ install_config { + + + + + + + + + + + + + - + + diff --git a/repos/gems/run/gui_fader.run b/repos/gems/run/gui_fader.run index 4121ce88d3..915e8bc2ad 100644 --- a/repos/gems/run/gui_fader.run +++ b/repos/gems/run/gui_fader.run @@ -36,18 +36,19 @@ install_config { - + + - - - + - - + + + + diff --git a/repos/gems/run/leitzentrale.run b/repos/gems/run/leitzentrale.run index 7c2a48014f..bba1ae0360 100644 --- a/repos/gems/run/leitzentrale.run +++ b/repos/gems/run/leitzentrale.run @@ -70,12 +70,11 @@ install_config { - + + - - - + @@ -93,8 +92,9 @@ install_config { - - + + + @@ -226,7 +226,7 @@ install_config { - + diff --git a/repos/gems/run/menu_view.run b/repos/gems/run/menu_view.run index dad398b284..b8afc0cd3d 100644 --- a/repos/gems/run/menu_view.run +++ b/repos/gems/run/menu_view.run @@ -40,18 +40,19 @@ install_config { - + + - - - + - - + + + + diff --git a/repos/gems/run/nano3d.run b/repos/gems/run/nano3d.run index 7ec6f7e4e1..4433122293 100644 --- a/repos/gems/run/nano3d.run +++ b/repos/gems/run/nano3d.run @@ -31,12 +31,11 @@ append config { - + + - - - + @@ -46,8 +45,10 @@ append config { - - + + + + diff --git a/repos/gems/run/sculpt.run b/repos/gems/run/sculpt.run index f7031210f4..ede18bb306 100644 --- a/repos/gems/run/sculpt.run +++ b/repos/gems/run/sculpt.run @@ -254,13 +254,13 @@ install_config { - - + + + - @@ -269,7 +269,7 @@ install_config { - + @@ -277,10 +277,9 @@ install_config { - - - - + + + diff --git a/repos/gems/run/sculpt/nitpicker.config b/repos/gems/run/sculpt/nitpicker.config index 9d8c3ea805..c043f2d17f 100644 --- a/repos/gems/run/sculpt/nitpicker.config +++ b/repos/gems/run/sculpt/nitpicker.config @@ -1,6 +1,8 @@ - + + + diff --git a/repos/gems/run/terminal_log.run b/repos/gems/run/terminal_log.run index c2e117542d..522229835e 100644 --- a/repos/gems/run/terminal_log.run +++ b/repos/gems/run/terminal_log.run @@ -40,26 +40,25 @@ install_config { - + + - - - + - - + + + - - + diff --git a/repos/gems/run/text_area.run b/repos/gems/run/text_area.run index e800f503dd..29dc3d9ae8 100644 --- a/repos/gems/run/text_area.run +++ b/repos/gems/run/text_area.run @@ -40,12 +40,11 @@ install_config { - + + - - - + @@ -59,8 +58,9 @@ install_config { - - + + + diff --git a/repos/gems/run/text_painter.run b/repos/gems/run/text_painter.run index c4e5dd49a6..f751616ab6 100644 --- a/repos/gems/run/text_painter.run +++ b/repos/gems/run/text_painter.run @@ -5,6 +5,8 @@ import_from_depot [depot_user]/src/[base_src] \ [depot_user]/src/init \ [depot_user]/src/libc \ [depot_user]/src/vfs \ + [depot_user]/src/nitpicker \ + [depot_user]/src/gui_fb \ [depot_user]/raw/ttf-bitstream-vera-minimal install_config { @@ -36,12 +38,36 @@ install_config { - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -70,6 +96,10 @@ install_config { build { server/vfs test/text_painter lib/vfs/ttf } +set fd [open [run_dir]/genode/focus w] +puts $fd " \" domain=\"default\"/>" +close $fd + build_boot_image { vfs test-text_painter vfs_ttf.lib.so } run_genode_until forever diff --git a/repos/gems/run/wm.run b/repos/gems/run/wm.run index 8a7aeba543..8183a24ac3 100644 --- a/repos/gems/run/wm.run +++ b/repos/gems/run/wm.run @@ -43,18 +43,19 @@ install_config { - + + - - - + - - + + + + diff --git a/repos/gems/src/app/driver_manager/main.cc b/repos/gems/src/app/driver_manager/main.cc index 149911a717..b29fb7fa81 100644 --- a/repos/gems/src/app/driver_manager/main.cc +++ b/repos/gems/src/app/driver_manager/main.cc @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -128,13 +128,11 @@ struct Driver_manager::Intel_fb_driver : Device_driver _gen_common_start_node_content(xml, "intel_fb_drv", "intel_fb_drv", Ram_quota{42*1024*1024}, Cap_quota{800}, Priority{0}); - _gen_provides_node(xml); xml.node("route", [&] () { _gen_config_route(xml, "fb_drv.config"); _gen_default_parent_route(xml); }); }); - _gen_forwarded_service(xml, "intel_fb_drv"); } }; @@ -147,13 +145,11 @@ struct Driver_manager::Vesa_fb_driver : Device_driver _gen_common_start_node_content(xml, "vesa_fb_drv", "vesa_fb_drv", Ram_quota{8*1024*1024}, Cap_quota{100}, Priority{-1}); - _gen_provides_node(xml); xml.node("route", [&] () { _gen_config_route(xml, "fb_drv.config"); _gen_default_parent_route(xml); }); }); - _gen_forwarded_service(xml, "vesa_fb_drv"); } }; @@ -193,13 +189,11 @@ struct Driver_manager::Boot_fb_driver : Device_driver _gen_common_start_node_content(xml, "fb_boot_drv", "fb_boot_drv", _ram_quota, Cap_quota{100}, Priority{-1}); - _gen_provides_node(xml); xml.node("route", [&] () { _gen_config_route(xml, "fb_drv.config"); _gen_default_parent_route(xml); }); }); - _gen_forwarded_service(xml, "fb_boot_drv"); } }; @@ -538,6 +532,7 @@ void Driver_manager::Main::_generate_init_config(Reporter &init_config) const _gen_parent_service_xml(xml, Platform::Session::service_name()); _gen_parent_service_xml(xml, Report::Session::service_name()); _gen_parent_service_xml(xml, Usb::Session::service_name()); + _gen_parent_service_xml(xml, Capture::Session::service_name()); }); diff --git a/repos/gems/src/test/driver_manager/main.cc b/repos/gems/src/test/driver_manager/main.cc index b330f76b8f..6479b217b5 100644 --- a/repos/gems/src/test/driver_manager/main.cc +++ b/repos/gems/src/test/driver_manager/main.cc @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -32,6 +31,7 @@ struct Test::Main Attached_rom_dataspace _config { _env, "config" }; Attached_rom_dataspace _block_devices { _env, "block_devices" }; + Attached_rom_dataspace _displays { _env, "displays" }; static bool _attribute_matches(char const *attr, Xml_node expected, Xml_node checked) { @@ -113,6 +113,14 @@ struct Test::Main Block::Connection<> block(_env, &packet_alloc, 128*1024, label.string()); }); + if (_config.xml().has_sub_node("check_displays")) { + _displays.update(); + if (!_displays.xml().has_sub_node("display")) + return; + + log("available displays: ", _displays.xml()); + } + log("all expected devices present and accessible"); } @@ -121,12 +129,6 @@ struct Test::Main Main(Env &env) : _env(env) { - if (_config.xml().has_sub_node("check_framebuffer")) { - log("connect to framebuffer driver"); - Framebuffer::Mode mode { .area = { 640, 480 } }; - Framebuffer::Connection fb(_env, mode); - } - if (_config.xml().has_sub_node("check_input")) { log("connect to input driver"); Input::Connection input(_env); diff --git a/repos/libports/recipes/src/vesa_drv/used_apis b/repos/libports/recipes/src/vesa_drv/used_apis index 6a2f674179..744efe168d 100644 --- a/repos/libports/recipes/src/vesa_drv/used_apis +++ b/repos/libports/recipes/src/vesa_drv/used_apis @@ -3,4 +3,4 @@ os blit platform_session timer_session -framebuffer_session +capture_session diff --git a/repos/libports/run/mesa.inc b/repos/libports/run/mesa.inc index bf4c028179..f4d4fb31c4 100644 --- a/repos/libports/run/mesa.inc +++ b/repos/libports/run/mesa.inc @@ -53,18 +53,18 @@ set config { - + + - - - + - - + + + diff --git a/repos/libports/run/mupdf.run b/repos/libports/run/mupdf.run index 4f1085bbdb..02a9e39af4 100644 --- a/repos/libports/run/mupdf.run +++ b/repos/libports/run/mupdf.run @@ -39,18 +39,19 @@ set config { - + + - - - + - - + + + + diff --git a/repos/libports/run/qt5_common.inc b/repos/libports/run/qt5_common.inc index d2b1533671..24e1005f2e 100644 --- a/repos/libports/run/qt5_common.inc +++ b/repos/libports/run/qt5_common.inc @@ -177,26 +177,28 @@ proc qt5_start_nodes { } { - + + - - - + - + - + + + - + diff --git a/repos/libports/src/drivers/framebuffer/vesa/main.cc b/repos/libports/src/drivers/framebuffer/vesa/main.cc index 4ec88818f1..cb6079df31 100644 --- a/repos/libports/src/drivers/framebuffer/vesa/main.cc +++ b/repos/libports/src/drivers/framebuffer/vesa/main.cc @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2007-2017 Genode Labs GmbH + * Copyright (C) 2007-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. @@ -17,231 +17,150 @@ #include #include #include -#include -#include #include -#include -#include #include -#include +#include +#include +#include /* local includes */ #include "framebuffer.h" - -namespace Framebuffer { - struct Session_component; - struct Root; +namespace Vesa_driver { + using namespace Genode; struct Main; - - using Genode::size_t; - using Genode::min; - using Genode::max; - using Genode::Dataspace_capability; - using Genode::Attached_rom_dataspace; - using Genode::Attached_ram_dataspace; } -class Framebuffer::Session_component : public Genode::Rpc_object +struct Vesa_driver::Main { - private: + using Pixel = Capture::Pixel; + using Area = Capture::Area; - Genode::Env &_env; + Env &_env; - unsigned const _scr_width, _scr_height, _scr_depth; - - Timer::Connection _timer { _env }; - - /* dataspace of physical frame buffer */ - Dataspace_capability _fb_cap; - void *_fb_addr; - - /* dataspace uses a back buffer (if '_buffered' is true) */ - Genode::Constructible _bb; - - void _refresh_buffered(int x, int y, int w, int h) - { - /* clip specified coordinates against screen boundaries */ - int x2 = min(x + w - 1, (int)_scr_width - 1), - y2 = min(y + h - 1, (int)_scr_height - 1); - int x1 = max(x, 0), - y1 = max(y, 0); - if (x1 > x2 || y1 > y2) return; - - /* determine bytes per pixel */ - int bypp = 0; - if (_scr_depth == 32) bypp = 4; - if (!bypp) return; - - /* copy pixels from back buffer to physical frame buffer */ - char *src = _bb->local_addr() + bypp*(_scr_width*y1 + x1), - *dst = (char *)_fb_addr + bypp*(_scr_width*y1 + x1); - - blit(src, bypp*_scr_width, dst, bypp*_scr_width, - bypp*(x2 - x1 + 1), y2 - y1 + 1); - } - - bool _buffered() const { return _bb.constructed(); } - - public: - - /** - * Constructor - */ - Session_component(Genode::Env &env, - unsigned scr_width, unsigned scr_height, unsigned scr_depth, - Dataspace_capability fb_cap, bool buffered) - : - _env(env), - _scr_width(scr_width), _scr_height(scr_height), _scr_depth(scr_depth), - _fb_cap(fb_cap) - { - if (!buffered) return; - - size_t const bb_size = _scr_width*_scr_height*_scr_depth/8; - try { _bb.construct(env.ram(), env.rm(), bb_size); } - catch (...) { - Genode::warning("could not allocate back buffer, disabled buffered output"); - return; - } - - _fb_addr = env.rm().attach(_fb_cap); - - Genode::log("using buffered output"); - } - - /** - * Destructor - */ - ~Session_component() - { - if (_buffered()) { - _bb.destruct(); - _env.rm().detach(_fb_addr); - } - } + Heap _heap { _env.ram(), _env.rm() }; - /*********************************** - ** Framebuffer session interface ** - ***********************************/ + /* + * Config + */ - Dataspace_capability dataspace() override - { - return _buffered() ? Dataspace_capability(_bb->cap()) - : Dataspace_capability(_fb_cap); - } + Attached_rom_dataspace _config { _env, "config" }; - Mode mode() const override - { - return Mode { .area = { _scr_width, _scr_height } }; - } + Area _size { 1, 1 }; - void mode_sigh(Genode::Signal_context_capability) override { } + void _handle_config(); - void sync_sigh(Genode::Signal_context_capability sigh) override - { - _timer.sigh(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); - } -}; + Signal_handler
_config_handler { _env.ep(), *this, &Main::_handle_config }; -/** - * Shortcut for single-client root component - */ -typedef Genode::Root_component Root_component; + /* + * Capture + */ -class Framebuffer::Root : public Root_component -{ - private: + Capture::Connection _capture { _env }; - Genode::Env &_env; - - Attached_rom_dataspace const &_config; - - unsigned _session_arg(char const *attr_name, char const *args, - char const *arg_name, unsigned default_value) - { - /* try to obtain value from config file */ - unsigned result = _config.xml().attribute_value(attr_name, - default_value); - - /* check session argument to override value from config file */ - return Genode::Arg_string::find_arg(args, arg_name).ulong_value(result); - } - - protected: - - Session_component *_create_session(char const *args) override - { - unsigned scr_width = _session_arg("width", args, "fb_width", 0); - unsigned scr_height = _session_arg("height", args, "fb_height", 0); - unsigned const scr_depth = 32; - - bool const buffered = _config.xml().attribute_value("buffered", true); - - if (Framebuffer::set_mode(scr_width, scr_height, scr_depth) != 0) { - Genode::warning("Could not set vesa mode ", - scr_width, "x", scr_height, "@", scr_depth); - throw Genode::Service_denied(); - } - - Genode::log("using video mode: ", - scr_width, "x", scr_height, "@", scr_depth); - - return new (md_alloc()) Session_component(_env, - scr_width, scr_height, scr_depth, - Framebuffer::hw_framebuffer(), - buffered); - } - - public: - - Root(Genode::Env &env, Genode::Allocator &alloc, - Attached_rom_dataspace const &config) - : - Root_component(&env.ep().rpc_ep(), &alloc), - _env(env), _config(config) - { } -}; + Constructible _captured_screen { }; -struct Framebuffer::Main -{ - Genode::Env &env; + /* + * Timer + */ - Genode::Heap heap { env.ram(), env.rm() }; + Timer::Connection _timer { _env }; - Attached_rom_dataspace config { env, "config" }; + Signal_handler
_timer_handler { _env.ep(), *this, &Main::_handle_timer }; - Root root { env, heap, config }; + void _handle_timer(); - Main(Genode::Env &env) : env(env) + + /* + * Driver + */ + + bool const _framebuffer_initialized = ( Framebuffer::init(_env, _heap), true ); + + Constructible _fb_ds { }; + + Main(Env &env) : _env(env) { - Genode::log("modified"); - try { Framebuffer::init(env, heap); } catch (...) { - Genode::error("H/W driver init failed"); - throw; - } + _config.sigh(_config_handler); + _timer.sigh(_timer_handler); - env.parent().announce(env.ep().manage(root)); + _handle_config(); } }; +void Vesa_driver::Main::_handle_timer() +{ + if (!_fb_ds.constructed()) + return; + + Surface surface(_fb_ds->local_addr(), _size); + + _captured_screen->apply_to_surface(surface); +} + + +void Vesa_driver::Main::_handle_config() +{ + _config.update(); + + Xml_node const config = _config.xml(); + + Area const configured_size { config.attribute_value("width", 0U), + config.attribute_value("height", 0U) }; + if (configured_size == _size) + return; + + _size = Area { }; + _fb_ds.destruct(); + _timer.trigger_periodic(0); + + /* set VESA mode */ + { + enum { BITS_PER_PIXEL = 32 }; + + struct Pretty_mode + { + Area size; + void print(Output &out) const { + Genode::print(out, "VESA mode ", size, "@", (int)BITS_PER_PIXEL); } + }; + + unsigned width = configured_size.w(), + height = configured_size.h(); + + if (Framebuffer::set_mode(width, height, BITS_PER_PIXEL) != 0) { + warning("could not set ", Pretty_mode{configured_size}); + return; + } + + /* + * Framebuffer::set_mode may return a size different from the passed + * argument. In paricular, when passing a size of (0,0), the function + * sets and returns the highest screen mode possible. + */ + _size = Area { width, height }; + + log("using ", Pretty_mode{_size}); + } + + /* enable pixel capturing */ + _fb_ds.construct(_env.rm(), Framebuffer::hw_framebuffer()); + _captured_screen.construct(_capture, _env.rm(), _size); + + unsigned long const period_ms = config.attribute_value("period_ms", 20U); + _timer.trigger_periodic(period_ms*1000); +} + + void Component::construct(Genode::Env &env) { /* XXX execute constructors of global statics */ env.exec_static_constructors(); - static Framebuffer::Main inst(env); + static Vesa_driver::Main inst(env); } diff --git a/repos/os/recipes/pkg/drivers_interactive-linux/archives b/repos/os/recipes/pkg/drivers_interactive-linux/archives index 98c969f10c..11d4a2de0a 100644 --- a/repos/os/recipes/pkg/drivers_interactive-linux/archives +++ b/repos/os/recipes/pkg/drivers_interactive-linux/archives @@ -1,3 +1,4 @@ _/src/fb_sdl _/src/input_filter +_/src/input_event_bridge _/raw/drivers_interactive-linux diff --git a/repos/os/recipes/raw/drivers_interactive-imx53_qsb/drivers.config b/repos/os/recipes/raw/drivers_interactive-imx53_qsb/drivers.config index 3d3564258d..f9b7f49345 100644 --- a/repos/os/recipes/raw/drivers_interactive-imx53_qsb/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-imx53_qsb/drivers.config @@ -10,13 +10,11 @@ + - - - @@ -59,7 +57,6 @@ - @@ -70,6 +67,7 @@ + @@ -77,10 +75,10 @@ - - - - + + + + diff --git a/repos/os/recipes/raw/drivers_interactive-linux/drivers.config b/repos/os/recipes/raw/drivers_interactive-linux/drivers.config index 330ea8a8ca..caafabec9f 100644 --- a/repos/os/recipes/raw/drivers_interactive-linux/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-linux/drivers.config @@ -5,21 +5,25 @@ + - - - + + + + + + + - - - - - + + + + @@ -27,7 +31,7 @@ - + diff --git a/repos/os/recipes/raw/drivers_interactive-pbxa9/drivers.config b/repos/os/recipes/raw/drivers_interactive-pbxa9/drivers.config index dda9b9fc43..8913739bef 100644 --- a/repos/os/recipes/raw/drivers_interactive-pbxa9/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-pbxa9/drivers.config @@ -7,13 +7,11 @@ + - - - @@ -64,25 +62,23 @@ - - - - - - + + + + + + - - - + diff --git a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config index cf46aca1f4..d873d9f766 100644 --- a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config @@ -10,13 +10,11 @@ + - - - @@ -77,8 +75,7 @@ - - + @@ -89,6 +86,7 @@ + diff --git a/repos/os/recipes/src/boot_fb_drv/used_apis b/repos/os/recipes/src/boot_fb_drv/used_apis index 254aab69aa..bcecfa3ccd 100644 --- a/repos/os/recipes/src/boot_fb_drv/used_apis +++ b/repos/os/recipes/src/boot_fb_drv/used_apis @@ -1,5 +1,5 @@ base os blit -framebuffer_session +capture_session timer_session diff --git a/repos/os/recipes/src/fb_sdl/used_apis b/repos/os/recipes/src/fb_sdl/used_apis index 4fa949cf7a..4d37a38acc 100644 --- a/repos/os/recipes/src/fb_sdl/used_apis +++ b/repos/os/recipes/src/fb_sdl/used_apis @@ -1,7 +1,7 @@ base-linux base os -input_session -framebuffer_session +event_session timer_session +capture_session blit diff --git a/repos/os/recipes/src/imx53_qsb_drivers/used_apis b/repos/os/recipes/src/imx53_qsb_drivers/used_apis index a1d0fa1905..22164f3795 100644 --- a/repos/os/recipes/src/imx53_qsb_drivers/used_apis +++ b/repos/os/recipes/src/imx53_qsb_drivers/used_apis @@ -3,6 +3,6 @@ os blit platform_session gpio_session -framebuffer_session +capture_session input_session timer_session diff --git a/repos/os/recipes/src/pbxa9_drivers/used_apis b/repos/os/recipes/src/pbxa9_drivers/used_apis index ba05df6f1c..5392b0ccbd 100644 --- a/repos/os/recipes/src/pbxa9_drivers/used_apis +++ b/repos/os/recipes/src/pbxa9_drivers/used_apis @@ -1,6 +1,6 @@ base os -framebuffer_session +capture_session input_session platform_session timer_session diff --git a/repos/os/recipes/src/rpi_fb_drv/used_apis b/repos/os/recipes/src/rpi_fb_drv/used_apis index 4e3ce1a129..f263fb769e 100644 --- a/repos/os/recipes/src/rpi_fb_drv/used_apis +++ b/repos/os/recipes/src/rpi_fb_drv/used_apis @@ -2,4 +2,4 @@ base os blit platform_session -framebuffer_session +capture_session diff --git a/repos/os/run/demo.run b/repos/os/run/demo.run index 2b6432fe87..ade5358b1d 100644 --- a/repos/os/run/demo.run +++ b/repos/os/run/demo.run @@ -46,12 +46,11 @@ install_config { - + + - - - + @@ -69,16 +68,18 @@ install_config { - + + + - + diff --git a/repos/os/run/fb_bench.run b/repos/os/run/fb_bench.run index ae366b32ac..9f6031142a 100644 --- a/repos/os/run/fb_bench.run +++ b/repos/os/run/fb_bench.run @@ -15,6 +15,8 @@ if {[get_cmd_switch --autopilot] && [have_spec linux]} { create_boot_directory import_from_depot [depot_user]/src/[base_src] \ [depot_user]/pkg/[drivers_interactive_pkg] \ + [depot_user]/src/nitpicker \ + [depot_user]/src/gui_fb \ [depot_user]/src/init build { test/fb_bench } @@ -45,12 +47,35 @@ install_config { - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -60,9 +85,14 @@ install_config { - RAM. --> + } +set fd [open [run_dir]/genode/focus w] +puts $fd " \" domain=\"default\"/>" +close $fd + build_boot_image { test-fb_bench } # disable QEMU graphic to enable testing on our machines without SDL and X diff --git a/repos/os/run/framebuffer.run b/repos/os/run/framebuffer.run index ec09d79b86..af4b9418bb 100644 --- a/repos/os/run/framebuffer.run +++ b/repos/os/run/framebuffer.run @@ -32,16 +32,17 @@ install_config { - + + - - - + + + } diff --git a/repos/os/run/loader.run b/repos/os/run/loader.run index dd4af94cd5..2e8ed9f9b7 100644 --- a/repos/os/run/loader.run +++ b/repos/os/run/loader.run @@ -36,18 +36,18 @@ install_config { - + + - - - + - - + + + diff --git a/repos/os/run/pointer.run b/repos/os/run/pointer.run index b49b2c8b63..f99eae560e 100644 --- a/repos/os/run/pointer.run +++ b/repos/os/run/pointer.run @@ -12,6 +12,7 @@ set build_components { server/report_rom server/dynamic_rom server/nitpicker + server/input_event_bridge app/pointer test/pointer test/nitpicker @@ -49,22 +50,31 @@ set config { - - + + - + - + - - - - - + - + + + + + + + + + + + + + + @@ -85,8 +95,9 @@ set config { - - + + + @@ -102,7 +113,6 @@ set config { - @@ -282,6 +292,7 @@ set boot_modules { pointer test-pointer testnit + input_event_bridge } # "lsort -unique" removes duplicates but core must be first diff --git a/repos/os/src/drivers/framebuffer/boot/framebuffer.cc b/repos/os/src/drivers/framebuffer/boot/framebuffer.cc deleted file mode 100644 index 15fdf9cdcf..0000000000 --- a/repos/os/src/drivers/framebuffer/boot/framebuffer.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* - * \brief Framebuffer driver that uses a framebuffer supplied by the core rom. - * \author Johannes Kliemann - * \date 2017-06-12 - */ - -/* - * Copyright (C) 2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#include -#include -#include - -using namespace Framebuffer; - -Session_component::Session_component(Genode::Env &env, - Genode::Xml_node pinfo) -: _env(env) -{ - enum { RGB_COLOR = 1 }; - - unsigned fb_boot_type = 0; - - try { - Genode::Xml_node fb = pinfo.sub_node("boot").sub_node("framebuffer"); - - fb.attribute("phys").value(_core_fb.addr); - fb.attribute("width").value(_core_fb.width); - fb.attribute("height").value(_core_fb.height); - fb.attribute("bpp").value(_core_fb.bpp); - fb.attribute("pitch").value(_core_fb.pitch); - fb_boot_type = fb.attribute_value("type", 0U); - } catch (...) { - Genode::error("No boot framebuffer information available."); - throw Genode::Service_denied(); - } - - Genode::log("Framebuffer with ", _core_fb.width, "x", _core_fb.height, - "x", _core_fb.bpp, " @ ", (void*)_core_fb.addr, - " type=", fb_boot_type, " pitch=", _core_fb.pitch); - - if (_core_fb.bpp != 32 || fb_boot_type != RGB_COLOR ) { - Genode::error("unsupported resolution (bpp or/and type)"); - throw Genode::Service_denied(); - } - - _fb_mem.construct(_env, _core_fb.addr, _core_fb.pitch * _core_fb.height, - true); - - _fb_mode = Mode { .area = { _core_fb.width, _core_fb.height } }; - - _fb_ram.construct(_env.ram(), _env.rm(), _core_fb.width * _core_fb.height * - _fb_mode.bytes_per_pixel()); -} - -Mode Session_component::mode() const { return _fb_mode; } - -void Session_component::mode_sigh(Genode::Signal_context_capability) { } - -void Session_component::sync_sigh(Genode::Signal_context_capability scc) -{ - timer.sigh(scc); - timer.trigger_periodic(10*1000); -} - -void Session_component::refresh(int const x, int const y, int const w, int const h) -{ - using namespace Genode; - - int const width = _core_fb.width; - int const height = _core_fb.height; - unsigned const bpp = 4; - unsigned const pitch = _core_fb.pitch; - - /* clip specified coordinates against screen boundaries */ - int const x2 = min(x + w - 1, width - 1), - y2 = min(y + h - 1, height - 1); - int const x1 = max(x, 0), - y1 = max(y, 0); - if (x1 > x2 || y1 > y2) - return; - - /* copy pixels from back buffer to physical frame buffer */ - char const *src = _fb_ram->local_addr() + bpp*width*y1 + bpp*x1; - char *dst = _fb_mem->local_addr() + pitch*y1 + bpp*x1; - - blit(src, bpp*width, dst, pitch, bpp*(x2 - x1 + 1), y2 - y1 + 1); -} - -Genode::Dataspace_capability Session_component::dataspace() -{ - return _fb_ram->cap(); -} diff --git a/repos/os/src/drivers/framebuffer/boot/include/framebuffer.h b/repos/os/src/drivers/framebuffer/boot/include/framebuffer.h deleted file mode 100644 index 0cdcaa0fb8..0000000000 --- a/repos/os/src/drivers/framebuffer/boot/include/framebuffer.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * \brief Framebuffer driver that uses a framebuffer supplied by the core rom. - * \author Johannes Kliemann - * \date 2017-06-12 - */ - -/* - * Copyright (C) 2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _FRAMEBUFFER_H_ -#define _FRAMEBUFFER_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Framebuffer { - - class Session_component; -} - -class Framebuffer::Session_component : public Genode::Rpc_object -{ - private: - - Genode::Env &_env; - - struct Fb_desc - { - Genode::uint64_t addr; - Genode::uint32_t width; - Genode::uint32_t height; - Genode::uint32_t pitch; - Genode::uint32_t bpp; - } _core_fb { }; - - Mode _fb_mode { }; - - Genode::Constructible _fb_mem { }; - Genode::Constructible _fb_ram { }; - - Timer::Connection timer { _env }; - - public: - Session_component(Genode::Env &, Genode::Xml_node); - Mode mode() const override; - void mode_sigh(Genode::Signal_context_capability) override; - void sync_sigh(Genode::Signal_context_capability) override; - void refresh(int, int, int, int) override; - Genode::Dataspace_capability dataspace() override; -}; - -#endif // _FRAMEBUFFER_H_ diff --git a/repos/os/src/drivers/framebuffer/boot/main.cc b/repos/os/src/drivers/framebuffer/boot/main.cc index 5d681fceaf..4551ba1e98 100644 --- a/repos/os/src/drivers/framebuffer/boot/main.cc +++ b/repos/os/src/drivers/framebuffer/boot/main.cc @@ -1,11 +1,12 @@ /* * \brief Framebuffer driver that uses a framebuffer supplied by the core rom. * \author Johannes Kliemann + * \author Norman Feske * \date 2017-06-12 */ /* - * Copyright (C) 2017 Genode Labs GmbH + * Copyright (C) 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,35 +14,102 @@ #include #include +#include #include -#include +#include +#include -#include +namespace Framebuffer { + using namespace Genode; + struct Main; +} -struct Main { - Genode::Env &env; +struct Framebuffer::Main +{ + using Area = Capture::Area; + using Pixel = Capture::Pixel; - Genode::Attached_rom_dataspace pinfo { - env, - "platform_info" - }; + Env &_env; - Framebuffer::Session_component fb { - env, - pinfo.xml(), - }; + Attached_rom_dataspace _platform_info { _env, "platform_info" }; - Genode::Static_root fb_root {env.ep().manage(fb)}; - - Main(Genode::Env &env) : env(env) + struct Info { - env.parent().announce(env.ep().manage(fb_root)); + addr_t addr; + Area size; + unsigned bpp; + unsigned pitch; + unsigned type; + + static Info from_platform_info(Xml_node const &node) + { + Info result { }; + node.with_sub_node("boot", [&] (Xml_node const &boot) { + boot.with_sub_node("framebuffer", [&] (Xml_node const &fb) { + result = { + .addr = fb.attribute_value("phys", 0UL), + .size = { fb.attribute_value("width", 0U), + fb.attribute_value("height", 0U) }, + .bpp = fb.attribute_value("bpp", 0U), + .pitch = fb.attribute_value("pitch", 0U), + .type = fb.attribute_value("type", 0U) + }; + }); + }); + return result; + } + + enum { TYPE_RGB_COLOR = 1 }; + + void print(Output &out) const + { + Genode::print(out, size, "x", bpp, " @ ", (void*)addr, " " + "type=", type, " pitch=", pitch); + } + }; + + Info const _info = Info::from_platform_info(_platform_info.xml()); + + void _check_info() const + { + if (_info.bpp != 32 || _info.type != Info::TYPE_RGB_COLOR ) { + error("unsupported resolution (bpp or/and type), platform info:\n", + _platform_info.xml()); + throw Exception(); + } + } + + bool const _checked_info = ( _check_info(), true ); + + Attached_io_mem_dataspace _fb_ds { _env, _info.addr, + _info.pitch*_info.size.h(), true }; + + Capture::Connection _capture { _env }; + + Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _info.size }; + + Timer::Connection _timer { _env }; + + Signal_handler
_timer_handler { _env.ep(), *this, &Main::_handle_timer }; + + void _handle_timer() + { + Area const phys_size { (uint32_t)(_info.pitch/sizeof(Pixel)), _info.size.h() }; + + Surface surface(_fb_ds.local_addr(), phys_size); + + _captured_screen.apply_to_surface(surface); + } + + Main(Env &env) : _env(env) + { + log("using boot framebuffer: ", _info); + + _timer.sigh(_timer_handler); + _timer.trigger_periodic(10*1000); } }; -void Component::construct(Genode::Env &env) { - static Main inst(env); - -} +void Component::construct(Genode::Env &env) { static Framebuffer::Main inst(env); } diff --git a/repos/os/src/drivers/framebuffer/boot/target.mk b/repos/os/src/drivers/framebuffer/boot/target.mk index 884d4b3726..4c449ef512 100644 --- a/repos/os/src/drivers/framebuffer/boot/target.mk +++ b/repos/os/src/drivers/framebuffer/boot/target.mk @@ -1,4 +1,3 @@ TARGET = fb_boot_drv LIBS = base blit -SRC_CC = main.cc framebuffer.cc -INC_DIR += $(PRG_DIR)/include +SRC_CC = main.cc diff --git a/repos/os/src/drivers/framebuffer/pl11x/main.cc b/repos/os/src/drivers/framebuffer/pl11x/main.cc index 81d9f05635..4c17090b8f 100644 --- a/repos/os/src/drivers/framebuffer/pl11x/main.cc +++ b/repos/os/src/drivers/framebuffer/pl11x/main.cc @@ -16,21 +16,15 @@ #include #include #include -#include -#include -#include #include #include #include +#include +#include +#include - -/*********************************************** - ** Implementation of the framebuffer service ** - ***********************************************/ - -namespace Framebuffer +namespace Pl11x_driver { - enum { SCR_WIDTH = 640, SCR_HEIGHT = 480, @@ -45,154 +39,51 @@ namespace Framebuffer FRAMEBUFFER_SIZE = SCR_WIDTH*SCR_HEIGHT*BYTES_PER_PIXEL, }; - class Session_component; - using namespace Genode; class Main; } -class Framebuffer::Session_component : - public Genode::Rpc_object + +struct Pl11x_driver::Main { - private: + using Area = Capture::Area; - Ram_dataspace_capability _fb_ds_cap; - addr_t _regs_base; - addr_t _sys_regs_base; - Timer::Connection _timer; + Env &_env; - enum { - /** - * Bit definitions of the lcd control register - */ - CTRL_ENABLED = 1 << 0, - CTRL_BPP_24 = 5 << 1, - CTRL_TFT = 1 << 5, - CTRL_BGR = 1 << 8, - CTRL_POWER = 1 << 11, - CTRL_VCOMP = 1 << 12, - - /** - * Bit definitions for CLCDC timing. - */ - CLCDC_IVS = 1 << 11, - CLCDC_IHS = 1 << 12, - CLCDC_BCD = 1 << 26, - }; - - enum Sp810_defs { - SP810_REG_OSCCLCD = 0x1c, - SP810_REG_LOCK = 0x20, - }; - - enum Pl11x_defs { - PL11X_REG_TIMING0 = 0, - PL11X_REG_TIMING1 = 1, - PL11X_REG_TIMING2 = 2, - PL11X_REG_TIMING3 = 3, - PL11X_REG_UPBASE = 4, - PL11X_REG_LPBASE = 5, - PL11X_REG_CTRL = 6, - PL11X_REG_IMSC = 7, - }; - - void sys_reg_write(unsigned reg, long value) { - *(volatile long *)(_sys_regs_base + sizeof(long)*reg) = value; } - - long sys_reg_read(unsigned reg) { - return *(volatile long *)(_sys_regs_base + sizeof(long)*reg); } - - void reg_write(unsigned reg, long value) { - *(volatile long *)(_regs_base + sizeof(long)*reg) = value; } - - long reg_read(unsigned reg) { - return *(volatile long *)(_regs_base + sizeof(long)*reg); } - - public: - - /** - * Constructor - */ - Session_component(Env & env, - void * regs_base, - void * sys_regs_base, - Ram_dataspace_capability fb_ds_cap, - Genode::addr_t fb_ds_bus_addr) - : _fb_ds_cap(fb_ds_cap), - _regs_base((addr_t)regs_base), - _sys_regs_base((addr_t)sys_regs_base), - _timer(env) - { - using namespace Genode; - - uint32_t tim0 = (SCR_WIDTH/16 - 1) << 2 - | (HSYNC_LEN - 1) << 8 - | (RIGHT_MARGIN - 1) << 16 - | (LEFT_MARGIN - 1) << 24; - uint32_t tim1 = (SCR_HEIGHT - 1) - | (VSYNC_LEN - 1) << 10 - | LOWER_MARGIN << 16 - | UPPER_MARGIN << 24; - uint32_t tim2 = ((SCR_WIDTH - 1) << 16) - | CLCDC_IVS | CLCDC_IHS | CLCDC_BCD; - uint32_t tim3 = 0; - uint32_t ctrl = reg_read(PL11X_REG_CTRL); - - /* reset video if already enabled */ - if (ctrl & CTRL_POWER) { - ctrl &= ~CTRL_POWER; - reg_write(PL11X_REG_CTRL, ctrl); - _timer.msleep(100); - } - if (ctrl & CTRL_ENABLED) { - ctrl &= ~CTRL_ENABLED; - reg_write(PL11X_REG_CTRL, ctrl); - _timer.msleep(100); - } - - ctrl = CTRL_BGR | CTRL_ENABLED | CTRL_TFT | CTRL_VCOMP | CTRL_BPP_24; - - /* init color-lcd oscillator */ - sys_reg_write(SP810_REG_LOCK, 0xa05f); - sys_reg_write(SP810_REG_OSCCLCD, 0x2c77); - sys_reg_write(SP810_REG_LOCK, 0); - - /* init video timing */ - reg_write(PL11X_REG_TIMING0, tim0); - reg_write(PL11X_REG_TIMING1, tim1); - reg_write(PL11X_REG_TIMING2, tim2); - reg_write(PL11X_REG_TIMING3, tim3); - - /* set framebuffer address and ctrl register */ - reg_write(PL11X_REG_UPBASE, fb_ds_bus_addr); - reg_write(PL11X_REG_LPBASE, 0); - reg_write(PL11X_REG_IMSC, 0); - reg_write(PL11X_REG_CTRL, ctrl); - _timer.msleep(100); - - /* power on */ - reg_write(PL11X_REG_CTRL, ctrl | CTRL_POWER); - } - - Genode::Dataspace_capability dataspace() override { return _fb_ds_cap; } - - Mode mode() const override { return Mode { .area { SCR_WIDTH, SCR_HEIGHT } }; } - - void mode_sigh(Genode::Signal_context_capability) override { } - - void sync_sigh(Genode::Signal_context_capability sigh) override - { - _timer.sigh(sigh); - _timer.trigger_periodic(10*1000); - } - - void refresh(int, int, int, int) override { } -}; + Area const _size { SCR_WIDTH, SCR_HEIGHT }; -struct Framebuffer::Main -{ - Env & _env; + /* + * Capture + */ + + Capture::Connection _capture { _env }; + + Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size }; + + + /* + * Timer + */ + + Timer::Connection _timer { _env }; + + Signal_handler
_timer_handler { _env.ep(), *this, &Main::_handle_timer }; + + void _handle_timer() + { + using Pixel = Capture::Pixel; + + Surface surface(_fb_ds.local_addr(), _size); + + _captured_screen.apply_to_surface(surface); + } + + + /* + * Driver + */ + Platform::Connection _platform { _env }; Platform::Device_client _pl11x_dev { _platform.device_by_property("compatible", "arm,pl111") }; @@ -204,34 +95,122 @@ struct Framebuffer::Main _sp810_dev.io_mem_dataspace() }; Ram_dataspace_capability _fb_ds_cap { _platform.alloc_dma_buffer(FRAMEBUFFER_SIZE) }; + Attached_dataspace _fb_ds { _env.rm(), _fb_ds_cap }; - Session_component _fb_session { _env, - _lcd_io_mem.local_addr(), - _sys_mem.local_addr(), - _fb_ds_cap, - _platform.bus_addr_dma_buffer(_fb_ds_cap) }; - - Static_root _fb_root { _env.ep().manage(_fb_session) }; + void _init_device(); Main(Env &env) : _env(env) { - log("--- pl11x framebuffer driver ---\n"); + _init_device(); - /* announce service */ - _env.parent().announce(env.ep().manage(_fb_root)); + _timer.sigh(_timer_handler); + _timer.trigger_periodic(20*1000); + } +}; + + +void Pl11x_driver::Main::_init_device() +{ + enum { + /** + * Bit definitions of the lcd control register + */ + CTRL_ENABLED = 1 << 0, + CTRL_BPP_24 = 5 << 1, + CTRL_TFT = 1 << 5, + CTRL_BGR = 1 << 8, + CTRL_POWER = 1 << 11, + CTRL_VCOMP = 1 << 12, + + /** + * Bit definitions for CLCDC timing. + */ + CLCDC_IVS = 1 << 11, + CLCDC_IHS = 1 << 12, + CLCDC_BCD = 1 << 26, + }; + + enum Sp810_defs { + SP810_REG_OSCCLCD = 0x1c, + SP810_REG_LOCK = 0x20, + }; + + enum Pl11x_defs { + PL11X_REG_TIMING0 = 0, + PL11X_REG_TIMING1 = 1, + PL11X_REG_TIMING2 = 2, + PL11X_REG_TIMING3 = 3, + PL11X_REG_UPBASE = 4, + PL11X_REG_LPBASE = 5, + PL11X_REG_CTRL = 6, + PL11X_REG_IMSC = 7, + }; + + addr_t const regs_base = (addr_t)_lcd_io_mem.local_addr(); + addr_t const sys_regs_base = (addr_t)_sys_mem.local_addr(); + + auto sys_reg_write = [&] (unsigned reg, long value) { + *(volatile long *)(sys_regs_base + sizeof(long)*reg) = value; }; + + auto reg_write = [&] (unsigned reg, long value) { + *(volatile long *)(regs_base + sizeof(long)*reg) = value; }; + + auto reg_read = [&] (unsigned reg) { + return *(volatile long *)(regs_base + sizeof(long)*reg); }; + + uint32_t const tim0 = (SCR_WIDTH/16 - 1) << 2 + | (HSYNC_LEN - 1) << 8 + | (RIGHT_MARGIN - 1) << 16 + | (LEFT_MARGIN - 1) << 24; + uint32_t const tim1 = (SCR_HEIGHT - 1) + | (VSYNC_LEN - 1) << 10 + | LOWER_MARGIN << 16 + | UPPER_MARGIN << 24; + uint32_t const tim2 = ((SCR_WIDTH - 1) << 16) + | CLCDC_IVS | CLCDC_IHS | CLCDC_BCD; + uint32_t const tim3 = 0; + + uint32_t ctrl = reg_read(PL11X_REG_CTRL); + + /* reset video if already enabled */ + if (ctrl & CTRL_POWER) { + ctrl &= ~CTRL_POWER; + reg_write(PL11X_REG_CTRL, ctrl); + _timer.msleep(100); + } + if (ctrl & CTRL_ENABLED) { + ctrl &= ~CTRL_ENABLED; + reg_write(PL11X_REG_CTRL, ctrl); + _timer.msleep(100); } - private: + ctrl = CTRL_BGR | CTRL_ENABLED | CTRL_TFT | CTRL_VCOMP | CTRL_BPP_24; - /* - * Noncopyable - */ - Main(Main const &); - Main &operator = (Main const &); -}; + /* init color-lcd oscillator */ + sys_reg_write(SP810_REG_LOCK, 0xa05f); + sys_reg_write(SP810_REG_OSCCLCD, 0x2c77); + sys_reg_write(SP810_REG_LOCK, 0); + + /* init video timing */ + reg_write(PL11X_REG_TIMING0, tim0); + reg_write(PL11X_REG_TIMING1, tim1); + reg_write(PL11X_REG_TIMING2, tim2); + reg_write(PL11X_REG_TIMING3, tim3); + + /* set framebuffer address and ctrl register */ + addr_t const fb_dma_base = (addr_t)_platform.bus_addr_dma_buffer(_fb_ds_cap); + reg_write(PL11X_REG_UPBASE, fb_dma_base); + reg_write(PL11X_REG_LPBASE, 0); + reg_write(PL11X_REG_IMSC, 0); + reg_write(PL11X_REG_CTRL, ctrl); + _timer.msleep(100); + + /* power on */ + reg_write(PL11X_REG_CTRL, ctrl | CTRL_POWER); +} void Component::construct(Genode::Env &env) { - static Framebuffer::Main main(env); + static Pl11x_driver::Main main(env); } diff --git a/repos/os/src/drivers/framebuffer/pl11x/target.mk b/repos/os/src/drivers/framebuffer/pl11x/target.mk index 7f4e1f99ce..a26af45428 100644 --- a/repos/os/src/drivers/framebuffer/pl11x/target.mk +++ b/repos/os/src/drivers/framebuffer/pl11x/target.mk @@ -1,4 +1,4 @@ TARGET = pl11x_fb_drv REQUIRES = arm_v7 SRC_CC = main.cc -LIBS = base +LIBS = base blit diff --git a/repos/os/src/drivers/framebuffer/spec/imx53/driver.h b/repos/os/src/drivers/framebuffer/spec/imx53/driver.h index c27f91cc55..1ba7fd3525 100644 --- a/repos/os/src/drivers/framebuffer/spec/imx53/driver.h +++ b/repos/os/src/drivers/framebuffer/spec/imx53/driver.h @@ -21,12 +21,14 @@ #include #include #include +#include /* local includes */ #include namespace Framebuffer { using namespace Genode; + using Area = Capture::Area; class Driver; }; @@ -46,7 +48,7 @@ class Framebuffer::Driver public: - enum Resolutions { BYTES_PER_PIXEL = 2 }; + enum Resolutions { BYTES_PER_PIXEL = 4 }; Driver(Genode::Env &env, Genode::Xml_node config) : _env(env), @@ -66,7 +68,8 @@ class Framebuffer::Driver return true; } - Mode mode() { return Mode { .area = { _width, _height } }; } + Area screen_size() const { return Area { _width, _height }; } + Ipu &ipu() { return _ipu; } }; diff --git a/repos/os/src/drivers/framebuffer/spec/imx53/main.cc b/repos/os/src/drivers/framebuffer/spec/imx53/main.cc index 0a9d644af4..87cfa54947 100644 --- a/repos/os/src/drivers/framebuffer/spec/imx53/main.cc +++ b/repos/os/src/drivers/framebuffer/spec/imx53/main.cc @@ -2,152 +2,78 @@ * \brief Frame-buffer driver for the i.MX53 * \author Nikolay Golikov * \author Stefan Kalkowski + * \author Norman Feske * \date 2012-06-21 */ +/* + * 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. + */ + /* Genode includes */ #include +#include #include #include -#include #include #include -#include -#include /* local includes */ #include namespace Framebuffer { using namespace Genode; - class Session_component; + struct Main; }; -class Framebuffer::Session_component : - public Genode::Rpc_object +struct Framebuffer::Main { - private: + using Pixel = Capture::Pixel; - /* - * Noncopyable - */ - Session_component(Session_component const &); - Session_component &operator = (Session_component const &); + Env &_env; - Genode::Env &_env; + Attached_rom_dataspace _config { _env, "config" }; - bool _buffered; - Mode _mode; - size_t _size; + Driver _driver { _env, _config.xml() }; - /* dataspace uses a back buffer (if '_buffered' is true) */ - Genode::Dataspace_capability _bb_ds; - void *_bb_addr; + Area const _size = _driver.screen_size(); - /* dataspace of physical frame buffer */ - Genode::Dataspace_capability _fb_ds; - void *_fb_addr; + Attached_ram_dataspace _fb_ds { _env.ram(), _env.rm(), + _size.count()*sizeof(Pixel), WRITE_COMBINED }; - Timer::Connection _timer { _env }; + Capture::Connection _capture { _env }; + Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size }; - Ipu &_ipu; + Timer::Connection _timer { _env }; - void _refresh_buffered(int x, int y, int w, int h) - { - /* 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; + Signal_handler
_timer_handler { _env.ep(), *this, &Main::_handle_timer }; - 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.h()*y1 + x1); - - blit(src, bypp*_mode.area.w(), dst, bypp*_mode.area.w(), - bypp*(x2 - x1 + 1), y2 - y1 + 1); - } - - public: - - Session_component(Genode::Env &env, Driver &driver, bool buffered) - : _env(env), - _buffered(buffered), - _mode(driver.mode()), - _size(_mode.bytes_per_pixel()*_mode.area.count()), - _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)), - _ipu(driver.ipu()) - { - if (!driver.init(Dataspace_client(_fb_ds).phys_addr())) { - error("could not initialize display"); - struct Could_not_initialize_display : Exception { }; - throw Could_not_initialize_display(); - } - } - - - /************************************** - ** Framebuffer::session interface ** - **************************************/ - - Dataspace_capability dataspace() override { return _buffered ? _bb_ds : _fb_ds; } - Mode mode() const override { return _mode; } - void mode_sigh(Genode::Signal_context_capability) override { } - - void sync_sigh(Genode::Signal_context_capability sigh) override - { - _timer.sigh(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); - } - - void overlay(Genode::addr_t phys_base, int x, int y, int alpha) override { - _ipu.overlay(phys_base, x, y, alpha); } -}; - - -static bool config_attribute(Genode::Xml_node node, const char *attr_name) -{ - return node.attribute_value(attr_name, false); -} - - -struct Main -{ - Genode::Env &_env; - Genode::Entrypoint &_ep; - - Genode::Attached_rom_dataspace _config { _env, "config" }; - - Framebuffer::Driver _driver { _env, _config.xml() }; - - Framebuffer::Session_component _fb_session { _env, _driver, - config_attribute(_config.xml(), "buffered") }; - - Genode::Static_root _fb_root { - _ep.manage(_fb_session) }; - - Main(Genode::Env &env) : _env(env), _ep(_env.ep()) + void _handle_timer() { - Genode::log("--- i.MX53 framebuffer driver ---"); + Surface surface(_fb_ds.local_addr(), _size); - _env.parent().announce(_ep.manage(_fb_root)); + _captured_screen.apply_to_surface(surface); + } + + Main(Env &env) : _env(env) + { + log("--- i.MX53 framebuffer driver ---"); + + if (!_driver.init(Dataspace_client(_fb_ds.cap()).phys_addr())) { + error("could not initialize display"); + struct Could_not_initialize_display : Exception { }; + throw Could_not_initialize_display(); + } + + _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/repos/os/src/drivers/framebuffer/spec/rpi/main.cc b/repos/os/src/drivers/framebuffer/spec/rpi/main.cc index 961c21962d..89a51886a2 100644 --- a/repos/os/src/drivers/framebuffer/spec/rpi/main.cc +++ b/repos/os/src/drivers/framebuffer/spec/rpi/main.cc @@ -17,131 +17,59 @@ #include #include #include -#include -#include +#include #include #include #include namespace Framebuffer { using namespace Genode; - class Session_component; struct Main; }; -class Framebuffer::Session_component : public Genode::Rpc_object -{ - private: - - size_t const _width; - size_t const _height; - Constructible _bb_mem { }; - Attached_io_mem_dataspace _fb_mem; - 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 = _bb_mem->local_addr() + bypp*(_width*y1 + x1), - *dst = _fb_mem.local_addr() + bypp*(_width*y1 + x1); - - blit(src, bypp*_width, dst, bypp*_width, - bypp*(x2 - x1 + 1), y2 - y1 + 1); - } - - public: - - Session_component(Genode::Env &env, addr_t phys_addr, - size_t size, size_t width, size_t height, - bool buffered) - : - _width(width), _height(height), _fb_mem(env, phys_addr, size), - _timer(env) - { - if (buffered) { - _bb_mem.construct(env.ram(), env.rm(), size); - } - } - - /************************************ - ** Framebuffer::Session interface ** - ************************************/ - - Dataspace_capability dataspace() override - { - if (_bb_mem.constructed()) - return _bb_mem->cap(); - else - return _fb_mem.cap(); - } - - 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 - { - _timer.sigh(sigh); - _timer.trigger_periodic(10*1000); - } - - void refresh(int x, int y, int w, int h) override - { - if (_bb_mem.constructed()) - _refresh_buffered(x, y, w, h); - } -}; - - -static bool config_buffered(Genode::Xml_node node) -{ - return node.attribute_value("buffered", false); -} - - struct Framebuffer::Main { - Env &_env; - Entrypoint &_ep; + using Area = Capture::Area; + using Pixel = Capture::Pixel; + + Env &_env; Attached_rom_dataspace _config { _env, "config" }; Platform::Connection _platform { _env }; - Platform::Framebuffer_info _fb_info { 1024, 768, 32 }; + Area const _size { 1024, 768 }; - Constructible _fb_session { }; - Constructible> _fb_root { }; + Platform::Framebuffer_info _fb_info { _size.w(), _size.h(), 32 }; - Main(Genode::Env &env) : _env(env), _ep(_env.ep()) + bool const _fb_initialized = ( _platform.setup_framebuffer(_fb_info), true ); + + Attached_io_mem_dataspace _fb_ds { _env, _fb_info.addr, _fb_info.size }; + + 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() { - log("--- fb_drv started ---"); + Area const phys_size { _fb_info.phys_width, _fb_info.phys_height }; - _platform.setup_framebuffer(_fb_info); + Surface surface(_fb_ds.local_addr(), phys_size); - _fb_session.construct(_env, _fb_info.addr, _fb_info.size, - _fb_info.phys_width, _fb_info.phys_height, - config_buffered(_config.xml())); + _captured_screen.apply_to_surface(surface); + } - _fb_root.construct(_ep.manage(*_fb_session)); + Main(Genode::Env &env) : _env(env) + { + log("--- rpi_fb_drv started ---"); - /* announce service */ - env.parent().announce(_ep.manage(*_fb_root)); + _timer.sigh(_timer_handler); + _timer.trigger_periodic(10*1000); } }; diff --git a/repos/os/src/drivers/framebuffer/spec/sdl/main.cc b/repos/os/src/drivers/framebuffer/spec/sdl/main.cc index b1b5e3864e..3cf8575e06 100644 --- a/repos/os/src/drivers/framebuffer/spec/sdl/main.cc +++ b/repos/os/src/drivers/framebuffer/spec/sdl/main.cc @@ -15,10 +15,9 @@ /* Genode includes */ #include #include -#include -#include +#include +#include #include -#include /* Linux includes */ #include @@ -26,12 +25,6 @@ /* local includes */ #include "convert_keycode.h" -namespace Framebuffer { - class Session_component; - using namespace Genode; -} - - namespace Fb_sdl { class Main; using namespace Genode; @@ -44,140 +37,6 @@ struct Sdl_videodriver_not_supported : Genode::Exception { }; struct Sdl_setvideomode_failed : Genode::Exception { }; -class Framebuffer::Session_component : public Rpc_object -{ - private: - - /* - * Noncopyable - */ - Session_component(Session_component const &); - Session_component &operator = (Session_component const &); - - Env &_env; - - Mode _next_mode; - Mode mutable _requested_mode = _next_mode; - Mode _mode = _next_mode; - - SDL_Surface *_screen { nullptr }; - - Constructible _fb_ds { }; - - Signal_context_capability _mode_sigh { }; - Signal_context_capability _sync_sigh { }; - - public: - - void submit_sync() - { - if (_sync_sigh.valid()) - Signal_transmitter(_sync_sigh).submit(); - } - - void submit_mode_change(Mode next_mode) - { - _next_mode = next_mode; - - if (_mode_sigh.valid()) - Signal_transmitter(_mode_sigh).submit(); - } - - /** - * Constructor - */ - Session_component(Env &env, Framebuffer::Mode next_mode) - : - _env(env), _next_mode(next_mode) - { } - - Dataspace_capability dataspace() override - { - unsigned const bpp = _requested_mode.bytes_per_pixel(); - unsigned const flags = SDL_SWSURFACE | SDL_RESIZABLE; - unsigned const w = _requested_mode.area.w(); - unsigned const h = _requested_mode.area.h(); - - if (SDL_VideoModeOK(w, h, bpp*8, flags)) - _screen = SDL_SetVideoMode(w, h, bpp*8, flags); - - if (!_screen) { - error("SDL_SetVideoMode failed (", Genode::Cstring(SDL_GetError()), ")"); - throw Sdl_setvideomode_failed(); - } - - /* - * Preserve content of old dataspace in new SDL screen to reduce - * flickering during resize. - * - * Note that flickering cannot fully be avoided because the host - * window is immediately cleared by 'SDL_SetVideoMode'. - */ - refresh(0, 0, w, h); - - _mode = _requested_mode; - - /* - * Allocate new dataspace, and initialize with the original pixels. - */ - _fb_ds.construct(_env.ram(), _env.rm(), w*h*bpp); - - blit(_screen->pixels, _screen->pitch, _fb_ds->local_addr(), bpp*w, - min(w, (unsigned)_screen->w)*bpp, - min(h, (unsigned)_screen->h)); - - return _fb_ds->cap(); - } - - Mode mode() const override - { - _requested_mode = _next_mode; - return _requested_mode; - } - - void mode_sigh(Signal_context_capability sigh) override - { - _mode_sigh = sigh; - } - - void sync_sigh(Signal_context_capability sigh) override - { - _sync_sigh = sigh; - } - - void refresh(int x, int y, int w, int h) override - { - if (!_fb_ds.constructed()) - return; - - /* clip refresh area to screen boundaries */ - int const x1 = max(x, 0); - int const y1 = max(y, 0); - int const x2 = min(x + w - 1, min((int)_mode.area.w(), _screen->w) - 1); - int const y2 = min(y + h - 1, min((int)_mode.area.h(), _screen->h) - 1); - - if (x1 > x2 || y1 > y2) - return; - - /* blit pixels from framebuffer dataspace to SDL screen */ - unsigned const bpp = _mode.bytes_per_pixel(); - - char const * const src_base = _fb_ds->local_addr(); - unsigned const src_pitch = bpp*_mode.area.w(); - char const * const src = src_base + y1*src_pitch + bpp*x1; - - unsigned const dst_pitch = _screen->pitch; - char * const dst_base = (char *)_screen->pixels; - char * const dst = dst_base + y1*dst_pitch + bpp*x1; - - blit(src, src_pitch, dst, dst_pitch, bpp*(x2 - x1 + 1), y2 - y1 + 1); - - /* flush pixels in sdl window */ - SDL_UpdateRect(_screen, x1, y1, x2 - x1 + 1, y2 - y1 + 1); - } -}; - - struct Fb_sdl::Main { Env &_env; @@ -185,34 +44,15 @@ struct Fb_sdl::Main Attached_rom_dataspace _config { _env, "config" }; Timer::Connection _timer { _env }; + Event::Connection _event { _env }; - unsigned const _fb_width = _config.xml().attribute_value("width", 1024UL); - unsigned const _fb_height = _config.xml().attribute_value("height", 768UL); + using Area = Capture::Area; + using Point = Capture::Area; + using Pixel = Capture::Pixel; + using Affected_rects = Capture::Session::Affected_rects; + using Event_batch = Event::Session_client::Batch; - Framebuffer::Mode _fb_mode { .area = { _fb_width, _fb_height } }; - - Framebuffer::Session_component _fb_session { _env, _fb_mode }; - - Static_root _fb_root { _env.ep().manage(_fb_session) }; - - Input::Session_component _input_session { _env, _env.ram() }; - Input::Root_component _input_root { _env.ep().rpc_ep(), _input_session }; - - Signal_handler
_timer_handler { - _env.ep(), *this, &Main::_handle_timer }; - - int _mx = 0, _my = 0; - - void _handle_sdl_event(SDL_Event const &event); - void _handle_sdl_events(); - - void _handle_timer() - { - _handle_sdl_events(); - _fb_session.submit_sync(); - } - - Main(Env &env) : _env(env) + void _init_sdl() { /* * Initialize libSDL window @@ -234,9 +74,103 @@ struct Fb_sdl::Main } SDL_ShowCursor(0); + } - _env.parent().announce(env.ep().manage(_fb_root)); - _env.parent().announce(env.ep().manage(_input_root)); + bool const _sdl_initialized = ( _init_sdl(), true ); + + struct Sdl_screen + { + Area const size; + + SDL_Surface &_sdl_surface = _init_sdl_surface(); + + SDL_Surface &_init_sdl_surface() + { + unsigned const bpp = 32; + unsigned const flags = SDL_SWSURFACE | SDL_RESIZABLE; + + SDL_Surface *surface_ptr = nullptr; + + if (SDL_VideoModeOK(size.w(), size.h(), bpp, flags)) + surface_ptr = SDL_SetVideoMode(size.w(), size.h(), bpp, flags); + + if (!surface_ptr) { + error("SDL_SetVideoMode failed (", Genode::Cstring(SDL_GetError()), ")"); + throw Sdl_setvideomode_failed(); + } + return *surface_ptr; + } + + Sdl_screen(Area size) : size(size) { } + + template + void with_surface(FN const &fn) + { + Surface surface { (Pixel *)_sdl_surface.pixels, size }; + fn(surface); + } + + void flush(Capture::Rect rect) + { + SDL_UpdateRect(&_sdl_surface, rect.x1(), rect.y1(), rect.w(), rect.h()); + } + }; + + Constructible _sdl_screen { }; + + Capture::Connection _capture { _env }; + + Constructible _captured_screen { }; + + Signal_handler
_timer_handler { + _env.ep(), *this, &Main::_handle_timer }; + + int _mx = 0, _my = 0; + + void _handle_sdl_event(Event_batch &, SDL_Event const &); + void _handle_sdl_events(); + + void _update_sdl_screen_from_capture() + { + Affected_rects const affected = _capture.capture_at(Capture::Point(0, 0)); + + _sdl_screen->with_surface([&] (Surface &surface) { + + _captured_screen->with_texture([&] (Texture const &texture) { + + affected.for_each_rect([&] (Capture::Rect const rect) { + + surface.clip(rect); + + Blit_painter::paint(surface, texture, Capture::Point(0, 0)); + }); + }); + }); + + /* flush pixels in SDL window */ + affected.for_each_rect([&] (Capture::Rect const rect) { + _sdl_screen->flush(rect); }); + } + + void _handle_timer() + { + _handle_sdl_events(); + + _update_sdl_screen_from_capture(); + } + + void _resize(Area size) + { + + _sdl_screen.construct(size); + _captured_screen.construct(_capture, _env.rm(), size); + _update_sdl_screen_from_capture(); + } + + Main(Env &env) : _env(env) + { + _resize(Area(_config.xml().attribute_value("width", 1024U), + _config.xml().attribute_value("height", 768U))); _timer.sigh(_timer_handler); _timer.trigger_periodic(100000000 / 5994); /* 59.94Hz */ @@ -244,7 +178,7 @@ struct Fb_sdl::Main }; -void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event) +void Fb_sdl::Main::_handle_sdl_event(Event_batch &batch, SDL_Event const &event) { using namespace Input; @@ -255,9 +189,7 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event) return; } - Framebuffer::Mode const mode { .area = { (unsigned)event.resize.w, - (unsigned)event.resize.h } }; - _fb_session.submit_mode_change(mode); + _resize(Area((unsigned)event.resize.w, (unsigned)event.resize.h)); return; } @@ -270,7 +202,7 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event) if (ox == _mx && oy == _my) return; - _input_session.submit(Absolute_motion{_mx, _my}); + batch.submit(Absolute_motion{_mx, _my}); return; } @@ -304,18 +236,18 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event) /* ignore */ return; - _input_session.submit(Release{keycode}); + batch.submit(Release{keycode}); return; case SDL_KEYDOWN: case SDL_MOUSEBUTTONDOWN: if (event.button.button == SDL_BUTTON_WHEELUP) - _input_session.submit(Wheel{0, 1}); + batch.submit(Wheel{0, 1}); else if (event.button.button == SDL_BUTTON_WHEELDOWN) - _input_session.submit(Wheel{0, -1}); + batch.submit(Wheel{0, -1}); else - _input_session.submit(Press{keycode}); + batch.submit(Press{keycode}); return; default: @@ -327,8 +259,12 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event) void Fb_sdl::Main::_handle_sdl_events() { SDL_Event event { }; - while (SDL_PollEvent(&event)) - _handle_sdl_event(event); + + _event.with_batch([&] (Event_batch &batch) { + + while (SDL_PollEvent(&event)) + _handle_sdl_event(batch, event); + }); } diff --git a/repos/os/src/test/framebuffer/main.cc b/repos/os/src/test/framebuffer/main.cc index e60c6a7327..890ac3b31b 100644 --- a/repos/os/src/test/framebuffer/main.cc +++ b/repos/os/src/test/framebuffer/main.cc @@ -1,13 +1,14 @@ /* - * \brief Basic test for framebuffer session + * \brief Basic test for framebuffer drivers * \author Martin Stein * \author Christian Helmuth * \author Stefan Kalkowski + * \author Norman Feske * \date 2012-01-09 */ /* - * 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. @@ -16,71 +17,107 @@ /* Genode includes */ #include #include -#include -#include -#include -#include +#include +#include +#include #include +namespace Test { -using Area = Genode::Surface_base::Area; -using Pixel = Genode::Pixel_rgb888; + using namespace Genode; -class Test_environment + using Area = Capture::Area; + using Point = Capture::Point; + using Pixel = Capture::Pixel; + + struct Capture_session; + class Main; +} + + +struct Test::Capture_session : Rpc_object +{ + Env &_env; + + Pixel const BLACK = { 0, 0, 0 }; + Pixel const BLUE = { 0, 0, 255 }; + Pixel const GREEN = { 0, 255, 0 }; + Pixel const RED = { 255, 0, 0 }; + Pixel const WHITE = { 255, 255, 255 }; + + enum State { STRIPES, ALL_BLUE, ALL_GREEN, ALL_RED, COLORED }; + + Area _size { 0, 0 }; + + Constructible _ds { }; + + State _state = STRIPES; + + unsigned long _sync_cnt = 0; + + enum { FRAME_CNT = 200 }; + + void _draw(); + + void _draw_frame(Pixel *, Pixel, Area); + + Capture_session(Env &env) : _env(env) { } + + + /******************************** + ** Capture::Session interface ** + ********************************/ + + Area screen_size() const override { return _size; } + + void screen_size_sigh(Signal_context_capability) override { } + + void buffer(Area size) override + { + _ds.construct(_env.ram(), _env.rm(), buffer_bytes(size)); + _size = size; + _draw(); + } + + Dataspace_capability dataspace() override + { + return _ds.constructed() ? _ds->cap() : Ram_dataspace_capability(); + } + + Affected_rects capture_at(Point) override + { + Affected_rects affected { }; + + if (_sync_cnt++ % FRAME_CNT == 0) { + _draw(); + affected.rects[0] = Rect(Point(0, 0), _size); + } + + return affected; + } +}; + + +class Test::Main { private: - using Ds = Genode::Constructible; + Env &_env; - Pixel const BLACK = { 0, 0, 0 }; - Pixel const BLUE = { 0, 0, 255 }; - Pixel const GREEN = { 0, 255, 0 }; - Pixel const RED = { 255, 0, 0 }; - Pixel const WHITE = { 255, 255, 255 }; + Capture_session _capture_session { _env }; - enum State { STRIPES, ALL_BLUE, ALL_GREEN, ALL_RED, COLORED }; - - Genode::Env &_env; - - Framebuffer::Mode _mode { }; - Framebuffer::Connection _fb { _env, _mode }; - Ds _fb_ds { }; - Genode::Signal_handler _mode_sigh; - Genode::Signal_handler _sync_sigh; - unsigned long _sync_cnt = 0; - State _state = STRIPES; - - enum { FRAME_CNT = 200 }; - - void _draw(); - void _mode_handle(); - - void _sync_handle() { - if (_sync_cnt++ % FRAME_CNT == 0) _draw(); } - - void _draw_frame(Pixel *, Pixel, Area); - - Genode::size_t _fb_bpp() { return _mode.bytes_per_pixel(); } - Genode::size_t _fb_size() { return _fb_ds->size(); } - Genode::addr_t _fb_base() { - return (Genode::addr_t) _fb_ds->local_addr(); } + Static_root _capture_root { _env.ep().manage(_capture_session) }; public: - Test_environment(Genode::Env &env) - : - _env(env), - _mode_sigh(_env.ep(), *this, &Test_environment::_mode_handle), - _sync_sigh(_env.ep(), *this, &Test_environment::_sync_handle) + Main(Env &env) : _env(env) { - _fb.mode_sigh(_mode_sigh); - _fb.sync_sigh(_sync_sigh); - _mode_handle(); + _env.parent().announce(env.ep().manage(_capture_root)); } }; -void Test_environment::_draw_frame(Pixel *p, Pixel c, Area area) +void Test::Capture_session::_draw_frame(Pixel *p, Pixel c, Area area) { unsigned const w = area.w(), h = area.h(); @@ -94,91 +131,81 @@ void Test_environment::_draw_frame(Pixel *p, Pixel c, Area area) } -void Test_environment::_draw() +void Test::Capture_session::_draw() { - using namespace Genode; + if (!_ds.constructed()) + return; + + addr_t const num_pixels = _size.count(); + + Pixel * const fb_base = _ds->local_addr(); switch(_state) { case STRIPES: { - Genode::log("black & white stripes"); - addr_t const stripe_width = _mode.area.w() / 4; + log("black & white stripes"); + addr_t const stripe_width = _size.w() / 4; addr_t stripe_o = 0; bool stripe = 0; - for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) { + for (addr_t o = 0; o < num_pixels; o++) { stripe_o++; if (stripe_o == stripe_width) { stripe_o = 0; stripe = !stripe; } - *(Pixel *)(_fb_base() + o) = stripe ? BLACK : WHITE; + fb_base[o] = stripe ? BLACK : WHITE; } - _draw_frame((Pixel *)_fb_base(), RED, _mode.area); + _draw_frame(fb_base, RED, _size); _state = ALL_BLUE; break; } case ALL_BLUE: { - Genode::log("blue"); - for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) - *(Pixel *)(_fb_base() + o) = BLUE; + log("blue"); + for (addr_t o = 0; o < num_pixels; o++) + fb_base[o] = BLUE; - _draw_frame((Pixel *)_fb_base(), RED, _mode.area); + _draw_frame(fb_base, RED, _size); _state = ALL_GREEN; break; } case ALL_GREEN: { - Genode::log("green"); - for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) - *(Pixel *)(_fb_base() + o) = GREEN; + log("green"); + for (addr_t o = 0; o < num_pixels; o++) + fb_base[o] = GREEN; - _draw_frame((Pixel *)_fb_base(), RED, _mode.area); + _draw_frame(fb_base, RED, _size); _state = ALL_RED; break; } case ALL_RED: { - Genode::log("red"); - for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) - *(Pixel *)(_fb_base() + o) = RED; + log("red"); + for (addr_t o = 0; o < num_pixels; o++) + fb_base[o] = RED; - _draw_frame((Pixel *)_fb_base(), WHITE, _mode.area); + _draw_frame(fb_base, WHITE, _size); _state = COLORED; break; } case COLORED: { - Genode::log("all colors mixed"); + log("all colors mixed"); unsigned i = 0; - for (addr_t o = 0; o < _fb_size(); o += _fb_bpp(), i++) - *(Pixel *)(_fb_base() + o) = Pixel(i>>16, i>>8, i); + for (addr_t o = 0; o < num_pixels; o++, i++) + fb_base[o] = Pixel(i>>16, i>>8, i); - _draw_frame((Pixel *)_fb_base(), WHITE, _mode.area); + _draw_frame(fb_base, WHITE, _size); _state = STRIPES; } }; - _fb.refresh(0, 0, _mode.area.w(), _mode.area.h()); -} - - -void Test_environment::_mode_handle() -{ - _mode = _fb.mode(); - if (_fb_ds.constructed()) - _fb_ds.destruct(); - - _fb_ds.construct(_env.rm(), _fb.dataspace()); - - Genode::log("framebuffer is ", _mode); - - _draw(); } void Component::construct(Genode::Env &env) { Genode::log("--- Test framebuffer ---"); - static Test_environment te(env); + static Test::Main main(env); } diff --git a/repos/ports/run/bash.run b/repos/ports/run/bash.run index 1c2de156ed..ca085052fe 100644 --- a/repos/ports/run/bash.run +++ b/repos/ports/run/bash.run @@ -11,6 +11,8 @@ import_from_depot [depot_user]/src/[base_src] \ [depot_user]/src/coreutils \ [depot_user]/src/vfs \ [depot_user]/src/vfs_pipe \ + [depot_user]/src/nitpicker \ + [depot_user]/src/gui_fb \ [depot_user]/src/fs_rom # write default vimrc file @@ -53,12 +55,35 @@ install_config { - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -66,6 +91,8 @@ install_config { + + @@ -125,6 +152,10 @@ install_config { } +set fd [open [run_dir]/genode/focus w] +puts $fd " \" domain=\"default\"/>" +close $fd + build { lib/ld test/fork test/execve } build_boot_image { ld.lib.so libc.lib.so libm.lib.so vfs.lib.so posix.lib.so } diff --git a/repos/ports/run/debug_nitpicker.run b/repos/ports/run/debug_nitpicker.run index 0f51e251df..1f2370ed47 100644 --- a/repos/ports/run/debug_nitpicker.run +++ b/repos/ports/run/debug_nitpicker.run @@ -70,20 +70,20 @@ install_config { - + + - - - + - + - + + - - - - + + + + } append_if [expr $use_framebuffer && [have_include "power_on/qemu"]] config { } @@ -408,7 +408,8 @@ append_if $use_usb config { append config { - + + @@ -430,16 +431,16 @@ append config { - - - + + - + + diff --git a/repos/ports/run/vbox5_genode_usb_hid.run b/repos/ports/run/vbox5_genode_usb_hid.run index 0bdb1cdb5f..99ee94fe13 100644 --- a/repos/ports/run/vbox5_genode_usb_hid.run +++ b/repos/ports/run/vbox5_genode_usb_hid.run @@ -146,19 +146,18 @@ append config { - - + - + - - + + diff --git a/repos/ports/run/vbox_share.inc b/repos/ports/run/vbox_share.inc index c8ccd6d5a1..1422479788 100644 --- a/repos/ports/run/vbox_share.inc +++ b/repos/ports/run/vbox_share.inc @@ -278,14 +278,14 @@ append config_of_app { - + - - + + diff --git a/repos/ports/run/vbox_win.inc b/repos/ports/run/vbox_win.inc index 553c969eff..348b1a0f36 100644 --- a/repos/ports/run/vbox_win.inc +++ b/repos/ports/run/vbox_win.inc @@ -125,9 +125,8 @@ append config_of_app { - + - @@ -182,7 +181,8 @@ append config_of_app { - + + @@ -198,7 +198,8 @@ append config_of_app { append_if [expr !$use_rumpfs] config_of_app { - + + diff --git a/repos/ports/run/vim.run b/repos/ports/run/vim.run index f591a256a0..eeef24f0d4 100644 --- a/repos/ports/run/vim.run +++ b/repos/ports/run/vim.run @@ -46,12 +46,11 @@ install_config { - + + - - - + @@ -66,8 +65,9 @@ install_config { - - + + + @@ -77,9 +77,8 @@ install_config { - - - + + diff --git a/repos/ports/run/virtualbox.run b/repos/ports/run/virtualbox.run index 511e2df5f5..35cbda963c 100644 --- a/repos/ports/run/virtualbox.run +++ b/repos/ports/run/virtualbox.run @@ -102,8 +102,7 @@ append_if [expr $use_usb] config { append_if [have_spec framebuffer] config { - - } + } append_if [expr [have_spec framebuffer] && [have_include power_on/qemu]] config { } append_if [expr [have_spec framebuffer] && [have_include power_on/qemu]] config { @@ -114,10 +113,7 @@ append_if [have_spec framebuffer] config { append_if [have_spec sdl] config { - - - - + } append_if [have_spec x86] config { @@ -169,9 +165,8 @@ append config { - + - } append_if [expr $use_ps2] config { @@ -182,7 +177,9 @@ append_if [expr $use_usb] config { append config { - + + + diff --git a/repos/ports/run/virtualbox_auto.inc b/repos/ports/run/virtualbox_auto.inc index 2c971cb09b..33ce58b735 100644 --- a/repos/ports/run/virtualbox_auto.inc +++ b/repos/ports/run/virtualbox_auto.inc @@ -352,8 +352,7 @@ append_if [have_spec framebuffer] config { - - + } append_if [have_spec x86] config {