From ad0afda3fe4f5e408e3610d8b76fdc7d1af33138 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 1 Jul 2013 22:26:29 +0100 Subject: [PATCH] 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 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 --- src/intel_list.h | 2 +- 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;