/* * \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_ */