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
This commit is contained in:
Norman Feske 2020-07-01 22:26:11 +02:00
parent 6743669ab8
commit c81af531a3
72 changed files with 1492 additions and 1908 deletions

View File

@ -9,13 +9,11 @@
<service name="CPU"/> <service name="CPU"/>
<service name="LOG"/> <service name="LOG"/>
<service name="Timer"/> <service name="Timer"/>
<service name="Capture"/>
</parent-provides> </parent-provides>
<default caps="60"/> <default caps="60"/>
<service name="Framebuffer">
<default-policy> <child name="fb_drv"/> </default-policy> </service>
<service name="Input"> <service name="Input">
<default-policy> <child name="usb_hid_drv"/> </default-policy> </service> <default-policy> <child name="usb_hid_drv"/> </default-policy> </service>
@ -57,7 +55,6 @@
<start name="fb_drv" caps="250"> <start name="fb_drv" caps="250">
<binary name="imx8_fb_drv"/> <binary name="imx8_fb_drv"/>
<resource name="RAM" quantum="80M"/> <resource name="RAM" quantum="80M"/>
<provides><service name="Framebuffer"/></provides>
<route> <route>
<service name="ROM" label="config"> <parent label="fb_drv.config"/> </service> <service name="ROM" label="config"> <parent label="fb_drv.config"/> </service>
<service name="IO_MEM"> <parent/> </service> <service name="IO_MEM"> <parent/> </service>
@ -68,6 +65,7 @@
<service name="CPU"> <parent/> </service> <service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service> <service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service> <service name="Timer"> <parent/> </service>
<service name="Capture"> <parent/> </service>
</route> </route>
</start> </start>
</config> </config>

View File

@ -9,13 +9,11 @@
<service name="CPU"/> <service name="CPU"/>
<service name="LOG"/> <service name="LOG"/>
<service name="Timer"/> <service name="Timer"/>
<service name="Capture"/>
</parent-provides> </parent-provides>
<default caps="60"/> <default caps="60"/>
<service name="Framebuffer">
<default-policy> <child name="fb_drv"/> </default-policy> </service>
<service name="Input"> <service name="Input">
<default-policy> <child name="input_drv"/> </default-policy> </service> <default-policy> <child name="input_drv"/> </default-policy> </service>
@ -39,7 +37,6 @@
<start name="fb_drv" caps="120"> <start name="fb_drv" caps="120">
<binary name="rpi_fb_drv"/> <binary name="rpi_fb_drv"/>
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides><service name="Framebuffer"/></provides>
<route> <route>
<service name="ROM" label="config"> <parent label="fb_drv.config"/> </service> <service name="ROM" label="config"> <parent label="fb_drv.config"/> </service>
<service name="Platform"> <child name="platform_drv"/> </service> <service name="Platform"> <child name="platform_drv"/> </service>
@ -49,6 +46,7 @@
<service name="CPU"> <parent/> </service> <service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service> <service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service> <service name="Timer"> <parent/> </service>
<service name="Capture"> <parent/> </service>
</route> </route>
</start> </start>

View File

@ -4,4 +4,4 @@ blit
platform_session platform_session
timer_session timer_session
report_session report_session
framebuffer_session capture_session

View File

@ -3,5 +3,5 @@ os
platform_session platform_session
timer_session timer_session
report_session report_session
framebuffer_session capture_session
blit blit

View File

@ -128,7 +128,6 @@ append config {
<start name="intel_fb_drv" caps="1000"> <start name="intel_fb_drv" caps="1000">
<resource name="RAM" quantum="60M"/> <resource name="RAM" quantum="60M"/>
<provides><service name="Framebuffer"/></provides>
<route> <route>
<service name="ROM" label="config"> <service name="ROM" label="config">
<child name="config_rom" label="fb_drv.config"/> </service> <child name="config_rom" label="fb_drv.config"/> </service>
@ -149,6 +148,8 @@ append config {
<start name="test-framebuffer" priority="-1"> <start name="test-framebuffer" priority="-1">
<resource name="RAM" quantum="10M"/> <resource name="RAM" quantum="10M"/>
<provides> <service name="Capture"/> </provides>
<config/>
</start> </start>
</config> </config>
</start> </start>

View File

@ -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 <base/component.h>
#include <base/rpc_server.h>
#include <root/component.h>
#include <dataspace/capability.h>
#include <framebuffer_session/framebuffer_session.h>
#include <timer_session/connection.h>
#include <util/reconstructible.h>
#include <base/attached_dataspace.h>
#include <base/attached_ram_dataspace.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
#include <os/pixel_rgb888.h>
#include <blit/blit.h>
#include <lx_emul_c.h>
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<Session>
{
private:
template <typename T> using Lazy = Genode::Constructible<T>;
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<unsigned>("force_width", 0);
}
int force_height_from_config()
{
return _config.xml().attribute_value<unsigned>("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<void>() || _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<char>() + 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<Framebuffer::Session_component, Genode::Single_client>
{
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<Session_component,
Genode::Single_client>(env.ep(), alloc),
session(env, config) { }
};
#endif /* __COMPONENT_H__ */

View File

@ -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 <base/component.h>
#include <dataspace/capability.h>
#include <capture_session/connection.h>
#include <timer_session/connection.h>
#include <util/reconstructible.h>
#include <base/attached_dataspace.h>
#include <base/attached_ram_dataspace.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
#include <lx_emul_c.h>
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<Capture::Connection::Screen> _captured_screen { };
Timer::Connection _capture_timer { _env };
Signal_handler<Driver> _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<Pixel> surface((Pixel *)_lx_config._lx.addr, phys_size);
_captured_screen->apply_to_surface(surface);
}
int _force_width_from_config()
{
return _config.xml().attribute_value<unsigned>("force_width", 0);
}
int _force_height_from_config()
{
return _config.xml().attribute_value<unsigned>("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__ */

View File

@ -17,7 +17,7 @@
#include <base/attached_io_mem_dataspace.h> #include <base/attached_io_mem_dataspace.h>
/* local includes */ /* local includes */
#include <component.h> #include <driver.h>
#include <lx_emul.h> #include <lx_emul.h>
#include <lx_emul_c.h> #include <lx_emul_c.h>
@ -1053,7 +1053,7 @@ Framebuffer::Driver::_preferred_mode(drm_connector *connector,
/* try to read configuration for connector */ /* try to read configuration for connector */
try { try {
Xml_node config = _session.config(); Xml_node config = _config.xml();
Xml_node xn = config.sub_node(); Xml_node xn = config.sub_node();
for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) { for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) {
if (!xn.has_type("connector")) if (!xn.has_type("connector"))
@ -1114,7 +1114,7 @@ void Framebuffer::Driver::finish_initialization()
generate_report(); generate_report();
_session.config_changed(); config_changed();
} }
@ -1122,21 +1122,21 @@ void Framebuffer::Driver::update_mode()
{ {
using namespace Genode; using namespace Genode;
Configuration old = _config; Configuration old = _lx_config;
_config = Configuration(); _lx_config = Configuration();
lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) { lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) {
unsigned brightness; unsigned brightness;
drm_display_mode * mode = _preferred_mode(c, brightness); drm_display_mode * mode = _preferred_mode(c, brightness);
if (!mode) return; if (!mode) return;
if (mode->hdisplay > _config._lx.width) _config._lx.width = mode->hdisplay; if (mode->hdisplay > _lx_config._lx.width) _lx_config._lx.width = mode->hdisplay;
if (mode->vdisplay > _config._lx.height) _config._lx.height = mode->vdisplay; 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"); Genode::error("updating framebuffer failed");
return; return;
} }
@ -1147,16 +1147,16 @@ void Framebuffer::Driver::update_mode()
unsigned brightness = MAX_BRIGHTNESS + 1; unsigned brightness = MAX_BRIGHTNESS + 1;
/* set mode */ /* 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)); _preferred_mode(c, brightness));
}); });
} }
/* force virtual framebuffer size if requested */ /* force virtual framebuffer size if requested */
if (int w = _session.force_width_from_config()) if (int w = _force_width_from_config())
_config._lx.width = min(_config._lx.width, w); _lx_config._lx.width = min(_lx_config._lx.width, w);
if (int h = _session.force_height_from_config()) if (int h = _force_height_from_config())
_config._lx.height = min(_config._lx.height, h); _lx_config._lx.height = min(_lx_config._lx.height, h);
if (old._lx.lx_fb) { if (old._lx.lx_fb) {
if (drm_framebuffer_read_refcount(old._lx.lx_fb) > 1) { if (drm_framebuffer_read_refcount(old._lx.lx_fb) > 1) {
@ -1197,8 +1197,8 @@ void Framebuffer::Driver::generate_report()
/* check for report configuration option */ /* check for report configuration option */
try { try {
_reporter.enabled(_session.config().sub_node("report") _reporter.enabled(_config.xml().sub_node("report")
.attribute_value(_reporter.name().string(), false)); .attribute_value(_reporter.name().string(), false));
} catch (...) { } catch (...) {
_reporter.enabled(false); _reporter.enabled(false);
} }

View File

@ -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 * This file is distributed under the terms of the GNU General Public License
* version 2. * version 2.
@ -19,8 +19,8 @@
#include <base/heap.h> #include <base/heap.h>
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
/* Server related local includes */ /* local includes */
#include <component.h> #include <driver.h>
/* Linux emulation environment includes */ /* Linux emulation environment includes */
#include <lx_emul.h> #include <lx_emul.h>
@ -32,7 +32,7 @@
#include <lx_kit/work.h> #include <lx_kit/work.h>
/* Linux module functions */ /* 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" void drm_connector_ida_init(); /* called by drm_core_init(void) normally */
extern "C" int module_irq_imx_irqsteer_init(); extern "C" int module_irq_imx_irqsteer_init();
extern "C" int module_imx_drm_pdrv_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_dcss_crtc_driver_init();
extern "C" int module_imx_hdp_imx_platform_driver_init(); extern "C" int module_imx_hdp_imx_platform_driver_init();
static void run_linux(void * m);
unsigned long jiffies; unsigned long jiffies;
namespace Framebuffer { struct Main; }
struct Main
struct Framebuffer::Main
{ {
Genode::Env &env; void _run_linux();
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 };
/**
* Entry for executing code in the Linux kernel context
*/
static void _run_linux_entry(void *m)
{
reinterpret_cast<Main*>(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 */ /* Linux task that handles the initialization */
Genode::Constructible<Lx::Task> linux; Constructible<Lx::Task> _linux;
Main(Genode::Env &env) : env(env) Signal_handler<Main> _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(bridge_lock);
LX_MUTEX_INIT(core_lock); LX_MUTEX_INIT(core_lock);
LX_MUTEX_INIT(component_mutex); LX_MUTEX_INIT(component_mutex);
/* init singleton Lx::Scheduler */ /* init singleton Lx::Scheduler */
Lx::scheduler(&env); Lx::scheduler(&_env);
Lx::malloc_init(env, heap); Lx::malloc_init(_env, _heap);
/* init singleton Lx::Timer */ /* init singleton Lx::Timer */
Lx::timer(&env, &ep, &heap, &jiffies); Lx::timer(&_env, &_ep, &_heap, &jiffies);
/* init singleton Lx::Irq */ /* init singleton Lx::Irq */
Lx::Irq::irq(&ep, &heap); Lx::Irq::irq(&_ep, &_heap);
/* init singleton Lx::Work */ /* init singleton Lx::Work */
Lx::Work::work_queue(&heap); Lx::Work::work_queue(&_heap);
linux.construct(run_linux, reinterpret_cast<void*>(this), _linux.construct(_run_linux_entry, reinterpret_cast<void*>(this),
"linux", Lx::Task::PRIORITY_0, Lx::scheduler()); "linux", Lx::Task::PRIORITY_0, Lx::scheduler());
/* give all task a first kick before returning */ /* give all task a first kick before returning */
Lx::scheduler().schedule(); 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<Policy_agent> 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<Main*>(m);
system_wq = alloc_workqueue("system_wq", 0, 0); system_wq = alloc_workqueue("system_wq", 0, 0);
radix_tree_init(); radix_tree_init();
@ -240,17 +229,17 @@ static void run_linux(void * m)
platform_device_register(display_subsystem_pdev); platform_device_register(display_subsystem_pdev);
main->root.session.driver().finish_initialization(); _driver.finish_initialization();
main->announce(); _driver.config_sigh(_policy_change_handler);
Policy_agent pa(*main); _config.sigh(_policy_change_handler);
main->root.session.driver().config_sigh(pa.handler);
main->config.sigh(pa.handler);
while (1) { while (1) {
Lx::scheduler().current()->block_and_schedule(); Lx::scheduler().current()->block_and_schedule();
while (pa.pending()) while (_policy_change_pending) {
main->root.session.config_changed(); _policy_change_pending = false;
_driver.config_changed();
}
} }
} }
@ -260,5 +249,5 @@ void Component::construct(Genode::Env &env)
/* XXX execute constructors of global statics */ /* XXX execute constructors of global statics */
env.exec_static_constructors(); env.exec_static_constructors();
static Main m(env); static Framebuffer::Main main(env);
} }

View File

@ -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 <base/component.h>
#include <base/rpc_server.h>
#include <root/component.h>
#include <dataspace/capability.h>
#include <framebuffer_session/framebuffer_session.h>
#include <timer_session/connection.h>
#include <util/reconstructible.h>
#include <base/attached_dataspace.h>
#include <base/attached_ram_dataspace.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
#include <blit/blit.h>
#include <lx_emul_c.h>
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<Driver> _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<Session>
{
private:
template <typename T> using Lazy = Genode::Constructible<T>;
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<Genode::uint64_t>("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<unsigned>("force_width", 0);
}
int force_height_from_config()
{
return _config.xml().attribute_value<unsigned>("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<void>() ||
_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<char>() + 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<Framebuffer::Session_component, Genode::Single_client>
{
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<Session_component,
Genode::Single_client>(env.ep(), alloc),
session(env, config) { }
};
#endif /* __COMPONENT_H__ */

View File

@ -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 <base/component.h>
#include <dataspace/capability.h>
#include <capture_session/connection.h>
#include <timer_session/connection.h>
#include <util/reconstructible.h>
#include <base/attached_dataspace.h>
#include <base/attached_ram_dataspace.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
#include <lx_emul_c.h>
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<Driver> _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<uint64_t>("poll", 0); }
/*
* Capture
*/
Capture::Connection _capture { _env };
Constructible<Capture::Connection::Screen> _captured_screen { };
Timer::Connection _capture_timer { _env };
Signal_handler<Driver> _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<Pixel> surface((Pixel *)_lx_config._lx.addr, phys_size);
_captured_screen->apply_to_surface(surface);
}
int _force_width_from_config()
{
return _config.xml().attribute_value<unsigned>("force_width", 0);
}
int _force_height_from_config()
{
return _config.xml().attribute_value<unsigned>("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__ */

View File

@ -19,7 +19,7 @@
#include <os/reporter.h> #include <os/reporter.h>
/* local includes */ /* local includes */
#include <component.h> #include <driver.h>
/* DRM-specific includes */ /* DRM-specific includes */
#include <lx_emul.h> #include <lx_emul.h>
@ -100,7 +100,7 @@ Framebuffer::Driver::_preferred_mode(drm_connector *connector,
/* try to read configuration for connector */ /* try to read configuration for connector */
try { try {
Xml_node config = _session.config(); Xml_node config = _config.xml();
Xml_node xn = config.sub_node(); Xml_node xn = config.sub_node();
for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) { for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) {
if (!xn.has_type("connector")) if (!xn.has_type("connector"))
@ -157,7 +157,7 @@ void Framebuffer::Driver::finish_initialization()
lx_c_set_driver(lx_drm_device, (void*)this); lx_c_set_driver(lx_drm_device, (void*)this);
generate_report(); generate_report();
_session.config_changed(); Driver::config_changed();
} }
@ -189,20 +189,20 @@ void Framebuffer::Driver::update_mode()
{ {
using namespace Genode; using namespace Genode;
Configuration old = _config; Configuration old = _lx_config;
_config = Configuration(); _lx_config = Configuration();
lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) { lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) {
unsigned brightness; unsigned brightness;
drm_display_mode * mode = _preferred_mode(c, brightness); drm_display_mode * mode = _preferred_mode(c, brightness);
if (!mode) return; if (!mode) return;
if (mode->hdisplay > _config._lx.width) _config._lx.width = mode->hdisplay; if (mode->hdisplay > _lx_config._lx.width) _lx_config._lx.width = mode->hdisplay;
if (mode->vdisplay > _config._lx.height) _config._lx.height = mode->vdisplay; 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"); Genode::error("updating framebuffer failed");
return; return;
} }
@ -213,7 +213,7 @@ void Framebuffer::Driver::update_mode()
unsigned brightness = MAX_BRIGHTNESS + 1; unsigned brightness = MAX_BRIGHTNESS + 1;
/* set mode */ /* 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)); _preferred_mode(c, brightness));
/* set sane brightness, ignore unsane values and let as is */ /* 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 */ /* force virtual framebuffer size if requested */
if (int w = _session.force_width_from_config()) if (int w = _force_width_from_config())
_config._lx.width = min(_config._lx.width, w); _lx_config._lx.width = min(_lx_config._lx.width, w);
if (int h = _session.force_height_from_config()) if (int h = _force_height_from_config())
_config._lx.height = min(_config._lx.height, h); _lx_config._lx.height = min(_lx_config._lx.height, h);
if (old._lx.addr) Lx::iounmap(old._lx.addr); if (old._lx.addr) Lx::iounmap(old._lx.addr);
if (old._lx.lx_fb) { if (old._lx.lx_fb) {
@ -268,7 +268,7 @@ void Framebuffer::Driver::generate_report()
/* check for report configuration option */ /* check for report configuration option */
try { try {
_reporter.enabled(_session.config().sub_node("report") _reporter.enabled(_config.xml().sub_node("report")
.attribute_value(_reporter.name().string(), false)); .attribute_value(_reporter.name().string(), false));
} catch (...) { } catch (...) {
_reporter.enabled(false); _reporter.enabled(false);

View File

@ -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 * This file is distributed under the terms of the GNU General Public License
* version 2. * version 2.
@ -18,8 +18,8 @@
#include <base/heap.h> #include <base/heap.h>
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
/* Server related local includes */ /* local includes */
#include <component.h> #include <driver.h>
/* Linux emulation environment includes */ /* Linux emulation environment includes */
#include <lx_emul.h> #include <lx_emul.h>
@ -33,110 +33,102 @@
#include <lx_kit/work.h> #include <lx_kit/work.h>
/* Linux module functions */ /* Linux module functions */
extern "C" void postcore_i2c_init(void); /* i2c-core-base.c */ extern "C" void postcore_i2c_init(void); /* i2c-core-base.c */
extern "C" int module_i915_init(); /* i915_drv.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 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" void drm_connector_ida_init(); /* called by drm_core_init(void) normally */
static void run_linux(void * m);
unsigned long jiffies; unsigned long jiffies;
namespace Framebuffer { struct Main; }
struct Main
struct Framebuffer::Main
{ {
Genode::Env &env; void _run_linux();
Genode::Entrypoint &ep { env.ep() };
Genode::Attached_rom_dataspace config { env, "config" }; /**
Genode::Heap heap { env.ram(), env.rm() }; * Entry for executing code in the Linux kernel context
Framebuffer::Root root { env, heap, config }; */
static void _run_linux_entry(void *m)
{
reinterpret_cast<Main*>(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 */ /* Linux task that handles the initialization */
Genode::Constructible<Lx::Task> linux; Constructible<Lx::Task> _linux;
Main(Genode::Env &env) : env(env) Signal_handler<Main> _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(bridge_lock);
LX_MUTEX_INIT(core_lock); LX_MUTEX_INIT(core_lock);
/* init singleton Lx::Scheduler */ /* init singleton Lx::Scheduler */
Lx::scheduler(&env); Lx::scheduler(&_env);
Lx::pci_init(env, env.ram(), heap); Lx::pci_init(_env, _env.ram(), _heap);
Lx::malloc_init(env, heap); Lx::malloc_init(_env, _heap);
/* init singleton Lx::Timer */ /* init singleton Lx::Timer */
Lx::timer(&env, &ep, &heap, &jiffies); Lx::timer(&_env, &_ep, &_heap, &jiffies);
/* init singleton Lx::Irq */ /* init singleton Lx::Irq */
Lx::Irq::irq(&ep, &heap); Lx::Irq::irq(&_ep, &_heap);
/* init singleton Lx::Work */ /* init singleton Lx::Work */
Lx::Work::work_queue(&heap); Lx::Work::work_queue(&_heap);
linux.construct(run_linux, reinterpret_cast<void*>(this), _linux.construct(_run_linux_entry, reinterpret_cast<void*>(this),
"linux", Lx::Task::PRIORITY_0, Lx::scheduler()); "linux", Lx::Task::PRIORITY_0, Lx::scheduler());
/* give all task a first kick before returning */ /* give all task a first kick before returning */
Lx::scheduler().schedule(); 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<Policy_agent> 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<Main*>(m);
system_wq = alloc_workqueue("system_wq", 0, 0); system_wq = alloc_workqueue("system_wq", 0, 0);
radix_tree_init(); radix_tree_init();
drm_connector_ida_init(); drm_connector_ida_init();
postcore_i2c_init(); postcore_i2c_init();
module_i915_init(); module_i915_init();
main->root.session.driver().finish_initialization();
main->announce();
Policy_agent pa(*main); _driver.finish_initialization();
main->root.session.driver().config_sigh(pa.handler); _driver.config_sigh(_policy_change_handler);
main->config.sigh(pa.handler);
_config.sigh(_policy_change_handler);
while (1) { while (1) {
Lx::scheduler().current()->block_and_schedule(); Lx::scheduler().current()->block_and_schedule();
while (pa.pending()) while (_policy_change_pending) {
main->root.session.config_changed(); _policy_change_pending = false;
_driver.config_changed();
}
} }
} }
@ -146,5 +138,5 @@ void Component::construct(Genode::Env &env)
/* XXX execute constructors of global statics */ /* XXX execute constructors of global statics */
env.exec_static_constructors(); env.exec_static_constructors();
static Main m(env); static Framebuffer::Main main(env);
} }

View File

@ -11,6 +11,7 @@
<service name="LOG"/> <service name="LOG"/>
<service name="Timer"/> <service name="Timer"/>
<service name="Report"/> <service name="Report"/>
<service name="Capture"/>
</parent-provides> </parent-provides>
<default-route> <default-route>
@ -19,9 +20,6 @@
<default caps="100"/> <default caps="100"/>
<service name="Framebuffer">
<default-policy> <child name="dynamic"/> </default-policy> </service>
<service name="Block"> <service name="Block">
<default-policy> <child name="dynamic"/> </default-policy> </service> <default-policy> <child name="dynamic"/> </default-policy> </service>
@ -228,6 +226,7 @@
<service name="IO_MEM"> <parent/> </service> <service name="IO_MEM"> <parent/> </service>
<service name="IO_PORT"> <parent/> </service> <service name="IO_PORT"> <parent/> </service>
<service name="Timer"> <parent/> </service> <service name="Timer"> <parent/> </service>
<service name="Capture"> <parent/> </service>
</route> </route>
</start> </start>

View File

@ -3,6 +3,6 @@ os
report_session report_session
block_session block_session
usb_session usb_session
framebuffer_session capture_session
timer_session timer_session
platform_session platform_session

View File

@ -37,18 +37,19 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<domain name="pointer" layer="1" label="no" content="client" origin="pointer" /> <domain name="pointer" layer="1" label="no" content="client" origin="pointer" />
<domain name="default" layer="2" label="no" content="client" hover="always" /> <domain name="default" layer="2" label="no" content="client" hover="always" />

View File

@ -39,12 +39,11 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="report_rom"> <start name="report_rom">
@ -58,8 +57,9 @@ install_config {
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides> <service name="Gui"/> </provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<report pointer="yes" /> <report pointer="yes" />
<domain name="default" layer="2" content="client" label="no"/> <domain name="default" layer="2" content="client" label="no"/>
<default-policy domain="default"/> <default-policy domain="default"/>
@ -168,6 +168,7 @@ install_config {
</service> </service>
<any-service> <parent/> <any-child/> </any-service> <any-service> <parent/> <any-child/> </any-service>
</route> </route>
<config> <default-policy/> </config>
</start> </start>
</config>} </config>}

View File

@ -41,18 +41,18 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker" caps="200"> <start name="nitpicker" caps="200">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides> <service name="Gui"/> </provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<domain name="" layer="2" content="client" label="no" /> <domain name="" layer="2" content="client" label="no" />
<default-policy domain=""/> <default-policy domain=""/>
<report pointer="yes" /> <report pointer="yes" />

View File

@ -50,18 +50,18 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom"> <config focus="rom" request_framebuffer="no">
<capture/>
<background color="#123456"/> <background color="#123456"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="3" content="client" label="no" hover="always" /> <domain name="default" layer="3" content="client" label="no" hover="always" />

View File

@ -11,6 +11,7 @@ import_from_depot [depot_user]/src/[base_src] \
[depot_user]/pkg/drivers_managed-pc \ [depot_user]/pkg/drivers_managed-pc \
[depot_user]/src/report_rom \ [depot_user]/src/report_rom \
[depot_user]/src/dynamic_rom \ [depot_user]/src/dynamic_rom \
[depot_user]/src/nitpicker \
[depot_user]/src/init [depot_user]/src/init
install_config { install_config {
@ -41,6 +42,7 @@ install_config {
<provides> <service name="Report"/> <service name="ROM"/> </provides> <provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="yes"> <config verbose="yes">
<policy label="test-driver_manager -> block_devices" report="drivers -> block_devices"/> <policy label="test-driver_manager -> block_devices" report="drivers -> block_devices"/>
<policy label="test-driver_manager -> displays" report="nitpicker -> displays"/>
</config> </config>
</start> </start>
@ -57,13 +59,13 @@ install_config {
<service name="ROM" label="numlock"> <child name="dynamic_rom"/> </service> <service name="ROM" label="numlock"> <child name="dynamic_rom"/> </service>
<service name="ROM" label="system"> <child name="dynamic_rom"/> </service> <service name="ROM" label="system"> <child name="dynamic_rom"/> </service>
<service name="ROM" label="usb_policy"><child name="dynamic_rom"/> </service> <service name="ROM" label="usb_policy"><child name="dynamic_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Report"> <child name="report_rom"/> </service> <service name="Capture"> <child name="nitpicker"/> </service>
<service name="Report"> <child name="report_rom"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides>
<service name="Input"/> <service name="Input"/>
<service name="Framebuffer"/>
<service name="Block"/> <service name="Block"/>
</provides> </provides>
</start> </start>
@ -95,16 +97,30 @@ install_config {
</config> </config>
</start> </start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no" request_input="no">
<capture/>
<report displays="yes"/>
</config>
<route>
<service name="Report"> <child name="report_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="test-driver_manager"> <start name="test-driver_manager">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<config> <config>
<check_ahci_block_device label="ahci-1" block_count="65536" block_size="512" <check_ahci_block_device label="ahci-1" block_count="65536" block_size="512"
model="QEMU HARDDISK"/> model="QEMU HARDDISK"/>
<check_input/> <check_input/>
<check_framebuffer/> <check_displays/>
</config> </config>
<route> <route>
<service name="ROM" label="block_devices"> <child name="report_rom"/> </service> <service name="ROM" label="block_devices"> <child name="report_rom"/> </service>
<service name="ROM" label="displays"> <child name="report_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service> <any-service> <parent/> <any-child/> </any-service>
</route> </route>
</start> </start>

View File

@ -36,18 +36,19 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="3" content="client" label="no" focus="click" hover="always" /> <domain name="default" layer="3" content="client" label="no" focus="click" hover="always" />

View File

@ -70,12 +70,11 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="report_rom"> <start name="report_rom">
@ -93,8 +92,9 @@ install_config {
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom"> <config focus="rom" request_framebuffer="no">
<capture/>
<report hover="yes" displays="yes"/> <report hover="yes" displays="yes"/>
<background color="#000000"/> <background color="#000000"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
@ -226,7 +226,7 @@ install_config {
<start name="ahci-2"> <start name="ahci-2">
<binary name="vfs_block"/> <binary name="vfs_block"/>
<resource name="RAM" quantum="10M"/> <resource name="RAM" quantum="12M"/>
<provides> <service name="Block"/> </provides> <provides> <service name="Block"/> </provides>
<config> <config>
<vfs> <vfs>

View File

@ -40,18 +40,19 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<background color="#123456"/> <background color="#123456"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="3" content="client" label="no" hover="always" /> <domain name="default" layer="3" content="client" label="no" hover="always" />

View File

@ -31,12 +31,11 @@ append config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="timer"> <start name="timer">
@ -46,8 +45,10 @@ append config {
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<domain name="default" layer="2" content="client" label="no"/> <domain name="default" layer="2" content="client" label="no"/>
<domain name="nano3d" layer="1" content="client" label="no" origin="pointer"/> <domain name="nano3d" layer="1" content="client" label="no" origin="pointer"/>

View File

@ -254,13 +254,13 @@ install_config {
<service name="ROM" label_last="usb_policy"> <service name="ROM" label_last="usb_policy">
<child name="config_fs_rom" label="usb"/> </service> <child name="config_fs_rom" label="usb"/> </service>
<service name="ROM" label_last="numlock"> <child name="report_rom"/> </service> <service name="ROM" label_last="numlock"> <child name="report_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Report"> <child name="fs_report"/> </service> <service name="Capture"> <child name="nitpicker"/> </service>
<service name="Report"> <child name="fs_report"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides>
<service name="Input"/> <service name="Input"/>
<service name="Framebuffer"/>
<service name="Block"/> <service name="Block"/>
<service name="Usb"/> <service name="Usb"/>
<service name="Platform"/> <service name="Platform"/>
@ -269,7 +269,7 @@ install_config {
<start name="nitpicker" caps="1000"> <start name="nitpicker" caps="1000">
<resource name="RAM" quantum="6M"/> <resource name="RAM" quantum="6M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<route> <route>
<service name="ROM" label="config"> <service name="ROM" label="config">
<child name="config_fs_rom" label="nitpicker"/> </service> <child name="config_fs_rom" label="nitpicker"/> </service>
@ -277,10 +277,9 @@ install_config {
<child name="nit_focus"/> </service> <child name="nit_focus"/> </service>
<service name="Report" label="keystate"> <service name="Report" label="keystate">
<child name="report_logger"/> </service> <child name="report_logger"/> </service>
<service name="Report"> <child name="report_rom"/> </service> <service name="Report"> <child name="report_rom"/> </service>
<service name="Framebuffer"> <child name="drivers"/> </service> <service name="Input"> <child name="drivers"/> </service>
<service name="Input"> <child name="drivers"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
</start> </start>

View File

@ -1,6 +1,8 @@
<config focus="rom"> <config focus="rom" request_framebuffer="no">
<capture/>
<report hover="yes" focus="yes" clicked="yes" keystate="no" displays="yes"/> <report hover="yes" focus="yes" clicked="yes" keystate="no" displays="yes"/>
<background color="#000000"/> <background color="#000000"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="lock" layer="2" content="client" label="no" hover="always" focus="click"/> <domain name="lock" layer="2" content="client" label="no" hover="always" focus="click"/>
<domain name="leitzentrale" layer="3" content="client" label="no" hover="always" focus="click" /> <domain name="leitzentrale" layer="3" content="client" label="no" hover="always" focus="click" />

View File

@ -40,26 +40,25 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="2M"/> <resource name="RAM" quantum="2M"/>
<provides> <service name="Gui"/> </provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="2" content="client" label="no" focus="click" hover="always" /> <domain name="default" layer="2" content="client" label="no" focus="click" hover="always" />
<policy label_prefix="pointer" domain="pointer"/> <policy label_prefix="pointer" domain="pointer"/>
<default-policy domain="default"/> <default-policy domain="default"/>
</config> </config>
<route> <route>
<service name="Input"> <child name="drivers"/> </service> <service name="Input"> <child name="drivers"/> </service>
<service name="Framebuffer"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service> <any-service> <parent/> <any-child/> </any-service>
</route> </route>
</start> </start>

View File

@ -40,12 +40,11 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="report_rom"> <start name="report_rom">
@ -59,8 +58,9 @@ install_config {
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom"> <config focus="rom" request_framebuffer="no">
<capture/>
<report hover="yes"/> <report hover="yes"/>
<background color="#123456"/> <background color="#123456"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />

View File

@ -5,6 +5,8 @@ import_from_depot [depot_user]/src/[base_src] \
[depot_user]/src/init \ [depot_user]/src/init \
[depot_user]/src/libc \ [depot_user]/src/libc \
[depot_user]/src/vfs \ [depot_user]/src/vfs \
[depot_user]/src/nitpicker \
[depot_user]/src/gui_fb \
[depot_user]/raw/ttf-bitstream-vera-minimal [depot_user]/raw/ttf-bitstream-vera-minimal
install_config { install_config {
@ -36,12 +38,36 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/> </start>
</provides>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<domain name="default" layer="2" content="client" label="no"
hover="always" width="1024" height="768"/>
<default-policy domain="default"/>
</config>
<route>
<service name="Input"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="gui_fb">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Framebuffer"/> <service name="Input"/> </provides>
<config/>
<route>
<service name="Gui"> <child name="nitpicker"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start> </start>
<start name="font_vfs"> <start name="font_vfs">
@ -70,6 +96,10 @@ install_config {
build { server/vfs test/text_painter lib/vfs/ttf } build { server/vfs test/text_painter lib/vfs/ttf }
set fd [open [run_dir]/genode/focus w]
puts $fd "<focus label=\"gui_fb -> \" domain=\"default\"/>"
close $fd
build_boot_image { vfs test-text_painter vfs_ttf.lib.so } build_boot_image { vfs test-text_painter vfs_ttf.lib.so }
run_genode_until forever run_genode_until forever

View File

@ -43,18 +43,19 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom"> <config focus="rom" request_framebuffer="no">
<capture/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="2" content="client" label="no" hover="always"/> <domain name="default" layer="2" content="client" label="no" hover="always"/>

View File

@ -18,7 +18,7 @@
#include <os/reporter.h> #include <os/reporter.h>
#include <block_session/block_session.h> #include <block_session/block_session.h>
#include <rm_session/rm_session.h> #include <rm_session/rm_session.h>
#include <framebuffer_session/framebuffer_session.h> #include <capture_session/capture_session.h>
#include <io_mem_session/io_mem_session.h> #include <io_mem_session/io_mem_session.h>
#include <io_port_session/io_port_session.h> #include <io_port_session/io_port_session.h>
#include <timer_session/timer_session.h> #include <timer_session/timer_session.h>
@ -128,13 +128,11 @@ struct Driver_manager::Intel_fb_driver : Device_driver
_gen_common_start_node_content(xml, "intel_fb_drv", "intel_fb_drv", _gen_common_start_node_content(xml, "intel_fb_drv", "intel_fb_drv",
Ram_quota{42*1024*1024}, Cap_quota{800}, Ram_quota{42*1024*1024}, Cap_quota{800},
Priority{0}); Priority{0});
_gen_provides_node<Framebuffer::Session>(xml);
xml.node("route", [&] () { xml.node("route", [&] () {
_gen_config_route(xml, "fb_drv.config"); _gen_config_route(xml, "fb_drv.config");
_gen_default_parent_route(xml); _gen_default_parent_route(xml);
}); });
}); });
_gen_forwarded_service<Framebuffer::Session>(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", _gen_common_start_node_content(xml, "vesa_fb_drv", "vesa_fb_drv",
Ram_quota{8*1024*1024}, Cap_quota{100}, Ram_quota{8*1024*1024}, Cap_quota{100},
Priority{-1}); Priority{-1});
_gen_provides_node<Framebuffer::Session>(xml);
xml.node("route", [&] () { xml.node("route", [&] () {
_gen_config_route(xml, "fb_drv.config"); _gen_config_route(xml, "fb_drv.config");
_gen_default_parent_route(xml); _gen_default_parent_route(xml);
}); });
}); });
_gen_forwarded_service<Framebuffer::Session>(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", _gen_common_start_node_content(xml, "fb_boot_drv", "fb_boot_drv",
_ram_quota, Cap_quota{100}, _ram_quota, Cap_quota{100},
Priority{-1}); Priority{-1});
_gen_provides_node<Framebuffer::Session>(xml);
xml.node("route", [&] () { xml.node("route", [&] () {
_gen_config_route(xml, "fb_drv.config"); _gen_config_route(xml, "fb_drv.config");
_gen_default_parent_route(xml); _gen_default_parent_route(xml);
}); });
}); });
_gen_forwarded_service<Framebuffer::Session>(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, Platform::Session::service_name());
_gen_parent_service_xml(xml, Report::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, Usb::Session::service_name());
_gen_parent_service_xml(xml, Capture::Session::service_name());
}); });

View File

@ -16,7 +16,6 @@
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
#include <base/allocator_avl.h> #include <base/allocator_avl.h>
#include <base/heap.h> #include <base/heap.h>
#include <framebuffer_session/connection.h>
#include <input_session/connection.h> #include <input_session/connection.h>
#include <block_session/connection.h> #include <block_session/connection.h>
@ -32,6 +31,7 @@ struct Test::Main
Attached_rom_dataspace _config { _env, "config" }; Attached_rom_dataspace _config { _env, "config" };
Attached_rom_dataspace _block_devices { _env, "block_devices" }; 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) 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()); 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"); log("all expected devices present and accessible");
} }
@ -121,12 +129,6 @@ struct Test::Main
Main(Env &env) : _env(env) 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")) { if (_config.xml().has_sub_node("check_input")) {
log("connect to input driver"); log("connect to input driver");
Input::Connection input(_env); Input::Connection input(_env);

View File

@ -3,4 +3,4 @@ os
blit blit
platform_session platform_session
timer_session timer_session
framebuffer_session capture_session

View File

@ -53,18 +53,18 @@ set config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker" caps="200"> <start name="nitpicker" caps="200">
<resource name="RAM" quantum="2M"/> <resource name="RAM" quantum="2M"/>
<provides> <service name="Gui"/> </provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="2" content="client" label="no" focus="click" hover="always" /> <domain name="default" layer="2" content="client" label="no" focus="click" hover="always" />
<policy label_prefix="pointer" domain="pointer"/> <policy label_prefix="pointer" domain="pointer"/>

View File

@ -39,18 +39,19 @@ set config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> </provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom"> <config focus="rom" request_framebuffer="no">
<capture/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="2" content="client" label="no" hover="always"/> <domain name="default" layer="2" content="client" label="no" hover="always"/>

View File

@ -177,26 +177,28 @@ proc qt5_start_nodes { } {
<service name="ROM" label="input_filter.config"> <parent label="qt5_input_filter.config"/> </service> <service name="ROM" label="input_filter.config"> <parent label="qt5_input_filter.config"/> </service>
<service name="ROM" label="input_filter -> capslock"> <child name="wm_report_rom"/> </service> <service name="ROM" label="input_filter -> capslock"> <child name="wm_report_rom"/> </service>
<service name="ROM" label="input_filter -> numlock.remap"> <child name="numlock_remap_rom"/> </service> <service name="ROM" label="input_filter -> numlock.remap"> <child name="numlock_remap_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker" caps="200"> <start name="nitpicker" caps="200">
<resource name="RAM" quantum="2M"/> <resource name="RAM" quantum="2M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<route> <route>
<service name="Report"> <child name="wm_report_rom"/> </service> <service name="Report"> <child name="wm_report_rom"/> </service>
<any-service> <parent /> <any-child /> </any-service> <any-service> <parent /> <any-child /> </any-service>
</route> </route>
<config> <config request_framebuffer="no">
<capture/>
<report focus="yes" hover="yes" xray="yes"/> <report focus="yes" hover="yes" xray="yes"/>
<domain name="pointer" layer="1" label="no" content="client" origin="pointer" /> <domain name="pointer" layer="1" label="no" content="client" origin="pointer" />
<domain name="default" layer="2" label="no" content="client" focus="click" hover="always" /> <domain name="default" layer="2" label="no" content="client"
focus="click" hover="always" width="1024" height="768"/>
<policy label_prefix="pointer" domain="pointer"/> <policy label_prefix="pointer" domain="pointer"/>
<default-policy domain="default"/> <default-policy domain="default"/>

View File

@ -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 * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
@ -17,231 +17,150 @@
#include <base/component.h> #include <base/component.h>
#include <base/heap.h> #include <base/heap.h>
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
#include <base/attached_ram_dataspace.h>
#include <root/component.h>
#include <util/reconstructible.h> #include <util/reconstructible.h>
#include <util/arg_string.h>
#include <blit/blit.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
#include <framebuffer_session/framebuffer_session.h> #include <capture_session/connection.h>
#include <blit/painter.h>
#include <os/pixel_rgb888.h>
/* local includes */ /* local includes */
#include "framebuffer.h" #include "framebuffer.h"
namespace Vesa_driver {
namespace Framebuffer { using namespace Genode;
struct Session_component;
struct Root;
struct Main; 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<Session> 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; Heap _heap { _env.ram(), _env.rm() };
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<Attached_ram_dataspace> _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<char>() + 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);
}
}
/*********************************** /*
** Framebuffer session interface ** * Config
***********************************/ */
Dataspace_capability dataspace() override Attached_rom_dataspace _config { _env, "config" };
{
return _buffered() ? Dataspace_capability(_bb->cap())
: Dataspace_capability(_fb_cap);
}
Mode mode() const override Area _size { 1, 1 };
{
return Mode { .area = { _scr_width, _scr_height } };
}
void mode_sigh(Genode::Signal_context_capability) override { } void _handle_config();
void sync_sigh(Genode::Signal_context_capability sigh) override Signal_handler<Main> _config_handler { _env.ep(), *this, &Main::_handle_config };
{
_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);
}
};
/** /*
* Shortcut for single-client root component * Capture
*/ */
typedef Genode::Root_component<Framebuffer::Session_component,
Genode::Single_client> Root_component;
class Framebuffer::Root : public Root_component Capture::Connection _capture { _env };
{
private:
Genode::Env &_env; Constructible<Capture::Connection::Screen> _captured_screen { };
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)
{ }
};
struct Framebuffer::Main /*
{ * Timer
Genode::Env &env; */
Genode::Heap heap { env.ram(), env.rm() }; Timer::Connection _timer { _env };
Attached_rom_dataspace config { env, "config" }; Signal_handler<Main> _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<Attached_dataspace> _fb_ds { };
Main(Env &env) : _env(env)
{ {
Genode::log("modified"); _config.sigh(_config_handler);
try { Framebuffer::init(env, heap); } catch (...) { _timer.sigh(_timer_handler);
Genode::error("H/W driver init failed");
throw;
}
env.parent().announce(env.ep().manage(root)); _handle_config();
} }
}; };
void Vesa_driver::Main::_handle_timer()
{
if (!_fb_ds.constructed())
return;
Surface<Pixel> surface(_fb_ds->local_addr<Pixel>(), _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) void Component::construct(Genode::Env &env)
{ {
/* XXX execute constructors of global statics */ /* XXX execute constructors of global statics */
env.exec_static_constructors(); env.exec_static_constructors();
static Framebuffer::Main inst(env); static Vesa_driver::Main inst(env);
} }

View File

@ -1,3 +1,4 @@
_/src/fb_sdl _/src/fb_sdl
_/src/input_filter _/src/input_filter
_/src/input_event_bridge
_/raw/drivers_interactive-linux _/raw/drivers_interactive-linux

View File

@ -10,13 +10,11 @@
<service name="CPU"/> <service name="CPU"/>
<service name="LOG"/> <service name="LOG"/>
<service name="Timer"/> <service name="Timer"/>
<service name="Capture"/>
</parent-provides> </parent-provides>
<default caps="60"/> <default caps="60"/>
<service name="Framebuffer">
<default-policy> <child name="fb_drv"/> </default-policy> </service>
<service name="Input"> <service name="Input">
<default-policy> <child name="dummy_input_drv"/> </default-policy> </service> <default-policy> <child name="dummy_input_drv"/> </default-policy> </service>
@ -59,7 +57,6 @@
<start name="fb_drv" caps="120"> <start name="fb_drv" caps="120">
<binary name="imx53_fb_drv"/> <binary name="imx53_fb_drv"/>
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides><service name="Framebuffer"/></provides>
<config width="800" height="480" display="0" buffered="true"/> <config width="800" height="480" display="0" buffered="true"/>
<route> <route>
<service name="ROM" label="config"> <parent label="fb_drv.config"/> </service> <service name="ROM" label="config"> <parent label="fb_drv.config"/> </service>
@ -70,6 +67,7 @@
<service name="CPU"> <parent/> </service> <service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service> <service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service> <service name="Timer"> <parent/> </service>
<service name="Capture"> <parent/> </service>
</route> </route>
</start> </start>
@ -77,10 +75,10 @@
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides> <service name="Input"/> </provides> <provides> <service name="Input"/> </provides>
<route> <route>
<service name="ROM"> <parent/> </service> <service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service> <service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service> <service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service> <service name="LOG"> <parent/> </service>
</route> </route>
</start> </start>
</config> </config>

View File

@ -5,21 +5,25 @@
<service name="CPU"/> <service name="CPU"/>
<service name="LOG"/> <service name="LOG"/>
<service name="Timer"/> <service name="Timer"/>
<service name="Capture"/>
</parent-provides> </parent-provides>
<service name="Framebuffer">
<default-policy> <child name="fb_sdl"/> </default-policy> </service>
<service name="Input"> <service name="Input">
<default-policy> <child name="input_filter"/> </default-policy> </service> <default-policy> <child name="input_filter"/> </default-policy> </service>
<start name="input_event_bridge" caps="100">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Input"/> <service name="Event"/> </provides>
<route> <any-service> <parent/> </any-service> </route>
<config/>
</start>
<start name="fb_sdl" caps="100" ld="no"> <start name="fb_sdl" caps="100" ld="no">
<resource name="RAM" quantum="10M"/> <resource name="RAM" quantum="10M"/>
<provides> <route>
<service name="Input"/> <service name="Event"> <child name="input_event_bridge"/> </service>
<service name="Framebuffer"/> <any-service> <parent/> </any-service>
</provides> </route>
<route> <any-service> <parent/> </any-service> </route>
</start> </start>
<start name="input_filter" caps="80"> <start name="input_filter" caps="80">
@ -27,7 +31,7 @@
<provides> <service name="Input"/> </provides> <provides> <service name="Input"/> </provides>
<route> <route>
<service name="ROM" label="config"> <parent label="input_filter.config"/> </service> <service name="ROM" label="config"> <parent label="input_filter.config"/> </service>
<service name="Input" label="sdl"> <child name="fb_sdl"/> </service> <service name="Input" label="sdl"> <child name="input_event_bridge"/> </service>
<service name="ROM"> <parent/> </service> <service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service> <service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service> <service name="CPU"> <parent/> </service>

View File

@ -7,13 +7,11 @@
<service name="CPU"/> <service name="CPU"/>
<service name="LOG"/> <service name="LOG"/>
<service name="Timer"/> <service name="Timer"/>
<service name="Capture"/>
</parent-provides> </parent-provides>
<default caps="100"/> <default caps="100"/>
<service name="Framebuffer">
<default-policy> <child name="fb_drv"/> </default-policy> </service>
<service name="Input"> <service name="Input">
<default-policy> <child name="input_filter"/> </default-policy> </service> <default-policy> <child name="input_filter"/> </default-policy> </service>
@ -64,25 +62,23 @@
<start name="fb_drv"> <start name="fb_drv">
<binary name="pl11x_fb_drv"/> <binary name="pl11x_fb_drv"/>
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides> <service name="Framebuffer"/> </provides>
<route> <route>
<service name="Platform"> <service name="Platform">
<child name="platform_drv"/> <child name="platform_drv"/>
</service> </service>
<service name="ROM"> <parent/> </service> <service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service> <service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service> <service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service> <service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service> <service name="Timer"> <parent/> </service>
<service name="Capture"> <parent/> </service>
</route> </route>
</start> </start>
<start name="ps2_drv"> <start name="ps2_drv">
<binary name="pl050_input_drv"/> <binary name="pl050_input_drv"/>
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
<route> <route>
<service name="Platform"> <service name="Platform">
<child name="platform_drv"/> <child name="platform_drv"/>

View File

@ -10,13 +10,11 @@
<service name="CPU"/> <service name="CPU"/>
<service name="LOG"/> <service name="LOG"/>
<service name="Timer"/> <service name="Timer"/>
<service name="Capture"/>
</parent-provides> </parent-provides>
<default caps="60"/> <default caps="60"/>
<service name="Framebuffer">
<default-policy> <child name="fb_drv"/> </default-policy> </service>
<service name="Input"> <service name="Input">
<default-policy> <child name="input_filter"/> </default-policy> </service> <default-policy> <child name="input_filter"/> </default-policy> </service>
@ -77,8 +75,7 @@
<start name="fb_drv" caps="120"> <start name="fb_drv" caps="120">
<binary name="vesa_fb_drv"/> <binary name="vesa_fb_drv"/>
<resource name="RAM" quantum="8M"/> <resource name="RAM" quantum="16M"/>
<provides><service name="Framebuffer"/></provides>
<route> <route>
<service name="ROM" label="config"> <parent label="fb_drv.config"/> </service> <service name="ROM" label="config"> <parent label="fb_drv.config"/> </service>
<service name="Platform"> <child name="platform_drv"/> </service> <service name="Platform"> <child name="platform_drv"/> </service>
@ -89,6 +86,7 @@
<service name="CPU"> <parent/> </service> <service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service> <service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service> <service name="Timer"> <parent/> </service>
<service name="Capture"> <parent/> </service>
</route> </route>
</start> </start>

View File

@ -1,5 +1,5 @@
base base
os os
blit blit
framebuffer_session capture_session
timer_session timer_session

View File

@ -1,7 +1,7 @@
base-linux base-linux
base base
os os
input_session event_session
framebuffer_session
timer_session timer_session
capture_session
blit blit

View File

@ -3,6 +3,6 @@ os
blit blit
platform_session platform_session
gpio_session gpio_session
framebuffer_session capture_session
input_session input_session
timer_session timer_session

View File

@ -1,6 +1,6 @@
base base
os os
framebuffer_session capture_session
input_session input_session
platform_session platform_session
timer_session timer_session

View File

@ -2,4 +2,4 @@ base
os os
blit blit
platform_session platform_session
framebuffer_session capture_session

View File

@ -46,12 +46,11 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="report_rom"> <start name="report_rom">
@ -69,16 +68,18 @@ install_config {
<start name="nitpicker_config"> <start name="nitpicker_config">
<binary name="rom_filter"/> <binary name="rom_filter"/>
<resource name="RAM" quantum="1096K"/> <resource name="RAM" quantum="1096K"/>
<provides><service name="ROM"/></provides> <provides> <service name="ROM"/> </provides>
<config> <config>
<input name="xray_enabled" rom="xray" node="xray"> <input name="xray_enabled" rom="xray" node="xray">
<attribute name="enabled" /> </input> <attribute name="enabled" /> </input>
<output node="config"> <output node="config">
<attribute name="request_framebuffer" value="no"/>
<attribute name="focus" value="rom"/> <attribute name="focus" value="rom"/>
<inline> <inline>
<report focus="yes" xray="yes" hover="yes" keystate="yes" <report focus="yes" xray="yes" hover="yes" keystate="yes"
clicked="yes"/> clicked="yes"/>
<capture/>
<domain name="pointer" layer="1" origin="pointer" <domain name="pointer" layer="1" origin="pointer"
content="client" label="no"/> content="client" label="no"/>
<domain name="panel" layer="2" <domain name="panel" layer="2"
@ -149,7 +150,7 @@ install_config {
<start name="nitpicker" caps="120"> <start name="nitpicker" caps="120">
<resource name="RAM" quantum="1216K"/> <resource name="RAM" quantum="1216K"/>
<provides> <service name="Gui"/> </provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<route> <route>
<service name="ROM" label="config"> <service name="ROM" label="config">
<child name="nitpicker_config"/> </service> <child name="nitpicker_config"/> </service>

View File

@ -15,6 +15,8 @@ if {[get_cmd_switch --autopilot] && [have_spec linux]} {
create_boot_directory create_boot_directory
import_from_depot [depot_user]/src/[base_src] \ import_from_depot [depot_user]/src/[base_src] \
[depot_user]/pkg/[drivers_interactive_pkg] \ [depot_user]/pkg/[drivers_interactive_pkg] \
[depot_user]/src/nitpicker \
[depot_user]/src/gui_fb \
[depot_user]/src/init [depot_user]/src/init
build { test/fb_bench } build { test/fb_bench }
@ -45,12 +47,35 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/> </start>
</provides>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<domain name="default" layer="1" width="1024" height="768"/>
<default-policy domain="default"/>
</config>
<route>
<service name="Input"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="gui_fb">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Framebuffer"/> <service name="Input"/> </provides>
<config/>
<route>
<service name="Gui"> <child name="nitpicker"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start> </start>
<start name="test-fb_bench"> <start name="test-fb_bench">
@ -60,9 +85,14 @@ install_config {
- RAM. - RAM.
--> -->
<resource name="RAM" quantum="72M"/> <resource name="RAM" quantum="72M"/>
<config/>
</start> </start>
</config>} </config>}
set fd [open [run_dir]/genode/focus w]
puts $fd "<focus label=\"gui_fb -> \" domain=\"default\"/>"
close $fd
build_boot_image { test-fb_bench } build_boot_image { test-fb_bench }
# disable QEMU graphic to enable testing on our machines without SDL and X # disable QEMU graphic to enable testing on our machines without SDL and X

View File

@ -32,16 +32,17 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="test-framebuffer"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="test-framebuffer"> <start name="test-framebuffer">
<resource name="RAM" quantum="10M"/> <resource name="RAM" quantum="10M"/>
<provides> <service name="Capture"/> </provides>
<config/>
</start> </start>
</config>} </config>}

View File

@ -36,18 +36,18 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides> <service name="Gui"/> </provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<domain name="" layer="2" /> <default-policy domain=""/> <domain name="" layer="2" /> <default-policy domain=""/>
</config> </config>
</start> </start>

View File

@ -12,6 +12,7 @@ set build_components {
server/report_rom server/report_rom
server/dynamic_rom server/dynamic_rom
server/nitpicker server/nitpicker
server/input_event_bridge
app/pointer app/pointer
test/pointer test/pointer
test/nitpicker test/nitpicker
@ -49,22 +50,31 @@ set config {
<service name="LOG"> <parent/> </service> <service name="LOG"> <parent/> </service>
</route> </route>
</start> </start>
<start name="fb_sdl" ld="no"> <start name="input_event_bridge">
<resource name="RAM" quantum="6M"/> <resource name="RAM" quantum="1M"/>
<provides> <provides>
<service name="Framebuffer"/> <service name="Event"/>
<service name="Input"/> <service name="Input"/>
</provides> </provides>
<config buffered="yes" width="1280" height="720" depth="16"/> <config/>
<route> <route>
<service name="ROM"> <parent/> </service> <any-service> <parent/> </any-service>
<service name="CPU"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <child name="timer"/> </service>
</route> </route>
</start> </start>
<alias name="input_drv" child="fb_sdl"/> <start name="fb_sdl" ld="no">
<resource name="RAM" quantum="6M"/>
<config buffered="yes" width="1280" height="720" depth="16"/>
<route>
<service name="ROM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="input_event_bridge"/> </service>
</route>
</start>
<alias name="input_drv" child="input_event_bridge"/>
<alias name="fb_drv" child="fb_sdl"/> <alias name="fb_drv" child="fb_sdl"/>
<start name="report_rom_nitpicker"> <start name="report_rom_nitpicker">
@ -85,8 +95,9 @@ set config {
</start> </start>
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> </provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config request_framebuffer="no">
<capture/>
<report focus="yes" hover="yes" xray="yes"/> <report focus="yes" hover="yes" xray="yes"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer"/> <domain name="pointer" layer="1" content="client" label="no" origin="pointer"/>
<domain name="default" layer="3" content="client" label="yes" hover="always" focus="click"/> <domain name="default" layer="3" content="client" label="yes" hover="always" focus="click"/>
@ -102,7 +113,6 @@ set config {
<service name="PD"> <parent/> </service> <service name="PD"> <parent/> </service>
<service name="LOG"> <parent/> </service> <service name="LOG"> <parent/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Framebuffer"> <child name="fb_drv"/> </service>
<service name="Input"> <child name="input_drv"/> </service> <service name="Input"> <child name="input_drv"/> </service>
<service name="Report"> <child name="report_rom_nitpicker"/> </service> <service name="Report"> <child name="report_rom_nitpicker"/> </service>
</route> </route>
@ -282,6 +292,7 @@ set boot_modules {
pointer pointer
test-pointer test-pointer
testnit testnit
input_event_bridge
} }
# "lsort -unique" removes duplicates but core must be first # "lsort -unique" removes duplicates but core must be first

View File

@ -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 <framebuffer.h>
#include <base/component.h>
#include <blit/blit.h>
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<char>() + bpp*width*y1 + bpp*x1;
char *dst = _fb_mem->local_addr<char>() + 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();
}

View File

@ -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 <base/component.h>
#include <framebuffer_session/framebuffer_session.h>
#include <base/attached_io_mem_dataspace.h>
#include <base/attached_ram_dataspace.h>
#include <base/signal.h>
#include <util/reconstructible.h>
#include <timer_session/connection.h>
#include <util/xml_node.h>
#include <os/pixel_rgb565.h>
#include <os/pixel_rgb888.h>
namespace Framebuffer {
class Session_component;
}
class Framebuffer::Session_component : public Genode::Rpc_object<Framebuffer::Session>
{
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<Genode::Attached_io_mem_dataspace> _fb_mem { };
Genode::Constructible<Genode::Attached_ram_dataspace> _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_

View File

@ -1,11 +1,12 @@
/* /*
* \brief Framebuffer driver that uses a framebuffer supplied by the core rom. * \brief Framebuffer driver that uses a framebuffer supplied by the core rom.
* \author Johannes Kliemann * \author Johannes Kliemann
* \author Norman Feske
* \date 2017-06-12 * \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 * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
@ -13,35 +14,102 @@
#include <base/component.h> #include <base/component.h>
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
#include <base/attached_io_mem_dataspace.h>
#include <dataspace/capability.h> #include <dataspace/capability.h>
#include <os/static_root.h> #include <capture_session/connection.h>
#include <timer_session/connection.h>
#include <framebuffer.h> 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 &_env;
env,
"platform_info"
};
Framebuffer::Session_component fb { Attached_rom_dataspace _platform_info { _env, "platform_info" };
env,
pinfo.xml(),
};
Genode::Static_root<Framebuffer::Session> fb_root {env.ep().manage(fb)}; struct Info
Main(Genode::Env &env) : env(env)
{ {
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<Main> _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<Pixel> surface(_fb_ds.local_addr<Pixel>(), 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); }
}

View File

@ -1,4 +1,3 @@
TARGET = fb_boot_drv TARGET = fb_boot_drv
LIBS = base blit LIBS = base blit
SRC_CC = main.cc framebuffer.cc SRC_CC = main.cc
INC_DIR += $(PRG_DIR)/include

View File

@ -16,21 +16,15 @@
#include <base/attached_dataspace.h> #include <base/attached_dataspace.h>
#include <base/component.h> #include <base/component.h>
#include <base/log.h> #include <base/log.h>
#include <dataspace/client.h>
#include <framebuffer_session/framebuffer_session.h>
#include <os/static_root.h>
#include <platform_session/connection.h> #include <platform_session/connection.h>
#include <platform_device/client.h> #include <platform_device/client.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
#include <capture_session/connection.h>
#include <blit/painter.h>
#include <os/pixel_rgb888.h>
namespace Pl11x_driver
/***********************************************
** Implementation of the framebuffer service **
***********************************************/
namespace Framebuffer
{ {
enum { enum {
SCR_WIDTH = 640, SCR_WIDTH = 640,
SCR_HEIGHT = 480, SCR_HEIGHT = 480,
@ -45,154 +39,51 @@ namespace Framebuffer
FRAMEBUFFER_SIZE = SCR_WIDTH*SCR_HEIGHT*BYTES_PER_PIXEL, FRAMEBUFFER_SIZE = SCR_WIDTH*SCR_HEIGHT*BYTES_PER_PIXEL,
}; };
class Session_component;
using namespace Genode; using namespace Genode;
class Main; class Main;
} }
class Framebuffer::Session_component :
public Genode::Rpc_object<Framebuffer::Session> struct Pl11x_driver::Main
{ {
private: using Area = Capture::Area;
Ram_dataspace_capability _fb_ds_cap; Env &_env;
addr_t _regs_base;
addr_t _sys_regs_base;
Timer::Connection _timer;
enum { Area const _size { SCR_WIDTH, SCR_HEIGHT };
/**
* 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 { }
};
struct Framebuffer::Main /*
{ * Capture
Env & _env; */
Capture::Connection _capture { _env };
Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size };
/*
* Timer
*/
Timer::Connection _timer { _env };
Signal_handler<Main> _timer_handler { _env.ep(), *this, &Main::_handle_timer };
void _handle_timer()
{
using Pixel = Capture::Pixel;
Surface<Pixel> surface(_fb_ds.local_addr<Pixel>(), _size);
_captured_screen.apply_to_surface(surface);
}
/*
* Driver
*/
Platform::Connection _platform { _env }; Platform::Connection _platform { _env };
Platform::Device_client _pl11x_dev { Platform::Device_client _pl11x_dev {
_platform.device_by_property("compatible", "arm,pl111") }; _platform.device_by_property("compatible", "arm,pl111") };
@ -204,34 +95,122 @@ struct Framebuffer::Main
_sp810_dev.io_mem_dataspace() }; _sp810_dev.io_mem_dataspace() };
Ram_dataspace_capability _fb_ds_cap { Ram_dataspace_capability _fb_ds_cap {
_platform.alloc_dma_buffer(FRAMEBUFFER_SIZE) }; _platform.alloc_dma_buffer(FRAMEBUFFER_SIZE) };
Attached_dataspace _fb_ds { _env.rm(), _fb_ds_cap };
Session_component _fb_session { _env, void _init_device();
_lcd_io_mem.local_addr<void*>(),
_sys_mem.local_addr<void*>(),
_fb_ds_cap,
_platform.bus_addr_dma_buffer(_fb_ds_cap) };
Static_root<Session> _fb_root { _env.ep().manage(_fb_session) };
Main(Env &env) : _env(env) Main(Env &env) : _env(env)
{ {
log("--- pl11x framebuffer driver ---\n"); _init_device();
/* announce service */ _timer.sigh(_timer_handler);
_env.parent().announce(env.ep().manage(_fb_root)); _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<void*>();
addr_t const sys_regs_base = (addr_t)_sys_mem.local_addr<void*>();
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;
/* /* init color-lcd oscillator */
* Noncopyable sys_reg_write(SP810_REG_LOCK, 0xa05f);
*/ sys_reg_write(SP810_REG_OSCCLCD, 0x2c77);
Main(Main const &); sys_reg_write(SP810_REG_LOCK, 0);
Main &operator = (Main const &);
}; /* 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) void Component::construct(Genode::Env &env)
{ {
static Framebuffer::Main main(env); static Pl11x_driver::Main main(env);
} }

View File

@ -1,4 +1,4 @@
TARGET = pl11x_fb_drv TARGET = pl11x_fb_drv
REQUIRES = arm_v7 REQUIRES = arm_v7
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base LIBS = base blit

View File

@ -21,12 +21,14 @@
#include <io_mem_session/connection.h> #include <io_mem_session/connection.h>
#include <platform_session/connection.h> #include <platform_session/connection.h>
#include <util/mmio.h> #include <util/mmio.h>
#include <capture_session/connection.h>
/* local includes */ /* local includes */
#include <ipu.h> #include <ipu.h>
namespace Framebuffer { namespace Framebuffer {
using namespace Genode; using namespace Genode;
using Area = Capture::Area;
class Driver; class Driver;
}; };
@ -46,7 +48,7 @@ class Framebuffer::Driver
public: public:
enum Resolutions { BYTES_PER_PIXEL = 2 }; enum Resolutions { BYTES_PER_PIXEL = 4 };
Driver(Genode::Env &env, Genode::Xml_node config) Driver(Genode::Env &env, Genode::Xml_node config)
: _env(env), : _env(env),
@ -66,7 +68,8 @@ class Framebuffer::Driver
return true; return true;
} }
Mode mode() { return Mode { .area = { _width, _height } }; } Area screen_size() const { return Area { _width, _height }; }
Ipu &ipu() { return _ipu; } Ipu &ipu() { return _ipu; }
}; };

View File

@ -2,152 +2,78 @@
* \brief Frame-buffer driver for the i.MX53 * \brief Frame-buffer driver for the i.MX53
* \author Nikolay Golikov <nik@ksyslabs.org> * \author Nikolay Golikov <nik@ksyslabs.org>
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com> * \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
* \author Norman Feske
* \date 2012-06-21 * \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 */ /* Genode includes */
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
#include <base/attached_ram_dataspace.h>
#include <base/component.h> #include <base/component.h>
#include <base/log.h> #include <base/log.h>
#include <imx_framebuffer_session/imx_framebuffer_session.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
#include <dataspace/client.h> #include <dataspace/client.h>
#include <os/static_root.h>
#include <blit/blit.h>
/* local includes */ /* local includes */
#include <driver.h> #include <driver.h>
namespace Framebuffer { namespace Framebuffer {
using namespace Genode; using namespace Genode;
class Session_component; struct Main;
}; };
class Framebuffer::Session_component : struct Framebuffer::Main
public Genode::Rpc_object<Framebuffer::Imx_session>
{ {
private: using Pixel = Capture::Pixel;
/* Env &_env;
* Noncopyable
*/
Session_component(Session_component const &);
Session_component &operator = (Session_component const &);
Genode::Env &_env; Attached_rom_dataspace _config { _env, "config" };
bool _buffered; Driver _driver { _env, _config.xml() };
Mode _mode;
size_t _size;
/* dataspace uses a back buffer (if '_buffered' is true) */ Area const _size = _driver.screen_size();
Genode::Dataspace_capability _bb_ds;
void *_bb_addr;
/* dataspace of physical frame buffer */ Attached_ram_dataspace _fb_ds { _env.ram(), _env.rm(),
Genode::Dataspace_capability _fb_ds; _size.count()*sizeof(Pixel), WRITE_COMBINED };
void *_fb_addr;
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) Signal_handler<Main> _timer_handler { _env.ep(), *this, &Main::_handle_timer };
{
/* 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(); void _handle_timer()
/* 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<Framebuffer::Session> _fb_root {
_ep.manage(_fb_session) };
Main(Genode::Env &env) : _env(env), _ep(_env.ep())
{ {
Genode::log("--- i.MX53 framebuffer driver ---"); Surface<Pixel> surface(_fb_ds.local_addr<Pixel>(), _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); }

View File

@ -17,131 +17,59 @@
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
#include <base/component.h> #include <base/component.h>
#include <util/reconstructible.h> #include <util/reconstructible.h>
#include <os/static_root.h> #include <capture_session/connection.h>
#include <framebuffer_session/framebuffer_session.h>
#include <platform_session/connection.h> #include <platform_session/connection.h>
#include <blit/blit.h> #include <blit/blit.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
namespace Framebuffer { namespace Framebuffer {
using namespace Genode; using namespace Genode;
class Session_component;
struct Main; struct Main;
}; };
class Framebuffer::Session_component : public Genode::Rpc_object<Framebuffer::Session>
{
private:
size_t const _width;
size_t const _height;
Constructible<Attached_ram_dataspace> _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<char>() + bypp*(_width*y1 + x1),
*dst = _fb_mem.local_addr<char>() + 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 struct Framebuffer::Main
{ {
Env &_env; using Area = Capture::Area;
Entrypoint &_ep; using Pixel = Capture::Pixel;
Env &_env;
Attached_rom_dataspace _config { _env, "config" }; Attached_rom_dataspace _config { _env, "config" };
Platform::Connection _platform { _env }; Platform::Connection _platform { _env };
Platform::Framebuffer_info _fb_info { 1024, 768, 32 }; Area const _size { 1024, 768 };
Constructible<Framebuffer::Session_component> _fb_session { }; Platform::Framebuffer_info _fb_info { _size.w(), _size.h(), 32 };
Constructible<Static_root<Framebuffer::Session>> _fb_root { };
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<Main> _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<Pixel> surface(_fb_ds.local_addr<Pixel>(), phys_size);
_fb_session.construct(_env, _fb_info.addr, _fb_info.size, _captured_screen.apply_to_surface(surface);
_fb_info.phys_width, _fb_info.phys_height, }
config_buffered(_config.xml()));
_fb_root.construct(_ep.manage(*_fb_session)); Main(Genode::Env &env) : _env(env)
{
log("--- rpi_fb_drv started ---");
/* announce service */ _timer.sigh(_timer_handler);
env.parent().announce(_ep.manage(*_fb_root)); _timer.trigger_periodic(10*1000);
} }
}; };

View File

@ -15,10 +15,9 @@
/* Genode includes */ /* Genode includes */
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
#include <base/component.h> #include <base/component.h>
#include <framebuffer_session/framebuffer_session.h> #include <event_session/connection.h>
#include <input/root.h> #include <capture_session/connection.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
#include <blit/blit.h>
/* Linux includes */ /* Linux includes */
#include <SDL/SDL.h> #include <SDL/SDL.h>
@ -26,12 +25,6 @@
/* local includes */ /* local includes */
#include "convert_keycode.h" #include "convert_keycode.h"
namespace Framebuffer {
class Session_component;
using namespace Genode;
}
namespace Fb_sdl { namespace Fb_sdl {
class Main; class Main;
using namespace Genode; using namespace Genode;
@ -44,140 +37,6 @@ struct Sdl_videodriver_not_supported : Genode::Exception { };
struct Sdl_setvideomode_failed : Genode::Exception { }; struct Sdl_setvideomode_failed : Genode::Exception { };
class Framebuffer::Session_component : public Rpc_object<Session>
{
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<Attached_ram_dataspace> _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<char>(), 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<char>();
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 struct Fb_sdl::Main
{ {
Env &_env; Env &_env;
@ -185,34 +44,15 @@ struct Fb_sdl::Main
Attached_rom_dataspace _config { _env, "config" }; Attached_rom_dataspace _config { _env, "config" };
Timer::Connection _timer { _env }; Timer::Connection _timer { _env };
Event::Connection _event { _env };
unsigned const _fb_width = _config.xml().attribute_value("width", 1024UL); using Area = Capture::Area;
unsigned const _fb_height = _config.xml().attribute_value("height", 768UL); 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 } }; void _init_sdl()
Framebuffer::Session_component _fb_session { _env, _fb_mode };
Static_root<Framebuffer::Session> _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<Main> _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)
{ {
/* /*
* Initialize libSDL window * Initialize libSDL window
@ -234,9 +74,103 @@ struct Fb_sdl::Main
} }
SDL_ShowCursor(0); SDL_ShowCursor(0);
}
_env.parent().announce(env.ep().manage(_fb_root)); bool const _sdl_initialized = ( _init_sdl(), true );
_env.parent().announce(env.ep().manage(_input_root));
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 <typename FN>
void with_surface(FN const &fn)
{
Surface<Pixel> 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> _sdl_screen { };
Capture::Connection _capture { _env };
Constructible<Capture::Connection::Screen> _captured_screen { };
Signal_handler<Main> _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<Pixel> &surface) {
_captured_screen->with_texture([&] (Texture<Pixel> 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.sigh(_timer_handler);
_timer.trigger_periodic(100000000 / 5994); /* 59.94Hz */ _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; using namespace Input;
@ -255,9 +189,7 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event)
return; return;
} }
Framebuffer::Mode const mode { .area = { (unsigned)event.resize.w, _resize(Area((unsigned)event.resize.w, (unsigned)event.resize.h));
(unsigned)event.resize.h } };
_fb_session.submit_mode_change(mode);
return; return;
} }
@ -270,7 +202,7 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event)
if (ox == _mx && oy == _my) if (ox == _mx && oy == _my)
return; return;
_input_session.submit(Absolute_motion{_mx, _my}); batch.submit(Absolute_motion{_mx, _my});
return; return;
} }
@ -304,18 +236,18 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event)
/* ignore */ /* ignore */
return; return;
_input_session.submit(Release{keycode}); batch.submit(Release{keycode});
return; return;
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_WHEELUP) 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) else if (event.button.button == SDL_BUTTON_WHEELDOWN)
_input_session.submit(Wheel{0, -1}); batch.submit(Wheel{0, -1});
else else
_input_session.submit(Press{keycode}); batch.submit(Press{keycode});
return; return;
default: default:
@ -327,8 +259,12 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event)
void Fb_sdl::Main::_handle_sdl_events() void Fb_sdl::Main::_handle_sdl_events()
{ {
SDL_Event event { }; 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);
});
} }

View File

@ -1,13 +1,14 @@
/* /*
* \brief Basic test for framebuffer session * \brief Basic test for framebuffer drivers
* \author Martin Stein * \author Martin Stein
* \author Christian Helmuth * \author Christian Helmuth
* \author Stefan Kalkowski * \author Stefan Kalkowski
* \author Norman Feske
* \date 2012-01-09 * \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 * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
@ -16,71 +17,107 @@
/* Genode includes */ /* Genode includes */
#include <base/component.h> #include <base/component.h>
#include <base/log.h> #include <base/log.h>
#include <framebuffer_session/connection.h> #include <os/static_root.h>
#include <base/attached_dataspace.h> #include <capture_session/capture_session.h>
#include <os/surface.h> #include <base/attached_ram_dataspace.h>
#include <os/pixel_rgb888.h>
#include <util/reconstructible.h> #include <util/reconstructible.h>
namespace Test {
using Area = Genode::Surface_base::Area; using namespace Genode;
using Pixel = Genode::Pixel_rgb888;
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<Capture::Session>
{
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<Attached_ram_dataspace> _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: private:
using Ds = Genode::Constructible<Genode::Attached_dataspace>; Env &_env;
Pixel const BLACK = { 0, 0, 0 }; Capture_session _capture_session { _env };
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 }; Static_root<Capture::Session> _capture_root { _env.ep().manage(_capture_session) };
Genode::Env &_env;
Framebuffer::Mode _mode { };
Framebuffer::Connection _fb { _env, _mode };
Ds _fb_ds { };
Genode::Signal_handler<Test_environment> _mode_sigh;
Genode::Signal_handler<Test_environment> _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<void>(); }
public: public:
Test_environment(Genode::Env &env) Main(Env &env) : _env(env)
:
_env(env),
_mode_sigh(_env.ep(), *this, &Test_environment::_mode_handle),
_sync_sigh(_env.ep(), *this, &Test_environment::_sync_handle)
{ {
_fb.mode_sigh(_mode_sigh); _env.parent().announce(env.ep().manage(_capture_root));
_fb.sync_sigh(_sync_sigh);
_mode_handle();
} }
}; };
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(); 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<Pixel>();
switch(_state) { switch(_state) {
case STRIPES: case STRIPES:
{ {
Genode::log("black & white stripes"); log("black & white stripes");
addr_t const stripe_width = _mode.area.w() / 4; addr_t const stripe_width = _size.w() / 4;
addr_t stripe_o = 0; addr_t stripe_o = 0;
bool stripe = 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++; stripe_o++;
if (stripe_o == stripe_width) { if (stripe_o == stripe_width) {
stripe_o = 0; stripe_o = 0;
stripe = !stripe; 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; _state = ALL_BLUE;
break; break;
} }
case ALL_BLUE: case ALL_BLUE:
{ {
Genode::log("blue"); log("blue");
for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) for (addr_t o = 0; o < num_pixels; o++)
*(Pixel *)(_fb_base() + o) = BLUE; fb_base[o] = BLUE;
_draw_frame((Pixel *)_fb_base(), RED, _mode.area); _draw_frame(fb_base, RED, _size);
_state = ALL_GREEN; _state = ALL_GREEN;
break; break;
} }
case ALL_GREEN: case ALL_GREEN:
{ {
Genode::log("green"); log("green");
for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) for (addr_t o = 0; o < num_pixels; o++)
*(Pixel *)(_fb_base() + o) = GREEN; fb_base[o] = GREEN;
_draw_frame((Pixel *)_fb_base(), RED, _mode.area); _draw_frame(fb_base, RED, _size);
_state = ALL_RED; _state = ALL_RED;
break; break;
} }
case ALL_RED: case ALL_RED:
{ {
Genode::log("red"); log("red");
for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) for (addr_t o = 0; o < num_pixels; o++)
*(Pixel *)(_fb_base() + o) = RED; fb_base[o] = RED;
_draw_frame((Pixel *)_fb_base(), WHITE, _mode.area); _draw_frame(fb_base, WHITE, _size);
_state = COLORED; _state = COLORED;
break; break;
} }
case COLORED: case COLORED:
{ {
Genode::log("all colors mixed"); log("all colors mixed");
unsigned i = 0; unsigned i = 0;
for (addr_t o = 0; o < _fb_size(); o += _fb_bpp(), i++) for (addr_t o = 0; o < num_pixels; o++, i++)
*(Pixel *)(_fb_base() + o) = Pixel(i>>16, i>>8, 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; _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) void Component::construct(Genode::Env &env)
{ {
Genode::log("--- Test framebuffer ---"); Genode::log("--- Test framebuffer ---");
static Test_environment te(env); static Test::Main main(env);
} }

View File

@ -11,6 +11,8 @@ import_from_depot [depot_user]/src/[base_src] \
[depot_user]/src/coreutils \ [depot_user]/src/coreutils \
[depot_user]/src/vfs \ [depot_user]/src/vfs \
[depot_user]/src/vfs_pipe \ [depot_user]/src/vfs_pipe \
[depot_user]/src/nitpicker \
[depot_user]/src/gui_fb \
[depot_user]/src/fs_rom [depot_user]/src/fs_rom
# write default vimrc file # write default vimrc file
@ -53,12 +55,35 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/> </start>
</provides>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<domain name="default" layer="2" content="client" label="no" hover="always"/>
<default-policy domain="default"/>
</config>
<route>
<service name="Input"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="gui_fb">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Framebuffer"/> <service name="Input"/> </provides>
<config/>
<route>
<service name="Gui"> <child name="nitpicker"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start> </start>
<start name="terminal" caps="110"> <start name="terminal" caps="110">
@ -66,6 +91,8 @@ install_config {
<provides><service name="Terminal"/></provides> <provides><service name="Terminal"/></provides>
<route> <route>
<service name="ROM" label="config"> <parent label="terminal.config"/> </service> <service name="ROM" label="config"> <parent label="terminal.config"/> </service>
<service name="Input"> <child name="gui_fb"/> </service>
<service name="Framebuffer"> <child name="gui_fb"/> </service>
<any-service> <parent/> <any-child/> </any-service> <any-service> <parent/> <any-child/> </any-service>
</route> </route>
</start> </start>
@ -125,6 +152,10 @@ install_config {
</start> </start>
</config>} </config>}
set fd [open [run_dir]/genode/focus w]
puts $fd "<focus label=\"gui_fb -> \" domain=\"default\"/>"
close $fd
build { lib/ld test/fork test/execve } 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 } build_boot_image { ld.lib.so libc.lib.so libm.lib.so vfs.lib.so posix.lib.so }

View File

@ -70,20 +70,20 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="gdb_monitor"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="gdb_monitor" caps="200"> <start name="gdb_monitor" caps="200">
<resource name="RAM" quantum="10M"/> <resource name="RAM" quantum="10M"/>
<provides> <service name="Gui"/> </provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config> <config>
<target name="nitpicker"> <target name="nitpicker">
<config> <config request_framebuffer="no">
<capture/>
<domain name="pointer" layer="1" xray="no" origin="pointer" <domain name="pointer" layer="1" xray="no" origin="pointer"
content="client" label="no"/> content="client" label="no"/>
<domain name="default" layer="3" content="client" <domain name="default" layer="3" content="client"

View File

@ -352,11 +352,11 @@ append_if $use_framebuffer config {
<start name="fb_drv" priority="-1" caps="130"> <start name="fb_drv" priority="-1" caps="130">
<binary name="vesa_fb_drv"/> <binary name="vesa_fb_drv"/>
<resource name="RAM" quantum="16M"/> <resource name="RAM" quantum="16M"/>
<provides><service name="Framebuffer"/></provides>
<route> <route>
<service name="Timer"><child name="timer"/></service> <service name="Timer"> <child name="timer"/></service>
<service name="Platform"><any-child/></service> <service name="Capture"> <child name="nitpicker"/></service>
<any-service><parent/></any-service> <service name="Platform"> <any-child/></service>
<any-service> <parent/> </any-service>
</route>} </route>}
append_if [expr $use_framebuffer && [have_include "power_on/qemu"]] config { append_if [expr $use_framebuffer && [have_include "power_on/qemu"]] config {
<config width="1280" height="960" depth="32" buffered="yes"/>} <config width="1280" height="960" depth="32" buffered="yes"/>}
@ -408,7 +408,8 @@ append_if $use_usb config {
append config { append config {
<start name="nitpicker" priority="-1" caps="120"> <start name="nitpicker" priority="-1" caps="120">
<resource name="RAM" quantum="8M"/> <resource name="RAM" quantum="8M"/>
<config> <config request_framebuffer="no">
<capture/>
<report focus="yes" /> <report focus="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="panel" layer="2" content="client" label="no" focus="none" /> <domain name="panel" layer="2" content="client" label="no" focus="none" />
@ -430,16 +431,16 @@ append config {
<default-policy domain=""/> <default-policy domain=""/>
</config> </config>
<route> <route>
<service name="Timer"> <child name="timer"/></service> <service name="Timer"> <child name="timer"/></service>
<service name="Framebuffer"><child name="fb_drv"/></service> <service name="Report"> <child name="report_rom"/></service>
<service name="Report"> <child name="report_rom"/></service>
<any-service><parent/><any-child/></any-service> <any-service><parent/><any-child/></any-service>
</route> </route>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
</start> </start>
<start name="pointer"> <start name="pointer">
<resource name="RAM" quantum="2M"/> <resource name="RAM" quantum="2M"/>
<config/>
</start> </start>
<start name="report_rom"> <start name="report_rom">

View File

@ -146,19 +146,18 @@ append config {
<start name="fb_drv" priority="-1"> <start name="fb_drv" priority="-1">
<binary name="vesa_fb_drv"/> <binary name="vesa_fb_drv"/>
<resource name="RAM" quantum="16M"/> <resource name="RAM" quantum="16M"/>
<provides><service name="Framebuffer"/></provides> <config/>
<config buffered="yes"/>
</start> </start>
<start name="nitpicker" priority="-1"> <start name="nitpicker" priority="-1">
<resource name="RAM" quantum="12M"/> <resource name="RAM" quantum="12M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<route> <route>
<service name="Framebuffer"> <child name="fb_drv" /> </service>
<service name="Report"> <child name="report_rom" /> </service> <service name="Report"> <child name="report_rom" /> </service>
<any-service> <parent/> <any-child /> </any-service> <any-service> <parent/> <any-child /> </any-service>
</route> </route>
<config> <config request_framebuffer="no">
<capture/>
<report focus="yes" hover="yes" /> <report focus="yes" hover="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />

View File

@ -278,14 +278,14 @@ append config_of_app {
<start name="nitpicker" priority="-1"> <start name="nitpicker" priority="-1">
<resource name="RAM" quantum="12M"/> <resource name="RAM" quantum="12M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<route> <route>
<service name="Framebuffer"> <child name="fb_drv" /> </service>
<service name="Input"> <child name="input_filter" /> </service> <service name="Input"> <child name="input_filter" /> </service>
<service name="Report"> <child name="report_rom" /> </service> <service name="Report"> <child name="report_rom" /> </service>
<any-service> <parent/> <any-child /> </any-service> <any-service> <parent/> <any-child /> </any-service>
</route> </route>
<config> <config request_framebuffer="no">
<capture/>
<report focus="yes" hover="yes" /> <report focus="yes" hover="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />

View File

@ -125,9 +125,8 @@ append config_of_app {
<start name="nitpicker" priority="-1" caps="150"> <start name="nitpicker" priority="-1" caps="150">
<resource name="RAM" quantum="12M"/> <resource name="RAM" quantum="12M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<route> <route>
<service name="Framebuffer"> <child name="fb_drv" /> </service>
<service name="Input"> <child name="input_filter" /> </service> <service name="Input"> <child name="input_filter" /> </service>
<service name="Report"> <child name="report_rom" /> </service> <service name="Report"> <child name="report_rom" /> </service>
<service name="ROM" label="config"> <service name="ROM" label="config">
@ -182,7 +181,8 @@ append config_of_app {
</rom> </rom>
<rom name="nitpicker.config"> <rom name="nitpicker.config">
<inline description="standard_mode"> <inline description="standard_mode">
<config> <config request_framebuffer="no">
<capture/>
<report focus="yes" hover="yes" /> <report focus="yes" hover="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
@ -198,7 +198,8 @@ append config_of_app {
append_if [expr !$use_rumpfs] config_of_app { append_if [expr !$use_rumpfs] config_of_app {
<inline description="shutdown"> <inline description="shutdown">
<config> <config request_framebuffer="no">
<capture/>
<report focus="yes" hover="yes" /> <report focus="yes" hover="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />

View File

@ -46,12 +46,11 @@ install_config {
<binary name="init"/> <binary name="init"/>
<route> <route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service> <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service> <service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service> <any-service> <parent/> </any-service>
</route> </route>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/> <service name="Framebuffer"/>
</provides>
</start> </start>
<start name="report_rom"> <start name="report_rom">
@ -66,8 +65,9 @@ install_config {
<start name="nitpicker"> <start name="nitpicker">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom"> <config focus="rom" request_framebuffer="no">
<capture/>
<report focus="yes" /> <!-- interpreted by clipboard --> <report focus="yes" /> <!-- interpreted by clipboard -->
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
@ -77,9 +77,8 @@ install_config {
<default-policy domain="default"/> <default-policy domain="default"/>
</config> </config>
<route> <route>
<service name="Report"> <child name="report_rom"/> </service> <service name="Report"> <child name="report_rom"/> </service>
<service name="Framebuffer"> <child name="drivers"/> </service> <service name="Input"> <child name="drivers"/> </service>
<service name="Input"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service> <any-service> <parent/> <any-child/> </any-service>
</route> </route>
</start> </start>

View File

@ -102,8 +102,7 @@ append_if [expr $use_usb] config {
append_if [have_spec framebuffer] config { append_if [have_spec framebuffer] config {
<start name="fb_drv" priority="-1" caps="150"> <start name="fb_drv" priority="-1" caps="150">
<binary name="vesa_fb_drv"/> <binary name="vesa_fb_drv"/>
<resource name="RAM" quantum="8M"/> <resource name="RAM" quantum="8M"/>}
<provides><service name="Framebuffer"/></provides>}
append_if [expr [have_spec framebuffer] && [have_include power_on/qemu]] config { append_if [expr [have_spec framebuffer] && [have_include power_on/qemu]] config {
<config width="1280" height="1024" buffered="yes"/>} <config width="1280" height="1024" buffered="yes"/>}
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 sdl] config {
<start name="fb_sdl" priority="-1" ld="no"> <start name="fb_sdl" priority="-1" ld="no">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides> <provides> <service name="Input"/> </provides>
<service name="Input"/>
<service name="Framebuffer"/>
</provides>
</start>} </start>}
append_if [have_spec x86] config { append_if [have_spec x86] config {
@ -169,9 +165,8 @@ append config {
<start name="nitpicker" priority="-1"> <start name="nitpicker" priority="-1">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<provides><service name="Gui"/></provides> <provides> <service name="Gui"/> <service name="Capture"/> </provides>
<route> <route>
<service name="Framebuffer"> <child name="fb_drv" /> </service>
<service name="Report"> <child name="report_rom" /> </service>} <service name="Report"> <child name="report_rom" /> </service>}
append_if [expr $use_ps2] config { append_if [expr $use_ps2] config {
@ -182,7 +177,9 @@ append_if [expr $use_usb] config {
append config { append config {
<any-service> <parent/> <any-child /> </any-service> <any-service> <parent/> <any-child /> </any-service>
</route> </route>
<config> <config request_framebuffer="no">
<capture/>
<report focus="yes" hover="yes" xray="yes" /> <report focus="yes" hover="yes" xray="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" /> <domain name="pointer" layer="1" content="client" label="no" origin="pointer" />

View File

@ -352,8 +352,7 @@ append_if [have_spec framebuffer] config {
<start name="fb_drv" priority="-1" caps="150"> <start name="fb_drv" priority="-1" caps="150">
<binary name="vesa_fb_drv"/> <binary name="vesa_fb_drv"/>
<resource name="RAM" quantum="16M"/> <resource name="RAM" quantum="16M"/>
<provides><service name="Framebuffer"/></provides> <config/>
<config buffered="yes"/>
</start>} </start>}
append_if [have_spec x86] config { append_if [have_spec x86] config {