gems: add Nitpicker_buffer and Dither_painter
The two utilities gems/nitpicker_buffer.h and gems/dither_painter.h were formerly private to the menu_view component.
This commit is contained in:
parent
c63bea825d
commit
2dde77f62c
|
@ -11,11 +11,13 @@
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DITHER_PAINTER_H_
|
#ifndef _INCLUDE__GEMS__DITHER_PAINTER_H_
|
||||||
#define _DITHER_PAINTER_H_
|
#define _INCLUDE__GEMS__DITHER_PAINTER_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
#include <util/dither_matrix.h>
|
#include <util/dither_matrix.h>
|
||||||
#include <os/surface.h>
|
#include <os/surface.h>
|
||||||
|
#include <os/texture.h>
|
||||||
|
|
||||||
|
|
||||||
struct Dither_painter
|
struct Dither_painter
|
||||||
|
@ -72,4 +74,4 @@ struct Dither_painter
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _DITHER_PAINTER_H_ */
|
#endif /* _INCLUDE__GEMS__DITHER_PAINTER_H_ */
|
177
repos/gems/include/gems/nitpicker_buffer.h
Normal file
177
repos/gems/include/gems/nitpicker_buffer.h
Normal file
|
@ -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 <ram_session/ram_session.h>
|
||||||
|
#include <nitpicker_session/connection.h>
|
||||||
|
#include <os/attached_dataspace.h>
|
||||||
|
#include <os/attached_ram_dataspace.h>
|
||||||
|
#include <os/surface.h>
|
||||||
|
#include <os/pixel_rgb565.h>
|
||||||
|
#include <os/pixel_alpha8.h>
|
||||||
|
#include <os/pixel_rgb888.h>
|
||||||
|
|
||||||
|
/* gems includes */
|
||||||
|
#include <gems/dither_painter.h>
|
||||||
|
|
||||||
|
|
||||||
|
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_rgb888> Pixel_surface;
|
||||||
|
typedef Genode::Surface<Pixel_alpha8> 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<Pixel_rgb888>(), size());
|
||||||
|
}
|
||||||
|
|
||||||
|
Alpha_surface alpha_surface()
|
||||||
|
{
|
||||||
|
return Alpha_surface(alpha_surface_ds.local_addr<Pixel_alpha8>(), 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 <typename DST_PT, typename SRC_PT>
|
||||||
|
void _convert_back_to_front(DST_PT *front_base,
|
||||||
|
Genode::Texture<SRC_PT> const &texture,
|
||||||
|
Rect const clip_rect)
|
||||||
|
{
|
||||||
|
Genode::Surface<DST_PT> 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<unsigned char>()
|
||||||
|
+ 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<Pixel_rgb888>
|
||||||
|
texture(pixel_surface_ds.local_addr<Pixel_rgb888>(),
|
||||||
|
alpha_surface_ds.local_addr<unsigned char>(),
|
||||||
|
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_rgb565>();
|
||||||
|
Pixel_alpha8 *alpha_base = fb_ds.local_addr<Pixel_alpha8>()
|
||||||
|
+ 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_ */
|
|
@ -18,146 +18,15 @@
|
||||||
#include <input/event.h>
|
#include <input/event.h>
|
||||||
#include <os/reporter.h>
|
#include <os/reporter.h>
|
||||||
|
|
||||||
|
/* gems includes */
|
||||||
|
#include <gems/nitpicker_buffer.h>
|
||||||
|
|
||||||
|
|
||||||
struct Menu_view::Main
|
struct Menu_view::Main
|
||||||
{
|
{
|
||||||
Nitpicker::Connection nitpicker;
|
Nitpicker::Connection nitpicker;
|
||||||
|
|
||||||
/*
|
Lazy_volatile_object<Nitpicker_buffer> buffer;
|
||||||
* 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_rgb888> pixel_surface()
|
|
||||||
{
|
|
||||||
return Surface<Pixel_rgb888>(pixel_surface_ds.local_addr<Pixel_rgb888>(), size());
|
|
||||||
}
|
|
||||||
|
|
||||||
Surface<Pixel_alpha8> alpha_surface()
|
|
||||||
{
|
|
||||||
return Surface<Pixel_alpha8>(alpha_surface_ds.local_addr<Pixel_alpha8>(), 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 <typename DST_PT, typename SRC_PT>
|
|
||||||
void _convert_back_to_front(DST_PT *front_base,
|
|
||||||
Texture<SRC_PT> const &texture,
|
|
||||||
Rect const clip_rect)
|
|
||||||
{
|
|
||||||
Surface<DST_PT> 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<unsigned char>()
|
|
||||||
+ 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<Pixel_rgb888>
|
|
||||||
texture(pixel_surface_ds.local_addr<Pixel_rgb888>(),
|
|
||||||
alpha_surface_ds.local_addr<unsigned char>(),
|
|
||||||
size());
|
|
||||||
|
|
||||||
// XXX track dirty rectangles
|
|
||||||
Rect const clip_rect(Point(0, 0), size());
|
|
||||||
|
|
||||||
Pixel_rgb565 *pixel_base = fb_ds.local_addr<Pixel_rgb565>();
|
|
||||||
Pixel_alpha8 *alpha_base = fb_ds.local_addr<Pixel_alpha8>()
|
|
||||||
+ 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> buffer;
|
|
||||||
|
|
||||||
Nitpicker::Session::View_handle view_handle = nitpicker.create_view();
|
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();
|
Area const size = root_widget.min_size();
|
||||||
|
|
||||||
if (!buffer.is_constructed() || size != old_size)
|
if (!buffer.is_constructed() || size != old_size)
|
||||||
buffer.construct(nitpicker, size);
|
buffer.construct(nitpicker, size, *env()->ram_session());
|
||||||
else
|
else
|
||||||
buffer->reset_surface();
|
buffer->reset_surface();
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
|
|
||||||
/* gems includes */
|
/* gems includes */
|
||||||
#include <gems/animator.h>
|
#include <gems/animator.h>
|
||||||
|
#include <gems/dither_painter.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include "style_database.h"
|
#include "style_database.h"
|
||||||
#include <dither_painter.h>
|
|
||||||
|
|
||||||
namespace Menu_view {
|
namespace Menu_view {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user