diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-07-01 22:26:29 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-07-01 22:51:22 +0100 |
commit | ad0afda3fe4f5e408e3610d8b76fdc7d1af33138 (patch) | |
tree | a588f276d96da1662c6a2f987eaba0427636f0fb | |
parent | 1c8a33a72e29261d6bf5a6c160765cbafa4d0b88 (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.h | 2 | ||||
-rw-r--r-- | src/sna/sna_damage.c | 42 |
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; |