diff --git a/demo/src/server/liquid_framebuffer/services.cc b/demo/src/server/liquid_framebuffer/services.cc index 7e326e9305..be9765e4b9 100644 --- a/demo/src/server/liquid_framebuffer/services.cc +++ b/demo/src/server/liquid_framebuffer/services.cc @@ -276,29 +276,37 @@ namespace Framebuffer Window_content &_window_content; + Genode::Signal_context_capability _sync_sigh; + public: Session_component(Window_content &window_content) : _window_content(window_content) { } - Genode::Dataspace_capability dataspace() + Genode::Dataspace_capability dataspace() override { _window_content.realloc_framebuffer(); return _window_content.fb_ds_cap(); } - Mode mode() const + Mode mode() const override { return Mode(_window_content.mode_size().w(), _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); } - 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); + + if (_sync_sigh.valid()) + Genode::Signal_transmitter(_sync_sigh).submit(); } }; @@ -311,7 +319,7 @@ namespace Framebuffer protected: - Session_component *_create_session(const char *args) { + Session_component *_create_session(const char *args) override { return new (md_alloc()) Session_component(_window_content); } public: diff --git a/libports/src/app/qt5/qt_avplay/framebuffer_session_component.cc b/libports/src/app/qt5/qt_avplay/framebuffer_session_component.cc index f4d5e39198..8e3d778bf7 100644 --- a/libports/src/app/qt5/qt_avplay/framebuffer_session_component.cc +++ b/libports/src/app/qt5/qt_avplay/framebuffer_session_component.cc @@ -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) { _framebuffer.refresh(x, y, w, h); diff --git a/libports/src/app/qt5/qt_avplay/framebuffer_session_component.h b/libports/src/app/qt5/qt_avplay/framebuffer_session_component.h index cf8b55814a..cd51abb042 100644 --- a/libports/src/app/qt5/qt_avplay/framebuffer_session_component.h +++ b/libports/src/app/qt5/qt_avplay/framebuffer_session_component.h @@ -45,10 +45,11 @@ namespace Framebuffer { int max_width = 0, int max_height = 0); - Genode::Dataspace_capability dataspace(); - Mode mode() const; - void mode_sigh(Genode::Signal_context_capability sigh_cap); - void refresh(int x, int y, int w, int h); + Genode::Dataspace_capability dataspace() override; + 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; }; } diff --git a/libports/src/drivers/framebuffer/vesa/main.cc b/libports/src/drivers/framebuffer/vesa/main.cc index c626171e76..a995e92899 100644 --- a/libports/src/drivers/framebuffer/vesa/main.cc +++ b/libports/src/drivers/framebuffer/vesa/main.cc @@ -94,6 +94,30 @@ namespace Framebuffer { Genode::Dataspace_capability _fb_ds; 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: /** @@ -146,43 +170,30 @@ namespace Framebuffer { ** Framebuffer session interface ** ***********************************/ - Dataspace_capability dataspace() { + Dataspace_capability dataspace() override { return _buffered ? Dataspace_capability(_bb_ds) : Dataspace_capability(_fb_ds); } - void release() { } - - Mode mode() const + Mode mode() const override { return Mode(_scr_width, _scr_height, _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 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 */ - 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; + void refresh(int x, int y, int w, int h) override + { + if (_buffered) + _refresh_buffered(x, y, w, h); - /* 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); + if (_sync_sigh.valid()) + Signal_transmitter(_sync_sigh).submit(); } }; @@ -196,7 +207,7 @@ namespace Framebuffer { { 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), scr_height = session_arg("height", args, "fb_height", 768), diff --git a/os/include/framebuffer_session/client.h b/os/include/framebuffer_session/client.h index a7abd170b4..1774403fd4 100644 --- a/os/include/framebuffer_session/client.h +++ b/os/include/framebuffer_session/client.h @@ -24,15 +24,18 @@ namespace Framebuffer { explicit Session_client(Session_capability session) : Genode::Rpc_client(session) { } - Genode::Dataspace_capability dataspace() { + Genode::Dataspace_capability dataspace() override { return call(); } - Mode mode() const { return call(); } + Mode mode() const override { return call(); } - void mode_sigh(Genode::Signal_context_capability sigh) { + void mode_sigh(Genode::Signal_context_capability sigh) override { call(sigh); } - void refresh(int x, int y, int w, int h) { + void sync_sigh(Genode::Signal_context_capability sigh) override { + call(sigh); } + + void refresh(int x, int y, int w, int h) override { call(x, y, w, h); } }; } diff --git a/os/include/framebuffer_session/framebuffer_session.h b/os/include/framebuffer_session/framebuffer_session.h index 2166cf54eb..4edabc05cc 100644 --- a/os/include/framebuffer_session/framebuffer_session.h +++ b/os/include/framebuffer_session/framebuffer_session.h @@ -105,6 +105,11 @@ namespace Framebuffer { */ 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 ** @@ -114,8 +119,10 @@ namespace Framebuffer { GENODE_RPC(Rpc_mode, Mode, mode); 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_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); }; } diff --git a/os/include/platform/imx53/imx_framebuffer_session/client.h b/os/include/platform/imx53/imx_framebuffer_session/client.h index 2928615af5..3d991e17d3 100644 --- a/os/include/platform/imx53/imx_framebuffer_session/client.h +++ b/os/include/platform/imx53/imx_framebuffer_session/client.h @@ -25,18 +25,21 @@ namespace Framebuffer { explicit Imx_client(Capability session) : Genode::Rpc_client(session) { } - Genode::Dataspace_capability dataspace() { + Genode::Dataspace_capability dataspace() override { return call(); } - Mode mode() const { return call(); } + Mode mode() const override { return call(); } - void mode_sigh(Genode::Signal_context_capability sigh) { + void mode_sigh(Genode::Signal_context_capability sigh) override { call(sigh); } - void refresh(int x, int y, int w, int h) { + void sync_sigh(Genode::Signal_context_capability sigh) override { + call(sigh); } + + void refresh(int x, int y, int w, int h) override { call(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(phys_addr, x, y, alpha); } }; } diff --git a/os/src/drivers/framebuffer/exynos5/main.cc b/os/src/drivers/framebuffer/exynos5/main.cc index e7b86a792a..7e5ff3534b 100644 --- a/os/src/drivers/framebuffer/exynos5/main.cc +++ b/os/src/drivers/framebuffer/exynos5/main.cc @@ -39,12 +39,13 @@ class Framebuffer::Session_component { private: - size_t _width; - size_t _height; - Driver::Format _format; - size_t _size; - Dataspace_capability _ds; - addr_t _phys_base; + size_t _width; + size_t _height; + Driver::Format _format; + size_t _size; + Dataspace_capability _ds; + addr_t _phys_base; + Signal_context_capability _sync_sigh; /** * Convert Driver::Format to Framebuffer::Mode::Format @@ -88,16 +89,25 @@ class Framebuffer::Session_component ** 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)); } - 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(); + } }; diff --git a/os/src/drivers/framebuffer/imx53/main.cc b/os/src/drivers/framebuffer/imx53/main.cc index 475b9defde..6d75cd1a38 100644 --- a/os/src/drivers/framebuffer/imx53/main.cc +++ b/os/src/drivers/framebuffer/imx53/main.cc @@ -41,8 +41,29 @@ class Framebuffer::Session_component : Genode::Dataspace_capability _fb_ds; void *_fb_addr; + Signal_context_capability _sync_sigh; + 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: Session_component(Driver &driver, bool buffered) @@ -68,29 +89,22 @@ class Framebuffer::Session_component : ** Framebuffer::session interface ** **************************************/ - Dataspace_capability dataspace() { return _buffered ? _bb_ds : _fb_ds; } - Mode mode() const { return _mode; } - void mode_sigh(Genode::Signal_context_capability) { } + 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 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 */ - 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; + void refresh(int x, int y, int w, int h) override + { + if (_buffered) + _refresh_buffered(x, y, w, h); - 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); + if (_sync_sigh.valid()) + Signal_transmitter(_sync_sigh).submit(); } void overlay(Genode::addr_t phys_base, int x, int y, int alpha) { diff --git a/os/src/drivers/framebuffer/omap4/main.cc b/os/src/drivers/framebuffer/omap4/main.cc index 08c801e7b2..3c20f60ca2 100644 --- a/os/src/drivers/framebuffer/omap4/main.cc +++ b/os/src/drivers/framebuffer/omap4/main.cc @@ -36,10 +36,11 @@ class Framebuffer::Session_component : public Genode::Rpc_object x2 || y1 > y2) return; + if (x1 <= x2 && y1 <= y2) { - /* copy pixels from shared dataspace to sdl surface */ - 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 pitch = _mode.bytes_per_pixel()*scr_width; + /* copy pixels from shared dataspace to sdl surface */ + 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 pitch = _mode.bytes_per_pixel()*scr_width; - char *src = (char *)fb_ds_addr + start_offset; - char *dst = (char *)screen->pixels + start_offset; + char *src = (char *)fb_ds_addr + start_offset; + char *dst = (char *)screen->pixels + start_offset; - for (int i = y1; i <= y2; i++, src += pitch, dst += pitch) - Genode::memcpy(dst, src, line_len); + for (int i = y1; i <= y2; i++, src += pitch, dst += pitch) + Genode::memcpy(dst, src, line_len); - /* flush pixels in sdl window */ - SDL_UpdateRect(screen, x1, y1, x2 - x1 + 1, y2 - y1 + 1); + /* flush pixels in sdl window */ + 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: - Session_component *_create_session(const char *args) { + Session_component *_create_session(const char *args) override { return new (md_alloc()) Session_component(); } public: diff --git a/os/src/server/nitpicker/main.cc b/os/src/server/nitpicker/main.cc index 46bb5f34b7..4f3cda5b6b 100644 --- a/os/src/server/nitpicker/main.cc +++ b/os/src/server/nitpicker/main.cc @@ -311,6 +311,7 @@ class Framebuffer::Session_component : public Genode::Rpc_object Canvas_accessor &_canvas_accessor; Buffer_provider &_buffer_provider; Signal_context_capability _mode_sigh; + Signal_context_capability _sync_sigh; Framebuffer::Mode _mode; bool _alpha = false; @@ -362,24 +363,26 @@ class Framebuffer::Session_component : public Genode::Rpc_object ** Framebuffer::Session interface ** ************************************/ - Dataspace_capability dataspace() + Dataspace_capability dataspace() override { _buffer = _buffer_provider.realloc_buffer(_mode, _alpha); 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, Rect(Point(x, y), Area(w, h))); @@ -391,6 +394,9 @@ class Framebuffer::Session_component : public Genode::Rpc_object _flush_merger.reset(); } _flush_merger.defer = true; + + if (_sync_sigh.valid()) + Signal_transmitter(_sync_sigh).submit(); } }; diff --git a/qt4/src/app/qt_avplay/framebuffer_session_component.cc b/qt4/src/app/qt_avplay/framebuffer_session_component.cc index d82b634d24..88ebc5d89d 100644 --- a/qt4/src/app/qt_avplay/framebuffer_session_component.cc +++ b/qt4/src/app/qt_avplay/framebuffer_session_component.cc @@ -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) { _framebuffer.refresh(x, y, w, h); diff --git a/qt4/src/app/qt_avplay/framebuffer_session_component.h b/qt4/src/app/qt_avplay/framebuffer_session_component.h index cf8b55814a..cd51abb042 100644 --- a/qt4/src/app/qt_avplay/framebuffer_session_component.h +++ b/qt4/src/app/qt_avplay/framebuffer_session_component.h @@ -45,10 +45,11 @@ namespace Framebuffer { int max_width = 0, int max_height = 0); - Genode::Dataspace_capability dataspace(); - Mode mode() const; - void mode_sigh(Genode::Signal_context_capability sigh_cap); - void refresh(int x, int y, int w, int h); + Genode::Dataspace_capability dataspace() override; + 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; }; }