diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-12-04 08:44:33 +1100 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-12-04 08:44:33 +1100 |
commit | 74bc25e9961347b1fce527ae38ac9e73670b6ee7 (patch) | |
tree | ce0990d215063422dc4030dac44d2893128a76b3 | |
parent | bac427661968d5960c5942858d03103d0ebd2c35 (diff) |
Add support for immediate damage refresh to fbdev
This makes the fbdev backend refresh damaged areas directly from
the screen->damaged callback instead of delayed to a "work". The
work is still there to handle console switches. In order to avoid
flicker and artifacts, we also disable refresh around cursor
updates and window content.
The demos flicker a lot in this mode, so they'll have to be fixed
to disable / enable refresh around some operations too (probably in
the widget code), but the overall performances are better for my
application as mouse cursor no longer triggers giant updates when
moving while something else is updating
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | twin_fbdev.c | 28 | ||||
-rw-r--r-- | twin_screen.c | 9 | ||||
-rw-r--r-- | twin_window.c | 8 |
3 files changed, 42 insertions, 3 deletions
diff --git a/twin_fbdev.c b/twin_fbdev.c index b8b6fdb..a81a658 100644 --- a/twin_fbdev.c +++ b/twin_fbdev.c @@ -42,6 +42,8 @@ #include "twin_fbdev.h" +#define _IMMEDIATE_REFRESH + /* We might want to have more error logging options */ #define SERROR(fmt...) do { fprintf(stderr, fmt); \ fprintf(stderr, " : %s\n", strerror(errno)); \ @@ -170,12 +172,13 @@ static void twin_fbdev_switch(twin_fbdev_t *tf, int activate) /* Restore fbdev settings */ if (twin_fbdev_apply_config(tf)) { + tf->active = 1; + /* Mark entire screen for refresh */ if (tf->screen) twin_screen_damage (tf->screen, 0, 0, tf->screen->width, tf->screen->height); - tf->active = 1; } } else { /* Allow switch. Maybe we want to expose some option @@ -200,12 +203,32 @@ static twin_bool_t twin_fbdev_work(void *closure) vt_switch_pending = 0; } +#ifndef _IMMEDIATE_REFRESH if (tf->screen && tf->active && twin_screen_damaged (tf->screen)) twin_screen_update(tf->screen); +#endif /* _IMMEDIATE_REFRESH */ + return TWIN_TRUE; } +#ifdef _IMMEDIATE_REFRESH +static void twin_fbdev_damaged(void *closure) +{ + twin_fbdev_t *tf = closure; + +#if 0 + DEBUG("fbdev damaged %d,%d,%d,%d, active=%d\n", + tf->screen->damage.left, tf->screen->damage.top, + tf->screen->damage.right, tf->screen->damage.bottom, + tf->active); +#endif + + if (tf->active && twin_screen_damaged (tf->screen)) + twin_screen_update(tf->screen); +} +#endif /* _IMMEDIATE_REFRESH */ + static void twin_fbdev_vtswitch(int sig) { signal(sig, twin_fbdev_vtswitch); @@ -464,6 +487,9 @@ twin_fbdev_t *twin_fbdev_create(int wanted_vt, int switch_sig) twin_set_file(twin_fbdev_read_events, tf->vt_fd, TWIN_READ, tf); +#ifdef _IMMEDIATE_REFRESH + twin_screen_register_damaged(tf->screen, twin_fbdev_damaged, tf); +#endif twin_fb = tf; return tf; diff --git a/twin_screen.c b/twin_screen.c index 0781c91..9ea46c7 100644 --- a/twin_screen.c +++ b/twin_screen.c @@ -293,8 +293,11 @@ void twin_screen_set_cursor (twin_screen_t *screen, twin_pixmap_t *pixmap, twin_fixed_t hotspot_x, twin_fixed_t hotspot_y) { + twin_screen_disable_update(screen); + if (screen->cursor) twin_screen_damage_cursor(screen); + screen->cursor = pixmap; screen->curs_hx = hotspot_x; screen->curs_hy = hotspot_y; @@ -303,12 +306,16 @@ twin_screen_set_cursor (twin_screen_t *screen, twin_pixmap_t *pixmap, pixmap->y = screen->curs_y - hotspot_y; twin_screen_damage_cursor(screen); } + + twin_screen_enable_update(screen); } static void twin_screen_update_cursor(twin_screen_t *screen, twin_coord_t x, twin_coord_t y) { + twin_screen_disable_update(screen); + if (screen->cursor) twin_screen_damage_cursor(screen); @@ -320,6 +327,8 @@ twin_screen_update_cursor(twin_screen_t *screen, screen->cursor->y = screen->curs_y - screen->curs_hy; twin_screen_damage_cursor(screen); } + + twin_screen_enable_update(screen); } static void _twin_adj_mouse_evt(twin_event_t *event, twin_pixmap_t *pixmap) diff --git a/twin_window.c b/twin_window.c index 0ca180b..e1933fa 100644 --- a/twin_window.c +++ b/twin_window.c @@ -343,12 +343,16 @@ twin_window_draw (twin_window_t *window) twin_pixmap_clip(pixmap, window->damage.left, window->damage.top, window->damage.right, window->damage.bottom); + twin_screen_disable_update(window->screen); + (*window->draw) (window); /* damage matching screen area */ twin_pixmap_damage(pixmap, - window->damage.left, window->damage.top, - window->damage.right, window->damage.bottom); + window->damage.left, window->damage.top, + window->damage.right, window->damage.bottom); + + twin_screen_enable_update(window->screen); /* clear damage and restore clip */ window->damage.left = window->damage.right = 0; |