summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-10-23 19:59:29 +0200
committerDavid Herrmann <dh.herrmann@gmail.com>2013-10-23 19:59:29 +0200
commit492da8a82832b47ee0fc3e27549ef77fbb38ba4e (patch)
treef6e1ad826c6a23ade267d5a834e7ae7cea0857eb
parent0ccfd9e707b6c0349321a9f640df27ac959007c7 (diff)
Render only changed cells
TSM has support for cell-ageing so render only cells that changed. Note that we still blit the buffer via cairo at the end, but this should be fast enough for any system. The actual rendering is often what causes performance-bottlenecks. Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
-rw-r--r--src/wlt_render.c46
-rw-r--r--src/wlterm.c3
-rw-r--r--src/wlterm.h5
3 files changed, 41 insertions, 13 deletions
diff --git a/src/wlt_render.c b/src/wlt_render.c
index 819b807..af5f702 100644
--- a/src/wlt_render.c
+++ b/src/wlt_render.c
@@ -43,6 +43,7 @@ struct wlt_renderer {
int stride;
uint8_t *data;
cairo_surface_t *surface;
+ tsm_age_t age;
};
static int wlt_renderer_realloc(struct wlt_renderer *rend, unsigned int width,
@@ -230,6 +231,13 @@ static void wlt_renderer_blend(struct wlt_renderer *rend,
}
}
+static bool overlap(const struct wlt_draw_ctx *ctx, double x1, double y1,
+ double x2, double y2)
+{
+ return (ctx->x1 < x2 && ctx->x2 > x1 &&
+ ctx->y1 < y2 && ctx->y2 > y1);
+}
+
static int wlt_renderer_draw_cell(struct tsm_screen *screen, uint32_t id,
const uint32_t *ch, size_t len,
unsigned int cwidth, unsigned int posx,
@@ -238,11 +246,25 @@ static int wlt_renderer_draw_cell(struct tsm_screen *screen, uint32_t id,
tsm_age_t age, void *data)
{
const struct wlt_draw_ctx *ctx = data;
+ struct wlt_renderer *rend = ctx->rend;
uint8_t fr, fg, fb, br, bg, bb;
unsigned int x, y;
struct wlt_glyph *glyph;
+ bool skip;
int r;
+ x = posx * ctx->cell_width;
+ y = posy * ctx->cell_height;
+
+ /* If the cell is inside of the dirty-region *and* our age and the
+ * cell age is non-zero *and* the cell-age is smaller than our age,
+ * then skip drawing as it's already on-screen. */
+ skip = overlap(ctx, x, y, x + ctx->cell_width, y + ctx->cell_height);
+ skip = skip && age && rend->age && age <= rend->age;
+
+ if (skip)
+ return 0;
+
/* invert colors if requested */
if (attr->inverse) {
fr = attr->br;
@@ -260,23 +282,20 @@ static int wlt_renderer_draw_cell(struct tsm_screen *screen, uint32_t id,
bb = attr->bb;
}
- x = posx * ctx->cell_width;
- y = posy * ctx->cell_height;
-
/* !len means background-only */
if (!len) {
- wlt_renderer_fill(ctx->rend, x, y, ctx->cell_width * cwidth,
+ wlt_renderer_fill(rend, x, y, ctx->cell_width * cwidth,
ctx->cell_height, br, bg, bb);
- return 0;
+ } else {
+ r = wlt_face_render(ctx->face, &glyph, id, ch, len, cwidth);
+ if (r < 0)
+ wlt_renderer_fill(rend, x, y, ctx->cell_width * cwidth,
+ ctx->cell_height, br, bg, bb);
+ else
+ wlt_renderer_blend(rend, glyph, x, y,
+ fr, fg, fb, br, bg, bb);
}
- r = wlt_face_render(ctx->face, &glyph, id, ch, len, cwidth);
- if (r < 0)
- return r;
-
- wlt_renderer_blend(ctx->rend, glyph, x, y,
- fr, fg, fb, br, bg, bb);
-
return 0;
}
@@ -290,7 +309,8 @@ void wlt_renderer_draw(const struct wlt_draw_ctx *ctx)
* but at least it's fast enough to render a whole screen. */
cairo_surface_flush(rend->surface);
- tsm_screen_draw(ctx->screen, wlt_renderer_draw_cell, (void*)ctx);
+ rend->age = tsm_screen_draw(ctx->screen, wlt_renderer_draw_cell,
+ (void*)ctx);
cairo_surface_mark_dirty(rend->surface);
cairo_set_source_surface(ctx->cr, rend->surface, 0, 0);
diff --git a/src/wlterm.c b/src/wlterm.c
index 1d30e83..e9d87e6 100644
--- a/src/wlterm.c
+++ b/src/wlterm.c
@@ -326,12 +326,15 @@ static gboolean term_redraw_cb(GtkWidget *widget, cairo_t *cr, gpointer data)
start = g_get_monotonic_time();
+ memset(&ctx, 0, sizeof(ctx));
ctx.rend = term->rend;
ctx.cr = cr;
ctx.face = term->face;
ctx.cell_width = term->cell_width;
ctx.cell_height = term->cell_height;
ctx.screen = term->screen;
+ cairo_clip_extents(cr, &ctx.x1, &ctx.y1, &ctx.x2, &ctx.y2);
+
wlt_renderer_draw(&ctx);
end = g_get_monotonic_time();
diff --git a/src/wlterm.h b/src/wlterm.h
index c5d9ace..758ed49 100644
--- a/src/wlterm.h
+++ b/src/wlterm.h
@@ -88,6 +88,11 @@ struct wlt_draw_ctx {
unsigned int cell_width;
unsigned int cell_height;
struct tsm_screen *screen;
+
+ double x1;
+ double y1;
+ double x2;
+ double y2;
};
int wlt_renderer_new(struct wlt_renderer **out, unsigned int width,