summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-07-01 22:26:29 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-07-01 22:51:22 +0100
commitad0afda3fe4f5e408e3610d8b76fdc7d1af33138 (patch)
treea588f276d96da1662c6a2f987eaba0427636f0fb
parent1c8a33a72e29261d6bf5a6c160765cbafa4d0b88 (diff)
sna: Fix checking the dirty boxes
I forgot how insane the data structure for the list of dirty boxes attached to the damage is. It is neither a simple list, nor does not store the count of boxes within each chunk. Fixes regression from commit 9026bb954646c0425360c2236e26c79d097142cd [2.21.11] Author: Chris Wilson <chris@chris-wilson.co.uk> Date: Fri Jun 28 15:59:17 2013 +0100 sna: Inspect the dirty boxes when querying whether damage contains a rectangle A side effect is that we now make sure that there is an upper bound to the amount of searching we do for the no-reduce fast path. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66430 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/intel_list.h2
-rw-r--r--src/sna/sna_damage.c42
2 files changed, 21 insertions, 23 deletions
diff --git a/src/intel_list.h b/src/intel_list.h
index cfaa1ad3..de0b6837 100644
--- a/src/intel_list.h
+++ b/src/intel_list.h
@@ -264,7 +264,7 @@ static inline void list_move_tail(struct list *list, struct list *head)
* @return True if the list contains one or more elements or False otherwise.
*/
static inline bool
-list_is_empty(struct list *head)
+list_is_empty(const struct list *head)
{
return head->next == head;
}
diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index d2a876db..30cc83b3 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -1341,46 +1341,44 @@ static bool box_overlaps(const BoxRec *a, const BoxRec *b)
bool _sna_damage_contains_box__no_reduce(const struct sna_damage *damage,
const BoxRec *box)
{
- struct sna_damage_box *iter;
- int ret;
+ int n, count;
+ BoxPtr b;
assert(damage && damage->mode != DAMAGE_ALL);
if (!box_contains(&damage->extents, box))
return false;
- ret = pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
+ n = pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
if (!damage->dirty)
- return ret == PIXMAN_REGION_IN;
+ return n == PIXMAN_REGION_IN;
if (damage->mode == DAMAGE_ADD) {
- if (ret == PIXMAN_REGION_IN)
+ if (n == PIXMAN_REGION_IN)
return true;
- list_for_each_entry(iter, &damage->embedded_box.list, list) {
- BoxPtr b;
- int n;
+ count = damage->embedded_box.size;
+ if (list_is_empty(&damage->embedded_box.list))
+ count -= damage->remain;
- b = (BoxPtr)(iter + 1);
- for (n = 0; n < iter->size; n++) {
- if (box_contains(&b[n], box))
- return true;
- }
+ b = damage->embedded_box.box;
+ for (n = 0; n < count; n++) {
+ if (box_contains(&b[n], box))
+ return true;
}
return false;
} else {
- if (ret != PIXMAN_REGION_IN)
+ if (n != PIXMAN_REGION_IN)
return false;
- list_for_each_entry(iter, &damage->embedded_box.list, list) {
- BoxPtr b;
- int n;
+ if (!list_is_empty(&damage->embedded_box.list))
+ return false;
- b = (BoxPtr)(iter + 1);
- for (n = 0; n < iter->size; n++) {
- if (box_overlaps(&b[n], box))
- return false;
- }
+ count = damage->embedded_box.size - damage->remain;
+ b = damage->embedded_box.box;
+ for (n = 0; n < count; n++) {
+ if (box_overlaps(&b[n], box))
+ return false;
}
return true;