Lines Matching refs:damage
37 * damage regions is an O(n^2) operation. Instead the accumulation of a
41 * As with the core of SNA, damage is handled modally. That is, it
121 const struct sna_damage *damage)
126 if (damage == NULL)
133 if (damage->mode == DAMAGE_ALL) {
135 damage->extents.x1, damage->extents.y1,
136 damage->extents.x2, damage->extents.y2);
138 if (damage->dirty) {
140 damage->mode == DAMAGE_SUBTRACT ? '-' : '+');
144 damage->extents.x1, damage->extents.y1,
145 damage->extents.x2, damage->extents.y2,
147 &damage->region),
148 damage_str, damage->dirty ? '*' : ' ');
156 last_box(struct sna_damage *damage)
158 return list_entry(damage->embedded_box.list.prev,
164 reset_embedded_box(struct sna_damage *damage)
166 damage->dirty = false;
167 damage->box = damage->embedded_box.box;
168 damage->embedded_box.size =
169 damage->remain = ARRAY_SIZE(damage->embedded_box.box);
170 list_init(&damage->embedded_box.list);
173 static void reset_extents(struct sna_damage *damage)
175 damage->extents.x1 = damage->extents.y1 = MAXSHORT;
176 damage->extents.x2 = damage->extents.y2 = MINSHORT;
181 struct sna_damage *damage;
184 damage = __freed_damage;
187 damage = malloc(sizeof(*damage));
188 if (damage == NULL)
191 reset_embedded_box(damage);
192 damage->mode = DAMAGE_ADD;
193 pixman_region_init(&damage->region);
194 reset_extents(damage);
196 return damage;
213 static void __sna_damage_reduce(struct sna_damage *damage)
217 pixman_region16_t *region = &damage->region;
220 assert(damage->mode != DAMAGE_ALL);
221 assert(damage->dirty);
225 nboxes = damage->embedded_box.size;
226 list_for_each_entry(iter, &damage->embedded_box.list, list)
228 DBG((" nboxes=%d, residual=%d\n", nboxes, damage->remain));
229 nboxes -= damage->remain;
235 tmp.extents = damage->embedded_box.box[0];
238 if (damage->mode == DAMAGE_ADD)
242 damage->extents = region->extents;
247 if (damage->mode == DAMAGE_ADD)
250 iter = last_box(damage);
251 n = iter->size - damage->remain;
262 if (boxes != damage->embedded_box.box) {
263 if (list_is_empty(&damage->embedded_box.list)) {
266 damage->embedded_box.box,
277 while (&iter->list != &damage->embedded_box.list) {
291 damage->embedded_box.box,
292 sizeof(damage->embedded_box.box));
293 n += damage->embedded_box.size;
297 if (damage->mode == DAMAGE_ADD) {
306 assert(damage->extents.x1 == region->extents.x1 &&
307 damage->extents.y1 == region->extents.y1 &&
308 damage->extents.x2 == region->extents.x2 &&
309 damage->extents.y2 == region->extents.y2);
318 assert(damage->extents.x1 <= region->extents.x1 &&
319 damage->extents.y1 <= region->extents.y1 &&
320 damage->extents.x2 >= region->extents.x2 &&
321 damage->extents.y2 >= region->extents.y2);
323 damage->extents = region->extents;
325 reset_extents(damage);
331 damage->mode = DAMAGE_ADD;
332 free_list(&damage->embedded_box.list);
333 reset_embedded_box(damage);
338 static bool _sna_damage_create_boxes(struct sna_damage *damage,
344 box = last_box(damage);
358 list_add_tail(&box->list, &damage->embedded_box.list);
360 box->size = damage->remain = n;
361 damage->box = (BoxRec *)(box + 1);
366 _sna_damage_create_elt(struct sna_damage *damage,
372 __FUNCTION__, damage->remain, count));
377 if (n > damage->remain)
378 n = damage->remain;
380 memcpy(damage->box, boxes, n * sizeof(BoxRec));
381 damage->box += n;
382 damage->remain -= n;
383 damage->dirty = true;
388 return damage;
392 assert(damage->remain == 0);
393 assert(damage->box - (BoxRec *)(last_box(damage)+1) == last_box(damage)->size);
395 if (!_sna_damage_create_boxes(damage, count)) {
398 if (!damage->dirty)
399 return damage;
401 mode = damage->mode;
402 __sna_damage_reduce(damage);
403 damage->mode = mode;
408 memcpy(damage->box, boxes, count * sizeof(BoxRec));
409 damage->box += count;
410 damage->remain -= count;
411 damage->dirty = true;
412 assert(damage->remain >= 0);
414 return damage;
418 _sna_damage_create_elt_from_boxes(struct sna_damage *damage,
424 DBG((" %s: prev=(remain %d)\n", __FUNCTION__, damage->remain));
429 if (n > damage->remain)
430 n = damage->remain;
433 damage->box[i].x1 = boxes[i].x1 + dx;
434 damage->box[i].x2 = boxes[i].x2 + dx;
435 damage->box[i].y1 = boxes[i].y1 + dy;
436 damage->box[i].y2 = boxes[i].y2 + dy;
438 damage->box += n;
439 damage->remain -= n;
440 damage->dirty = true;
445 return damage;
449 assert(damage->remain == 0);
450 assert(damage->box - (BoxRec *)(last_box(damage)+1) == last_box(damage)->size);
452 if (!_sna_damage_create_boxes(damage, count)) {
455 if (!damage->dirty)
456 return damage;
458 mode = damage->mode;
459 __sna_damage_reduce(damage);
460 damage->mode = mode;
466 damage->box[i].x1 = boxes[i].x1 + dx;
467 damage->box[i].x2 = boxes[i].x2 + dx;
468 damage->box[i].y1 = boxes[i].y1 + dy;
469 damage->box[i].y2 = boxes[i].y2 + dy;
471 damage->box += count;
472 damage->remain -= count;
473 damage->dirty = true;
474 assert(damage->remain >= 0);
476 return damage;
480 _sna_damage_create_elt_from_rectangles(struct sna_damage *damage,
487 __FUNCTION__, damage->remain, count));
492 if (n > damage->remain)
493 n = damage->remain;
496 damage->box[i].x1 = r[i].x + dx;
497 damage->box[i].x2 = damage->box[i].x1 + r[i].width;
498 damage->box[i].y1 = r[i].y + dy;
499 damage->box[i].y2 = damage->box[i].y1 + r[i].height;
501 damage->box += n;
502 damage->remain -= n;
503 damage->dirty = true;
508 return damage;
512 assert(damage->remain == 0);
513 assert(damage->box - (BoxRec *)(last_box(damage)+1) == last_box(damage)->size);
515 if (!_sna_damage_create_boxes(damage, count)) {
518 if (!damage->dirty)
519 return damage;
521 mode = damage->mode;
522 __sna_damage_reduce(damage);
523 damage->mode = mode;
529 damage->box[i].x1 = r[i].x + dx;
530 damage->box[i].x2 = damage->box[i].x1 + r[i].width;
531 damage->box[i].y1 = r[i].y + dy;
532 damage->box[i].y2 = damage->box[i].y1 + r[i].height;
534 damage->box += count;
535 damage->remain -= count;
536 damage->dirty = true;
537 assert(damage->remain >= 0);
539 return damage;
543 _sna_damage_create_elt_from_points(struct sna_damage *damage,
550 __FUNCTION__, damage->remain, count));
555 if (n > damage->remain)
556 n = damage->remain;
559 damage->box[i].x1 = p[i].x + dx;
560 damage->box[i].x2 = damage->box[i].x1 + 1;
561 damage->box[i].y1 = p[i].y + dy;
562 damage->box[i].y2 = damage->box[i].y1 + 1;
564 damage->box += n;
565 damage->remain -= n;
566 damage->dirty = true;
571 return damage;
575 assert(damage->remain == 0);
576 assert(damage->box - (BoxRec *)(last_box(damage)+1) == last_box(damage)->size);
578 if (!_sna_damage_create_boxes(damage, count)) {
581 if (!damage->dirty)
582 return damage;
584 mode = damage->mode;
585 __sna_damage_reduce(damage);
586 damage->mode = mode;
592 damage->box[i].x1 = p[i].x + dx;
593 damage->box[i].x2 = damage->box[i].x1 + 1;
594 damage->box[i].y1 = p[i].y + dy;
595 damage->box[i].y2 = damage->box[i].y1 + 1;
597 damage->box += count;
598 damage->remain -= count;
599 damage->dirty = true;
600 assert(damage->remain >= 0);
602 return damage;
605 static void damage_union(struct sna_damage *damage, const BoxRec *box)
607 DBG(("%s: extending damage (%d, %d), (%d, %d) by (%d, %d), (%d, %d)\n",
609 damage->extents.x1, damage->extents.y1,
610 damage->extents.x2, damage->extents.y2,
613 if (damage->extents.x2 < damage->extents.x1) {
614 damage->extents = *box;
616 if (damage->extents.x1 > box->x1)
617 damage->extents.x1 = box->x1;
618 if (damage->extents.x2 < box->x2)
619 damage->extents.x2 = box->x2;
621 if (damage->extents.y1 > box->y1)
622 damage->extents.y1 = box->y1;
623 if (damage->extents.y2 < box->y2)
624 damage->extents.y2 = box->y2;
626 assert(damage->extents.x2 > damage->extents.x1);
627 assert(damage->extents.y2 > damage->extents.y1);
642 static struct sna_damage *__sna_damage_add_box(struct sna_damage *damage,
646 return damage;
648 if (!damage) {
649 damage = _sna_damage_create();
650 if (damage == NULL)
652 } else switch (damage->mode) {
654 return damage;
656 __sna_damage_reduce(damage);
661 if (region_is_singular_or_empty(&damage->region) ||
662 box_contains_region(box, &damage->region)) {
663 _pixman_region_union_box(&damage->region, box);
664 assert(damage->region.extents.x2 > damage->region.extents.x1);
665 assert(damage->region.extents.y2 > damage->region.extents.y1);
666 damage_union(damage, box);
667 return damage;
670 if (pixman_region_contains_rectangle(&damage->region,
672 return damage;
674 damage_union(damage, box);
675 return _sna_damage_create_elt(damage, box, 1);
678 inline static struct sna_damage *__sna_damage_add(struct sna_damage *damage,
683 if (!damage) {
684 damage = _sna_damage_create();
685 if (damage == NULL)
687 } else switch (damage->mode) {
689 return damage;
691 __sna_damage_reduce(damage);
697 return __sna_damage_add_box(damage, ®ion->extents);
699 if (region_is_singular_or_empty(&damage->region)) {
700 pixman_region_union(&damage->region, &damage->region, region);
701 assert(damage->region.extents.x2 > damage->region.extents.x1);
702 assert(damage->region.extents.y2 > damage->region.extents.y1);
703 damage_union(damage, ®ion->extents);
704 return damage;
707 if (pixman_region_contains_rectangle(&damage->region,
709 return damage;
711 damage_union(damage, ®ion->extents);
712 return _sna_damage_create_elt(damage,
718 fastcall struct sna_damage *_sna_damage_add(struct sna_damage *damage,
725 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
728 damage = __sna_damage_add(damage, region);
731 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)));
732 assert(region_num_rects(&damage->region));
733 assert(damage->region.extents.x2 > damage->region.extents.x1);
734 assert(damage->region.extents.y2 > damage->region.extents.y1);
736 return damage;
739 fastcall struct sna_damage *_sna_damage_add(struct sna_damage *damage,
742 return __sna_damage_add(damage, region);
747 __sna_damage_add_boxes(struct sna_damage *damage,
756 if (!damage) {
757 damage = _sna_damage_create();
758 if (damage == NULL)
760 } else switch (damage->mode) {
762 return damage;
764 __sna_damage_reduce(damage);
791 return __sna_damage_add_box(damage, &extents);
793 if (pixman_region_contains_rectangle(&damage->region,
795 return damage;
797 damage_union(damage, &extents);
798 return _sna_damage_create_elt_from_boxes(damage, box, n, dx, dy);
802 struct sna_damage *_sna_damage_add_boxes(struct sna_damage *damage,
809 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
812 damage = __sna_damage_add_boxes(damage, b, n, dx, dy);
815 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)));
816 if (region_num_rects(&damage->region)) {
817 assert(damage->region.extents.x2 > damage->region.extents.x1);
818 assert(damage->region.extents.y2 > damage->region.extents.y1);
821 return damage;
824 struct sna_damage *_sna_damage_add_boxes(struct sna_damage *damage,
828 return __sna_damage_add_boxes(damage, b, n, dx, dy);
833 __sna_damage_add_rectangles(struct sna_damage *damage,
867 return __sna_damage_add_box(damage, &extents);
869 if (!damage) {
870 damage = _sna_damage_create();
871 if (damage == NULL)
873 } else switch (damage->mode) {
875 return damage;
877 __sna_damage_reduce(damage);
882 if (pixman_region_contains_rectangle(&damage->region,
884 return damage;
886 damage_union(damage, &extents);
887 return _sna_damage_create_elt_from_rectangles(damage, r, n, dx, dy);
891 struct sna_damage *_sna_damage_add_rectangles(struct sna_damage *damage,
898 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
901 damage = __sna_damage_add_rectangles(damage, r, n, dx, dy);
904 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)));
905 if (region_num_rects(&damage->region)) {
906 assert(damage->region.extents.x2 > damage->region.extents.x1);
907 assert(damage->region.extents.y2 > damage->region.extents.y1);
910 return damage;
913 struct sna_damage *_sna_damage_add_rectangles(struct sna_damage *damage,
917 return __sna_damage_add_rectangles(damage, r, n, dx, dy);
923 __sna_damage_add_points(struct sna_damage *damage,
951 return __sna_damage_add_box(damage, &extents);
953 if (!damage) {
954 damage = _sna_damage_create();
955 if (damage == NULL)
957 } else switch (damage->mode) {
959 return damage;
961 __sna_damage_reduce(damage);
966 if (pixman_region_contains_rectangle(&damage->region,
968 return damage;
970 damage_union(damage, &extents);
971 return _sna_damage_create_elt_from_points(damage, p, n, dx, dy);
975 struct sna_damage *_sna_damage_add_points(struct sna_damage *damage,
982 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
985 damage = __sna_damage_add_points(damage, p, n, dx, dy);
988 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)));
989 if (region_num_rects(&damage->region)) {
990 assert(damage->region.extents.x2 > damage->region.extents.x1);
991 assert(damage->region.extents.y2 > damage->region.extents.y1);
994 return damage;
997 struct sna_damage *_sna_damage_add_points(struct sna_damage *damage,
1001 return __sna_damage_add_points(damage, p, n, dx, dy);
1006 fastcall struct sna_damage *_sna_damage_add_box(struct sna_damage *damage,
1012 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
1015 damage = __sna_damage_add_box(damage, box);
1018 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)));
1019 assert(region_num_rects(&damage->region));
1020 assert(damage->region.extents.x2 > damage->region.extents.x1);
1021 assert(damage->region.extents.y2 > damage->region.extents.y1);
1023 return damage;
1026 fastcall struct sna_damage *_sna_damage_add_box(struct sna_damage *damage,
1029 return __sna_damage_add_box(damage, box);
1033 struct sna_damage *__sna_damage_all(struct sna_damage *damage,
1038 if (damage) {
1039 pixman_region_fini(&damage->region);
1040 free_list(&damage->embedded_box.list);
1041 reset_embedded_box(damage);
1043 damage = _sna_damage_create();
1044 if (damage == NULL)
1048 pixman_region_init_rect(&damage->region, 0, 0, width, height);
1049 damage->extents = damage->region.extents;
1050 damage->mode = DAMAGE_ALL;
1052 return damage;
1055 struct sna_damage *_sna_damage_is_all(struct sna_damage *damage,
1059 damage->dirty ? "*" : ""));
1061 damage->extents.x1, damage->extents.y1,
1062 damage->extents.x2, damage->extents.y2));
1064 assert(damage->mode == DAMAGE_ADD);
1065 assert(damage->extents.x1 == 0 &&
1066 damage->extents.y1 == 0 &&
1067 damage->extents.x2 == width &&
1068 damage->extents.y2 == height);
1070 if (damage->dirty) {
1071 __sna_damage_reduce(damage);
1072 assert(RegionNotEmpty(&damage->region));
1075 if (damage->region.data) {
1077 return damage;
1080 assert(damage->extents.x1 == 0 &&
1081 damage->extents.y1 == 0 &&
1082 damage->extents.x2 == width &&
1083 damage->extents.y2 == height);
1085 return __sna_damage_all(damage, width, height);
1099 static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage,
1102 if (damage == NULL)
1105 if (RegionNil(&damage->region)) {
1107 __sna_damage_destroy(damage);
1113 if (!sna_damage_overlaps_box(damage, ®ion->extents))
1114 return damage;
1117 box_contains(®ion->extents, &damage->extents))
1120 if (damage->mode == DAMAGE_ALL) {
1121 pixman_region_subtract(&damage->region,
1122 &damage->region,
1124 if (damage->region.extents.x2 <= damage->region.extents.x1 ||
1125 damage->region.extents.y2 <= damage->region.extents.y1)
1128 damage->extents = damage->region.extents;
1129 damage->mode = DAMAGE_ADD;
1130 return damage;
1133 if (damage->mode != DAMAGE_SUBTRACT) {
1134 if (damage->dirty) {
1135 __sna_damage_reduce(damage);
1136 assert(RegionNotEmpty(&damage->region));
1139 if (pixman_region_equal(region, &damage->region))
1142 if (region_is_singular(&damage->region) &&
1144 pixman_region_subtract(&damage->region,
1145 &damage->region,
1147 if (damage->region.extents.x2 <= damage->region.extents.x1 ||
1148 damage->region.extents.y2 <= damage->region.extents.y1)
1151 damage->extents = damage->region.extents;
1152 assert(pixman_region_not_empty(&damage->region));
1153 return damage;
1156 damage->mode = DAMAGE_SUBTRACT;
1159 return _sna_damage_create_elt(damage,
1165 fastcall struct sna_damage *_sna_damage_subtract(struct sna_damage *damage,
1172 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
1175 damage = __sna_damage_subtract(damage, region);
1178 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)));
1180 return damage;
1183 fastcall struct sna_damage *_sna_damage_subtract(struct sna_damage *damage,
1186 return __sna_damage_subtract(damage, region);
1190 inline static struct sna_damage *__sna_damage_subtract_box(struct sna_damage *damage,
1195 if (damage == NULL)
1198 if (RegionNil(&damage->region)) {
1199 __sna_damage_destroy(damage);
1203 if (!sna_damage_overlaps_box(damage, box))
1204 return damage;
1206 if (box_contains(box, &damage->extents)) {
1207 __sna_damage_destroy(damage);
1211 if (damage->mode != DAMAGE_SUBTRACT) {
1212 if (damage->dirty) {
1213 __sna_damage_reduce(damage);
1214 assert(RegionNotEmpty(&damage->region));
1217 if (region_is_singular(&damage->region)) {
1221 pixman_region_subtract(&damage->region,
1222 &damage->region,
1224 damage->extents = damage->region.extents;
1225 damage->mode = DAMAGE_ADD;
1226 return damage;
1229 damage->mode = DAMAGE_SUBTRACT;
1232 return _sna_damage_create_elt(damage, box, 1);
1236 fastcall struct sna_damage *_sna_damage_subtract_box(struct sna_damage *damage,
1242 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
1245 damage = __sna_damage_subtract_box(damage, box);
1248 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)));
1250 return damage;
1253 fastcall struct sna_damage *_sna_damage_subtract_box(struct sna_damage *damage,
1256 return __sna_damage_subtract_box(damage, box);
1260 static struct sna_damage *__sna_damage_subtract_boxes(struct sna_damage *damage,
1267 if (damage == NULL)
1270 if (RegionNil(&damage->region)) {
1271 __sna_damage_destroy(damage);
1298 if (!sna_damage_overlaps_box(damage, &extents))
1299 return damage;
1302 return __sna_damage_subtract_box(damage, &extents);
1304 if (damage->mode != DAMAGE_SUBTRACT) {
1305 if (damage->dirty) {
1306 __sna_damage_reduce(damage);
1307 assert(RegionNotEmpty(&damage->region));
1310 damage->mode = DAMAGE_SUBTRACT;
1313 return _sna_damage_create_elt_from_boxes(damage, box, n, dx, dy);
1317 fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage,
1324 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
1329 damage = __sna_damage_subtract_boxes(damage, box, n, dx, dy);
1332 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)));
1334 return damage;
1337 fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage,
1341 return __sna_damage_subtract_boxes(damage, box, n, dx, dy);
1348 struct sna_damage *damage = *_damage;
1352 if (damage->mode == DAMAGE_ALL)
1355 if (!sna_damage_overlaps_box(damage, box))
1358 ret = pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
1359 if (!damage->dirty)
1362 if (damage->mode == DAMAGE_ADD) {
1366 count = damage->embedded_box.size;
1367 if (list_is_empty(&damage->embedded_box.list))
1368 count -= damage->remain;
1370 b = damage->embedded_box.box;
1379 count = damage->embedded_box.size;
1380 if (list_is_empty(&damage->embedded_box.list))
1381 count -= damage->remain;
1383 b = damage->embedded_box.box;
1390 __sna_damage_reduce(damage);
1391 if (!pixman_region_not_empty(&damage->region)) {
1392 __sna_damage_destroy(damage);
1397 return pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
1401 int _sna_damage_contains_box(struct sna_damage **damage,
1408 _debug_describe_damage(damage_buf, sizeof(damage_buf), *damage),
1411 ret = __sna_damage_contains_box(damage, box);
1421 int _sna_damage_contains_box(struct sna_damage **damage,
1424 return __sna_damage_contains_box(damage, box);
1434 bool _sna_damage_contains_box__no_reduce(const struct sna_damage *damage,
1440 assert(damage && damage->mode != DAMAGE_ALL);
1441 if (!box_contains(&damage->extents, box))
1444 n = pixman_region_contains_rectangle((pixman_region16_t *)&damage->region, (BoxPtr)box);
1445 if (!damage->dirty)
1448 if (damage->mode == DAMAGE_ADD) {
1452 count = damage->embedded_box.size;
1453 if (list_is_empty(&damage->embedded_box.list))
1454 count -= damage->remain;
1456 b = damage->embedded_box.box;
1467 if (!list_is_empty(&damage->embedded_box.list))
1470 count = damage->embedded_box.size - damage->remain;
1471 b = damage->embedded_box.box;
1481 static bool __sna_damage_intersect(struct sna_damage *damage,
1484 assert(damage && damage->mode != DAMAGE_ALL);
1487 if (region->extents.x2 <= damage->extents.x1 ||
1488 region->extents.x1 >= damage->extents.x2)
1491 if (region->extents.y2 <= damage->extents.y1 ||
1492 region->extents.y1 >= damage->extents.y2)
1495 if (damage->dirty)
1496 __sna_damage_reduce(damage);
1498 if (!pixman_region_not_empty(&damage->region))
1502 RegionIntersect(result, &damage->region, region);
1508 bool _sna_damage_intersect(struct sna_damage *damage,
1516 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
1519 ret = __sna_damage_intersect(damage, region, result);
1529 bool _sna_damage_intersect(struct sna_damage *damage,
1532 return __sna_damage_intersect(damage, region, result);
1536 static int __sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes)
1538 assert(damage && damage->mode != DAMAGE_ALL);
1540 if (damage->dirty)
1541 __sna_damage_reduce(damage);
1543 assert(!damage->dirty);
1544 assert(damage->mode == DAMAGE_ADD);
1546 *boxes = region_rects(&damage->region);
1547 return region_num_rects(&damage->region);
1550 struct sna_damage *_sna_damage_reduce(struct sna_damage *damage)
1554 __sna_damage_reduce(damage);
1556 assert(!damage->dirty);
1557 assert(damage->mode == DAMAGE_ADD);
1559 if (!pixman_region_not_empty(&damage->region)) {
1560 __sna_damage_destroy(damage);
1561 damage = NULL;
1564 return damage;
1568 int _sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes)
1574 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)));
1576 count = __sna_damage_get_boxes(damage, boxes);
1582 int _sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes)
1584 return __sna_damage_get_boxes(damage, boxes);
1603 void __sna_damage_destroy(struct sna_damage *damage)
1605 free_list(&damage->embedded_box.list);
1607 pixman_region_fini(&damage->region);
1608 *(void **)damage = __freed_damage;
1609 __freed_damage = damage;
1666 struct sna_damage **damage,
1673 if (!DAMAGE_IS_ALL(*damage))
1674 sna_damage_add(damage, &tmp);
1679 struct sna_damage **damage,
1687 if (!DAMAGE_IS_ALL(*damage))
1688 sna_damage_add_box(damage, &r.extents);
1693 struct sna_damage **damage,
1700 sna_damage_subtract(damage, &tmp);
1705 struct sna_damage **damage,
1713 sna_damage_subtract_box(damage, &r.extents);
1718 struct sna_damage **damage,
1725 if (!DAMAGE_IS_ALL(*damage))
1726 sna_damage_all(damage, test->width, test->height);
1731 struct sna_damage **damage,
1737 d_num = *damage ? sna_damage_get_boxes(*damage, &d_boxes) : 0;
1741 ERR(("%s: damage and ref contain different number of rectangles\n",
1747 ERR(("%s: damage and ref contain different rectangles\n",
1758 struct sna_damage **damage,
1767 struct sna_damage **damage,
1778 struct sna_damage *damage;
1788 damage = _sna_damage_create();
1792 op[rand() % ARRAY_SIZE(op)](&test, &damage, &ref);
1795 if (!check[rand() % ARRAY_SIZE(check)](&test, &damage, &ref)) {
1796 FatalError("%s: failed - region = %s, damage = %s\n", __FUNCTION__,
1798 _debug_describe_damage(damage_buf, sizeof(damage_buf), damage));
1802 sna_damage_destroy(&damage);
1807 void _sna_damage_debug_get_region(struct sna_damage *damage, RegionRec *r)
1813 RegionCopy(r, &damage->region);
1814 if (!damage->dirty)
1817 nboxes = damage->embedded_box.size;
1818 list_for_each_entry(iter, &damage->embedded_box.list, list)
1820 nboxes -= damage->remain;
1827 tmp.extents = damage->embedded_box.box[0];
1830 if (damage->mode == DAMAGE_ADD)
1838 if (damage->mode == DAMAGE_ADD)
1841 iter = last_box(damage);
1842 n = iter->size - damage->remain;
1847 if (list_is_empty(&damage->embedded_box.list)) {
1849 damage->embedded_box.box,
1858 while (&iter->list != &damage->embedded_box.list) {
1869 damage->embedded_box.box,
1870 sizeof(damage->embedded_box.box));
1871 n += damage->embedded_box.size;
1874 if (damage->mode == DAMAGE_ADD) {
1883 assert(damage->extents.x1 == r->extents.x1 &&
1884 damage->extents.y1 == r->extents.y1 &&
1885 damage->extents.x2 == r->extents.x2 &&
1886 damage->extents.y2 == r->extents.y2);
1894 assert(damage->extents.x1 <= r->extents.x1 &&
1895 damage->extents.y1 <= r->extents.y1 &&
1896 damage->extents.x2 >= r->extents.x2 &&
1897 damage->extents.y2 >= r->extents.y2);