LCOV - code coverage report
Current view: top level - tests - test-region.c (source / functions) Hit Total Coverage
Test: out.info Lines: 258 264 97.7 %
Date: 2022-01-27 10:43:00 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
       2             : /*
       3             :    Copyright (C) 2009 Red Hat, Inc.
       4             : 
       5             :    This library is free software; you can redistribute it and/or
       6             :    modify it under the terms of the GNU Lesser General Public
       7             :    License as published by the Free Software Foundation; either
       8             :    version 2.1 of the License, or (at your option) any later version.
       9             : 
      10             :    This library is distributed in the hope that it will be useful,
      11             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :    Lesser General Public License for more details.
      14             : 
      15             :    You should have received a copy of the GNU Lesser General Public
      16             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      17             : */
      18             : #include <config.h>
      19             : 
      20             : #include <stdio.h>
      21             : #include <string.h>
      22             : #include <stdlib.h>
      23             : #include <spice/macros.h>
      24             : 
      25             : #include <common/region.h>
      26             : 
      27      700000 : static int slow_region_test(const QRegion *rgn, const QRegion *other_rgn, int query)
      28             : {
      29             :     pixman_region32_t intersection;
      30             :     int res;
      31             : 
      32      700000 :     pixman_region32_init(&intersection);
      33      700000 :     pixman_region32_intersect(&intersection,
      34             :                               (pixman_region32_t *)rgn,
      35             :                               (pixman_region32_t *)other_rgn);
      36             : 
      37      700000 :     res = 0;
      38             : 
      39     1100000 :     if (query & REGION_TEST_SHARED &&
      40      400000 :         pixman_region32_not_empty(&intersection)) {
      41      356824 :         res |= REGION_TEST_SHARED;
      42             :     }
      43             : 
      44     1100000 :     if (query & REGION_TEST_LEFT_EXCLUSIVE &&
      45      400000 :         !pixman_region32_equal(&intersection, (pixman_region32_t *)rgn)) {
      46      373704 :         res |= REGION_TEST_LEFT_EXCLUSIVE;
      47             :     }
      48             : 
      49     1100000 :     if (query & REGION_TEST_RIGHT_EXCLUSIVE &&
      50      400000 :         !pixman_region32_equal(&intersection, (pixman_region32_t *)other_rgn)) {
      51      374408 :         res |= REGION_TEST_RIGHT_EXCLUSIVE;
      52             :     }
      53             : 
      54      700000 :     pixman_region32_fini(&intersection);
      55             : 
      56      700000 :     return res;
      57             : }
      58             : 
      59             : 
      60     1902195 : static int rect_is_valid(const SpiceRect *r)
      61             : {
      62     1902195 :     if (r->top > r->bottom || r->left > r->right) {
      63           0 :         return FALSE;
      64             :     }
      65     1902195 :     return TRUE;
      66             : }
      67             : 
      68     1902195 : static void rect_set(SpiceRect *r, int32_t top, int32_t left, int32_t bottom, int32_t right)
      69             : {
      70     1902195 :     r->top = top;
      71     1902195 :     r->left = left;
      72     1902195 :     r->bottom = bottom;
      73     1902195 :     r->right = right;
      74     1902195 :     g_assert_true(rect_is_valid(r));
      75     1902195 : }
      76             : 
      77      200000 : static void random_region(QRegion *reg)
      78             : {
      79             :     int i;
      80             :     int num_rects;
      81             :     int x, y, w, h;
      82             :     SpiceRect _r;
      83      200000 :     SpiceRect *r = &_r;
      84             : 
      85      200000 :     region_clear(reg);
      86             : 
      87      200000 :     num_rects = rand() % 20;
      88     2102181 :     for (i = 0; i < num_rects; i++) {
      89     1902181 :         x = rand()%100;
      90     1902181 :         y = rand()%100;
      91     1902181 :         w = rand()%100;
      92     1902181 :         h = rand()%100;
      93     1902181 :         rect_set(r,
      94             :                  x, y,
      95             :                  x+w, y+h);
      96     1902181 :         region_add(reg, r);
      97             :     }
      98      200000 : }
      99             : 
     100          17 : static void test(const QRegion *r1, const QRegion *r2, int *expected)
     101             : {
     102          17 :     g_debug("r1 is_empty %s [%s]",
     103             :             region_is_empty(r1) ? "TRUE" : "FALSE",
     104             :             (region_is_empty(r1) == *expected) ? "OK" : "ERR");
     105          17 :     g_assert_cmpint(region_is_empty(r1), ==, *expected);
     106          17 :     expected++;
     107          17 :     g_debug("r2 is_empty %s [%s]",
     108             :             region_is_empty(r2) ? "TRUE" : "FALSE",
     109             :             (region_is_empty(r2) == *expected) ? "OK" : "ERR");
     110          17 :     g_assert_cmpint(region_is_empty(r2), ==, *expected);
     111          17 :     expected++;
     112          17 :     g_debug("is_equal %s [%s]",
     113             :             region_is_equal(r1, r2) ? "TRUE" : "FALSE",
     114             :             (region_is_equal(r1, r2) == *expected) ? "OK" : "ERR");
     115          17 :     g_assert_cmpint(region_is_equal(r1, r2), ==, *expected);
     116          17 :     expected++;
     117          17 :     g_debug("intersects %s [%s]",
     118             :             region_intersects(r1, r2) ? "TRUE" : "FALSE",
     119             :             (region_intersects(r1, r2) == *expected) ? "OK" : "ERR");
     120          17 :     g_assert_cmpint(region_intersects(r1, r2), ==, *expected);
     121          17 :     expected++;
     122          17 :     g_debug("contains %s [%s]",
     123             :             region_contains(r1, r2) ? "TRUE" : "FALSE",
     124             :             (region_contains(r1, r2) == *expected) ? "OK" : "ERR");
     125          17 :     g_assert_cmpint(region_contains(r1, r2), ==, *expected);
     126          17 :     expected++;
     127          17 : }
     128             : 
     129             : enum {
     130             :     EXPECT_R1_EMPTY,
     131             :     EXPECT_R2_EMPTY,
     132             :     EXPECT_EQUAL,
     133             :     EXPECT_SECT,
     134             :     EXPECT_CONT,
     135             : };
     136             : 
     137           1 : static void test_region(void)
     138             : {
     139             :     QRegion _r1, _r2, _r3;
     140           1 :     QRegion *r1 = &_r1;
     141           1 :     QRegion *r2 = &_r2;
     142           1 :     QRegion *r3 = &_r3;
     143             :     SpiceRect _r;
     144           1 :     SpiceRect *r = &_r;
     145             :     int expected[5];
     146             :     int i, j;
     147             : 
     148           1 :     region_init(r1);
     149           1 :     region_init(r2);
     150             : 
     151           1 :     g_debug("dump r1 empty rgn [%s]", region_is_valid(r1) ? "VALID" : "INVALID");
     152             :     //region_dump(r1, "");
     153           1 :     expected[EXPECT_R1_EMPTY] = TRUE;
     154           1 :     expected[EXPECT_R2_EMPTY] = TRUE;
     155           1 :     expected[EXPECT_EQUAL] = TRUE;
     156           1 :     expected[EXPECT_SECT] = FALSE;
     157           1 :     expected[EXPECT_CONT] = TRUE;
     158           1 :     test(r1, r2, expected);
     159           1 :     g_debug("\n");
     160             : 
     161           1 :     region_clone(r3, r1);
     162           1 :     g_debug("dump r3 clone rgn [%s]", region_is_valid(r3) ? "VALID" : "INVALID");
     163             :     //region_dump(r3, "");
     164           1 :     expected[EXPECT_R1_EMPTY] = TRUE;
     165           1 :     expected[EXPECT_R2_EMPTY] = TRUE;
     166           1 :     expected[EXPECT_EQUAL] = TRUE;
     167           1 :     expected[EXPECT_SECT] = FALSE;
     168           1 :     expected[EXPECT_CONT] = TRUE;
     169           1 :     test(r1, r3, expected);
     170           1 :     region_destroy(r3);
     171           1 :     g_debug("\n");
     172             : 
     173           1 :     rect_set(r, 0, 0, 100, 100);
     174           1 :     region_add(r1, r);
     175           1 :     g_debug("dump r1 [%s]", region_is_valid(r1) ? "VALID" : "INVALID");
     176             :     //region_dump(r1, "");
     177           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     178           1 :     expected[EXPECT_R2_EMPTY] = TRUE;
     179           1 :     expected[EXPECT_EQUAL] = FALSE;
     180           1 :     expected[EXPECT_SECT] = FALSE;
     181           1 :     expected[EXPECT_CONT] = TRUE;
     182           1 :     test(r1, r2, expected);
     183           1 :     g_debug("\n");
     184             : 
     185           1 :     region_clear(r1);
     186           1 :     rect_set(r, 0, 0, 0, 0);
     187           1 :     region_add(r1, r);
     188           1 :     g_debug("dump r1 [%s]", region_is_valid(r1) ? "VALID" : "INVALID");
     189             :     //region_dump(r1, "");
     190           1 :     expected[EXPECT_R1_EMPTY] = TRUE;
     191           1 :     expected[EXPECT_R2_EMPTY] = TRUE;
     192           1 :     expected[EXPECT_EQUAL] = TRUE;
     193           1 :     expected[EXPECT_SECT] = FALSE;
     194           1 :     expected[EXPECT_CONT] = TRUE;
     195           1 :     test(r1, r2, expected);
     196           1 :     g_debug("\n");
     197             : 
     198           1 :     rect_set(r, -100, -100, 0, 0);
     199           1 :     region_add(r1, r);
     200           1 :     g_debug("dump r1 [%s]", region_is_valid(r1) ? "VALID" : "INVALID");
     201             :     //region_dump(r1, "");
     202           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     203           1 :     expected[EXPECT_R2_EMPTY] = TRUE;
     204           1 :     expected[EXPECT_EQUAL] = FALSE;
     205           1 :     expected[EXPECT_SECT] = FALSE;
     206           1 :     expected[EXPECT_CONT] = TRUE;
     207           1 :     test(r1, r2, expected);
     208           1 :     g_debug("\n");
     209             : 
     210           1 :     region_clear(r1);
     211           1 :     rect_set(r, -100, -100, 100, 100);
     212           1 :     region_add(r1, r);
     213           1 :     g_debug("dump r1 [%s]", region_is_valid(r1) ? "VALID" : "INVALID");
     214             :     //region_dump(r1, "");
     215           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     216           1 :     expected[EXPECT_R2_EMPTY] = TRUE;
     217           1 :     expected[EXPECT_EQUAL] = FALSE;
     218           1 :     expected[EXPECT_SECT] = FALSE;
     219           1 :     expected[EXPECT_CONT] = TRUE;
     220           1 :     test(r1, r2, expected);
     221           1 :     g_debug("\n");
     222             : 
     223             : 
     224           1 :     region_clear(r1);
     225           1 :     region_clear(r2);
     226             : 
     227           1 :     rect_set(r, 100, 100, 200, 200);
     228           1 :     region_add(r1, r);
     229           1 :     g_debug("dump r1 [%s]", region_is_valid(r1) ? "VALID" : "INVALID");
     230             :     //region_dump(r1, "");
     231           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     232           1 :     expected[EXPECT_R2_EMPTY] = TRUE;
     233           1 :     expected[EXPECT_EQUAL] = FALSE;
     234           1 :     expected[EXPECT_SECT] = FALSE;
     235           1 :     expected[EXPECT_CONT] = TRUE;
     236           1 :     test(r1, r2, expected);
     237           1 :     g_debug("\n");
     238             : 
     239           1 :     rect_set(r, 300, 300, 400, 400);
     240           1 :     region_add(r1, r);
     241           1 :     g_debug("dump r1 [%s]", region_is_valid(r1) ? "VALID" : "INVALID");
     242             :     //region_dump(r1, "");
     243           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     244           1 :     expected[EXPECT_R2_EMPTY] = TRUE;
     245           1 :     expected[EXPECT_EQUAL] = FALSE;
     246           1 :     expected[EXPECT_SECT] = FALSE;
     247           1 :     expected[EXPECT_CONT] = TRUE;
     248           1 :     test(r1, r2, expected);
     249           1 :     g_debug("\n");
     250             : 
     251           1 :     rect_set(r, 500, 500, 600, 600);
     252           1 :     region_add(r2, r);
     253           1 :     g_debug("dump r2 [%s]", region_is_valid(r2) ? "VALID" : "INVALID");
     254             :     //region_dump(r2, "");
     255           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     256           1 :     expected[EXPECT_R2_EMPTY] = FALSE;
     257           1 :     expected[EXPECT_EQUAL] = FALSE;
     258           1 :     expected[EXPECT_SECT] = FALSE;
     259           1 :     expected[EXPECT_CONT] = FALSE;
     260           1 :     test(r1, r2, expected);
     261           1 :     g_debug("\n");
     262             : 
     263           1 :     region_clear(r2);
     264             : 
     265           1 :     rect_set(r, 100, 100, 200, 200);
     266           1 :     region_add(r2, r);
     267           1 :     rect_set(r, 300, 300, 400, 400);
     268           1 :     region_add(r2, r);
     269           1 :     g_debug("dump r2 [%s]", region_is_valid(r2) ? "VALID" : "INVALID");
     270             :     //region_dump(r2, "");
     271           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     272           1 :     expected[EXPECT_R2_EMPTY] = FALSE;
     273           1 :     expected[EXPECT_EQUAL] = TRUE;
     274           1 :     expected[EXPECT_SECT] = TRUE;
     275           1 :     expected[EXPECT_CONT] = TRUE;
     276           1 :     test(r1, r2, expected);
     277           1 :     g_debug("\n");
     278             : 
     279           1 :     region_clear(r2);
     280             : 
     281           1 :     rect_set(r, 100, 100, 200, 200);
     282           1 :     region_add(r2, r);
     283           1 :     g_debug("dump r2 [%s]", region_is_valid(r2) ? "VALID" : "INVALID");
     284             :     //region_dump(r2, "");
     285           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     286           1 :     expected[EXPECT_R2_EMPTY] = FALSE;
     287           1 :     expected[EXPECT_EQUAL] = FALSE;
     288           1 :     expected[EXPECT_SECT] = TRUE;
     289           1 :     expected[EXPECT_CONT] = TRUE;
     290           1 :     test(r1, r2, expected);
     291           1 :     g_debug("\n");
     292             : 
     293           1 :     region_clear(r2);
     294             : 
     295           1 :     rect_set(r, -2000, -2000, -1000, -1000);
     296           1 :     region_add(r2, r);
     297           1 :     g_debug("dump r2 [%s]", region_is_valid(r2) ? "VALID" : "INVALID");
     298             :     //region_dump(r2, "");
     299           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     300           1 :     expected[EXPECT_R2_EMPTY] = FALSE;
     301           1 :     expected[EXPECT_EQUAL] = FALSE;
     302           1 :     expected[EXPECT_SECT] = FALSE;
     303           1 :     expected[EXPECT_CONT] = FALSE;
     304           1 :     test(r1, r2, expected);
     305           1 :     g_debug("\n");
     306             : 
     307           1 :     region_clear(r2);
     308             : 
     309           1 :     rect_set(r, -2000, -2000, 1000, 1000);
     310           1 :     region_add(r2, r);
     311           1 :     g_debug("dump r2 [%s]", region_is_valid(r2) ? "VALID" : "INVALID");
     312             :     //region_dump(r2, "");
     313           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     314           1 :     expected[EXPECT_R2_EMPTY] = FALSE;
     315           1 :     expected[EXPECT_EQUAL] = FALSE;
     316           1 :     expected[EXPECT_SECT] = TRUE;
     317           1 :     expected[EXPECT_CONT] = FALSE;
     318           1 :     test(r1, r2, expected);
     319           1 :     g_debug("\n");
     320             : 
     321           1 :     region_clear(r2);
     322             : 
     323           1 :     rect_set(r, 150, 150, 175, 175);
     324           1 :     region_add(r2, r);
     325           1 :     g_debug("dump r2 [%s]", region_is_valid(r2) ? "VALID" : "INVALID");
     326             :     //region_dump(r2, "");
     327           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     328           1 :     expected[EXPECT_R2_EMPTY] = FALSE;
     329           1 :     expected[EXPECT_EQUAL] = FALSE;
     330           1 :     expected[EXPECT_SECT] = TRUE;
     331           1 :     expected[EXPECT_CONT] = TRUE;
     332           1 :     test(r1, r2, expected);
     333           1 :     g_debug("\n");
     334             : 
     335           1 :     region_clear(r2);
     336             : 
     337           1 :     rect_set(r, 150, 150, 350, 350);
     338           1 :     region_add(r2, r);
     339           1 :     g_debug("dump r2 [%s]", region_is_valid(r2) ? "VALID" : "INVALID");
     340             :     //region_dump(r2, "");
     341           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     342           1 :     expected[EXPECT_R2_EMPTY] = FALSE;
     343           1 :     expected[EXPECT_EQUAL] = FALSE;
     344           1 :     expected[EXPECT_SECT] = TRUE;
     345           1 :     expected[EXPECT_CONT] = FALSE;
     346           1 :     test(r1, r2, expected);
     347           1 :     g_debug("\n");
     348             : 
     349           1 :     region_and(r2, r1);
     350           1 :     g_debug("dump r2 and r1 [%s]", region_is_valid(r2) ? "VALID" : "INVALID");
     351             :     //region_dump(r2, "");
     352           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     353           1 :     expected[EXPECT_R2_EMPTY] = FALSE;
     354           1 :     expected[EXPECT_EQUAL] = FALSE;
     355           1 :     expected[EXPECT_SECT] = TRUE;
     356           1 :     expected[EXPECT_CONT] = FALSE;
     357           1 :     test(r2, r1, expected);
     358           1 :     g_debug("\n");
     359             : 
     360             : 
     361           1 :     region_clone(r3, r1);
     362           1 :     g_debug("dump r3 clone rgn [%s]", region_is_valid(r3) ? "VALID" : "INVALID");
     363             :     //region_dump(r3, "");
     364           1 :     expected[EXPECT_R1_EMPTY] = FALSE;
     365           1 :     expected[EXPECT_R2_EMPTY] = FALSE;
     366           1 :     expected[EXPECT_EQUAL] = TRUE;
     367           1 :     expected[EXPECT_SECT] = TRUE;
     368           1 :     expected[EXPECT_CONT] = TRUE;
     369           1 :     test(r1, r3, expected);
     370           1 :     g_debug("\n");
     371             : 
     372           1 :     j = 0;
     373      100001 :     for (i = 0; i < 100000; i++) {
     374             :         int res1, res2, test;
     375      100000 :         int tests[] = {
     376             :             REGION_TEST_LEFT_EXCLUSIVE,
     377             :             REGION_TEST_RIGHT_EXCLUSIVE,
     378             :             REGION_TEST_SHARED,
     379             :             REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE,
     380             :             REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_SHARED,
     381             :             REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED,
     382             :             REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED
     383             :         };
     384             : 
     385      100000 :         random_region(r1);
     386      100000 :         random_region(r2);
     387             : 
     388      800000 :         for (test = 0; test < 7; test++) {
     389      700000 :             res1 = region_test(r1, r2, tests[test]);
     390      700000 :             res2 = slow_region_test(r1, r2, tests[test]);
     391      700000 :             if (res1 != res2) {
     392           0 :                 g_warning("Error in region_test %d, got %d, expected %d, query=%d",
     393             :                           j, res1, res2, tests[test]);
     394           0 :                 g_debug("r1:");
     395           0 :                 region_dump(r1, "");
     396           0 :                 g_debug("r2:");
     397           0 :                 region_dump(r2, "");
     398             :             }
     399      700000 :             g_assert_cmpint(res1, ==, res2);
     400      700000 :             j++;
     401             :         }
     402             :     }
     403             : 
     404           1 :     region_destroy(r3);
     405           1 :     region_destroy(r1);
     406           1 :     region_destroy(r2);
     407           1 : }
     408             : 
     409           1 : int main(int argc, char **argv)
     410             : {
     411           1 :     g_test_init(&argc, &argv, NULL);
     412             : 
     413           1 :     g_test_add_func("/spice-common/region", test_region);
     414             : 
     415           1 :     return g_test_run();
     416             : }

Generated by: LCOV version 1.14