mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 20:05:54 +00:00
nitpicker: remove dirty_rect state from view stack
In the presence of potentially multiple output back ends, this dirty_rect state must be maintained individually per back end. Instead of storing the dirty_rect as view-stack member, the view stack now calls a new 'Damage::mark_as_damaged' interface, which allows nitpicker to propagate this information to multiple back ends. Unfortunately, the patch must remove the per-view dirty_rect state. Issue #3812
This commit is contained in:
parent
067a7ad7e9
commit
795a817a33
@ -22,6 +22,7 @@
|
||||
#include <framebuffer_session/connection.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
#include <util/dirty_rect.h>
|
||||
|
||||
/* local includes */
|
||||
#include "types.h"
|
||||
@ -195,7 +196,7 @@ class Nitpicker::Gui_root : public Root_component<Gui_session>,
|
||||
};
|
||||
|
||||
|
||||
struct Nitpicker::Main : Focus_updater
|
||||
struct Nitpicker::Main : Focus_updater, View_stack::Damage
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
@ -225,15 +226,33 @@ struct Nitpicker::Main : Focus_updater
|
||||
|
||||
Area size = screen.size();
|
||||
|
||||
typedef Genode::Dirty_rect<Rect, 3> Dirty_rect;
|
||||
|
||||
Dirty_rect dirty_rect { };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Framebuffer_screen(Region_map &rm, Framebuffer::Session &fb)
|
||||
: framebuffer(fb), fb_ds(rm, framebuffer.dataspace()) { }
|
||||
:
|
||||
framebuffer(fb), fb_ds(rm, framebuffer.dataspace())
|
||||
{
|
||||
dirty_rect.mark_as_dirty(Rect(Point(0, 0), size));
|
||||
}
|
||||
};
|
||||
|
||||
Reconstructible<Framebuffer_screen> _fb_screen = { _env.rm(), _framebuffer };
|
||||
|
||||
/**
|
||||
* View_stack::Damage interface
|
||||
*/
|
||||
void mark_as_damaged(Rect rect) override
|
||||
{
|
||||
if (_fb_screen.constructed()) {
|
||||
_fb_screen->dirty_rect.mark_as_dirty(rect);
|
||||
}
|
||||
}
|
||||
|
||||
Point _initial_pointer_pos()
|
||||
{
|
||||
Area const scr_size = _fb_screen->screen.size();
|
||||
@ -266,7 +285,7 @@ struct Nitpicker::Main : Focus_updater
|
||||
Tff_font const _font { _binary_default_tff_start, _glyph_buffer };
|
||||
|
||||
Focus _focus { };
|
||||
View_stack _view_stack { _fb_screen->screen.size(), _focus, _font };
|
||||
View_stack _view_stack { _fb_screen->screen.size(), _focus, _font, *this };
|
||||
User_state _user_state { _focus, _global_keys, _view_stack, _initial_pointer_pos() };
|
||||
|
||||
View_owner _global_view_owner { };
|
||||
@ -361,16 +380,6 @@ struct Nitpicker::Main : Focus_updater
|
||||
*/
|
||||
bool _motion_activity = false;
|
||||
|
||||
/**
|
||||
* Perform redraw and flush pixels to the framebuffer
|
||||
*/
|
||||
void _draw_and_flush()
|
||||
{
|
||||
_view_stack.draw(_fb_screen->screen).flush([&] (Rect const &rect) {
|
||||
_framebuffer.refresh(rect.x1(), rect.y1(),
|
||||
rect.w(), rect.h()); });
|
||||
}
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
_view_stack.default_background(_builtin_background);
|
||||
@ -471,13 +480,19 @@ void Nitpicker::Main::_handle_input()
|
||||
if (result.motion_activity)
|
||||
_view_stack.geometry(_pointer_origin, Rect(_user_state.pointer_pos(), Area()));
|
||||
|
||||
/* perform redraw and flush pixels to the framebuffer */
|
||||
_view_stack.draw(_fb_screen->screen).flush([&] (Rect const &rect) {
|
||||
/* perform redraw */
|
||||
{
|
||||
/* call 'Dirty_rect::flush' on a copy to preserve the state */
|
||||
Dirty_rect dirty_rect = _fb_screen->dirty_rect;
|
||||
dirty_rect.flush([&] (Rect const &rect) {
|
||||
_view_stack.draw(_fb_screen->screen, rect); });
|
||||
}
|
||||
|
||||
/* flush pixels to the framebuffer, reset dirty_rect */
|
||||
_fb_screen->dirty_rect.flush([&] (Rect const &rect) {
|
||||
_framebuffer.refresh(rect.x1(), rect.y1(),
|
||||
rect.w(), rect.h()); });
|
||||
|
||||
_view_stack.mark_all_views_as_clean();
|
||||
|
||||
/* deliver framebuffer synchronization events */
|
||||
for (Gui_session *s = _session_list.first(); s; s = s->next())
|
||||
s->submit_sync();
|
||||
|
@ -17,7 +17,6 @@
|
||||
/* Genode includes */
|
||||
#include <util/string.h>
|
||||
#include <util/list.h>
|
||||
#include <util/dirty_rect.h>
|
||||
#include <base/weak_ptr.h>
|
||||
#include <base/rpc_server.h>
|
||||
|
||||
@ -30,8 +29,6 @@ namespace Nitpicker {
|
||||
class Buffer;
|
||||
class Focus;
|
||||
|
||||
typedef Dirty_rect<Rect, 3> Dirty_rect;
|
||||
|
||||
/*
|
||||
* For each buffer, there is a list of views that belong to this buffer.
|
||||
*/
|
||||
@ -104,7 +101,6 @@ class Nitpicker::View : private Same_buffer_list_elem,
|
||||
Point _buffer_off { }; /* offset to the visible buffer area */
|
||||
View_owner &_owner;
|
||||
Title _title { "" };
|
||||
Dirty_rect _dirty_rect { };
|
||||
|
||||
List<View_parent_elem> _children { };
|
||||
|
||||
@ -274,23 +270,6 @@ class Nitpicker::View : private Same_buffer_list_elem,
|
||||
* Return true if input at screen position 'p' refers to the view
|
||||
*/
|
||||
bool input_response_at(Point p) const;
|
||||
|
||||
/**
|
||||
* Mark part of view as dirty
|
||||
*
|
||||
* \param rect dirty rectangle in absolute coordinates
|
||||
*/
|
||||
void mark_as_dirty(Rect rect) { _dirty_rect.mark_as_dirty(rect); }
|
||||
|
||||
/**
|
||||
* Return dirty-rectangle information
|
||||
*/
|
||||
Dirty_rect dirty_rect() const { return _dirty_rect; }
|
||||
|
||||
/**
|
||||
* Reset dirty rectangle
|
||||
*/
|
||||
void mark_as_clean() { _dirty_rect = Dirty_rect(); }
|
||||
};
|
||||
|
||||
#endif /* _VIEW_H_ */
|
||||
|
@ -190,9 +190,8 @@ void View_stack::draw_rec(Canvas_base &canvas, Font const &font,
|
||||
if (next && left.valid()) draw_rec(canvas, font, next, left);
|
||||
|
||||
/* draw current view */
|
||||
view->dirty_rect().flush([&] (Rect const &dirty_rect) {
|
||||
|
||||
Clip_guard clip_guard(canvas, Rect::intersect(clipped, dirty_rect));
|
||||
{
|
||||
Clip_guard clip_guard(canvas, clipped);
|
||||
|
||||
/* draw background if view is transparent */
|
||||
if (view->uses_alpha())
|
||||
@ -200,7 +199,7 @@ void View_stack::draw_rec(Canvas_base &canvas, Font const &font,
|
||||
|
||||
view->frame(canvas, _focus);
|
||||
view->draw(canvas, font, _focus);
|
||||
});
|
||||
}
|
||||
|
||||
/* draw areas at the bottom/right of the current view */
|
||||
if (next && right.valid()) draw_rec(canvas, font, next, right);
|
||||
@ -213,8 +212,7 @@ void View_stack::refresh_view(View &view, Rect const rect)
|
||||
/* rectangle constrained to view geometry */
|
||||
Rect const view_rect = Rect::intersect(rect, _outline(view));
|
||||
|
||||
for (View *v = _first_view(); v; v = v->view_stack_next())
|
||||
_mark_view_as_dirty(*v, view_rect);
|
||||
_damage.mark_as_damaged(view_rect);
|
||||
|
||||
view.for_each_child([&] (View &child) { refresh_view(child, rect); });
|
||||
}
|
||||
@ -286,7 +284,7 @@ void View_stack::title(View &view, const char *title)
|
||||
view.title(_font, title);
|
||||
_place_labels(view.abs_geometry());
|
||||
|
||||
_mark_view_as_dirty(view, _outline(view));
|
||||
_damage.mark_as_damaged(_outline(view));
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,13 @@ namespace Nitpicker { class View_stack; }
|
||||
|
||||
class Nitpicker::View_stack
|
||||
{
|
||||
public:
|
||||
|
||||
struct Damage : Interface, Noncopyable
|
||||
{
|
||||
virtual void mark_as_damaged(Rect) = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Area _size;
|
||||
@ -30,7 +37,7 @@ class Nitpicker::View_stack
|
||||
Font const &_font;
|
||||
List<View_stack_elem> _views { };
|
||||
View *_default_background = nullptr;
|
||||
Dirty_rect mutable _dirty_rect { };
|
||||
Damage &_damage;
|
||||
|
||||
/**
|
||||
* Return outline geometry of a view
|
||||
@ -79,27 +86,15 @@ class Nitpicker::View_stack
|
||||
template <typename VIEW>
|
||||
VIEW *_next_view(VIEW &view) const;
|
||||
|
||||
/**
|
||||
* Schedule 'rect' to be redrawn
|
||||
*/
|
||||
void _mark_view_as_dirty(View &view, Rect rect)
|
||||
{
|
||||
_dirty_rect.mark_as_dirty(rect);
|
||||
|
||||
view.mark_as_dirty(rect);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
View_stack(Area size, Focus &focus, Font const &font)
|
||||
View_stack(Area size, Focus &focus, Font const &font, Damage &damage)
|
||||
:
|
||||
_size(size), _focus(focus), _font(font)
|
||||
{
|
||||
_dirty_rect.mark_as_dirty(Rect(Point(0, 0), _size));
|
||||
}
|
||||
_size(size), _focus(focus), _font(font), _damage(damage)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Return size
|
||||
@ -121,16 +116,11 @@ class Nitpicker::View_stack
|
||||
void draw_rec(Canvas_base &, Font const &, View const *, Rect) const;
|
||||
|
||||
/**
|
||||
* Draw dirty areas
|
||||
* Draw specified area
|
||||
*/
|
||||
Dirty_rect draw(Canvas_base &canvas) const
|
||||
void draw(Canvas_base &canvas, Rect rect) const
|
||||
{
|
||||
Dirty_rect result = _dirty_rect;
|
||||
|
||||
_dirty_rect.flush([&] (Rect const &rect) {
|
||||
draw_rec(canvas, _font, _first_view(), rect); });
|
||||
|
||||
return result;
|
||||
draw_rec(canvas, _font, _first_view(), rect);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -141,19 +131,7 @@ class Nitpicker::View_stack
|
||||
Rect const whole_screen(Point(), _size);
|
||||
|
||||
_place_labels(whole_screen);
|
||||
_dirty_rect.mark_as_dirty(whole_screen);
|
||||
|
||||
for (View *view = _first_view(); view; view = view->view_stack_next())
|
||||
view->mark_as_dirty(_outline(*view));
|
||||
}
|
||||
|
||||
/**
|
||||
* mark all view-local dirty rectangles a clean
|
||||
*/
|
||||
void mark_all_views_as_clean()
|
||||
{
|
||||
for (View *view = _first_view(); view; view = view->view_stack_next())
|
||||
view->mark_as_clean();
|
||||
_damage.mark_as_damaged(whole_screen);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user