diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-08 11:45:11 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-08 14:34:01 +0000 |
commit | 26042b2660d87044e1920a1267d9984c00c9566a (patch) | |
tree | 9a398054f22fec0ab7b5afc8477a49ebac485e7f | |
parent | 3f7ea44bf19a03ee81b683885c9c2416092254a3 (diff) |
sna: Bubble sort the partial buffer list back into order after trimming padding
After reducing the used size in the partial buffer, we need to resort
the list to maintain the list in decreasing amount of available space.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 08d4db70..0c1b2b1d 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -2163,6 +2163,9 @@ static void _kgem_bo_delete_partial(struct kgem *kgem, struct kgem_bo *bo) if (list_is_empty(&io->base.list)) return; + DBG(("%s: size=%d, offset=%d, parent used=%d\n", + __FUNCTION__, bo->size, bo->delta, io->used)); + if (bo->size == io->used) { assert(io->base.exec == NULL); assert(io->base.refcnt >= 2); @@ -2976,12 +2979,41 @@ struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem, return NULL; if (height & 1) { + struct kgem_partial_bo *io = (struct kgem_partial_bo *)bo->proxy; + int remain; + /* Having padded this surface to ensure that accesses to * the last pair of rows is valid, remove the padding so * that it can be allocated to other pixmaps. */ - ((struct kgem_partial_bo *)bo->proxy)->used -= stride; + io->used -= stride; bo->size -= stride; + + /* And bubble-sort the partial back into place */ + remain = io->alloc - io->used; + while (io->base.list.prev != &kgem->partial) { + struct kgem_partial_bo *p; + + p = list_entry(io->base.list.prev, + struct kgem_partial_bo, + base.list); + if (remain <= p->alloc - p->used) + break; + + assert(p->base.list.next == &io->base.list); + io->base.list.prev = p->base.list.prev; + p->base.list.prev->next = &io->base.list; + p->base.list.prev = &io->base.list; + + p->base.list.next = io->base.list.next; + io->base.list.next->prev = &p->base.list; + io->base.list.next = &p->base.list; + + assert(p->base.list.next->prev == &p->base.list); + assert(io->base.list.prev->next == &io->base.list); + } + + assert(validate_partials(kgem)); } bo->pitch = stride; |