source: libcaca/trunk/tests/dirty.cpp @ 3912

Last change on this file since 3912 was 3579, checked in by Sam Hocevar, 11 years ago

Add unit tests for efficient dirty rectangle merging.

  • Property svn:keywords set to Id
File size: 9.3 KB
RevLine 
[3449]1/*
2 *  caca-test     testsuite program for libcaca
[3494]3 *  Copyright (c) 2009 Sam Hocevar <sam@hocevar.net>
[3449]4 *                All Rights Reserved
5 *
6 *  $Id: dirty.cpp 3579 2009-07-26 16:20:20Z sam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15#include "config.h"
16
17#include <cppunit/extensions/HelperMacros.h>
18#include <cppunit/TestCaller.h>
19#include <cppunit/TestCase.h>
20#include <cppunit/TestSuite.h>
21
22#include "caca.h"
23
24class DirtyTest : public CppUnit::TestCase
25{
26    CPPUNIT_TEST_SUITE(DirtyTest);
27    CPPUNIT_TEST(test_create);
[3513]28    CPPUNIT_TEST(test_put_char_dirty);
29    CPPUNIT_TEST(test_put_char_not_dirty);
[3579]30    CPPUNIT_TEST(test_simplify);
[3513]31    CPPUNIT_TEST(test_box);
[3556]32    CPPUNIT_TEST(test_blit);
[3449]33    CPPUNIT_TEST_SUITE_END();
34
35public:
36    DirtyTest() : CppUnit::TestCase("Dirty Rectangles Test") {}
37
38    void setUp() {}
39
40    void tearDown() {}
41
42    void test_create()
43    {
44        caca_canvas_t *cv;
[3567]45        int dx, dy, dw, dh;
[3449]46
[3567]47        /* Check that we only have one dirty rectangle upon creation. */
[3449]48        cv = caca_create_canvas(WIDTH, HEIGHT);
[3567]49        CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
[3449]50
[3567]51        /* Check that our only rectangle contains the whole canvas. */
[3494]52        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
[3567]53        CPPUNIT_ASSERT_EQUAL(0, dx);
54        CPPUNIT_ASSERT_EQUAL(0, dy);
55        CPPUNIT_ASSERT_EQUAL(WIDTH, dw);
56        CPPUNIT_ASSERT_EQUAL(HEIGHT, dh);
[3470]57
[3449]58        /* Invalidate the dirty rectangle and check that it stays so. */
[3494]59        caca_clear_dirty_rect_list(cv);
[3567]60        CPPUNIT_ASSERT_EQUAL(0, caca_get_dirty_rect_count(cv));
[3449]61
62        caca_free_canvas(cv);
63    }
64
[3513]65    void test_put_char_dirty()
[3449]66    {
67        caca_canvas_t *cv;
[3567]68        int dx, dy, dw, dh;
[3449]69
70        cv = caca_create_canvas(WIDTH, HEIGHT);
71
[3567]72        /* Check that one character creates a 1x1 dirty rect. */
[3494]73        caca_clear_dirty_rect_list(cv);
[3449]74        caca_put_char(cv, 7, 3, 'x');
[3567]75
76        CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
[3494]77        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
[3567]78        CPPUNIT_ASSERT_EQUAL(7, dx);
79        CPPUNIT_ASSERT_EQUAL(3, dy);
80        CPPUNIT_ASSERT_EQUAL(1, dw);
81        CPPUNIT_ASSERT_EQUAL(1, dh);
[3449]82
[3567]83        /* Check that a fullwidth character creates a 2x1 dirty rect. */
[3449]84        caca_clear_canvas(cv);
[3494]85        caca_clear_dirty_rect_list(cv);
[3449]86        caca_put_char(cv, 7, 3, 0x2f06 /* ⼆ */);
[3567]87
88        CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
[3494]89        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
[3567]90        CPPUNIT_ASSERT_EQUAL(7, dx);
91        CPPUNIT_ASSERT_EQUAL(3, dy);
92        CPPUNIT_ASSERT_EQUAL(2, dw);
93        CPPUNIT_ASSERT_EQUAL(1, dh);
[3449]94
[3567]95        /* Check that a character over a fullwidth character creates a
96         * 2x1 dirty rect because of clobbering on the left side. */
[3449]97        caca_clear_canvas(cv);
98        caca_put_char(cv, 7, 3, 0x2f06 /* ⼆ */);
[3494]99        caca_clear_dirty_rect_list(cv);
[3449]100        caca_put_char(cv, 7, 3, 'x');
[3567]101
102        CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
[3494]103        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
[3567]104        CPPUNIT_ASSERT_EQUAL(7, dx);
105        CPPUNIT_ASSERT_EQUAL(3, dy);
106        CPPUNIT_ASSERT_EQUAL(2, dw);
107        CPPUNIT_ASSERT_EQUAL(1, dh);
[3449]108
[3567]109        /* Check that a character over a fullwidth character creates a
110         * 2x1 dirty rect because of clobbering on the right side. */
[3449]111        caca_clear_canvas(cv);
112        caca_put_char(cv, 7, 3, 0x2f06 /* ⼆ */);
[3494]113        caca_clear_dirty_rect_list(cv);
[3449]114        caca_put_char(cv, 8, 3, 'x');
[3567]115
116        CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
[3494]117        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
[3567]118        CPPUNIT_ASSERT_EQUAL(7, dx);
119        CPPUNIT_ASSERT_EQUAL(3, dy);
120        CPPUNIT_ASSERT_EQUAL(2, dw);
121        CPPUNIT_ASSERT_EQUAL(1, dh);
[3449]122
[3567]123        /* Check that a fullwidth character over a fullwidth character creates
124         * a 3x1 dirty rect because of clobbering on the left side. */
[3449]125        caca_clear_canvas(cv);
126        caca_put_char(cv, 7, 3, 0x2f06 /* ⼆ */);
[3494]127        caca_clear_dirty_rect_list(cv);
[3449]128        caca_put_char(cv, 6, 3, 0x2f06 /* ⼆ */);
[3567]129
130        CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
[3494]131        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
[3567]132        CPPUNIT_ASSERT_EQUAL(6, dx);
133        CPPUNIT_ASSERT_EQUAL(3, dy);
134        CPPUNIT_ASSERT_EQUAL(3, dw);
135        CPPUNIT_ASSERT_EQUAL(1, dh);
[3449]136
[3567]137        /* Check that a fullwidth character over a fullwidth character creates
138         * a 3x1 dirty rect because of clobbering on the right side. */
[3449]139        caca_clear_canvas(cv);
140        caca_put_char(cv, 7, 3, 0x2f06 /* ⼆ */);
[3494]141        caca_clear_dirty_rect_list(cv);
[3449]142        caca_put_char(cv, 8, 3, 0x2f06 /* ⼆ */);
[3567]143
144        CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
[3494]145        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
[3567]146        CPPUNIT_ASSERT_EQUAL(7, dx);
147        CPPUNIT_ASSERT_EQUAL(3, dy);
148        CPPUNIT_ASSERT_EQUAL(3, dw);
149        CPPUNIT_ASSERT_EQUAL(1, dh);
[3449]150    }
151
[3513]152    void test_put_char_not_dirty()
153    {
154        caca_canvas_t *cv;
155
156        cv = caca_create_canvas(WIDTH, HEIGHT);
157
[3567]158        /* Check that pasting the same character does not cause a dirty
159         * rectangle to be created. */
[3513]160        caca_put_char(cv, 7, 3, 'x');
161        caca_clear_dirty_rect_list(cv);
162        caca_put_char(cv, 7, 3, 'x');
163
[3567]164        CPPUNIT_ASSERT_EQUAL(0, caca_get_dirty_rect_count(cv));
165
166        /* Check that pasting the same fullwidth character does not cause
167         * a dirty rectangle to be created. */
[3513]168        caca_clear_canvas(cv);
169        caca_put_char(cv, 7, 3, 0x2f06 /* ⼆ */);
170        caca_clear_dirty_rect_list(cv);
171        caca_put_char(cv, 7, 3, 0x2f06 /* ⼆ */);
[3567]172
173        CPPUNIT_ASSERT_EQUAL(0, caca_get_dirty_rect_count(cv));
[3513]174    }
175
[3579]176    void test_simplify()
177    {
178        caca_canvas_t *cv;
179        int dx, dy, dw, dh;
180
181        cv = caca_create_canvas(WIDTH, HEIGHT);
182
183        /* Check that N adjacent blits only create one dirty rectangle */
184        caca_clear_dirty_rect_list(cv);
185        for(int i = 0; i < 10; i++)
186        {
187            caca_put_char(cv, 7 + i, 3, '-');
188
189            CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
190            caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
191            CPPUNIT_ASSERT_EQUAL(7, dx);
192            CPPUNIT_ASSERT_EQUAL(3, dy);
193            CPPUNIT_ASSERT_EQUAL(1 + i, dw);
194            CPPUNIT_ASSERT_EQUAL(1, dh);
195        }
196
197        /* Check that N adjacent blits only create one dirty rectangle */
198        caca_clear_dirty_rect_list(cv);
199        for(int j = 0; j < 10; j++)
200        {
201            caca_put_char(cv, 7, 3 + j, '|');
202
203            CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
204            caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
205            CPPUNIT_ASSERT_EQUAL(7, dx);
206            CPPUNIT_ASSERT_EQUAL(3, dy);
207            CPPUNIT_ASSERT_EQUAL(1, dw);
208            CPPUNIT_ASSERT_EQUAL(1 + j, dh);
209        }
210    }
211
[3513]212    void test_box()
213    {
214        caca_canvas_t *cv;
[3567]215        int dx, dy, dw, dh;
[3513]216
217        cv = caca_create_canvas(WIDTH, HEIGHT);
218        caca_clear_dirty_rect_list(cv);
219
[3567]220        /* Check that a filled box creates one dirty rectangle of the same
221         * size. */
[3513]222        caca_fill_box(cv, 7, 3, 14, 9, 'x');
[3567]223
224        CPPUNIT_ASSERT_EQUAL(1, caca_get_dirty_rect_count(cv));
[3513]225        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
[3567]226        CPPUNIT_ASSERT_EQUAL(7, dx);
227        CPPUNIT_ASSERT_EQUAL(3, dy);
228        CPPUNIT_ASSERT_EQUAL(14, dw);
229        CPPUNIT_ASSERT_EQUAL(9, dh);
[3513]230
[3567]231        /* Check that the same filled box does not create a new dirty
232         * rectangle. */
[3513]233        caca_clear_dirty_rect_list(cv);
234        caca_fill_box(cv, 7, 3, 14, 9, 'x');
[3567]235
236        CPPUNIT_ASSERT_EQUAL(0, caca_get_dirty_rect_count(cv));
[3513]237    }
238
[3556]239    void test_blit()
240    {
241        caca_canvas_t *cv, *cv2;
242        int i, dx, dy, dw, dh;
243
244        cv = caca_create_canvas(WIDTH, HEIGHT);
245        caca_clear_dirty_rect_list(cv);
246        cv2 = caca_create_canvas(2, 2);
247        caca_fill_box(cv2, 0, 0, 2, 1, 'x');
248
[3557]249        /* Check that blitting a canvas make a dirty rectangle
250         * only for modified lines */
[3567]251        /* FIXME: check this test's validity */
[3557]252
[3556]253        caca_blit(cv, 1, 1, cv2, NULL);
254        i = caca_get_dirty_rect_count(cv);
[3567]255        CPPUNIT_ASSERT_EQUAL(1, i);
[3556]256        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
257
[3567]258        CPPUNIT_ASSERT(1 == dx);
259        CPPUNIT_ASSERT(1 == dy);
260        CPPUNIT_ASSERT(2 <= dw);
261        CPPUNIT_ASSERT(1 == dh);
[3557]262
263        caca_clear_canvas(cv);
264        caca_clear_dirty_rect_list(cv);
265
266        /* Check that blitting a canvas make a dirty rectangle
267         * only for modified chars when we have a mask */
[3567]268        /* FIXME: check this test's validity */
[3557]269
270        caca_blit(cv, 1, 1, cv2, cv2);
271        i = caca_get_dirty_rect_count(cv);
[3567]272        CPPUNIT_ASSERT_EQUAL(1, i);
[3557]273        caca_get_dirty_rect(cv, 0, &dx, &dy, &dw, &dh);
274
[3567]275        CPPUNIT_ASSERT(1 == dx);
276        CPPUNIT_ASSERT(1 == dy);
277        CPPUNIT_ASSERT(2 == dw);
278        CPPUNIT_ASSERT(1 == dh);
279
280        CPPUNIT_ASSERT(' ' == caca_get_char(cv, 0, 0));
281
[3556]282    }
283
[3449]284private:
[3567]285    static int const WIDTH, HEIGHT;
[3449]286};
287
[3567]288int const DirtyTest::WIDTH = 80;
289int const DirtyTest::HEIGHT = 50;
290
[3449]291CPPUNIT_TEST_SUITE_REGISTRATION(DirtyTest);
292
Note: See TracBrowser for help on using the repository browser.