From 1f797292884f0007a9c408184812afab36952412 Mon Sep 17 00:00:00 2001 From: Pascal Terjan Date: Sun, 19 Jul 2009 20:37:12 +0000 Subject: [PATCH] * When blitting, only add dirty rectangles on changed lines, or on changed chars if we have a mask --- caca/string.c | 22 +++++++++++++++------- tests/dirty.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/caca/string.c b/caca/string.c index bff1436..62b709f 100644 --- a/caca/string.c +++ b/caca/string.c @@ -448,14 +448,25 @@ int caca_blit(caca_canvas_t *dst, int x, int y, if(mask->chars[srcix + i] == (uint32_t)' ') continue; - dst->chars[dstix + i] = src->chars[srcix + i]; - dst->attrs[dstix + i] = src->attrs[srcix + i]; + if(dst->chars[dstix + i] != src->chars[srcix + i] || + dst->attrs[dstix + i] != src->attrs[srcix + i]) + { + dst->chars[dstix + i] = src->chars[srcix + i]; + dst->attrs[dstix + i] = src->attrs[srcix + i]; + caca_add_dirty_rect(dst, x + starti + i, y + j, 1, 1); + } } } else { - memcpy(dst->chars + dstix, src->chars + srcix, stride * 4); - memcpy(dst->attrs + dstix, src->attrs + srcix, stride * 4); + if(memcmp(dst->chars + dstix, src->chars + srcix, stride * 4) || + memcmp(dst->attrs + dstix, src->attrs + srcix, stride * 4)) + { + /* FIXME be more precise ? */ + memcpy(dst->chars + dstix, src->chars + srcix, stride * 4); + memcpy(dst->attrs + dstix, src->attrs + srcix, stride * 4); + caca_add_dirty_rect(dst, x + starti, y + j, stride, 1); + } } /* Fix split fullwidth chars */ @@ -466,9 +477,6 @@ int caca_blit(caca_canvas_t *dst, int x, int y, dst->chars[dstix + stride - 1] = ' '; } - caca_add_dirty_rect(dst, starti + x - bleed_left, startj + y, - endi - starti + bleed_left + bleed_right, - endj - startj); return 0; } diff --git a/tests/dirty.cpp b/tests/dirty.cpp index f64d878..6d285c0 100644 --- a/tests/dirty.cpp +++ b/tests/dirty.cpp @@ -28,6 +28,7 @@ class DirtyTest : public CppUnit::TestCase CPPUNIT_TEST(test_put_char_dirty); CPPUNIT_TEST(test_put_char_not_dirty); CPPUNIT_TEST(test_box); + CPPUNIT_TEST(test_blit); CPPUNIT_TEST_SUITE_END(); public: @@ -185,6 +186,29 @@ public: CPPUNIT_ASSERT_EQUAL(i, 0); } + void test_blit() + { + caca_canvas_t *cv, *cv2; + int i, dx, dy, dw, dh; + + cv = caca_create_canvas(WIDTH, HEIGHT); + caca_clear_dirty_rect_list(cv); + cv2 = caca_create_canvas(2, 2); + caca_fill_box(cv2, 0, 0, 2, 1, 'x'); + + caca_blit(cv, 1, 1, cv2, NULL); + i = caca_get_dirty_rect_count(cv); + CPPUNIT_ASSERT_EQUAL(i, 1); + caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh); + + /* Check that blitting a canvas make a dirty rectangle + * only for modified lines */ + CPPUNIT_ASSERT(dx == 1); + CPPUNIT_ASSERT(dy == 1); + CPPUNIT_ASSERT(dw >= 2); + CPPUNIT_ASSERT(dh == 1); + } + private: static int const WIDTH = 80, HEIGHT = 50; };