diff --git a/repos/os/src/drivers/framebuffer/rpi/main.cc b/repos/os/src/drivers/framebuffer/rpi/main.cc index a96b627f04..583b720399 100644 --- a/repos/os/src/drivers/framebuffer/rpi/main.cc +++ b/repos/os/src/drivers/framebuffer/rpi/main.cc @@ -12,13 +12,17 @@ */ /* Genode includes */ +#include #include +#include #include +#include #include #include #include #include #include +#include namespace Framebuffer { using namespace Genode; @@ -30,23 +34,57 @@ class Framebuffer::Session_component : public Genode::Rpc_object _bb_mem; + Attached_io_mem_dataspace _fb_mem; + Signal_context_capability _sync_sigh; + + 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.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 = _bb_mem->local_addr() + bypp*(_width*y1 + x1), + *dst = _fb_mem.local_addr() + bypp*(_width*y1 + x1); + + blit(src, bypp*_width, dst, bypp*_width, + bypp*(x2 - x1 + 1), y2 - y1 + 1); + } public: - Session_component(addr_t phys_addr, size_t size, size_t width, size_t height) + Session_component(addr_t phys_addr, size_t size, + size_t width, size_t height, + bool buffered) : _width(width), _height(height), _fb_mem(phys_addr, size) - { } + { + if (buffered) { + _bb_mem.construct(env()->ram_session(), size); + } + } /************************************ ** Framebuffer::Session interface ** ************************************/ - Dataspace_capability dataspace() override { return _fb_mem.cap(); } + Dataspace_capability dataspace() override + { + if (_bb_mem.is_constructed()) + return _bb_mem->cap(); + else + return _fb_mem.cap(); + } Mode mode() const override { @@ -60,14 +98,27 @@ class Framebuffer::Session_component : public Genode::Rpc_objectxml_node().attribute("buffered").has_value("yes"); + } catch (...) { + return false; + } +} + + int main(int, char **) { using namespace Framebuffer; @@ -93,7 +144,8 @@ int main(int, char **) static Session_component fb_session(fb_info.addr, fb_info.size, fb_info.phys_width, - fb_info.phys_height); + fb_info.phys_height, + config_is_buffered()); static Static_root fb_root(ep.manage(&fb_session)); /* diff --git a/repos/os/src/drivers/framebuffer/rpi/target.mk b/repos/os/src/drivers/framebuffer/rpi/target.mk index 12d1f93de1..6317680e6f 100644 --- a/repos/os/src/drivers/framebuffer/rpi/target.mk +++ b/repos/os/src/drivers/framebuffer/rpi/target.mk @@ -1,7 +1,7 @@ TARGET = fb_drv REQUIRES = platform_rpi SRC_CC = main.cc -LIBS = base +LIBS = base blit config INC_DIR += $(PRG_DIR) # enable C++11 support