diff --git a/repos/gems/src/app/menu_view/dither_painter.h b/repos/gems/include/gems/dither_painter.h similarity index 91% rename from repos/gems/src/app/menu_view/dither_painter.h rename to repos/gems/include/gems/dither_painter.h index 655e7da2c..74619620b 100644 --- a/repos/gems/src/app/menu_view/dither_painter.h +++ b/repos/gems/include/gems/dither_painter.h @@ -11,11 +11,13 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _DITHER_PAINTER_H_ -#define _DITHER_PAINTER_H_ +#ifndef _INCLUDE__GEMS__DITHER_PAINTER_H_ +#define _INCLUDE__GEMS__DITHER_PAINTER_H_ +/* Genode includes */ #include #include +#include struct Dither_painter @@ -72,4 +74,4 @@ struct Dither_painter } }; -#endif /* _DITHER_PAINTER_H_ */ +#endif /* _INCLUDE__GEMS__DITHER_PAINTER_H_ */ diff --git a/repos/gems/include/gems/nitpicker_buffer.h b/repos/gems/include/gems/nitpicker_buffer.h new file mode 100644 index 000000000..4e7db0a24 --- /dev/null +++ b/repos/gems/include/gems/nitpicker_buffer.h @@ -0,0 +1,177 @@ +/* + * \brief Utility for the buffered pixel output via nitpicker + * \author Norman Feske + * \date 2014-08-22 + */ + +/* + * Copyright (C) 2014 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__GEMS__NITPICKER_BUFFER_H_ +#define _INCLUDE__GEMS__NITPICKER_BUFFER_H_ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* gems includes */ +#include + + +struct Nitpicker_buffer +{ + typedef Genode::Pixel_rgb888 Pixel_rgb888; + typedef Genode::Pixel_rgb565 Pixel_rgb565; + typedef Genode::Pixel_alpha8 Pixel_alpha8; + + typedef Genode::Surface Pixel_surface; + typedef Genode::Surface Alpha_surface; + + typedef Genode::Surface_base::Area Area; + typedef Genode::Surface_base::Rect Rect; + + typedef Genode::Attached_ram_dataspace Ram_ds; + + Genode::Ram_session &ram; + + Nitpicker::Connection &nitpicker; + + Framebuffer::Mode const mode; + + /** + * Return dataspace capability for virtual framebuffer + */ + Genode::Dataspace_capability _ds_cap(Nitpicker::Connection &nitpicker) + { + /* setup virtual framebuffer mode */ + nitpicker.buffer(mode, true); + + if (mode.format() != Framebuffer::Mode::RGB565) { + PWRN("Color mode %d not supported\n", (int)mode.format()); + return Genode::Dataspace_capability(); + } + + return nitpicker.framebuffer()->dataspace(); + } + + Genode::Attached_dataspace fb_ds { _ds_cap(nitpicker) }; + + Genode::size_t pixel_surface_num_bytes() const + { + return size().count()*sizeof(Pixel_rgb888); + } + + Genode::size_t alpha_surface_num_bytes() const + { + return size().count(); + } + + Ram_ds pixel_surface_ds { &ram, pixel_surface_num_bytes() }; + Ram_ds alpha_surface_ds { &ram, alpha_surface_num_bytes() }; + + /** + * Constructor + */ + Nitpicker_buffer(Nitpicker::Connection &nitpicker, Area size, + Genode::Ram_session &ram) + : + ram(ram), nitpicker(nitpicker), + mode(size.w(), size.h(), nitpicker.mode().format()) + { } + + /** + * Return size of virtual framebuffer + */ + Area size() const + { + return Area(mode.width(), mode.height()); + } + + /** + * Return back buffer as RGB888 painting surface + */ + Pixel_surface pixel_surface() + { + return Pixel_surface(pixel_surface_ds.local_addr(), size()); + } + + Alpha_surface alpha_surface() + { + return Alpha_surface(alpha_surface_ds.local_addr(), size()); + } + + void reset_surface() + { + Genode::size_t const num_pixels = pixel_surface().size().count(); + Genode::memset(alpha_surface().addr(), 0, num_pixels); + Genode::memset(pixel_surface().addr(), 0, num_pixels*sizeof(Pixel_rgb888)); + } + + template + void _convert_back_to_front(DST_PT *front_base, + Genode::Texture const &texture, + Rect const clip_rect) + { + Genode::Surface surface(front_base, size()); + + surface.clip(clip_rect); + + Dither_painter::paint(surface, texture); + } + + void _update_input_mask() + { + unsigned const num_pixels = size().count(); + + unsigned char * const alpha_base = fb_ds.local_addr() + + mode.bytes_per_pixel()*num_pixels; + + unsigned char * const input_base = alpha_base + num_pixels; + + unsigned char const *src = alpha_base; + unsigned char *dst = input_base; + + /* + * Set input mask for all pixels where the alpha value is above a + * given threshold. The threshold is defines such that typical + * drop shadows are below the value. + */ + unsigned char const threshold = 100; + + for (unsigned i = 0; i < num_pixels; i++) + *dst++ = (*src++) > threshold; + } + + void flush_surface() + { + /* represent back buffer as texture */ + Genode::Texture + texture(pixel_surface_ds.local_addr(), + alpha_surface_ds.local_addr(), + size()); + + // XXX track dirty rectangles + Rect const clip_rect(Genode::Surface_base::Point(0, 0), size()); + + Pixel_rgb565 *pixel_base = fb_ds.local_addr(); + Pixel_alpha8 *alpha_base = fb_ds.local_addr() + + mode.bytes_per_pixel()*size().count(); + + _convert_back_to_front(pixel_base, texture, clip_rect); + _convert_back_to_front(alpha_base, texture, clip_rect); + + _update_input_mask(); + } +}; + +#endif /* _INCLUDE__GEMS__NITPICKER_BUFFER_H_ */ diff --git a/repos/gems/src/app/menu_view/main.cc b/repos/gems/src/app/menu_view/main.cc index f18b3fb1d..92daf60b5 100644 --- a/repos/gems/src/app/menu_view/main.cc +++ b/repos/gems/src/app/menu_view/main.cc @@ -18,146 +18,15 @@ #include #include +/* gems includes */ +#include + struct Menu_view::Main { Nitpicker::Connection nitpicker; - /* - * The back buffer (surface) is RGB888 with interleaved alpha values. - */ - struct Buffer - { - Nitpicker::Connection &nitpicker; - - Framebuffer::Mode const mode; - - /** - * Return dataspace capability for virtual framebuffer - */ - Dataspace_capability _ds_cap(Nitpicker::Connection &nitpicker) - { - /* setup virtual framebuffer mode */ - nitpicker.buffer(mode, true); - - if (mode.format() != Framebuffer::Mode::RGB565) { - PWRN("Color mode %d not supported\n", (int)mode.format()); - return Dataspace_capability(); - } - - return nitpicker.framebuffer()->dataspace(); - } - - Attached_dataspace fb_ds { _ds_cap(nitpicker) }; - - size_t pixel_surface_num_bytes() const - { - return size().count()*sizeof(Pixel_rgb888); - } - - size_t alpha_surface_num_bytes() const - { - return size().count(); - } - - Attached_ram_dataspace pixel_surface_ds { env()->ram_session(), pixel_surface_num_bytes() }; - Attached_ram_dataspace alpha_surface_ds { env()->ram_session(), alpha_surface_num_bytes() }; - - /** - * Constructor - */ - Buffer(Nitpicker::Connection &nitpicker, Area size) - : - nitpicker(nitpicker), - mode(size.w(), size.h(), nitpicker.mode().format()) - { } - - /** - * Return size of virtual framebuffer - */ - Surface_base::Area size() const - { - return Surface_base::Area(mode.width(), mode.height()); - } - - /** - * Return back buffer as RGB888 painting surface - */ - Surface pixel_surface() - { - return Surface(pixel_surface_ds.local_addr(), size()); - } - - Surface alpha_surface() - { - return Surface(alpha_surface_ds.local_addr(), size()); - } - - void reset_surface() - { - size_t const num_pixels = pixel_surface().size().count(); - Genode::memset(alpha_surface().addr(), 0, num_pixels); - Genode::memset(pixel_surface().addr(), 0, num_pixels*sizeof(Pixel_rgb888)); - } - - template - void _convert_back_to_front(DST_PT *front_base, - Texture const &texture, - Rect const clip_rect) - { - Surface surface(front_base, size()); - - surface.clip(clip_rect); - - Dither_painter::paint(surface, texture); - } - - void _update_input_mask() - { - unsigned const num_pixels = size().count(); - - unsigned char * const alpha_base = fb_ds.local_addr() - + mode.bytes_per_pixel()*num_pixels; - - unsigned char * const input_base = alpha_base + num_pixels; - - unsigned char const *src = alpha_base; - unsigned char *dst = input_base; - - /* - * Set input mask for all pixels where the alpha value is above a - * given threshold. The threshold is defines such that typical - * drop shadows are below the value. - */ - unsigned char const threshold = 100; - - for (unsigned i = 0; i < num_pixels; i++) - *dst++ = (*src++) > threshold; - } - - void flush_surface() - { - /* represent back buffer as texture */ - Texture - texture(pixel_surface_ds.local_addr(), - alpha_surface_ds.local_addr(), - size()); - - // XXX track dirty rectangles - Rect const clip_rect(Point(0, 0), size()); - - Pixel_rgb565 *pixel_base = fb_ds.local_addr(); - Pixel_alpha8 *alpha_base = fb_ds.local_addr() - + mode.bytes_per_pixel()*size().count(); - - _convert_back_to_front(pixel_base, texture, clip_rect); - _convert_back_to_front(alpha_base, texture, clip_rect); - - _update_input_mask(); - } - }; - - Lazy_volatile_object buffer; + Lazy_volatile_object buffer; Nitpicker::Session::View_handle view_handle = nitpicker.create_view(); @@ -386,7 +255,7 @@ void Menu_view::Main::handle_frame_timer(unsigned) Area const size = root_widget.min_size(); if (!buffer.is_constructed() || size != old_size) - buffer.construct(nitpicker, size); + buffer.construct(nitpicker, size, *env()->ram_session()); else buffer->reset_surface(); diff --git a/repos/gems/src/app/menu_view/widgets.h b/repos/gems/src/app/menu_view/widgets.h index 62bf987d7..0cf5f7bfa 100644 --- a/repos/gems/src/app/menu_view/widgets.h +++ b/repos/gems/src/app/menu_view/widgets.h @@ -24,10 +24,10 @@ /* gems includes */ #include +#include /* local includes */ #include "style_database.h" -#include namespace Menu_view {