summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-13 10:03:28 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-13 10:15:56 +0000
commit94217a4dd908f1368dfdef90797ce74a081663fb (patch)
treec0fa6186e299184a87b2e0f3bcbe386de4f667d9 /src
parent65ef369c733ab45945a7d5fe4b76fe5c7167b51b (diff)
sna: Decouple dirty pixmaps from list if we fail to upload them
Rather than iterate endlessly trying to upload the same pixmap when failing to flush dirty CPU damage, try again on the next flush. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/sna/sna_accel.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e0709b6d..9f606051 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -9657,6 +9657,7 @@ sna_accel_flush_callback(CallbackListPtr *list,
pointer user_data, pointer call_data)
{
struct sna *sna = user_data;
+ struct list preserve;
if ((sna->kgem.sync|sna->kgem.flush) == 0 &&
list_is_empty(&sna->dirty_pixmaps))
@@ -9665,12 +9666,20 @@ sna_accel_flush_callback(CallbackListPtr *list,
DBG(("%s\n", __FUNCTION__));
/* flush any pending damage from shadow copies to tfp clients */
+ list_init(&preserve);
while (!list_is_empty(&sna->dirty_pixmaps)) {
struct sna_pixmap *priv = list_first_entry(&sna->dirty_pixmaps,
struct sna_pixmap,
list);
assert(priv->cpu_damage != NULL);
- sna_pixmap_move_to_gpu(priv->pixmap, MOVE_READ);
+ if (!sna_pixmap_move_to_gpu(priv->pixmap, MOVE_READ))
+ list_move(&priv->list, &preserve);
+ }
+ if (!list_is_empty(&preserve)) {
+ sna->dirty_pixmaps.next = preserve.next;
+ preserve.next->prev = &sna->dirty_pixmaps;
+ preserve.prev->next = &sna->dirty_pixmaps;
+ sna->dirty_pixmaps.prev = preserve.prev;
}
kgem_submit(&sna->kgem);