diff --git a/repos/os/src/test/framebuffer/main.cc b/repos/os/src/test/framebuffer/main.cc index f82839725e..54a9ac1b8a 100644 --- a/repos/os/src/test/framebuffer/main.cc +++ b/repos/os/src/test/framebuffer/main.cc @@ -2,6 +2,7 @@ * \brief Basic test for framebuffer session * \author Martin Stein * \author Christian Helmuth + * \author Stefan Kalkowski * \date 2012-01-09 */ @@ -13,101 +14,151 @@ */ /* Genode includes */ -#include +#include +#include #include -#include -#include -#include +#include +#include +#include class Test_environment { private: - Timer::Connection _timer; - Framebuffer::Connection _fb; - Framebuffer::Mode const _mode{_fb.mode()}; + using Ds = Genode::Lazy_volatile_object; - Genode::Dataspace_capability const _ds_cap{_fb.dataspace()}; - void * const _base{Genode::env()->rm_session()->attach(_ds_cap)}; - - public: - - Test_environment() - { - PINF("framebuffer is %dx%d@%d", - _mode.width(), _mode.height(), _mode.format()); - - if (_mode.bytes_per_pixel() != 2) { - PERR("pixel format not supported"); - throw -1; - } - } - - void complete_step() - { - _fb.refresh(0, 0, _mode.width(), _mode.height()); - _timer.msleep(2000); - } - - Framebuffer::Mode fb_mode() const { return _mode; } - unsigned fb_bpp() const { return _mode.bytes_per_pixel(); } - Genode::addr_t fb_base() const { return (Genode::addr_t) _base; } - Genode::size_t fb_size() const { return _mode.width() - * _mode.height() - * _mode.bytes_per_pixel(); } -}; - - -int main() -{ - using namespace Genode; - - printf("--- Test framebuffer ---\n"); - static Test_environment te; - - addr_t const stripe_width = te.fb_mode().width() / 4; - while (1) { - enum { + enum Color { BLACK = 0x0, BLUE = 0x1f, GREEN = 0x7e0, RED = 0xf800, WHITE = 0xffff, }; - PINF("black & white stripes"); - addr_t stripe_o = 0; - bool stripe = 0; - for (addr_t o = 0; o < te.fb_size(); o += te.fb_bpp()) { - stripe_o++; - if (stripe_o == stripe_width) { - stripe_o = 0; - stripe = !stripe; - } - *(uint16_t volatile *)(te.fb_base() + o) = stripe ? BLACK : WHITE; + + enum State { STRIPES, ALL_BLUE, ALL_GREEN, ALL_RED, COLORED }; + + Framebuffer::Connection _fb; + Framebuffer::Mode _mode; + Ds _fb_ds; + Genode::Signal_handler _mode_sigh; + Genode::Signal_handler _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(); } + + 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(); } + + public: + + Test_environment(Genode::Entrypoint &ep) + : _mode_sigh(ep, *this, &Test_environment::_mode_handle), + _sync_sigh(ep, *this, &Test_environment::_sync_handle) + { + _fb.mode_sigh(_mode_sigh); + _fb.sync_sigh(_sync_sigh); + _mode_handle(); } - te.complete_step(); +}; - PINF("blue"); - for (addr_t o = 0; o < te.fb_size(); o += te.fb_bpp()) - *(uint16_t volatile *)(te.fb_base() + o) = BLUE; - te.complete_step(); - PINF("green"); - for (addr_t o = 0; o < te.fb_size(); o += te.fb_bpp()) - *(uint16_t volatile *)(te.fb_base() + o) = GREEN; - te.complete_step(); +void Test_environment::_draw() +{ + using namespace Genode; - PINF("red"); - for (addr_t o = 0; o < te.fb_size(); o += te.fb_bpp()) - *(uint16_t volatile *)(te.fb_base() + o) = RED; - te.complete_step(); - - PINF("all colors mixed"); - unsigned i = 0; - for (addr_t o = 0; o < te.fb_size(); o += te.fb_bpp(), i++) - *(uint16_t volatile *)(te.fb_base() + o) = i; - te.complete_step(); - } + switch(_state) { + case STRIPES: + { + Genode::log("black & white stripes"); + addr_t const stripe_width = _mode.width() / 4; + addr_t stripe_o = 0; + bool stripe = 0; + for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) { + stripe_o++; + if (stripe_o == stripe_width) { + stripe_o = 0; + stripe = !stripe; + } + *(uint16_t volatile *)(_fb_base() + o) = stripe ? BLACK : WHITE; + } + _state = ALL_BLUE; + break; + } + case ALL_BLUE: + { + Genode::log("blue"); + for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) + *(uint16_t volatile *)(_fb_base() + o) = BLUE; + _state = ALL_GREEN; + break; + } + case ALL_GREEN: + { + Genode::log("green"); + for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) + *(uint16_t volatile *)(_fb_base() + o) = GREEN; + _state = ALL_RED; + break; + } + case ALL_RED: + { + Genode::log("red"); + for (addr_t o = 0; o < _fb_size(); o += _fb_bpp()) + *(uint16_t volatile *)(_fb_base() + o) = RED; + _state = COLORED; + break; + } + case COLORED: + { + Genode::log("all colors mixed"); + unsigned i = 0; + for (addr_t o = 0; o < _fb_size(); o += _fb_bpp(), i++) + *(uint16_t volatile *)(_fb_base() + o) = i; + _state = STRIPES; + } + }; + _fb.refresh(0, 0, _mode.width(), _mode.height()); } + +void Test_environment::_mode_handle() +{ + _mode = _fb.mode(); + if (_fb_ds.is_constructed()) + _fb_ds.destruct(); + + _fb_ds.construct(_fb.dataspace()); + + Genode::log("framebuffer is ", _mode.width(), "x", _mode.height(), + "@", (int)_mode.format()); + + if (_mode.bytes_per_pixel() != 2) { + Genode::error("pixel format not supported"); + throw -1; + } + + _draw(); +} + + +void Component::construct(Genode::Env &env) +{ + using namespace Genode; + + Genode::log("--- Test framebuffer ---\n"); + static Test_environment te(env.ep()); +} + + +Genode::size_t Component::stack_size() { + return 4*1024*sizeof(long); }