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 9026bb9546 [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>
This commit is contained in:
parent
1c8a33a72e
commit
ad0afda3fe
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue