mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-02 08:42:52 +00:00
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:
parent
6743669ab8
commit
c81af531a3
@ -9,13 +9,11 @@
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Capture"/>
|
||||
</parent-provides>
|
||||
|
||||
<default caps="60"/>
|
||||
|
||||
<service name="Framebuffer">
|
||||
<default-policy> <child name="fb_drv"/> </default-policy> </service>
|
||||
|
||||
<service name="Input">
|
||||
<default-policy> <child name="usb_hid_drv"/> </default-policy> </service>
|
||||
|
||||
@ -57,7 +55,6 @@
|
||||
<start name="fb_drv" caps="250">
|
||||
<binary name="imx8_fb_drv"/>
|
||||
<resource name="RAM" quantum="80M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="fb_drv.config"/> </service>
|
||||
<service name="IO_MEM"> <parent/> </service>
|
||||
@ -68,6 +65,7 @@
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Capture"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
</config>
|
||||
|
@ -9,13 +9,11 @@
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Capture"/>
|
||||
</parent-provides>
|
||||
|
||||
<default caps="60"/>
|
||||
|
||||
<service name="Framebuffer">
|
||||
<default-policy> <child name="fb_drv"/> </default-policy> </service>
|
||||
|
||||
<service name="Input">
|
||||
<default-policy> <child name="input_drv"/> </default-policy> </service>
|
||||
|
||||
@ -39,7 +37,6 @@
|
||||
<start name="fb_drv" caps="120">
|
||||
<binary name="rpi_fb_drv"/>
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="fb_drv.config"/> </service>
|
||||
<service name="Platform"> <child name="platform_drv"/> </service>
|
||||
@ -49,6 +46,7 @@
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Capture"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
|
@ -4,4 +4,4 @@ blit
|
||||
platform_session
|
||||
timer_session
|
||||
report_session
|
||||
framebuffer_session
|
||||
capture_session
|
||||
|
@ -3,5 +3,5 @@ os
|
||||
platform_session
|
||||
timer_session
|
||||
report_session
|
||||
framebuffer_session
|
||||
capture_session
|
||||
blit
|
||||
|
@ -128,7 +128,6 @@ append config {
|
||||
|
||||
<start name="intel_fb_drv" caps="1000">
|
||||
<resource name="RAM" quantum="60M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
<route>
|
||||
<service name="ROM" label="config">
|
||||
<child name="config_rom" label="fb_drv.config"/> </service>
|
||||
@ -149,6 +148,8 @@ append config {
|
||||
|
||||
<start name="test-framebuffer" priority="-1">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides> <service name="Capture"/> </provides>
|
||||
<config/>
|
||||
</start>
|
||||
</config>
|
||||
</start>
|
||||
|
@ -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__ */
|
156
repos/dde_linux/src/drivers/framebuffer/imx8/include/driver.h
Normal file
156
repos/dde_linux/src/drivers/framebuffer/imx8/include/driver.h
Normal 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__ */
|
@ -17,7 +17,7 @@
|
||||
#include <base/attached_io_mem_dataspace.h>
|
||||
|
||||
/* local includes */
|
||||
#include <component.h>
|
||||
#include <driver.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
#include <lx_emul_c.h>
|
||||
@ -1053,7 +1053,7 @@ Framebuffer::Driver::_preferred_mode(drm_connector *connector,
|
||||
|
||||
/* try to read configuration for connector */
|
||||
try {
|
||||
Xml_node config = _session.config();
|
||||
Xml_node config = _config.xml();
|
||||
Xml_node xn = config.sub_node();
|
||||
for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) {
|
||||
if (!xn.has_type("connector"))
|
||||
@ -1114,7 +1114,7 @@ void Framebuffer::Driver::finish_initialization()
|
||||
|
||||
generate_report();
|
||||
|
||||
_session.config_changed();
|
||||
config_changed();
|
||||
}
|
||||
|
||||
|
||||
@ -1122,21 +1122,21 @@ void Framebuffer::Driver::update_mode()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Configuration old = _config;
|
||||
_config = Configuration();
|
||||
Configuration old = _lx_config;
|
||||
_lx_config = Configuration();
|
||||
|
||||
lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) {
|
||||
unsigned brightness;
|
||||
drm_display_mode * mode = _preferred_mode(c, brightness);
|
||||
if (!mode) return;
|
||||
if (mode->hdisplay > _config._lx.width) _config._lx.width = mode->hdisplay;
|
||||
if (mode->vdisplay > _config._lx.height) _config._lx.height = mode->vdisplay;
|
||||
if (mode->hdisplay > _lx_config._lx.width) _lx_config._lx.width = mode->hdisplay;
|
||||
if (mode->vdisplay > _lx_config._lx.height) _lx_config._lx.height = mode->vdisplay;
|
||||
|
||||
});
|
||||
|
||||
lx_c_allocate_framebuffer(lx_drm_device, &_config._lx);
|
||||
lx_c_allocate_framebuffer(lx_drm_device, &_lx_config._lx);
|
||||
|
||||
if (!_config._lx.lx_fb) {
|
||||
if (!_lx_config._lx.lx_fb) {
|
||||
Genode::error("updating framebuffer failed");
|
||||
return;
|
||||
}
|
||||
@ -1147,16 +1147,16 @@ void Framebuffer::Driver::update_mode()
|
||||
unsigned brightness = MAX_BRIGHTNESS + 1;
|
||||
|
||||
/* set mode */
|
||||
lx_c_set_mode(lx_drm_device, c, _config._lx.lx_fb,
|
||||
lx_c_set_mode(lx_drm_device, c, _lx_config._lx.lx_fb,
|
||||
_preferred_mode(c, brightness));
|
||||
});
|
||||
}
|
||||
|
||||
/* force virtual framebuffer size if requested */
|
||||
if (int w = _session.force_width_from_config())
|
||||
_config._lx.width = min(_config._lx.width, w);
|
||||
if (int h = _session.force_height_from_config())
|
||||
_config._lx.height = min(_config._lx.height, h);
|
||||
if (int w = _force_width_from_config())
|
||||
_lx_config._lx.width = min(_lx_config._lx.width, w);
|
||||
if (int h = _force_height_from_config())
|
||||
_lx_config._lx.height = min(_lx_config._lx.height, h);
|
||||
|
||||
if (old._lx.lx_fb) {
|
||||
if (drm_framebuffer_read_refcount(old._lx.lx_fb) > 1) {
|
||||
@ -1197,8 +1197,8 @@ void Framebuffer::Driver::generate_report()
|
||||
|
||||
/* check for report configuration option */
|
||||
try {
|
||||
_reporter.enabled(_session.config().sub_node("report")
|
||||
.attribute_value(_reporter.name().string(), false));
|
||||
_reporter.enabled(_config.xml().sub_node("report")
|
||||
.attribute_value(_reporter.name().string(), false));
|
||||
} catch (...) {
|
||||
_reporter.enabled(false);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-2019 Genode Labs GmbH
|
||||
* Copyright (C) 2015-2020 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
@ -19,8 +19,8 @@
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
|
||||
/* Server related local includes */
|
||||
#include <component.h>
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
/* Linux emulation environment includes */
|
||||
#include <lx_emul.h>
|
||||
@ -32,7 +32,7 @@
|
||||
#include <lx_kit/work.h>
|
||||
|
||||
/* Linux module functions */
|
||||
extern "C" void radix_tree_init(); /* called by start_kernel(void) normally */
|
||||
extern "C" void radix_tree_init(); /* called by start_kernel(void) normally */
|
||||
extern "C" void drm_connector_ida_init(); /* called by drm_core_init(void) normally */
|
||||
extern "C" int module_irq_imx_irqsteer_init();
|
||||
extern "C" int module_imx_drm_pdrv_init();
|
||||
@ -40,90 +40,79 @@ extern "C" int module_dcss_driver_init();
|
||||
extern "C" int module_dcss_crtc_driver_init();
|
||||
extern "C" int module_imx_hdp_imx_platform_driver_init();
|
||||
|
||||
|
||||
static void run_linux(void * m);
|
||||
|
||||
unsigned long jiffies;
|
||||
|
||||
namespace Framebuffer { struct Main; }
|
||||
|
||||
struct Main
|
||||
|
||||
struct Framebuffer::Main
|
||||
{
|
||||
Genode::Env &env;
|
||||
Genode::Entrypoint &ep { env.ep() };
|
||||
Genode::Attached_rom_dataspace config { env, "config" };
|
||||
Genode::Heap heap { env.ram(), env.rm() };
|
||||
Framebuffer::Root root { env, heap, config };
|
||||
void _run_linux();
|
||||
|
||||
/**
|
||||
* Entry for executing code in the Linux kernel context
|
||||
*/
|
||||
static void _run_linux_entry(void *m)
|
||||
{
|
||||
reinterpret_cast<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 */
|
||||
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(core_lock);
|
||||
LX_MUTEX_INIT(component_mutex);
|
||||
|
||||
/* init singleton Lx::Scheduler */
|
||||
Lx::scheduler(&env);
|
||||
Lx::scheduler(&_env);
|
||||
|
||||
Lx::malloc_init(env, heap);
|
||||
Lx::malloc_init(_env, _heap);
|
||||
|
||||
/* init singleton Lx::Timer */
|
||||
Lx::timer(&env, &ep, &heap, &jiffies);
|
||||
Lx::timer(&_env, &_ep, &_heap, &jiffies);
|
||||
|
||||
/* init singleton Lx::Irq */
|
||||
Lx::Irq::irq(&ep, &heap);
|
||||
Lx::Irq::irq(&_ep, &_heap);
|
||||
|
||||
/* init singleton Lx::Work */
|
||||
Lx::Work::work_queue(&heap);
|
||||
Lx::Work::work_queue(&_heap);
|
||||
|
||||
linux.construct(run_linux, reinterpret_cast<void*>(this),
|
||||
"linux", Lx::Task::PRIORITY_0, Lx::scheduler());
|
||||
_linux.construct(_run_linux_entry, reinterpret_cast<void*>(this),
|
||||
"linux", Lx::Task::PRIORITY_0, Lx::scheduler());
|
||||
|
||||
/* give all task a first kick before returning */
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
|
||||
void announce() { env.parent().announce(ep.manage(root)); }
|
||||
|
||||
Lx::Task &linux_task() { return *linux; }
|
||||
};
|
||||
|
||||
|
||||
struct Policy_agent
|
||||
void Framebuffer::Main::_run_linux()
|
||||
{
|
||||
Main &main;
|
||||
Genode::Signal_handler<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);
|
||||
|
||||
radix_tree_init();
|
||||
@ -240,17 +229,17 @@ static void run_linux(void * m)
|
||||
platform_device_register(display_subsystem_pdev);
|
||||
|
||||
|
||||
main->root.session.driver().finish_initialization();
|
||||
main->announce();
|
||||
_driver.finish_initialization();
|
||||
_driver.config_sigh(_policy_change_handler);
|
||||
|
||||
Policy_agent pa(*main);
|
||||
main->root.session.driver().config_sigh(pa.handler);
|
||||
main->config.sigh(pa.handler);
|
||||
_config.sigh(_policy_change_handler);
|
||||
|
||||
while (1) {
|
||||
Lx::scheduler().current()->block_and_schedule();
|
||||
while (pa.pending())
|
||||
main->root.session.config_changed();
|
||||
while (_policy_change_pending) {
|
||||
_policy_change_pending = false;
|
||||
_driver.config_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,5 +249,5 @@ void Component::construct(Genode::Env &env)
|
||||
/* XXX execute constructors of global statics */
|
||||
env.exec_static_constructors();
|
||||
|
||||
static Main m(env);
|
||||
static Framebuffer::Main main(env);
|
||||
}
|
||||
|
@ -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__ */
|
168
repos/dde_linux/src/drivers/framebuffer/intel/include/driver.h
Normal file
168
repos/dde_linux/src/drivers/framebuffer/intel/include/driver.h
Normal 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__ */
|
@ -19,7 +19,7 @@
|
||||
#include <os/reporter.h>
|
||||
|
||||
/* local includes */
|
||||
#include <component.h>
|
||||
#include <driver.h>
|
||||
|
||||
/* DRM-specific includes */
|
||||
#include <lx_emul.h>
|
||||
@ -100,7 +100,7 @@ Framebuffer::Driver::_preferred_mode(drm_connector *connector,
|
||||
|
||||
/* try to read configuration for connector */
|
||||
try {
|
||||
Xml_node config = _session.config();
|
||||
Xml_node config = _config.xml();
|
||||
Xml_node xn = config.sub_node();
|
||||
for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) {
|
||||
if (!xn.has_type("connector"))
|
||||
@ -157,7 +157,7 @@ void Framebuffer::Driver::finish_initialization()
|
||||
lx_c_set_driver(lx_drm_device, (void*)this);
|
||||
|
||||
generate_report();
|
||||
_session.config_changed();
|
||||
Driver::config_changed();
|
||||
}
|
||||
|
||||
|
||||
@ -189,20 +189,20 @@ void Framebuffer::Driver::update_mode()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Configuration old = _config;
|
||||
_config = Configuration();
|
||||
Configuration old = _lx_config;
|
||||
_lx_config = Configuration();
|
||||
|
||||
lx_for_each_connector(lx_drm_device, [&] (drm_connector *c) {
|
||||
unsigned brightness;
|
||||
drm_display_mode * mode = _preferred_mode(c, brightness);
|
||||
if (!mode) return;
|
||||
if (mode->hdisplay > _config._lx.width) _config._lx.width = mode->hdisplay;
|
||||
if (mode->vdisplay > _config._lx.height) _config._lx.height = mode->vdisplay;
|
||||
if (mode->hdisplay > _lx_config._lx.width) _lx_config._lx.width = mode->hdisplay;
|
||||
if (mode->vdisplay > _lx_config._lx.height) _lx_config._lx.height = mode->vdisplay;
|
||||
});
|
||||
|
||||
lx_c_allocate_framebuffer(lx_drm_device, &_config._lx);
|
||||
lx_c_allocate_framebuffer(lx_drm_device, &_lx_config._lx);
|
||||
|
||||
if (!_config._lx.lx_fb) {
|
||||
if (!_lx_config._lx.lx_fb) {
|
||||
Genode::error("updating framebuffer failed");
|
||||
return;
|
||||
}
|
||||
@ -213,7 +213,7 @@ void Framebuffer::Driver::update_mode()
|
||||
unsigned brightness = MAX_BRIGHTNESS + 1;
|
||||
|
||||
/* set mode */
|
||||
lx_c_set_mode(lx_drm_device, c, _config._lx.lx_fb,
|
||||
lx_c_set_mode(lx_drm_device, c, _lx_config._lx.lx_fb,
|
||||
_preferred_mode(c, brightness));
|
||||
|
||||
/* set sane brightness, ignore unsane values and let as is */
|
||||
@ -223,10 +223,10 @@ void Framebuffer::Driver::update_mode()
|
||||
}
|
||||
|
||||
/* force virtual framebuffer size if requested */
|
||||
if (int w = _session.force_width_from_config())
|
||||
_config._lx.width = min(_config._lx.width, w);
|
||||
if (int h = _session.force_height_from_config())
|
||||
_config._lx.height = min(_config._lx.height, h);
|
||||
if (int w = _force_width_from_config())
|
||||
_lx_config._lx.width = min(_lx_config._lx.width, w);
|
||||
if (int h = _force_height_from_config())
|
||||
_lx_config._lx.height = min(_lx_config._lx.height, h);
|
||||
|
||||
if (old._lx.addr) Lx::iounmap(old._lx.addr);
|
||||
if (old._lx.lx_fb) {
|
||||
@ -268,7 +268,7 @@ void Framebuffer::Driver::generate_report()
|
||||
|
||||
/* check for report configuration option */
|
||||
try {
|
||||
_reporter.enabled(_session.config().sub_node("report")
|
||||
_reporter.enabled(_config.xml().sub_node("report")
|
||||
.attribute_value(_reporter.name().string(), false));
|
||||
} catch (...) {
|
||||
_reporter.enabled(false);
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Genode Labs GmbH
|
||||
* Copyright (C) 2015-2020 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
@ -18,8 +18,8 @@
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
|
||||
/* Server related local includes */
|
||||
#include <component.h>
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
/* Linux emulation environment includes */
|
||||
#include <lx_emul.h>
|
||||
@ -33,110 +33,102 @@
|
||||
#include <lx_kit/work.h>
|
||||
|
||||
/* Linux module functions */
|
||||
extern "C" void postcore_i2c_init(void); /* i2c-core-base.c */
|
||||
extern "C" int module_i915_init(); /* i915_drv.c */
|
||||
extern "C" void radix_tree_init(); /* called by start_kernel(void) normally */
|
||||
extern "C" void postcore_i2c_init(void); /* i2c-core-base.c */
|
||||
extern "C" int module_i915_init(); /* i915_drv.c */
|
||||
extern "C" void radix_tree_init(); /* called by start_kernel(void) normally */
|
||||
extern "C" void drm_connector_ida_init(); /* called by drm_core_init(void) normally */
|
||||
|
||||
static void run_linux(void * m);
|
||||
|
||||
unsigned long jiffies;
|
||||
|
||||
namespace Framebuffer { struct Main; }
|
||||
|
||||
struct Main
|
||||
|
||||
struct Framebuffer::Main
|
||||
{
|
||||
Genode::Env &env;
|
||||
Genode::Entrypoint &ep { env.ep() };
|
||||
Genode::Attached_rom_dataspace config { env, "config" };
|
||||
Genode::Heap heap { env.ram(), env.rm() };
|
||||
Framebuffer::Root root { env, heap, config };
|
||||
void _run_linux();
|
||||
|
||||
/**
|
||||
* Entry for executing code in the Linux kernel context
|
||||
*/
|
||||
static void _run_linux_entry(void *m)
|
||||
{
|
||||
reinterpret_cast<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 */
|
||||
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(core_lock);
|
||||
|
||||
/* init singleton Lx::Scheduler */
|
||||
Lx::scheduler(&env);
|
||||
Lx::scheduler(&_env);
|
||||
|
||||
Lx::pci_init(env, env.ram(), heap);
|
||||
Lx::malloc_init(env, heap);
|
||||
Lx::pci_init(_env, _env.ram(), _heap);
|
||||
Lx::malloc_init(_env, _heap);
|
||||
|
||||
/* init singleton Lx::Timer */
|
||||
Lx::timer(&env, &ep, &heap, &jiffies);
|
||||
Lx::timer(&_env, &_ep, &_heap, &jiffies);
|
||||
|
||||
/* init singleton Lx::Irq */
|
||||
Lx::Irq::irq(&ep, &heap);
|
||||
Lx::Irq::irq(&_ep, &_heap);
|
||||
|
||||
/* init singleton Lx::Work */
|
||||
Lx::Work::work_queue(&heap);
|
||||
Lx::Work::work_queue(&_heap);
|
||||
|
||||
linux.construct(run_linux, reinterpret_cast<void*>(this),
|
||||
"linux", Lx::Task::PRIORITY_0, Lx::scheduler());
|
||||
_linux.construct(_run_linux_entry, reinterpret_cast<void*>(this),
|
||||
"linux", Lx::Task::PRIORITY_0, Lx::scheduler());
|
||||
|
||||
/* give all task a first kick before returning */
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
|
||||
void announce() { env.parent().announce(ep.manage(root)); }
|
||||
|
||||
Lx::Task &linux_task() { return *linux; }
|
||||
};
|
||||
|
||||
|
||||
struct Policy_agent
|
||||
void Framebuffer::Main::_run_linux()
|
||||
{
|
||||
Main &main;
|
||||
Genode::Signal_handler<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);
|
||||
|
||||
radix_tree_init();
|
||||
drm_connector_ida_init();
|
||||
postcore_i2c_init();
|
||||
module_i915_init();
|
||||
main->root.session.driver().finish_initialization();
|
||||
main->announce();
|
||||
|
||||
Policy_agent pa(*main);
|
||||
main->root.session.driver().config_sigh(pa.handler);
|
||||
main->config.sigh(pa.handler);
|
||||
_driver.finish_initialization();
|
||||
_driver.config_sigh(_policy_change_handler);
|
||||
|
||||
_config.sigh(_policy_change_handler);
|
||||
|
||||
while (1) {
|
||||
Lx::scheduler().current()->block_and_schedule();
|
||||
while (pa.pending())
|
||||
main->root.session.config_changed();
|
||||
while (_policy_change_pending) {
|
||||
_policy_change_pending = false;
|
||||
_driver.config_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,5 +138,5 @@ void Component::construct(Genode::Env &env)
|
||||
/* XXX execute constructors of global statics */
|
||||
env.exec_static_constructors();
|
||||
|
||||
static Main m(env);
|
||||
static Framebuffer::Main main(env);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
<service name="LOG"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Report"/>
|
||||
<service name="Capture"/>
|
||||
</parent-provides>
|
||||
|
||||
<default-route>
|
||||
@ -19,9 +20,6 @@
|
||||
|
||||
<default caps="100"/>
|
||||
|
||||
<service name="Framebuffer">
|
||||
<default-policy> <child name="dynamic"/> </default-policy> </service>
|
||||
|
||||
<service name="Block">
|
||||
<default-policy> <child name="dynamic"/> </default-policy> </service>
|
||||
|
||||
@ -228,6 +226,7 @@
|
||||
<service name="IO_MEM"> <parent/> </service>
|
||||
<service name="IO_PORT"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Capture"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
|
@ -3,6 +3,6 @@ os
|
||||
report_session
|
||||
block_session
|
||||
usb_session
|
||||
framebuffer_session
|
||||
capture_session
|
||||
timer_session
|
||||
platform_session
|
||||
|
@ -37,18 +37,19 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
|
||||
<domain name="pointer" layer="1" label="no" content="client" origin="pointer" />
|
||||
<domain name="default" layer="2" label="no" content="client" hover="always" />
|
||||
|
||||
|
@ -39,12 +39,11 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="report_rom">
|
||||
@ -58,8 +57,9 @@ install_config {
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Gui"/> </provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<report pointer="yes" />
|
||||
<domain name="default" layer="2" content="client" label="no"/>
|
||||
<default-policy domain="default"/>
|
||||
@ -168,6 +168,7 @@ install_config {
|
||||
</service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
<config> <default-policy/> </config>
|
||||
</start>
|
||||
</config>}
|
||||
|
||||
|
@ -41,18 +41,18 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker" caps="200">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Gui"/> </provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<domain name="" layer="2" content="client" label="no" />
|
||||
<default-policy domain=""/>
|
||||
<report pointer="yes" />
|
||||
|
@ -50,18 +50,18 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<config focus="rom">
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config focus="rom" request_framebuffer="no">
|
||||
<capture/>
|
||||
<background color="#123456"/>
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
<domain name="default" layer="3" content="client" label="no" hover="always" />
|
||||
|
@ -11,6 +11,7 @@ import_from_depot [depot_user]/src/[base_src] \
|
||||
[depot_user]/pkg/drivers_managed-pc \
|
||||
[depot_user]/src/report_rom \
|
||||
[depot_user]/src/dynamic_rom \
|
||||
[depot_user]/src/nitpicker \
|
||||
[depot_user]/src/init
|
||||
|
||||
install_config {
|
||||
@ -41,6 +42,7 @@ install_config {
|
||||
<provides> <service name="Report"/> <service name="ROM"/> </provides>
|
||||
<config verbose="yes">
|
||||
<policy label="test-driver_manager -> block_devices" report="drivers -> block_devices"/>
|
||||
<policy label="test-driver_manager -> displays" report="nitpicker -> displays"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
@ -57,13 +59,13 @@ install_config {
|
||||
<service name="ROM" label="numlock"> <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="Timer"> <child name="timer"/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Capture"> <child name="nitpicker"/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/>
|
||||
<service name="Framebuffer"/>
|
||||
<service name="Block"/>
|
||||
</provides>
|
||||
</start>
|
||||
@ -95,16 +97,30 @@ install_config {
|
||||
</config>
|
||||
</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">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<config>
|
||||
<check_ahci_block_device label="ahci-1" block_count="65536" block_size="512"
|
||||
model="QEMU HARDDISK"/>
|
||||
<check_input/>
|
||||
<check_framebuffer/>
|
||||
<check_displays/>
|
||||
</config>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
</start>
|
||||
|
@ -36,18 +36,19 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
<domain name="default" layer="3" content="client" label="no" focus="click" hover="always" />
|
||||
|
||||
|
@ -70,12 +70,11 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="report_rom">
|
||||
@ -93,8 +92,9 @@ install_config {
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<config focus="rom">
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config focus="rom" request_framebuffer="no">
|
||||
<capture/>
|
||||
<report hover="yes" displays="yes"/>
|
||||
<background color="#000000"/>
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
@ -226,7 +226,7 @@ install_config {
|
||||
|
||||
<start name="ahci-2">
|
||||
<binary name="vfs_block"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<provides> <service name="Block"/> </provides>
|
||||
<config>
|
||||
<vfs>
|
||||
|
@ -40,18 +40,19 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
|
||||
<background color="#123456"/>
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
<domain name="default" layer="3" content="client" label="no" hover="always" />
|
||||
|
@ -31,12 +31,11 @@ append config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="timer">
|
||||
@ -46,8 +45,10 @@ append config {
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
|
||||
<domain name="default" layer="2" content="client" label="no"/>
|
||||
<domain name="nano3d" layer="1" content="client" label="no" origin="pointer"/>
|
||||
|
||||
|
@ -254,13 +254,13 @@ install_config {
|
||||
<service name="ROM" label_last="usb_policy">
|
||||
<child name="config_fs_rom" label="usb"/> </service>
|
||||
<service name="ROM" label_last="numlock"> <child name="report_rom"/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Report"> <child name="fs_report"/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Capture"> <child name="nitpicker"/> </service>
|
||||
<service name="Report"> <child name="fs_report"/> </service>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/>
|
||||
<service name="Framebuffer"/>
|
||||
<service name="Block"/>
|
||||
<service name="Usb"/>
|
||||
<service name="Platform"/>
|
||||
@ -269,7 +269,7 @@ install_config {
|
||||
|
||||
<start name="nitpicker" caps="1000">
|
||||
<resource name="RAM" quantum="6M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<route>
|
||||
<service name="ROM" label="config">
|
||||
<child name="config_fs_rom" label="nitpicker"/> </service>
|
||||
@ -277,10 +277,9 @@ install_config {
|
||||
<child name="nit_focus"/> </service>
|
||||
<service name="Report" label="keystate">
|
||||
<child name="report_logger"/> </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="Timer"> <child name="timer"/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="Input"> <child name="drivers"/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
@ -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"/>
|
||||
<background color="#000000"/>
|
||||
|
||||
<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="leitzentrale" layer="3" content="client" label="no" hover="always" focus="click" />
|
||||
|
@ -40,26 +40,25 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides> <service name="Gui"/> </provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
<domain name="default" layer="2" content="client" label="no" focus="click" hover="always" />
|
||||
<policy label_prefix="pointer" domain="pointer"/>
|
||||
<default-policy domain="default"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Input"> <child name="drivers"/> </service>
|
||||
<service name="Framebuffer"> <child name="drivers"/> </service>
|
||||
<service name="Input"> <child name="drivers"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
@ -40,12 +40,11 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="report_rom">
|
||||
@ -59,8 +58,9 @@ install_config {
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<config focus="rom">
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config focus="rom" request_framebuffer="no">
|
||||
<capture/>
|
||||
<report hover="yes"/>
|
||||
<background color="#123456"/>
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
|
@ -5,6 +5,8 @@ import_from_depot [depot_user]/src/[base_src] \
|
||||
[depot_user]/src/init \
|
||||
[depot_user]/src/libc \
|
||||
[depot_user]/src/vfs \
|
||||
[depot_user]/src/nitpicker \
|
||||
[depot_user]/src/gui_fb \
|
||||
[depot_user]/raw/ttf-bitstream-vera-minimal
|
||||
|
||||
install_config {
|
||||
@ -36,12 +38,36 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<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 name="font_vfs">
|
||||
@ -70,6 +96,10 @@ install_config {
|
||||
|
||||
build { server/vfs test/text_painter lib/vfs/ttf }
|
||||
|
||||
set fd [open [run_dir]/genode/focus w]
|
||||
puts $fd "<focus label=\"gui_fb -> \" domain=\"default\"/>"
|
||||
close $fd
|
||||
|
||||
build_boot_image { vfs test-text_painter vfs_ttf.lib.so }
|
||||
|
||||
run_genode_until forever
|
||||
|
@ -43,18 +43,19 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<config focus="rom">
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config focus="rom" request_framebuffer="no">
|
||||
<capture/>
|
||||
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
<domain name="default" layer="2" content="client" label="no" hover="always"/>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <os/reporter.h>
|
||||
#include <block_session/block_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_port_session/io_port_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",
|
||||
Ram_quota{42*1024*1024}, Cap_quota{800},
|
||||
Priority{0});
|
||||
_gen_provides_node<Framebuffer::Session>(xml);
|
||||
xml.node("route", [&] () {
|
||||
_gen_config_route(xml, "fb_drv.config");
|
||||
_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",
|
||||
Ram_quota{8*1024*1024}, Cap_quota{100},
|
||||
Priority{-1});
|
||||
_gen_provides_node<Framebuffer::Session>(xml);
|
||||
xml.node("route", [&] () {
|
||||
_gen_config_route(xml, "fb_drv.config");
|
||||
_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",
|
||||
_ram_quota, Cap_quota{100},
|
||||
Priority{-1});
|
||||
_gen_provides_node<Framebuffer::Session>(xml);
|
||||
xml.node("route", [&] () {
|
||||
_gen_config_route(xml, "fb_drv.config");
|
||||
_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, Report::Session::service_name());
|
||||
_gen_parent_service_xml(xml, Usb::Session::service_name());
|
||||
_gen_parent_service_xml(xml, Capture::Session::service_name());
|
||||
});
|
||||
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/allocator_avl.h>
|
||||
#include <base/heap.h>
|
||||
#include <framebuffer_session/connection.h>
|
||||
#include <input_session/connection.h>
|
||||
#include <block_session/connection.h>
|
||||
|
||||
@ -32,6 +31,7 @@ struct Test::Main
|
||||
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
Attached_rom_dataspace _block_devices { _env, "block_devices" };
|
||||
Attached_rom_dataspace _displays { _env, "displays" };
|
||||
|
||||
static bool _attribute_matches(char const *attr, Xml_node expected, Xml_node checked)
|
||||
{
|
||||
@ -113,6 +113,14 @@ struct Test::Main
|
||||
Block::Connection<> block(_env, &packet_alloc, 128*1024, label.string());
|
||||
});
|
||||
|
||||
if (_config.xml().has_sub_node("check_displays")) {
|
||||
_displays.update();
|
||||
if (!_displays.xml().has_sub_node("display"))
|
||||
return;
|
||||
|
||||
log("available displays: ", _displays.xml());
|
||||
}
|
||||
|
||||
log("all expected devices present and accessible");
|
||||
}
|
||||
|
||||
@ -121,12 +129,6 @@ struct Test::Main
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
if (_config.xml().has_sub_node("check_framebuffer")) {
|
||||
log("connect to framebuffer driver");
|
||||
Framebuffer::Mode mode { .area = { 640, 480 } };
|
||||
Framebuffer::Connection fb(_env, mode);
|
||||
}
|
||||
|
||||
if (_config.xml().has_sub_node("check_input")) {
|
||||
log("connect to input driver");
|
||||
Input::Connection input(_env);
|
||||
|
@ -3,4 +3,4 @@ os
|
||||
blit
|
||||
platform_session
|
||||
timer_session
|
||||
framebuffer_session
|
||||
capture_session
|
||||
|
@ -53,18 +53,18 @@ set config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker" caps="200">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides> <service name="Gui"/> </provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
<domain name="default" layer="2" content="client" label="no" focus="click" hover="always" />
|
||||
<policy label_prefix="pointer" domain="pointer"/>
|
||||
|
@ -39,18 +39,19 @@ set config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides> <service name="Gui"/> </provides>
|
||||
<config focus="rom">
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config focus="rom" request_framebuffer="no">
|
||||
<capture/>
|
||||
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
<domain name="default" layer="2" content="client" label="no" hover="always"/>
|
||||
|
||||
|
@ -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 -> capslock"> <child name="wm_report_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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker" caps="200">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<route>
|
||||
<service name="Report"> <child name="wm_report_rom"/> </service>
|
||||
<any-service> <parent /> <any-child /> </any-service>
|
||||
</route>
|
||||
<config>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
|
||||
<report focus="yes" hover="yes" xray="yes"/>
|
||||
|
||||
<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"/>
|
||||
<default-policy domain="default"/>
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-2017 Genode Labs GmbH
|
||||
* Copyright (C) 2007-2020 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
@ -17,231 +17,150 @@
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <root/component.h>
|
||||
#include <util/reconstructible.h>
|
||||
#include <util/arg_string.h>
|
||||
#include <blit/blit.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 */
|
||||
#include "framebuffer.h"
|
||||
|
||||
|
||||
namespace Framebuffer {
|
||||
struct Session_component;
|
||||
struct Root;
|
||||
namespace Vesa_driver {
|
||||
using namespace Genode;
|
||||
struct Main;
|
||||
|
||||
using Genode::size_t;
|
||||
using Genode::min;
|
||||
using Genode::max;
|
||||
using Genode::Dataspace_capability;
|
||||
using Genode::Attached_rom_dataspace;
|
||||
using Genode::Attached_ram_dataspace;
|
||||
}
|
||||
|
||||
|
||||
class Framebuffer::Session_component : public Genode::Rpc_object<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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
|
||||
/***********************************
|
||||
** Framebuffer session interface **
|
||||
***********************************/
|
||||
/*
|
||||
* Config
|
||||
*/
|
||||
|
||||
Dataspace_capability dataspace() override
|
||||
{
|
||||
return _buffered() ? Dataspace_capability(_bb->cap())
|
||||
: Dataspace_capability(_fb_cap);
|
||||
}
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
Mode mode() const override
|
||||
{
|
||||
return Mode { .area = { _scr_width, _scr_height } };
|
||||
}
|
||||
Area _size { 1, 1 };
|
||||
|
||||
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||
void _handle_config();
|
||||
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_timer.sigh(sigh);
|
||||
_timer.trigger_periodic(10*1000);
|
||||
}
|
||||
|
||||
void refresh(int x, int y, int w, int h) override
|
||||
{
|
||||
if (_buffered())
|
||||
_refresh_buffered(x, y, w, h);
|
||||
}
|
||||
};
|
||||
Signal_handler<Main> _config_handler { _env.ep(), *this, &Main::_handle_config };
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for single-client root component
|
||||
*/
|
||||
typedef Genode::Root_component<Framebuffer::Session_component,
|
||||
Genode::Single_client> Root_component;
|
||||
/*
|
||||
* Capture
|
||||
*/
|
||||
|
||||
class Framebuffer::Root : public Root_component
|
||||
{
|
||||
private:
|
||||
Capture::Connection _capture { _env };
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
Attached_rom_dataspace const &_config;
|
||||
|
||||
unsigned _session_arg(char const *attr_name, char const *args,
|
||||
char const *arg_name, unsigned default_value)
|
||||
{
|
||||
/* try to obtain value from config file */
|
||||
unsigned result = _config.xml().attribute_value(attr_name,
|
||||
default_value);
|
||||
|
||||
/* check session argument to override value from config file */
|
||||
return Genode::Arg_string::find_arg(args, arg_name).ulong_value(result);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(char const *args) override
|
||||
{
|
||||
unsigned scr_width = _session_arg("width", args, "fb_width", 0);
|
||||
unsigned scr_height = _session_arg("height", args, "fb_height", 0);
|
||||
unsigned const scr_depth = 32;
|
||||
|
||||
bool const buffered = _config.xml().attribute_value("buffered", true);
|
||||
|
||||
if (Framebuffer::set_mode(scr_width, scr_height, scr_depth) != 0) {
|
||||
Genode::warning("Could not set vesa mode ",
|
||||
scr_width, "x", scr_height, "@", scr_depth);
|
||||
throw Genode::Service_denied();
|
||||
}
|
||||
|
||||
Genode::log("using video mode: ",
|
||||
scr_width, "x", scr_height, "@", scr_depth);
|
||||
|
||||
return new (md_alloc()) Session_component(_env,
|
||||
scr_width, scr_height, scr_depth,
|
||||
Framebuffer::hw_framebuffer(),
|
||||
buffered);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Env &env, Genode::Allocator &alloc,
|
||||
Attached_rom_dataspace const &config)
|
||||
:
|
||||
Root_component(&env.ep().rpc_ep(), &alloc),
|
||||
_env(env), _config(config)
|
||||
{ }
|
||||
};
|
||||
Constructible<Capture::Connection::Screen> _captured_screen { };
|
||||
|
||||
|
||||
struct Framebuffer::Main
|
||||
{
|
||||
Genode::Env &env;
|
||||
/*
|
||||
* Timer
|
||||
*/
|
||||
|
||||
Genode::Heap heap { env.ram(), env.rm() };
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
Attached_rom_dataspace config { env, "config" };
|
||||
Signal_handler<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");
|
||||
try { Framebuffer::init(env, heap); } catch (...) {
|
||||
Genode::error("H/W driver init failed");
|
||||
throw;
|
||||
}
|
||||
_config.sigh(_config_handler);
|
||||
_timer.sigh(_timer_handler);
|
||||
|
||||
env.parent().announce(env.ep().manage(root));
|
||||
_handle_config();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Vesa_driver::Main::_handle_timer()
|
||||
{
|
||||
if (!_fb_ds.constructed())
|
||||
return;
|
||||
|
||||
Surface<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)
|
||||
{
|
||||
/* XXX execute constructors of global statics */
|
||||
env.exec_static_constructors();
|
||||
|
||||
static Framebuffer::Main inst(env);
|
||||
static Vesa_driver::Main inst(env);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
_/src/fb_sdl
|
||||
_/src/input_filter
|
||||
_/src/input_event_bridge
|
||||
_/raw/drivers_interactive-linux
|
||||
|
@ -10,13 +10,11 @@
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Capture"/>
|
||||
</parent-provides>
|
||||
|
||||
<default caps="60"/>
|
||||
|
||||
<service name="Framebuffer">
|
||||
<default-policy> <child name="fb_drv"/> </default-policy> </service>
|
||||
|
||||
<service name="Input">
|
||||
<default-policy> <child name="dummy_input_drv"/> </default-policy> </service>
|
||||
|
||||
@ -59,7 +57,6 @@
|
||||
<start name="fb_drv" caps="120">
|
||||
<binary name="imx53_fb_drv"/>
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
<config width="800" height="480" display="0" buffered="true"/>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="fb_drv.config"/> </service>
|
||||
@ -70,6 +67,7 @@
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Capture"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
@ -77,10 +75,10 @@
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
<route>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
</config>
|
||||
|
@ -5,21 +5,25 @@
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Capture"/>
|
||||
</parent-provides>
|
||||
|
||||
<service name="Framebuffer">
|
||||
<default-policy> <child name="fb_sdl"/> </default-policy> </service>
|
||||
|
||||
<service name="Input">
|
||||
<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">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides>
|
||||
<service name="Input"/>
|
||||
<service name="Framebuffer"/>
|
||||
</provides>
|
||||
<route> <any-service> <parent/> </any-service> </route>
|
||||
<route>
|
||||
<service name="Event"> <child name="input_event_bridge"/> </service>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="input_filter" caps="80">
|
||||
@ -27,7 +31,7 @@
|
||||
<provides> <service name="Input"/> </provides>
|
||||
<route>
|
||||
<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="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
|
@ -7,13 +7,11 @@
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Capture"/>
|
||||
</parent-provides>
|
||||
|
||||
<default caps="100"/>
|
||||
|
||||
<service name="Framebuffer">
|
||||
<default-policy> <child name="fb_drv"/> </default-policy> </service>
|
||||
|
||||
<service name="Input">
|
||||
<default-policy> <child name="input_filter"/> </default-policy> </service>
|
||||
|
||||
@ -64,25 +62,23 @@
|
||||
<start name="fb_drv">
|
||||
<binary name="pl11x_fb_drv"/>
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides> <service name="Framebuffer"/> </provides>
|
||||
<route>
|
||||
<service name="Platform">
|
||||
<child name="platform_drv"/>
|
||||
</service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Capture"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="ps2_drv">
|
||||
<binary name="pl050_input_drv"/>
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
<route>
|
||||
<service name="Platform">
|
||||
<child name="platform_drv"/>
|
||||
|
@ -10,13 +10,11 @@
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Capture"/>
|
||||
</parent-provides>
|
||||
|
||||
<default caps="60"/>
|
||||
|
||||
<service name="Framebuffer">
|
||||
<default-policy> <child name="fb_drv"/> </default-policy> </service>
|
||||
|
||||
<service name="Input">
|
||||
<default-policy> <child name="input_filter"/> </default-policy> </service>
|
||||
|
||||
@ -77,8 +75,7 @@
|
||||
|
||||
<start name="fb_drv" caps="120">
|
||||
<binary name="vesa_fb_drv"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="fb_drv.config"/> </service>
|
||||
<service name="Platform"> <child name="platform_drv"/> </service>
|
||||
@ -89,6 +86,7 @@
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Capture"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
base
|
||||
os
|
||||
blit
|
||||
framebuffer_session
|
||||
capture_session
|
||||
timer_session
|
||||
|
@ -1,7 +1,7 @@
|
||||
base-linux
|
||||
base
|
||||
os
|
||||
input_session
|
||||
framebuffer_session
|
||||
event_session
|
||||
timer_session
|
||||
capture_session
|
||||
blit
|
||||
|
@ -3,6 +3,6 @@ os
|
||||
blit
|
||||
platform_session
|
||||
gpio_session
|
||||
framebuffer_session
|
||||
capture_session
|
||||
input_session
|
||||
timer_session
|
||||
|
@ -1,6 +1,6 @@
|
||||
base
|
||||
os
|
||||
framebuffer_session
|
||||
capture_session
|
||||
input_session
|
||||
platform_session
|
||||
timer_session
|
||||
|
@ -2,4 +2,4 @@ base
|
||||
os
|
||||
blit
|
||||
platform_session
|
||||
framebuffer_session
|
||||
capture_session
|
||||
|
@ -46,12 +46,11 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="report_rom">
|
||||
@ -69,16 +68,18 @@ install_config {
|
||||
<start name="nitpicker_config">
|
||||
<binary name="rom_filter"/>
|
||||
<resource name="RAM" quantum="1096K"/>
|
||||
<provides><service name="ROM"/></provides>
|
||||
<provides> <service name="ROM"/> </provides>
|
||||
<config>
|
||||
<input name="xray_enabled" rom="xray" node="xray">
|
||||
<attribute name="enabled" /> </input>
|
||||
|
||||
<output node="config">
|
||||
<attribute name="request_framebuffer" value="no"/>
|
||||
<attribute name="focus" value="rom"/>
|
||||
<inline>
|
||||
<report focus="yes" xray="yes" hover="yes" keystate="yes"
|
||||
clicked="yes"/>
|
||||
<capture/>
|
||||
<domain name="pointer" layer="1" origin="pointer"
|
||||
content="client" label="no"/>
|
||||
<domain name="panel" layer="2"
|
||||
@ -149,7 +150,7 @@ install_config {
|
||||
|
||||
<start name="nitpicker" caps="120">
|
||||
<resource name="RAM" quantum="1216K"/>
|
||||
<provides> <service name="Gui"/> </provides>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<route>
|
||||
<service name="ROM" label="config">
|
||||
<child name="nitpicker_config"/> </service>
|
||||
|
@ -15,6 +15,8 @@ if {[get_cmd_switch --autopilot] && [have_spec linux]} {
|
||||
create_boot_directory
|
||||
import_from_depot [depot_user]/src/[base_src] \
|
||||
[depot_user]/pkg/[drivers_interactive_pkg] \
|
||||
[depot_user]/src/nitpicker \
|
||||
[depot_user]/src/gui_fb \
|
||||
[depot_user]/src/init
|
||||
build { test/fb_bench }
|
||||
|
||||
@ -45,12 +47,35 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<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 name="test-fb_bench">
|
||||
@ -60,9 +85,14 @@ install_config {
|
||||
- RAM.
|
||||
-->
|
||||
<resource name="RAM" quantum="72M"/>
|
||||
<config/>
|
||||
</start>
|
||||
</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 }
|
||||
|
||||
# disable QEMU graphic to enable testing on our machines without SDL and X
|
||||
|
@ -32,16 +32,17 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="test-framebuffer">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides> <service name="Capture"/> </provides>
|
||||
<config/>
|
||||
</start>
|
||||
</config>}
|
||||
|
||||
|
@ -36,18 +36,18 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Gui"/> </provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<domain name="" layer="2" /> <default-policy domain=""/>
|
||||
</config>
|
||||
</start>
|
||||
|
@ -12,6 +12,7 @@ set build_components {
|
||||
server/report_rom
|
||||
server/dynamic_rom
|
||||
server/nitpicker
|
||||
server/input_event_bridge
|
||||
app/pointer
|
||||
test/pointer
|
||||
test/nitpicker
|
||||
@ -49,22 +50,31 @@ set config {
|
||||
<service name="LOG"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="fb_sdl" ld="no">
|
||||
<resource name="RAM" quantum="6M"/>
|
||||
<start name="input_event_bridge">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides>
|
||||
<service name="Framebuffer"/>
|
||||
<service name="Event"/>
|
||||
<service name="Input"/>
|
||||
</provides>
|
||||
<config buffered="yes" width="1280" height="720" depth="16"/>
|
||||
<config/>
|
||||
<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>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
</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"/>
|
||||
|
||||
<start name="report_rom_nitpicker">
|
||||
@ -85,8 +95,9 @@ set config {
|
||||
</start>
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides> <service name="Gui"/> </provides>
|
||||
<config>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<report focus="yes" hover="yes" xray="yes"/>
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer"/>
|
||||
<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="LOG"> <parent/> </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="Report"> <child name="report_rom_nitpicker"/> </service>
|
||||
</route>
|
||||
@ -282,6 +292,7 @@ set boot_modules {
|
||||
pointer
|
||||
test-pointer
|
||||
testnit
|
||||
input_event_bridge
|
||||
}
|
||||
|
||||
# "lsort -unique" removes duplicates but core must be first
|
||||
|
@ -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();
|
||||
}
|
@ -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_
|
@ -1,11 +1,12 @@
|
||||
/*
|
||||
* \brief Framebuffer driver that uses a framebuffer supplied by the core rom.
|
||||
* \author Johannes Kliemann
|
||||
* \author Norman Feske
|
||||
* \date 2017-06-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 Genode Labs GmbH
|
||||
* Copyright (C) 2020 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
@ -13,35 +14,102 @@
|
||||
|
||||
#include <base/component.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/attached_io_mem_dataspace.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,
|
||||
"platform_info"
|
||||
};
|
||||
Env &_env;
|
||||
|
||||
Framebuffer::Session_component fb {
|
||||
env,
|
||||
pinfo.xml(),
|
||||
};
|
||||
Attached_rom_dataspace _platform_info { _env, "platform_info" };
|
||||
|
||||
Genode::Static_root<Framebuffer::Session> fb_root {env.ep().manage(fb)};
|
||||
|
||||
Main(Genode::Env &env) : env(env)
|
||||
struct Info
|
||||
{
|
||||
env.parent().announce(env.ep().manage(fb_root));
|
||||
addr_t addr;
|
||||
Area size;
|
||||
unsigned bpp;
|
||||
unsigned pitch;
|
||||
unsigned type;
|
||||
|
||||
static Info from_platform_info(Xml_node const &node)
|
||||
{
|
||||
Info result { };
|
||||
node.with_sub_node("boot", [&] (Xml_node const &boot) {
|
||||
boot.with_sub_node("framebuffer", [&] (Xml_node const &fb) {
|
||||
result = {
|
||||
.addr = fb.attribute_value("phys", 0UL),
|
||||
.size = { fb.attribute_value("width", 0U),
|
||||
fb.attribute_value("height", 0U) },
|
||||
.bpp = fb.attribute_value("bpp", 0U),
|
||||
.pitch = fb.attribute_value("pitch", 0U),
|
||||
.type = fb.attribute_value("type", 0U)
|
||||
};
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
enum { TYPE_RGB_COLOR = 1 };
|
||||
|
||||
void print(Output &out) const
|
||||
{
|
||||
Genode::print(out, size, "x", bpp, " @ ", (void*)addr, " "
|
||||
"type=", type, " pitch=", pitch);
|
||||
}
|
||||
};
|
||||
|
||||
Info const _info = Info::from_platform_info(_platform_info.xml());
|
||||
|
||||
void _check_info() const
|
||||
{
|
||||
if (_info.bpp != 32 || _info.type != Info::TYPE_RGB_COLOR ) {
|
||||
error("unsupported resolution (bpp or/and type), platform info:\n",
|
||||
_platform_info.xml());
|
||||
throw Exception();
|
||||
}
|
||||
}
|
||||
|
||||
bool const _checked_info = ( _check_info(), true );
|
||||
|
||||
Attached_io_mem_dataspace _fb_ds { _env, _info.addr,
|
||||
_info.pitch*_info.size.h(), true };
|
||||
|
||||
Capture::Connection _capture { _env };
|
||||
|
||||
Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _info.size };
|
||||
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
Signal_handler<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); }
|
||||
|
@ -1,4 +1,3 @@
|
||||
TARGET = fb_boot_drv
|
||||
LIBS = base blit
|
||||
SRC_CC = main.cc framebuffer.cc
|
||||
INC_DIR += $(PRG_DIR)/include
|
||||
SRC_CC = main.cc
|
||||
|
@ -16,21 +16,15 @@
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <base/component.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_device/client.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <capture_session/connection.h>
|
||||
#include <blit/painter.h>
|
||||
#include <os/pixel_rgb888.h>
|
||||
|
||||
|
||||
/***********************************************
|
||||
** Implementation of the framebuffer service **
|
||||
***********************************************/
|
||||
|
||||
namespace Framebuffer
|
||||
namespace Pl11x_driver
|
||||
{
|
||||
|
||||
enum {
|
||||
SCR_WIDTH = 640,
|
||||
SCR_HEIGHT = 480,
|
||||
@ -45,154 +39,51 @@ namespace Framebuffer
|
||||
FRAMEBUFFER_SIZE = SCR_WIDTH*SCR_HEIGHT*BYTES_PER_PIXEL,
|
||||
};
|
||||
|
||||
class Session_component;
|
||||
|
||||
using namespace Genode;
|
||||
class Main;
|
||||
}
|
||||
|
||||
class Framebuffer::Session_component :
|
||||
public Genode::Rpc_object<Framebuffer::Session>
|
||||
|
||||
struct Pl11x_driver::Main
|
||||
{
|
||||
private:
|
||||
using Area = Capture::Area;
|
||||
|
||||
Ram_dataspace_capability _fb_ds_cap;
|
||||
addr_t _regs_base;
|
||||
addr_t _sys_regs_base;
|
||||
Timer::Connection _timer;
|
||||
Env &_env;
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Bit definitions of the lcd control register
|
||||
*/
|
||||
CTRL_ENABLED = 1 << 0,
|
||||
CTRL_BPP_24 = 5 << 1,
|
||||
CTRL_TFT = 1 << 5,
|
||||
CTRL_BGR = 1 << 8,
|
||||
CTRL_POWER = 1 << 11,
|
||||
CTRL_VCOMP = 1 << 12,
|
||||
|
||||
/**
|
||||
* Bit definitions for CLCDC timing.
|
||||
*/
|
||||
CLCDC_IVS = 1 << 11,
|
||||
CLCDC_IHS = 1 << 12,
|
||||
CLCDC_BCD = 1 << 26,
|
||||
};
|
||||
|
||||
enum Sp810_defs {
|
||||
SP810_REG_OSCCLCD = 0x1c,
|
||||
SP810_REG_LOCK = 0x20,
|
||||
};
|
||||
|
||||
enum Pl11x_defs {
|
||||
PL11X_REG_TIMING0 = 0,
|
||||
PL11X_REG_TIMING1 = 1,
|
||||
PL11X_REG_TIMING2 = 2,
|
||||
PL11X_REG_TIMING3 = 3,
|
||||
PL11X_REG_UPBASE = 4,
|
||||
PL11X_REG_LPBASE = 5,
|
||||
PL11X_REG_CTRL = 6,
|
||||
PL11X_REG_IMSC = 7,
|
||||
};
|
||||
|
||||
void sys_reg_write(unsigned reg, long value) {
|
||||
*(volatile long *)(_sys_regs_base + sizeof(long)*reg) = value; }
|
||||
|
||||
long sys_reg_read(unsigned reg) {
|
||||
return *(volatile long *)(_sys_regs_base + sizeof(long)*reg); }
|
||||
|
||||
void reg_write(unsigned reg, long value) {
|
||||
*(volatile long *)(_regs_base + sizeof(long)*reg) = value; }
|
||||
|
||||
long reg_read(unsigned reg) {
|
||||
return *(volatile long *)(_regs_base + sizeof(long)*reg); }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(Env & env,
|
||||
void * regs_base,
|
||||
void * sys_regs_base,
|
||||
Ram_dataspace_capability fb_ds_cap,
|
||||
Genode::addr_t fb_ds_bus_addr)
|
||||
: _fb_ds_cap(fb_ds_cap),
|
||||
_regs_base((addr_t)regs_base),
|
||||
_sys_regs_base((addr_t)sys_regs_base),
|
||||
_timer(env)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
uint32_t tim0 = (SCR_WIDTH/16 - 1) << 2
|
||||
| (HSYNC_LEN - 1) << 8
|
||||
| (RIGHT_MARGIN - 1) << 16
|
||||
| (LEFT_MARGIN - 1) << 24;
|
||||
uint32_t tim1 = (SCR_HEIGHT - 1)
|
||||
| (VSYNC_LEN - 1) << 10
|
||||
| LOWER_MARGIN << 16
|
||||
| UPPER_MARGIN << 24;
|
||||
uint32_t tim2 = ((SCR_WIDTH - 1) << 16)
|
||||
| CLCDC_IVS | CLCDC_IHS | CLCDC_BCD;
|
||||
uint32_t tim3 = 0;
|
||||
uint32_t ctrl = reg_read(PL11X_REG_CTRL);
|
||||
|
||||
/* reset video if already enabled */
|
||||
if (ctrl & CTRL_POWER) {
|
||||
ctrl &= ~CTRL_POWER;
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
_timer.msleep(100);
|
||||
}
|
||||
if (ctrl & CTRL_ENABLED) {
|
||||
ctrl &= ~CTRL_ENABLED;
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
_timer.msleep(100);
|
||||
}
|
||||
|
||||
ctrl = CTRL_BGR | CTRL_ENABLED | CTRL_TFT | CTRL_VCOMP | CTRL_BPP_24;
|
||||
|
||||
/* init color-lcd oscillator */
|
||||
sys_reg_write(SP810_REG_LOCK, 0xa05f);
|
||||
sys_reg_write(SP810_REG_OSCCLCD, 0x2c77);
|
||||
sys_reg_write(SP810_REG_LOCK, 0);
|
||||
|
||||
/* init video timing */
|
||||
reg_write(PL11X_REG_TIMING0, tim0);
|
||||
reg_write(PL11X_REG_TIMING1, tim1);
|
||||
reg_write(PL11X_REG_TIMING2, tim2);
|
||||
reg_write(PL11X_REG_TIMING3, tim3);
|
||||
|
||||
/* set framebuffer address and ctrl register */
|
||||
reg_write(PL11X_REG_UPBASE, fb_ds_bus_addr);
|
||||
reg_write(PL11X_REG_LPBASE, 0);
|
||||
reg_write(PL11X_REG_IMSC, 0);
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
_timer.msleep(100);
|
||||
|
||||
/* power on */
|
||||
reg_write(PL11X_REG_CTRL, ctrl | CTRL_POWER);
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability dataspace() override { return _fb_ds_cap; }
|
||||
|
||||
Mode mode() const override { return Mode { .area { SCR_WIDTH, SCR_HEIGHT } }; }
|
||||
|
||||
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_timer.sigh(sigh);
|
||||
_timer.trigger_periodic(10*1000);
|
||||
}
|
||||
|
||||
void refresh(int, int, int, int) override { }
|
||||
};
|
||||
Area const _size { SCR_WIDTH, SCR_HEIGHT };
|
||||
|
||||
|
||||
struct Framebuffer::Main
|
||||
{
|
||||
Env & _env;
|
||||
/*
|
||||
* Capture
|
||||
*/
|
||||
|
||||
Capture::Connection _capture { _env };
|
||||
|
||||
Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size };
|
||||
|
||||
|
||||
/*
|
||||
* Timer
|
||||
*/
|
||||
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
Signal_handler<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::Device_client _pl11x_dev {
|
||||
_platform.device_by_property("compatible", "arm,pl111") };
|
||||
@ -204,34 +95,122 @@ struct Framebuffer::Main
|
||||
_sp810_dev.io_mem_dataspace() };
|
||||
Ram_dataspace_capability _fb_ds_cap {
|
||||
_platform.alloc_dma_buffer(FRAMEBUFFER_SIZE) };
|
||||
Attached_dataspace _fb_ds { _env.rm(), _fb_ds_cap };
|
||||
|
||||
Session_component _fb_session { _env,
|
||||
_lcd_io_mem.local_addr<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) };
|
||||
void _init_device();
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
log("--- pl11x framebuffer driver ---\n");
|
||||
_init_device();
|
||||
|
||||
/* announce service */
|
||||
_env.parent().announce(env.ep().manage(_fb_root));
|
||||
_timer.sigh(_timer_handler);
|
||||
_timer.trigger_periodic(20*1000);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Pl11x_driver::Main::_init_device()
|
||||
{
|
||||
enum {
|
||||
/**
|
||||
* Bit definitions of the lcd control register
|
||||
*/
|
||||
CTRL_ENABLED = 1 << 0,
|
||||
CTRL_BPP_24 = 5 << 1,
|
||||
CTRL_TFT = 1 << 5,
|
||||
CTRL_BGR = 1 << 8,
|
||||
CTRL_POWER = 1 << 11,
|
||||
CTRL_VCOMP = 1 << 12,
|
||||
|
||||
/**
|
||||
* Bit definitions for CLCDC timing.
|
||||
*/
|
||||
CLCDC_IVS = 1 << 11,
|
||||
CLCDC_IHS = 1 << 12,
|
||||
CLCDC_BCD = 1 << 26,
|
||||
};
|
||||
|
||||
enum Sp810_defs {
|
||||
SP810_REG_OSCCLCD = 0x1c,
|
||||
SP810_REG_LOCK = 0x20,
|
||||
};
|
||||
|
||||
enum Pl11x_defs {
|
||||
PL11X_REG_TIMING0 = 0,
|
||||
PL11X_REG_TIMING1 = 1,
|
||||
PL11X_REG_TIMING2 = 2,
|
||||
PL11X_REG_TIMING3 = 3,
|
||||
PL11X_REG_UPBASE = 4,
|
||||
PL11X_REG_LPBASE = 5,
|
||||
PL11X_REG_CTRL = 6,
|
||||
PL11X_REG_IMSC = 7,
|
||||
};
|
||||
|
||||
addr_t const regs_base = (addr_t)_lcd_io_mem.local_addr<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;
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Main(Main const &);
|
||||
Main &operator = (Main const &);
|
||||
};
|
||||
/* init color-lcd oscillator */
|
||||
sys_reg_write(SP810_REG_LOCK, 0xa05f);
|
||||
sys_reg_write(SP810_REG_OSCCLCD, 0x2c77);
|
||||
sys_reg_write(SP810_REG_LOCK, 0);
|
||||
|
||||
/* init video timing */
|
||||
reg_write(PL11X_REG_TIMING0, tim0);
|
||||
reg_write(PL11X_REG_TIMING1, tim1);
|
||||
reg_write(PL11X_REG_TIMING2, tim2);
|
||||
reg_write(PL11X_REG_TIMING3, tim3);
|
||||
|
||||
/* set framebuffer address and ctrl register */
|
||||
addr_t const fb_dma_base = (addr_t)_platform.bus_addr_dma_buffer(_fb_ds_cap);
|
||||
reg_write(PL11X_REG_UPBASE, fb_dma_base);
|
||||
reg_write(PL11X_REG_LPBASE, 0);
|
||||
reg_write(PL11X_REG_IMSC, 0);
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
_timer.msleep(100);
|
||||
|
||||
/* power on */
|
||||
reg_write(PL11X_REG_CTRL, ctrl | CTRL_POWER);
|
||||
}
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
static Framebuffer::Main main(env);
|
||||
static Pl11x_driver::Main main(env);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
TARGET = pl11x_fb_drv
|
||||
REQUIRES = arm_v7
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base blit
|
||||
|
@ -21,12 +21,14 @@
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <platform_session/connection.h>
|
||||
#include <util/mmio.h>
|
||||
#include <capture_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include <ipu.h>
|
||||
|
||||
namespace Framebuffer {
|
||||
using namespace Genode;
|
||||
using Area = Capture::Area;
|
||||
class Driver;
|
||||
};
|
||||
|
||||
@ -46,7 +48,7 @@ class Framebuffer::Driver
|
||||
|
||||
public:
|
||||
|
||||
enum Resolutions { BYTES_PER_PIXEL = 2 };
|
||||
enum Resolutions { BYTES_PER_PIXEL = 4 };
|
||||
|
||||
Driver(Genode::Env &env, Genode::Xml_node config)
|
||||
: _env(env),
|
||||
@ -66,7 +68,8 @@ class Framebuffer::Driver
|
||||
return true;
|
||||
}
|
||||
|
||||
Mode mode() { return Mode { .area = { _width, _height } }; }
|
||||
Area screen_size() const { return Area { _width, _height }; }
|
||||
|
||||
Ipu &ipu() { return _ipu; }
|
||||
};
|
||||
|
||||
|
@ -2,152 +2,78 @@
|
||||
* \brief Frame-buffer driver for the i.MX53
|
||||
* \author Nikolay Golikov <nik@ksyslabs.org>
|
||||
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
|
||||
* \author Norman Feske
|
||||
* \date 2012-06-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2020 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <base/log.h>
|
||||
#include <imx_framebuffer_session/imx_framebuffer_session.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <os/static_root.h>
|
||||
#include <blit/blit.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
namespace Framebuffer {
|
||||
using namespace Genode;
|
||||
class Session_component;
|
||||
struct Main;
|
||||
};
|
||||
|
||||
|
||||
class Framebuffer::Session_component :
|
||||
public Genode::Rpc_object<Framebuffer::Imx_session>
|
||||
struct Framebuffer::Main
|
||||
{
|
||||
private:
|
||||
using Pixel = Capture::Pixel;
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Session_component(Session_component const &);
|
||||
Session_component &operator = (Session_component const &);
|
||||
Env &_env;
|
||||
|
||||
Genode::Env &_env;
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
bool _buffered;
|
||||
Mode _mode;
|
||||
size_t _size;
|
||||
Driver _driver { _env, _config.xml() };
|
||||
|
||||
/* dataspace uses a back buffer (if '_buffered' is true) */
|
||||
Genode::Dataspace_capability _bb_ds;
|
||||
void *_bb_addr;
|
||||
Area const _size = _driver.screen_size();
|
||||
|
||||
/* dataspace of physical frame buffer */
|
||||
Genode::Dataspace_capability _fb_ds;
|
||||
void *_fb_addr;
|
||||
Attached_ram_dataspace _fb_ds { _env.ram(), _env.rm(),
|
||||
_size.count()*sizeof(Pixel), WRITE_COMBINED };
|
||||
|
||||
Timer::Connection _timer { _env };
|
||||
Capture::Connection _capture { _env };
|
||||
|
||||
Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size };
|
||||
|
||||
Ipu &_ipu;
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
void _refresh_buffered(int x, int y, int w, int h)
|
||||
{
|
||||
/* clip specified coordinates against screen boundaries */
|
||||
int x2 = min(x + w - 1, (int)_mode.area.w() - 1),
|
||||
y2 = min(y + h - 1, (int)_mode.area.h() - 1);
|
||||
int x1 = max(x, 0),
|
||||
y1 = max(y, 0);
|
||||
if (x1 > x2 || y1 > y2) return;
|
||||
Signal_handler<Main> _timer_handler { _env.ep(), *this, &Main::_handle_timer };
|
||||
|
||||
int bypp = _mode.bytes_per_pixel();
|
||||
|
||||
/* copy pixels from back buffer to physical frame buffer */
|
||||
char *src = (char *)_bb_addr + bypp*(_mode.area.w()*y1 + x1),
|
||||
*dst = (char *)_fb_addr + bypp*(_mode.area.h()*y1 + x1);
|
||||
|
||||
blit(src, bypp*_mode.area.w(), dst, bypp*_mode.area.w(),
|
||||
bypp*(x2 - x1 + 1), y2 - y1 + 1);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Session_component(Genode::Env &env, Driver &driver, bool buffered)
|
||||
: _env(env),
|
||||
_buffered(buffered),
|
||||
_mode(driver.mode()),
|
||||
_size(_mode.bytes_per_pixel()*_mode.area.count()),
|
||||
_bb_ds(buffered ? _env.ram().alloc(_size)
|
||||
: Genode::Ram_dataspace_capability()),
|
||||
_bb_addr(buffered ? (void*)_env.rm().attach(_bb_ds) : 0),
|
||||
_fb_ds(_env.ram().alloc(_size, WRITE_COMBINED)),
|
||||
_fb_addr((void*)_env.rm().attach(_fb_ds)),
|
||||
_ipu(driver.ipu())
|
||||
{
|
||||
if (!driver.init(Dataspace_client(_fb_ds).phys_addr())) {
|
||||
error("could not initialize display");
|
||||
struct Could_not_initialize_display : Exception { };
|
||||
throw Could_not_initialize_display();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
** Framebuffer::session interface **
|
||||
**************************************/
|
||||
|
||||
Dataspace_capability dataspace() override { return _buffered ? _bb_ds : _fb_ds; }
|
||||
Mode mode() const override { return _mode; }
|
||||
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_timer.sigh(sigh);
|
||||
_timer.trigger_periodic(10*1000);
|
||||
}
|
||||
|
||||
void refresh(int x, int y, int w, int h) override
|
||||
{
|
||||
if (_buffered)
|
||||
_refresh_buffered(x, y, w, h);
|
||||
}
|
||||
|
||||
void overlay(Genode::addr_t phys_base, int x, int y, int alpha) override {
|
||||
_ipu.overlay(phys_base, x, y, alpha); }
|
||||
};
|
||||
|
||||
|
||||
static bool config_attribute(Genode::Xml_node node, const char *attr_name)
|
||||
{
|
||||
return node.attribute_value(attr_name, false);
|
||||
}
|
||||
|
||||
|
||||
struct Main
|
||||
{
|
||||
Genode::Env &_env;
|
||||
Genode::Entrypoint &_ep;
|
||||
|
||||
Genode::Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
Framebuffer::Driver _driver { _env, _config.xml() };
|
||||
|
||||
Framebuffer::Session_component _fb_session { _env, _driver,
|
||||
config_attribute(_config.xml(), "buffered") };
|
||||
|
||||
Genode::Static_root<Framebuffer::Session> _fb_root {
|
||||
_ep.manage(_fb_session) };
|
||||
|
||||
Main(Genode::Env &env) : _env(env), _ep(_env.ep())
|
||||
void _handle_timer()
|
||||
{
|
||||
Genode::log("--- i.MX53 framebuffer driver ---");
|
||||
Surface<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); }
|
||||
|
@ -17,131 +17,59 @@
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <util/reconstructible.h>
|
||||
#include <os/static_root.h>
|
||||
#include <framebuffer_session/framebuffer_session.h>
|
||||
#include <capture_session/connection.h>
|
||||
#include <platform_session/connection.h>
|
||||
#include <blit/blit.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
namespace Framebuffer {
|
||||
using namespace Genode;
|
||||
class Session_component;
|
||||
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
|
||||
{
|
||||
Env &_env;
|
||||
Entrypoint &_ep;
|
||||
using Area = Capture::Area;
|
||||
using Pixel = Capture::Pixel;
|
||||
|
||||
Env &_env;
|
||||
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
Platform::Connection _platform { _env };
|
||||
|
||||
Platform::Framebuffer_info _fb_info { 1024, 768, 32 };
|
||||
Area const _size { 1024, 768 };
|
||||
|
||||
Constructible<Framebuffer::Session_component> _fb_session { };
|
||||
Constructible<Static_root<Framebuffer::Session>> _fb_root { };
|
||||
Platform::Framebuffer_info _fb_info { _size.w(), _size.h(), 32 };
|
||||
|
||||
Main(Genode::Env &env) : _env(env), _ep(_env.ep())
|
||||
bool const _fb_initialized = ( _platform.setup_framebuffer(_fb_info), true );
|
||||
|
||||
Attached_io_mem_dataspace _fb_ds { _env, _fb_info.addr, _fb_info.size };
|
||||
|
||||
Capture::Connection _capture { _env };
|
||||
|
||||
Capture::Connection::Screen _captured_screen { _capture, _env.rm(), _size };
|
||||
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
Signal_handler<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,
|
||||
_fb_info.phys_width, _fb_info.phys_height,
|
||||
config_buffered(_config.xml()));
|
||||
_captured_screen.apply_to_surface(surface);
|
||||
}
|
||||
|
||||
_fb_root.construct(_ep.manage(*_fb_session));
|
||||
Main(Genode::Env &env) : _env(env)
|
||||
{
|
||||
log("--- rpi_fb_drv started ---");
|
||||
|
||||
/* announce service */
|
||||
env.parent().announce(_ep.manage(*_fb_root));
|
||||
_timer.sigh(_timer_handler);
|
||||
_timer.trigger_periodic(10*1000);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -15,10 +15,9 @@
|
||||
/* Genode includes */
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <framebuffer_session/framebuffer_session.h>
|
||||
#include <input/root.h>
|
||||
#include <event_session/connection.h>
|
||||
#include <capture_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <blit/blit.h>
|
||||
|
||||
/* Linux includes */
|
||||
#include <SDL/SDL.h>
|
||||
@ -26,12 +25,6 @@
|
||||
/* local includes */
|
||||
#include "convert_keycode.h"
|
||||
|
||||
namespace Framebuffer {
|
||||
class Session_component;
|
||||
using namespace Genode;
|
||||
}
|
||||
|
||||
|
||||
namespace Fb_sdl {
|
||||
class Main;
|
||||
using namespace Genode;
|
||||
@ -44,140 +37,6 @@ struct Sdl_videodriver_not_supported : Genode::Exception { };
|
||||
struct Sdl_setvideomode_failed : Genode::Exception { };
|
||||
|
||||
|
||||
class Framebuffer::Session_component : public Rpc_object<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
|
||||
{
|
||||
Env &_env;
|
||||
@ -185,34 +44,15 @@ struct Fb_sdl::Main
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
Timer::Connection _timer { _env };
|
||||
Event::Connection _event { _env };
|
||||
|
||||
unsigned const _fb_width = _config.xml().attribute_value("width", 1024UL);
|
||||
unsigned const _fb_height = _config.xml().attribute_value("height", 768UL);
|
||||
using Area = Capture::Area;
|
||||
using Point = Capture::Area;
|
||||
using Pixel = Capture::Pixel;
|
||||
using Affected_rects = Capture::Session::Affected_rects;
|
||||
using Event_batch = Event::Session_client::Batch;
|
||||
|
||||
Framebuffer::Mode _fb_mode { .area = { _fb_width, _fb_height } };
|
||||
|
||||
Framebuffer::Session_component _fb_session { _env, _fb_mode };
|
||||
|
||||
Static_root<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)
|
||||
void _init_sdl()
|
||||
{
|
||||
/*
|
||||
* Initialize libSDL window
|
||||
@ -234,9 +74,103 @@ struct Fb_sdl::Main
|
||||
}
|
||||
|
||||
SDL_ShowCursor(0);
|
||||
}
|
||||
|
||||
_env.parent().announce(env.ep().manage(_fb_root));
|
||||
_env.parent().announce(env.ep().manage(_input_root));
|
||||
bool const _sdl_initialized = ( _init_sdl(), true );
|
||||
|
||||
struct Sdl_screen
|
||||
{
|
||||
Area const size;
|
||||
|
||||
SDL_Surface &_sdl_surface = _init_sdl_surface();
|
||||
|
||||
SDL_Surface &_init_sdl_surface()
|
||||
{
|
||||
unsigned const bpp = 32;
|
||||
unsigned const flags = SDL_SWSURFACE | SDL_RESIZABLE;
|
||||
|
||||
SDL_Surface *surface_ptr = nullptr;
|
||||
|
||||
if (SDL_VideoModeOK(size.w(), size.h(), bpp, flags))
|
||||
surface_ptr = SDL_SetVideoMode(size.w(), size.h(), bpp, flags);
|
||||
|
||||
if (!surface_ptr) {
|
||||
error("SDL_SetVideoMode failed (", Genode::Cstring(SDL_GetError()), ")");
|
||||
throw Sdl_setvideomode_failed();
|
||||
}
|
||||
return *surface_ptr;
|
||||
}
|
||||
|
||||
Sdl_screen(Area size) : size(size) { }
|
||||
|
||||
template <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.trigger_periodic(100000000 / 5994); /* 59.94Hz */
|
||||
@ -244,7 +178,7 @@ struct Fb_sdl::Main
|
||||
};
|
||||
|
||||
|
||||
void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event)
|
||||
void Fb_sdl::Main::_handle_sdl_event(Event_batch &batch, SDL_Event const &event)
|
||||
{
|
||||
using namespace Input;
|
||||
|
||||
@ -255,9 +189,7 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event)
|
||||
return;
|
||||
}
|
||||
|
||||
Framebuffer::Mode const mode { .area = { (unsigned)event.resize.w,
|
||||
(unsigned)event.resize.h } };
|
||||
_fb_session.submit_mode_change(mode);
|
||||
_resize(Area((unsigned)event.resize.w, (unsigned)event.resize.h));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -270,7 +202,7 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event)
|
||||
if (ox == _mx && oy == _my)
|
||||
return;
|
||||
|
||||
_input_session.submit(Absolute_motion{_mx, _my});
|
||||
batch.submit(Absolute_motion{_mx, _my});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -304,18 +236,18 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event)
|
||||
/* ignore */
|
||||
return;
|
||||
|
||||
_input_session.submit(Release{keycode});
|
||||
batch.submit(Release{keycode});
|
||||
return;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
|
||||
if (event.button.button == SDL_BUTTON_WHEELUP)
|
||||
_input_session.submit(Wheel{0, 1});
|
||||
batch.submit(Wheel{0, 1});
|
||||
else if (event.button.button == SDL_BUTTON_WHEELDOWN)
|
||||
_input_session.submit(Wheel{0, -1});
|
||||
batch.submit(Wheel{0, -1});
|
||||
else
|
||||
_input_session.submit(Press{keycode});
|
||||
batch.submit(Press{keycode});
|
||||
return;
|
||||
|
||||
default:
|
||||
@ -327,8 +259,12 @@ void Fb_sdl::Main::_handle_sdl_event(SDL_Event const &event)
|
||||
void Fb_sdl::Main::_handle_sdl_events()
|
||||
{
|
||||
SDL_Event event { };
|
||||
while (SDL_PollEvent(&event))
|
||||
_handle_sdl_event(event);
|
||||
|
||||
_event.with_batch([&] (Event_batch &batch) {
|
||||
|
||||
while (SDL_PollEvent(&event))
|
||||
_handle_sdl_event(batch, event);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
/*
|
||||
* \brief Basic test for framebuffer session
|
||||
* \brief Basic test for framebuffer drivers
|
||||
* \author Martin Stein
|
||||
* \author Christian Helmuth
|
||||
* \author Stefan Kalkowski
|
||||
* \author Norman Feske
|
||||
* \date 2012-01-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
* Copyright (C) 2012-2020 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
@ -16,71 +17,107 @@
|
||||
/* Genode includes */
|
||||
#include <base/component.h>
|
||||
#include <base/log.h>
|
||||
#include <framebuffer_session/connection.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <os/surface.h>
|
||||
#include <os/pixel_rgb888.h>
|
||||
#include <os/static_root.h>
|
||||
#include <capture_session/capture_session.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
namespace Test {
|
||||
|
||||
using Area = Genode::Surface_base::Area;
|
||||
using Pixel = Genode::Pixel_rgb888;
|
||||
using namespace Genode;
|
||||
|
||||
class Test_environment
|
||||
using Area = Capture::Area;
|
||||
using Point = Capture::Point;
|
||||
using Pixel = Capture::Pixel;
|
||||
|
||||
struct Capture_session;
|
||||
class Main;
|
||||
}
|
||||
|
||||
|
||||
struct Test::Capture_session : Rpc_object<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:
|
||||
|
||||
using Ds = Genode::Constructible<Genode::Attached_dataspace>;
|
||||
Env &_env;
|
||||
|
||||
Pixel const BLACK = { 0, 0, 0 };
|
||||
Pixel const BLUE = { 0, 0, 255 };
|
||||
Pixel const GREEN = { 0, 255, 0 };
|
||||
Pixel const RED = { 255, 0, 0 };
|
||||
Pixel const WHITE = { 255, 255, 255 };
|
||||
Capture_session _capture_session { _env };
|
||||
|
||||
enum State { STRIPES, ALL_BLUE, ALL_GREEN, ALL_RED, COLORED };
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
Framebuffer::Mode _mode { };
|
||||
Framebuffer::Connection _fb { _env, _mode };
|
||||
Ds _fb_ds { };
|
||||
Genode::Signal_handler<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>(); }
|
||||
Static_root<Capture::Session> _capture_root { _env.ep().manage(_capture_session) };
|
||||
|
||||
public:
|
||||
|
||||
Test_environment(Genode::Env &env)
|
||||
:
|
||||
_env(env),
|
||||
_mode_sigh(_env.ep(), *this, &Test_environment::_mode_handle),
|
||||
_sync_sigh(_env.ep(), *this, &Test_environment::_sync_handle)
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
_fb.mode_sigh(_mode_sigh);
|
||||
_fb.sync_sigh(_sync_sigh);
|
||||
_mode_handle();
|
||||
_env.parent().announce(env.ep().manage(_capture_root));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Test_environment::_draw_frame(Pixel *p, Pixel c, Area area)
|
||||
void Test::Capture_session::_draw_frame(Pixel *p, Pixel c, Area area)
|
||||
{
|
||||
unsigned const w = area.w(), h = area.h();
|
||||
|
||||
@ -94,91 +131,81 @@ void Test_environment::_draw_frame(Pixel *p, Pixel c, Area area)
|
||||
}
|
||||
|
||||
|
||||
void Test_environment::_draw()
|
||||
void Test::Capture_session::_draw()
|
||||
{
|
||||
using namespace Genode;
|
||||
if (!_ds.constructed())
|
||||
return;
|
||||
|
||||
addr_t const num_pixels = _size.count();
|
||||
|
||||
Pixel * const fb_base = _ds->local_addr<Pixel>();
|
||||
|
||||
switch(_state) {
|
||||
case STRIPES:
|
||||
{
|
||||
Genode::log("black & white stripes");
|
||||
addr_t const stripe_width = _mode.area.w() / 4;
|
||||
log("black & white stripes");
|
||||
addr_t const stripe_width = _size.w() / 4;
|
||||
addr_t stripe_o = 0;
|
||||
bool stripe = 0;
|
||||
for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) {
|
||||
for (addr_t o = 0; o < num_pixels; o++) {
|
||||
stripe_o++;
|
||||
if (stripe_o == stripe_width) {
|
||||
stripe_o = 0;
|
||||
stripe = !stripe;
|
||||
}
|
||||
*(Pixel *)(_fb_base() + o) = stripe ? BLACK : WHITE;
|
||||
fb_base[o] = stripe ? BLACK : WHITE;
|
||||
}
|
||||
|
||||
_draw_frame((Pixel *)_fb_base(), RED, _mode.area);
|
||||
_draw_frame(fb_base, RED, _size);
|
||||
_state = ALL_BLUE;
|
||||
break;
|
||||
}
|
||||
case ALL_BLUE:
|
||||
{
|
||||
Genode::log("blue");
|
||||
for (addr_t o = 0; o < _fb_size(); o += _fb_bpp())
|
||||
*(Pixel *)(_fb_base() + o) = BLUE;
|
||||
log("blue");
|
||||
for (addr_t o = 0; o < num_pixels; o++)
|
||||
fb_base[o] = BLUE;
|
||||
|
||||
_draw_frame((Pixel *)_fb_base(), RED, _mode.area);
|
||||
_draw_frame(fb_base, RED, _size);
|
||||
_state = ALL_GREEN;
|
||||
break;
|
||||
}
|
||||
case ALL_GREEN:
|
||||
{
|
||||
Genode::log("green");
|
||||
for (addr_t o = 0; o < _fb_size(); o += _fb_bpp())
|
||||
*(Pixel *)(_fb_base() + o) = GREEN;
|
||||
log("green");
|
||||
for (addr_t o = 0; o < num_pixels; o++)
|
||||
fb_base[o] = GREEN;
|
||||
|
||||
_draw_frame((Pixel *)_fb_base(), RED, _mode.area);
|
||||
_draw_frame(fb_base, RED, _size);
|
||||
_state = ALL_RED;
|
||||
break;
|
||||
}
|
||||
case ALL_RED:
|
||||
{
|
||||
Genode::log("red");
|
||||
for (addr_t o = 0; o < _fb_size(); o += _fb_bpp())
|
||||
*(Pixel *)(_fb_base() + o) = RED;
|
||||
log("red");
|
||||
for (addr_t o = 0; o < num_pixels; o++)
|
||||
fb_base[o] = RED;
|
||||
|
||||
_draw_frame((Pixel *)_fb_base(), WHITE, _mode.area);
|
||||
_draw_frame(fb_base, WHITE, _size);
|
||||
_state = COLORED;
|
||||
break;
|
||||
}
|
||||
case COLORED:
|
||||
{
|
||||
Genode::log("all colors mixed");
|
||||
log("all colors mixed");
|
||||
unsigned i = 0;
|
||||
for (addr_t o = 0; o < _fb_size(); o += _fb_bpp(), i++)
|
||||
*(Pixel *)(_fb_base() + o) = Pixel(i>>16, i>>8, i);
|
||||
for (addr_t o = 0; o < num_pixels; o++, i++)
|
||||
fb_base[o] = Pixel(i>>16, i>>8, i);
|
||||
|
||||
_draw_frame((Pixel *)_fb_base(), WHITE, _mode.area);
|
||||
_draw_frame(fb_base, WHITE, _size);
|
||||
_state = STRIPES;
|
||||
}
|
||||
};
|
||||
_fb.refresh(0, 0, _mode.area.w(), _mode.area.h());
|
||||
}
|
||||
|
||||
|
||||
void Test_environment::_mode_handle()
|
||||
{
|
||||
_mode = _fb.mode();
|
||||
if (_fb_ds.constructed())
|
||||
_fb_ds.destruct();
|
||||
|
||||
_fb_ds.construct(_env.rm(), _fb.dataspace());
|
||||
|
||||
Genode::log("framebuffer is ", _mode);
|
||||
|
||||
_draw();
|
||||
}
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
Genode::log("--- Test framebuffer ---");
|
||||
static Test_environment te(env);
|
||||
static Test::Main main(env);
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ import_from_depot [depot_user]/src/[base_src] \
|
||||
[depot_user]/src/coreutils \
|
||||
[depot_user]/src/vfs \
|
||||
[depot_user]/src/vfs_pipe \
|
||||
[depot_user]/src/nitpicker \
|
||||
[depot_user]/src/gui_fb \
|
||||
[depot_user]/src/fs_rom
|
||||
|
||||
# write default vimrc file
|
||||
@ -53,12 +55,35 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<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 name="terminal" caps="110">
|
||||
@ -66,6 +91,8 @@ install_config {
|
||||
<provides><service name="Terminal"/></provides>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
</start>
|
||||
@ -125,6 +152,10 @@ install_config {
|
||||
</start>
|
||||
</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_boot_image { ld.lib.so libc.lib.so libm.lib.so vfs.lib.so posix.lib.so }
|
||||
|
@ -70,20 +70,20 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="gdb_monitor" caps="200">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides> <service name="Gui"/> </provides>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config>
|
||||
<target name="nitpicker">
|
||||
<config>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<domain name="pointer" layer="1" xray="no" origin="pointer"
|
||||
content="client" label="no"/>
|
||||
<domain name="default" layer="3" content="client"
|
||||
|
@ -352,11 +352,11 @@ append_if $use_framebuffer config {
|
||||
<start name="fb_drv" priority="-1" caps="130">
|
||||
<binary name="vesa_fb_drv"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
<route>
|
||||
<service name="Timer"><child name="timer"/></service>
|
||||
<service name="Platform"><any-child/></service>
|
||||
<any-service><parent/></any-service>
|
||||
<service name="Timer"> <child name="timer"/></service>
|
||||
<service name="Capture"> <child name="nitpicker"/></service>
|
||||
<service name="Platform"> <any-child/></service>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>}
|
||||
append_if [expr $use_framebuffer && [have_include "power_on/qemu"]] config {
|
||||
<config width="1280" height="960" depth="32" buffered="yes"/>}
|
||||
@ -408,7 +408,8 @@ append_if $use_usb config {
|
||||
append config {
|
||||
<start name="nitpicker" priority="-1" caps="120">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<config>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<report focus="yes" />
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
<domain name="panel" layer="2" content="client" label="no" focus="none" />
|
||||
@ -430,16 +431,16 @@ append config {
|
||||
<default-policy domain=""/>
|
||||
</config>
|
||||
<route>
|
||||
<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="Timer"> <child name="timer"/></service>
|
||||
<service name="Report"> <child name="report_rom"/></service>
|
||||
<any-service><parent/><any-child/></any-service>
|
||||
</route>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="pointer">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<config/>
|
||||
</start>
|
||||
|
||||
<start name="report_rom">
|
||||
|
@ -146,19 +146,18 @@ append config {
|
||||
<start name="fb_drv" priority="-1">
|
||||
<binary name="vesa_fb_drv"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
<config buffered="yes"/>
|
||||
<config/>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker" priority="-1">
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<route>
|
||||
<service name="Framebuffer"> <child name="fb_drv" /> </service>
|
||||
<service name="Report"> <child name="report_rom" /> </service>
|
||||
<any-service> <parent/> <any-child /> </any-service>
|
||||
</route>
|
||||
<config>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<report focus="yes" hover="yes" />
|
||||
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
|
@ -278,14 +278,14 @@ append config_of_app {
|
||||
|
||||
<start name="nitpicker" priority="-1">
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<route>
|
||||
<service name="Framebuffer"> <child name="fb_drv" /> </service>
|
||||
<service name="Input"> <child name="input_filter" /> </service>
|
||||
<service name="Report"> <child name="report_rom" /> </service>
|
||||
<any-service> <parent/> <any-child /> </any-service>
|
||||
</route>
|
||||
<config>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<report focus="yes" hover="yes" />
|
||||
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
|
@ -125,9 +125,8 @@ append config_of_app {
|
||||
|
||||
<start name="nitpicker" priority="-1" caps="150">
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<route>
|
||||
<service name="Framebuffer"> <child name="fb_drv" /> </service>
|
||||
<service name="Input"> <child name="input_filter" /> </service>
|
||||
<service name="Report"> <child name="report_rom" /> </service>
|
||||
<service name="ROM" label="config">
|
||||
@ -182,7 +181,8 @@ append config_of_app {
|
||||
</rom>
|
||||
<rom name="nitpicker.config">
|
||||
<inline description="standard_mode">
|
||||
<config>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<report focus="yes" hover="yes" />
|
||||
|
||||
<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 {
|
||||
<inline description="shutdown">
|
||||
<config>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
<report focus="yes" hover="yes" />
|
||||
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
|
@ -46,12 +46,11 @@ install_config {
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<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>
|
||||
</route>
|
||||
<provides>
|
||||
<service name="Input"/> <service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="report_rom">
|
||||
@ -66,8 +65,9 @@ install_config {
|
||||
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<config focus="rom">
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<config focus="rom" request_framebuffer="no">
|
||||
<capture/>
|
||||
|
||||
<report focus="yes" /> <!-- interpreted by clipboard -->
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
@ -77,9 +77,8 @@ install_config {
|
||||
<default-policy domain="default"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="Framebuffer"> <child name="drivers"/> </service>
|
||||
<service name="Input"> <child name="drivers"/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="Input"> <child name="drivers"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
@ -102,8 +102,7 @@ append_if [expr $use_usb] config {
|
||||
append_if [have_spec framebuffer] config {
|
||||
<start name="fb_drv" priority="-1" caps="150">
|
||||
<binary name="vesa_fb_drv"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides><service name="Framebuffer"/></provides>}
|
||||
<resource name="RAM" quantum="8M"/>}
|
||||
append_if [expr [have_spec framebuffer] && [have_include power_on/qemu]] config {
|
||||
<config width="1280" height="1024" buffered="yes"/>}
|
||||
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 {
|
||||
<start name="fb_sdl" priority="-1" ld="no">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides>
|
||||
<service name="Input"/>
|
||||
<service name="Framebuffer"/>
|
||||
</provides>
|
||||
<provides> <service name="Input"/> </provides>
|
||||
</start>}
|
||||
|
||||
append_if [have_spec x86] config {
|
||||
@ -169,9 +165,8 @@ append config {
|
||||
|
||||
<start name="nitpicker" priority="-1">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Gui"/></provides>
|
||||
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
|
||||
<route>
|
||||
<service name="Framebuffer"> <child name="fb_drv" /> </service>
|
||||
<service name="Report"> <child name="report_rom" /> </service>}
|
||||
|
||||
append_if [expr $use_ps2] config {
|
||||
@ -182,7 +177,9 @@ append_if [expr $use_usb] config {
|
||||
append config {
|
||||
<any-service> <parent/> <any-child /> </any-service>
|
||||
</route>
|
||||
<config>
|
||||
<config request_framebuffer="no">
|
||||
<capture/>
|
||||
|
||||
<report focus="yes" hover="yes" xray="yes" />
|
||||
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
|
@ -352,8 +352,7 @@ append_if [have_spec framebuffer] config {
|
||||
<start name="fb_drv" priority="-1" caps="150">
|
||||
<binary name="vesa_fb_drv"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
<config buffered="yes"/>
|
||||
<config/>
|
||||
</start>}
|
||||
|
||||
append_if [have_spec x86] config {
|
||||
|
Loading…
x
Reference in New Issue
Block a user