diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-13 10:03:28 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-13 10:15:56 +0000 |
commit | 94217a4dd908f1368dfdef90797ce74a081663fb (patch) | |
tree | c0fa6186e299184a87b2e0f3bcbe386de4f667d9 /src | |
parent | 65ef369c733ab45945a7d5fe4b76fe5c7167b51b (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.c | 11 |
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); |