summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-12-04 08:44:33 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-12-04 08:44:33 +1100
commit74bc25e9961347b1fce527ae38ac9e73670b6ee7 (patch)
treece0990d215063422dc4030dac44d2893128a76b3
parentbac427661968d5960c5942858d03103d0ebd2c35 (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.c28
-rw-r--r--twin_screen.c9
-rw-r--r--twin_window.c8
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;