mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 22:23:16 +00:00
os: Add 'Framebuffer::Session::sync_sigh'
The new framebuffer-session function allows a client to register a handler for receiving display-synchronization events.
This commit is contained in:
parent
0b04f9de25
commit
5de17d4223
@ -276,29 +276,37 @@ namespace Framebuffer
|
|||||||
|
|
||||||
Window_content &_window_content;
|
Window_content &_window_content;
|
||||||
|
|
||||||
|
Genode::Signal_context_capability _sync_sigh;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Session_component(Window_content &window_content)
|
Session_component(Window_content &window_content)
|
||||||
: _window_content(window_content) { }
|
: _window_content(window_content) { }
|
||||||
|
|
||||||
Genode::Dataspace_capability dataspace()
|
Genode::Dataspace_capability dataspace() override
|
||||||
{
|
{
|
||||||
_window_content.realloc_framebuffer();
|
_window_content.realloc_framebuffer();
|
||||||
return _window_content.fb_ds_cap();
|
return _window_content.fb_ds_cap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mode mode() const
|
Mode mode() const override
|
||||||
{
|
{
|
||||||
return Mode(_window_content.mode_size().w(),
|
return Mode(_window_content.mode_size().w(),
|
||||||
_window_content.mode_size().h(), Mode::RGB565);
|
_window_content.mode_size().h(), Mode::RGB565);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mode_sigh(Genode::Signal_context_capability sigh) {
|
void mode_sigh(Genode::Signal_context_capability sigh) override {
|
||||||
_window_content.mode_sigh(sigh); }
|
_window_content.mode_sigh(sigh); }
|
||||||
|
|
||||||
void refresh(int x, int y, int w, int h)
|
void sync_sigh(Genode::Signal_context_capability sigh) override {
|
||||||
|
_sync_sigh = sigh; }
|
||||||
|
|
||||||
|
void refresh(int x, int y, int w, int h) override
|
||||||
{
|
{
|
||||||
_window_content.redraw_area(x, y, w, h);
|
_window_content.redraw_area(x, y, w, h);
|
||||||
|
|
||||||
|
if (_sync_sigh.valid())
|
||||||
|
Genode::Signal_transmitter(_sync_sigh).submit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -311,7 +319,7 @@ namespace Framebuffer
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Session_component *_create_session(const char *args) {
|
Session_component *_create_session(const char *args) override {
|
||||||
return new (md_alloc()) Session_component(_window_content); }
|
return new (md_alloc()) Session_component(_window_content); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -76,6 +76,11 @@ namespace Framebuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Session_component::sync_sigh(Genode::Signal_context_capability sigh_cap)
|
||||||
|
{
|
||||||
|
_framebuffer.sync_sigh(sigh_cap);
|
||||||
|
}
|
||||||
|
|
||||||
void Session_component::refresh(int x, int y, int w, int h)
|
void Session_component::refresh(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
_framebuffer.refresh(x, y, w, h);
|
_framebuffer.refresh(x, y, w, h);
|
||||||
|
@ -45,10 +45,11 @@ namespace Framebuffer {
|
|||||||
int max_width = 0,
|
int max_width = 0,
|
||||||
int max_height = 0);
|
int max_height = 0);
|
||||||
|
|
||||||
Genode::Dataspace_capability dataspace();
|
Genode::Dataspace_capability dataspace() override;
|
||||||
Mode mode() const;
|
Mode mode() const override;
|
||||||
void mode_sigh(Genode::Signal_context_capability sigh_cap);
|
void mode_sigh(Genode::Signal_context_capability) override;
|
||||||
void refresh(int x, int y, int w, int h);
|
void sync_sigh(Genode::Signal_context_capability) override;
|
||||||
|
void refresh(int, int, int, int) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,30 @@ namespace Framebuffer {
|
|||||||
Genode::Dataspace_capability _fb_ds;
|
Genode::Dataspace_capability _fb_ds;
|
||||||
void *_fb_addr;
|
void *_fb_addr;
|
||||||
|
|
||||||
|
Genode::Signal_context_capability _sync_sigh;
|
||||||
|
|
||||||
|
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_mode == 16) bypp = 2;
|
||||||
|
if (!bypp) return;
|
||||||
|
|
||||||
|
/* copy pixels from back buffer to physical frame buffer */
|
||||||
|
char *src = (char *)_bb_addr + bypp*(_scr_width*y + x),
|
||||||
|
*dst = (char *)_fb_addr + bypp*(_scr_width*y + x);
|
||||||
|
|
||||||
|
blit(src, bypp*_scr_width, dst, bypp*_scr_width,
|
||||||
|
bypp*(x2 - x1 + 1), y2 - y1 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,43 +170,30 @@ namespace Framebuffer {
|
|||||||
** Framebuffer session interface **
|
** Framebuffer session interface **
|
||||||
***********************************/
|
***********************************/
|
||||||
|
|
||||||
Dataspace_capability dataspace() {
|
Dataspace_capability dataspace() override {
|
||||||
return _buffered ? Dataspace_capability(_bb_ds)
|
return _buffered ? Dataspace_capability(_bb_ds)
|
||||||
: Dataspace_capability(_fb_ds); }
|
: Dataspace_capability(_fb_ds); }
|
||||||
|
|
||||||
void release() { }
|
Mode mode() const override
|
||||||
|
|
||||||
Mode mode() const
|
|
||||||
{
|
{
|
||||||
return Mode(_scr_width, _scr_height,
|
return Mode(_scr_width, _scr_height,
|
||||||
_scr_mode == 16 ? Mode::RGB565 : Mode::INVALID);
|
_scr_mode == 16 ? Mode::RGB565 : Mode::INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mode_sigh(Genode::Signal_context_capability) { }
|
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||||
|
|
||||||
/* not implemented */
|
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||||
void refresh(int x, int y, int w, int h)
|
|
||||||
{
|
{
|
||||||
if (!_buffered) return;
|
_sync_sigh = sigh;
|
||||||
|
}
|
||||||
|
|
||||||
/* clip specified coordinates against screen boundaries */
|
void refresh(int x, int y, int w, int h) override
|
||||||
int x2 = min(x + w - 1, (int)_scr_width - 1),
|
{
|
||||||
y2 = min(y + h - 1, (int)_scr_height - 1);
|
if (_buffered)
|
||||||
int x1 = max(x, 0),
|
_refresh_buffered(x, y, w, h);
|
||||||
y1 = max(y, 0);
|
|
||||||
if (x1 > x2 || y1 > y2) return;
|
|
||||||
|
|
||||||
/* determine bytes per pixel */
|
if (_sync_sigh.valid())
|
||||||
int bypp = 0;
|
Signal_transmitter(_sync_sigh).submit();
|
||||||
if (_scr_mode == 16) bypp = 2;
|
|
||||||
if (!bypp) return;
|
|
||||||
|
|
||||||
/* copy pixels from back buffer to physical frame buffer */
|
|
||||||
char *src = (char *)_bb_addr + bypp*(_scr_width*y + x),
|
|
||||||
*dst = (char *)_fb_addr + bypp*(_scr_width*y + x);
|
|
||||||
|
|
||||||
blit(src, bypp*_scr_width, dst, bypp*_scr_width,
|
|
||||||
bypp*(x2 - x1 + 1), y2 - y1 + 1);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -196,7 +207,7 @@ namespace Framebuffer {
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Session_component *_create_session(const char *args)
|
Session_component *_create_session(const char *args) override
|
||||||
{
|
{
|
||||||
unsigned long scr_width = session_arg("width", args, "fb_width", 1024),
|
unsigned long scr_width = session_arg("width", args, "fb_width", 1024),
|
||||||
scr_height = session_arg("height", args, "fb_height", 768),
|
scr_height = session_arg("height", args, "fb_height", 768),
|
||||||
|
@ -24,15 +24,18 @@ namespace Framebuffer {
|
|||||||
explicit Session_client(Session_capability session)
|
explicit Session_client(Session_capability session)
|
||||||
: Genode::Rpc_client<Session>(session) { }
|
: Genode::Rpc_client<Session>(session) { }
|
||||||
|
|
||||||
Genode::Dataspace_capability dataspace() {
|
Genode::Dataspace_capability dataspace() override {
|
||||||
return call<Rpc_dataspace>(); }
|
return call<Rpc_dataspace>(); }
|
||||||
|
|
||||||
Mode mode() const { return call<Rpc_mode>(); }
|
Mode mode() const override { return call<Rpc_mode>(); }
|
||||||
|
|
||||||
void mode_sigh(Genode::Signal_context_capability sigh) {
|
void mode_sigh(Genode::Signal_context_capability sigh) override {
|
||||||
call<Rpc_mode_sigh>(sigh); }
|
call<Rpc_mode_sigh>(sigh); }
|
||||||
|
|
||||||
void refresh(int x, int y, int w, int h) {
|
void sync_sigh(Genode::Signal_context_capability sigh) override {
|
||||||
|
call<Rpc_sync_sigh>(sigh); }
|
||||||
|
|
||||||
|
void refresh(int x, int y, int w, int h) override {
|
||||||
call<Rpc_refresh>(x, y, w, h); }
|
call<Rpc_refresh>(x, y, w, h); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,11 @@ namespace Framebuffer {
|
|||||||
*/
|
*/
|
||||||
virtual void refresh(int x, int y, int w, int h) = 0;
|
virtual void refresh(int x, int y, int w, int h) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register signal handler for refresh synchronization
|
||||||
|
*/
|
||||||
|
virtual void sync_sigh(Genode::Signal_context_capability) = 0;
|
||||||
|
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
** RPC declaration **
|
** RPC declaration **
|
||||||
@ -114,8 +119,10 @@ namespace Framebuffer {
|
|||||||
GENODE_RPC(Rpc_mode, Mode, mode);
|
GENODE_RPC(Rpc_mode, Mode, mode);
|
||||||
GENODE_RPC(Rpc_refresh, void, refresh, int, int, int, int);
|
GENODE_RPC(Rpc_refresh, void, refresh, int, int, int, int);
|
||||||
GENODE_RPC(Rpc_mode_sigh, void, mode_sigh, Genode::Signal_context_capability);
|
GENODE_RPC(Rpc_mode_sigh, void, mode_sigh, Genode::Signal_context_capability);
|
||||||
|
GENODE_RPC(Rpc_sync_sigh, void, sync_sigh, Genode::Signal_context_capability);
|
||||||
|
|
||||||
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_mode, Rpc_mode_sigh, Rpc_refresh);
|
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_mode, Rpc_mode_sigh, Rpc_refresh,
|
||||||
|
Rpc_sync_sigh);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,18 +25,21 @@ namespace Framebuffer {
|
|||||||
explicit Imx_client(Capability<Imx_session> session)
|
explicit Imx_client(Capability<Imx_session> session)
|
||||||
: Genode::Rpc_client<Imx_session>(session) { }
|
: Genode::Rpc_client<Imx_session>(session) { }
|
||||||
|
|
||||||
Genode::Dataspace_capability dataspace() {
|
Genode::Dataspace_capability dataspace() override {
|
||||||
return call<Rpc_dataspace>(); }
|
return call<Rpc_dataspace>(); }
|
||||||
|
|
||||||
Mode mode() const { return call<Rpc_mode>(); }
|
Mode mode() const override { return call<Rpc_mode>(); }
|
||||||
|
|
||||||
void mode_sigh(Genode::Signal_context_capability sigh) {
|
void mode_sigh(Genode::Signal_context_capability sigh) override {
|
||||||
call<Rpc_mode_sigh>(sigh); }
|
call<Rpc_mode_sigh>(sigh); }
|
||||||
|
|
||||||
void refresh(int x, int y, int w, int h) {
|
void sync_sigh(Genode::Signal_context_capability sigh) override {
|
||||||
|
call<Rpc_sync_sigh>(sigh); }
|
||||||
|
|
||||||
|
void refresh(int x, int y, int w, int h) override {
|
||||||
call<Rpc_refresh>(x, y, w, h); }
|
call<Rpc_refresh>(x, y, w, h); }
|
||||||
|
|
||||||
void overlay(Genode::addr_t phys_addr, int x, int y, int alpha) {
|
void overlay(Genode::addr_t phys_addr, int x, int y, int alpha) override {
|
||||||
call<Rpc_overlay>(phys_addr, x, y, alpha); }
|
call<Rpc_overlay>(phys_addr, x, y, alpha); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,13 @@ class Framebuffer::Session_component
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
size_t _width;
|
size_t _width;
|
||||||
size_t _height;
|
size_t _height;
|
||||||
Driver::Format _format;
|
Driver::Format _format;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
Dataspace_capability _ds;
|
Dataspace_capability _ds;
|
||||||
addr_t _phys_base;
|
addr_t _phys_base;
|
||||||
|
Signal_context_capability _sync_sigh;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert Driver::Format to Framebuffer::Mode::Format
|
* Convert Driver::Format to Framebuffer::Mode::Format
|
||||||
@ -88,16 +89,25 @@ class Framebuffer::Session_component
|
|||||||
** Framebuffer::Session interface **
|
** Framebuffer::Session interface **
|
||||||
************************************/
|
************************************/
|
||||||
|
|
||||||
Dataspace_capability dataspace() { return _ds; }
|
Dataspace_capability dataspace() override { return _ds; }
|
||||||
|
|
||||||
Mode mode() const
|
Mode mode() const override
|
||||||
{
|
{
|
||||||
return Mode(_width, _height, _convert_format(_format));
|
return Mode(_width, _height, _convert_format(_format));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mode_sigh(Genode::Signal_context_capability) { }
|
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||||
|
|
||||||
void refresh(int, int, int, int) { }
|
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||||
|
{
|
||||||
|
_sync_sigh = sigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh(int, int, int, int) override
|
||||||
|
{
|
||||||
|
if (_sync_sigh.valid())
|
||||||
|
Signal_transmitter(_sync_sigh).submit();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,8 +41,29 @@ class Framebuffer::Session_component :
|
|||||||
Genode::Dataspace_capability _fb_ds;
|
Genode::Dataspace_capability _fb_ds;
|
||||||
void *_fb_addr;
|
void *_fb_addr;
|
||||||
|
|
||||||
|
Signal_context_capability _sync_sigh;
|
||||||
|
|
||||||
Ipu &_ipu;
|
Ipu &_ipu;
|
||||||
|
|
||||||
|
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.width() - 1),
|
||||||
|
y2 = min(y + h - 1, (int)_mode.height() - 1);
|
||||||
|
int x1 = max(x, 0),
|
||||||
|
y1 = max(y, 0);
|
||||||
|
if (x1 > x2 || y1 > y2) return;
|
||||||
|
|
||||||
|
int bypp = _mode.bytes_per_pixel();
|
||||||
|
|
||||||
|
/* copy pixels from back buffer to physical frame buffer */
|
||||||
|
char *src = (char *)_bb_addr + bypp*(_mode.width()*y + x),
|
||||||
|
*dst = (char *)_fb_addr + bypp*(_mode.width()*y + x);
|
||||||
|
|
||||||
|
blit(src, bypp*_mode.width(), dst, bypp*_mode.width(),
|
||||||
|
bypp*(x2 - x1 + 1), y2 - y1 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Session_component(Driver &driver, bool buffered)
|
Session_component(Driver &driver, bool buffered)
|
||||||
@ -68,29 +89,22 @@ class Framebuffer::Session_component :
|
|||||||
** Framebuffer::session interface **
|
** Framebuffer::session interface **
|
||||||
**************************************/
|
**************************************/
|
||||||
|
|
||||||
Dataspace_capability dataspace() { return _buffered ? _bb_ds : _fb_ds; }
|
Dataspace_capability dataspace() override { return _buffered ? _bb_ds : _fb_ds; }
|
||||||
Mode mode() const { return _mode; }
|
Mode mode() const override { return _mode; }
|
||||||
void mode_sigh(Genode::Signal_context_capability) { }
|
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||||
|
|
||||||
void refresh(int x, int y, int w, int h)
|
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||||
{
|
{
|
||||||
if (!_buffered) return;
|
_sync_sigh = sigh;
|
||||||
|
}
|
||||||
|
|
||||||
/* clip specified coordinates against screen boundaries */
|
void refresh(int x, int y, int w, int h) override
|
||||||
int x2 = min(x + w - 1, (int)_mode.width() - 1),
|
{
|
||||||
y2 = min(y + h - 1, (int)_mode.height() - 1);
|
if (_buffered)
|
||||||
int x1 = max(x, 0),
|
_refresh_buffered(x, y, w, h);
|
||||||
y1 = max(y, 0);
|
|
||||||
if (x1 > x2 || y1 > y2) return;
|
|
||||||
|
|
||||||
int bypp = _mode.bytes_per_pixel();
|
if (_sync_sigh.valid())
|
||||||
|
Signal_transmitter(_sync_sigh).submit();
|
||||||
/* copy pixels from back buffer to physical frame buffer */
|
|
||||||
char *src = (char *)_bb_addr + bypp*(_mode.width()*y + x),
|
|
||||||
*dst = (char *)_fb_addr + bypp*(_mode.width()*y + x);
|
|
||||||
|
|
||||||
blit(src, bypp*_mode.width(), dst, bypp*_mode.width(),
|
|
||||||
bypp*(x2 - x1 + 1), y2 - y1 + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay(Genode::addr_t phys_base, int x, int y, int alpha) {
|
void overlay(Genode::addr_t phys_base, int x, int y, int alpha) {
|
||||||
|
@ -36,10 +36,11 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Framebuffer::Se
|
|||||||
|
|
||||||
size_t _width;
|
size_t _width;
|
||||||
size_t _height;
|
size_t _height;
|
||||||
Driver::Format _format;
|
Driver::Format _format;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
Dataspace_capability _ds;
|
Dataspace_capability _ds;
|
||||||
addr_t _phys_base;
|
addr_t _phys_base;
|
||||||
|
Signal_context_capability _sync_sigh;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert Driver::Format to Framebuffer::Mode::Format
|
* Convert Driver::Format to Framebuffer::Mode::Format
|
||||||
@ -75,18 +76,27 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Framebuffer::Se
|
|||||||
** Framebuffer::Session interface **
|
** Framebuffer::Session interface **
|
||||||
************************************/
|
************************************/
|
||||||
|
|
||||||
Dataspace_capability dataspace() { return _ds; }
|
Dataspace_capability dataspace() override { return _ds; }
|
||||||
|
|
||||||
Mode mode() const
|
Mode mode() const override
|
||||||
{
|
{
|
||||||
return Mode(_width,
|
return Mode(_width,
|
||||||
_height,
|
_height,
|
||||||
_convert_format(_format));
|
_convert_format(_format));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mode_sigh(Genode::Signal_context_capability) { }
|
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||||
|
|
||||||
void refresh(int, int, int, int) { }
|
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||||
|
{
|
||||||
|
_sync_sigh = sigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh(int, int, int, int) override
|
||||||
|
{
|
||||||
|
if (_sync_sigh.valid())
|
||||||
|
Signal_transmitter(_sync_sigh).submit();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,11 +55,12 @@ namespace Framebuffer
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Genode::Dataspace_capability _fb_ds_cap;
|
Genode::Dataspace_capability _fb_ds_cap;
|
||||||
Genode::Dataspace_client _fb_ds;
|
Genode::Dataspace_client _fb_ds;
|
||||||
Genode::addr_t _regs_base;
|
Genode::addr_t _regs_base;
|
||||||
Genode::addr_t _sys_regs_base;
|
Genode::addr_t _sys_regs_base;
|
||||||
Timer::Connection _timer;
|
Timer::Connection _timer;
|
||||||
|
Genode::Signal_context_capability _sync_sigh;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/**
|
/**
|
||||||
@ -155,13 +156,19 @@ namespace Framebuffer
|
|||||||
reg_write(PL11X_REG_CTRL, ctrl | CTRL_POWER);
|
reg_write(PL11X_REG_CTRL, ctrl | CTRL_POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::Dataspace_capability dataspace() { return _fb_ds_cap; }
|
Genode::Dataspace_capability dataspace() override { return _fb_ds_cap; }
|
||||||
|
|
||||||
Mode mode() const { return Mode(SCR_WIDTH, SCR_HEIGHT, Mode::RGB565); }
|
Mode mode() const override { return Mode(SCR_WIDTH, SCR_HEIGHT, Mode::RGB565); }
|
||||||
|
|
||||||
void mode_sigh(Genode::Signal_context_capability) { }
|
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||||
|
|
||||||
void refresh(int x, int y, int w, int h) { }
|
void sync_sigh(Genode::Signal_context_capability sigh) override { _sync_sigh = sigh; }
|
||||||
|
|
||||||
|
void refresh(int x, int y, int w, int h) override
|
||||||
|
{
|
||||||
|
if (_sync_sigh.valid())
|
||||||
|
Genode::Signal_transmitter(_sync_sigh).submit();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -175,7 +182,7 @@ namespace Framebuffer
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Session_component *_create_session(const char *args) {
|
Session_component *_create_session(const char *args) override {
|
||||||
return new (md_alloc()) Session_component(_lcd_regs_base,
|
return new (md_alloc()) Session_component(_lcd_regs_base,
|
||||||
_sys_regs_base,
|
_sys_regs_base,
|
||||||
_fb_ds_cap); }
|
_fb_ds_cap); }
|
||||||
|
@ -30,9 +30,10 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Framebuffer::Se
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
size_t const _width;
|
size_t const _width;
|
||||||
size_t const _height;
|
size_t const _height;
|
||||||
Attached_io_mem_dataspace _fb_mem;
|
Attached_io_mem_dataspace _fb_mem;
|
||||||
|
Signal_context_capability _sync_sigh;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -45,16 +46,25 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Framebuffer::Se
|
|||||||
** Framebuffer::Session interface **
|
** Framebuffer::Session interface **
|
||||||
************************************/
|
************************************/
|
||||||
|
|
||||||
Dataspace_capability dataspace() { return _fb_mem.cap(); }
|
Dataspace_capability dataspace() override { return _fb_mem.cap(); }
|
||||||
|
|
||||||
Mode mode() const
|
Mode mode() const override
|
||||||
{
|
{
|
||||||
return Mode(_width, _height, Mode::RGB565);
|
return Mode(_width, _height, Mode::RGB565);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mode_sigh(Genode::Signal_context_capability) { }
|
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||||
|
|
||||||
void refresh(int, int, int, int) { }
|
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||||
|
{
|
||||||
|
_sync_sigh = sigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh(int, int, int, int) override
|
||||||
|
{
|
||||||
|
if (_sync_sigh.valid())
|
||||||
|
Signal_transmitter(_sync_sigh).submit();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,6 +52,8 @@ namespace Framebuffer {
|
|||||||
|
|
||||||
Mode _mode;
|
Mode _mode;
|
||||||
|
|
||||||
|
Genode::Signal_context_capability _sync_sigh;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,13 +61,18 @@ namespace Framebuffer {
|
|||||||
*/
|
*/
|
||||||
Session_component() : _mode(scr_width, scr_height, Mode::RGB565) { }
|
Session_component() : _mode(scr_width, scr_height, Mode::RGB565) { }
|
||||||
|
|
||||||
Genode::Dataspace_capability dataspace() { return fb_ds_cap; }
|
Genode::Dataspace_capability dataspace() override { return fb_ds_cap; }
|
||||||
|
|
||||||
Mode mode() const { return _mode; }
|
Mode mode() const override { return _mode; }
|
||||||
|
|
||||||
void mode_sigh(Genode::Signal_context_capability) { }
|
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||||
|
|
||||||
void refresh(int x, int y, int w, int h)
|
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||||
|
{
|
||||||
|
_sync_sigh = sigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh(int x, int y, int w, int h) override
|
||||||
{
|
{
|
||||||
/* clip refresh area to screen boundaries */
|
/* clip refresh area to screen boundaries */
|
||||||
int x1 = Genode::max(x, 0);
|
int x1 = Genode::max(x, 0);
|
||||||
@ -73,21 +80,25 @@ namespace Framebuffer {
|
|||||||
int x2 = Genode::min(x + w - 1, scr_width - 1);
|
int x2 = Genode::min(x + w - 1, scr_width - 1);
|
||||||
int y2 = Genode::min(y + h - 1, scr_height - 1);
|
int y2 = Genode::min(y + h - 1, scr_height - 1);
|
||||||
|
|
||||||
if (x1 > x2 || y1 > y2) return;
|
if (x1 <= x2 && y1 <= y2) {
|
||||||
|
|
||||||
/* copy pixels from shared dataspace to sdl surface */
|
/* copy pixels from shared dataspace to sdl surface */
|
||||||
const int start_offset = _mode.bytes_per_pixel()*(y1*scr_width + x1);
|
const int start_offset = _mode.bytes_per_pixel()*(y1*scr_width + x1);
|
||||||
const int line_len = _mode.bytes_per_pixel()*(x2 - x1 + 1);
|
const int line_len = _mode.bytes_per_pixel()*(x2 - x1 + 1);
|
||||||
const int pitch = _mode.bytes_per_pixel()*scr_width;
|
const int pitch = _mode.bytes_per_pixel()*scr_width;
|
||||||
|
|
||||||
char *src = (char *)fb_ds_addr + start_offset;
|
char *src = (char *)fb_ds_addr + start_offset;
|
||||||
char *dst = (char *)screen->pixels + start_offset;
|
char *dst = (char *)screen->pixels + start_offset;
|
||||||
|
|
||||||
for (int i = y1; i <= y2; i++, src += pitch, dst += pitch)
|
for (int i = y1; i <= y2; i++, src += pitch, dst += pitch)
|
||||||
Genode::memcpy(dst, src, line_len);
|
Genode::memcpy(dst, src, line_len);
|
||||||
|
|
||||||
/* flush pixels in sdl window */
|
/* flush pixels in sdl window */
|
||||||
SDL_UpdateRect(screen, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
SDL_UpdateRect(screen, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_sync_sigh.valid())
|
||||||
|
Genode::Signal_transmitter(_sync_sigh).submit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,7 +113,7 @@ namespace Framebuffer {
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Session_component *_create_session(const char *args) {
|
Session_component *_create_session(const char *args) override {
|
||||||
return new (md_alloc()) Session_component(); }
|
return new (md_alloc()) Session_component(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -311,6 +311,7 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
|||||||
Canvas_accessor &_canvas_accessor;
|
Canvas_accessor &_canvas_accessor;
|
||||||
Buffer_provider &_buffer_provider;
|
Buffer_provider &_buffer_provider;
|
||||||
Signal_context_capability _mode_sigh;
|
Signal_context_capability _mode_sigh;
|
||||||
|
Signal_context_capability _sync_sigh;
|
||||||
Framebuffer::Mode _mode;
|
Framebuffer::Mode _mode;
|
||||||
bool _alpha = false;
|
bool _alpha = false;
|
||||||
|
|
||||||
@ -362,24 +363,26 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
|||||||
** Framebuffer::Session interface **
|
** Framebuffer::Session interface **
|
||||||
************************************/
|
************************************/
|
||||||
|
|
||||||
Dataspace_capability dataspace()
|
Dataspace_capability dataspace() override
|
||||||
{
|
{
|
||||||
_buffer = _buffer_provider.realloc_buffer(_mode, _alpha);
|
_buffer = _buffer_provider.realloc_buffer(_mode, _alpha);
|
||||||
|
|
||||||
return _buffer ? _buffer->ds_cap() : Genode::Ram_dataspace_capability();
|
return _buffer ? _buffer->ds_cap() : Genode::Ram_dataspace_capability();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mode mode() const
|
Mode mode() const override { return _mode; }
|
||||||
|
|
||||||
|
void mode_sigh(Signal_context_capability sigh) override
|
||||||
{
|
{
|
||||||
return _mode;
|
_mode_sigh = sigh;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mode_sigh(Signal_context_capability mode_sigh)
|
void sync_sigh(Signal_context_capability sigh) override
|
||||||
{
|
{
|
||||||
_mode_sigh = mode_sigh;
|
_sync_sigh = sigh;
|
||||||
}
|
}
|
||||||
|
|
||||||
void refresh(int x, int y, int w, int h)
|
void refresh(int x, int y, int w, int h) override
|
||||||
{
|
{
|
||||||
_view_stack.update_session_views(_canvas(), _session,
|
_view_stack.update_session_views(_canvas(), _session,
|
||||||
Rect(Point(x, y), Area(w, h)));
|
Rect(Point(x, y), Area(w, h)));
|
||||||
@ -391,6 +394,9 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
|||||||
_flush_merger.reset();
|
_flush_merger.reset();
|
||||||
}
|
}
|
||||||
_flush_merger.defer = true;
|
_flush_merger.defer = true;
|
||||||
|
|
||||||
|
if (_sync_sigh.valid())
|
||||||
|
Signal_transmitter(_sync_sigh).submit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,6 +76,12 @@ namespace Framebuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Session_component::sync_sigh(Genode::Signal_context_capability sigh_cap)
|
||||||
|
{
|
||||||
|
_framebuffer.sync_sigh(sigh_cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Session_component::refresh(int x, int y, int w, int h)
|
void Session_component::refresh(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
_framebuffer.refresh(x, y, w, h);
|
_framebuffer.refresh(x, y, w, h);
|
||||||
|
@ -45,10 +45,11 @@ namespace Framebuffer {
|
|||||||
int max_width = 0,
|
int max_width = 0,
|
||||||
int max_height = 0);
|
int max_height = 0);
|
||||||
|
|
||||||
Genode::Dataspace_capability dataspace();
|
Genode::Dataspace_capability dataspace() override;
|
||||||
Mode mode() const;
|
Mode mode() const override;
|
||||||
void mode_sigh(Genode::Signal_context_capability sigh_cap);
|
void mode_sigh(Genode::Signal_context_capability) override;
|
||||||
void refresh(int x, int y, int w, int h);
|
void sync_sigh(Genode::Signal_context_capability) override;
|
||||||
|
void refresh(int, int, int, int) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user