diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-06-19 09:47:02 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-06-19 09:47:02 +0100 |
commit | b1aab55d594f03e51c3abf1743d00c56ef6d7797 (patch) | |
tree | 7a6c70a6e6592c4fe83dfb8c8b031754c6cd8dfc /src | |
parent | f4b930318c68e0e07d677ebc7b4caa27912561db (diff) |
sna: Always readback shadow damage after replacing the buffer
Instead track what we explicitly want to discard for the next operation,
so that we don't have to copy back the whole buffer if we have to
replace the shadow and intend to overwrite it all.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/sna.h | 1 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 15 | ||||
-rw-r--r-- | src/sna/sna_display.c | 109 |
3 files changed, 84 insertions, 41 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 76869444..1985ad84 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -290,6 +290,7 @@ struct sna { int max_crtc_width, max_crtc_height; RegionRec shadow_region; + RegionRec shadow_cancel; struct list shadow_crtc; bool shadow_dirty; diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index f53bddee..77d15df0 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -3726,17 +3726,16 @@ use_gpu_bo: if (flags & IGNORE_CPU) { region.extents = *box; region.data = NULL; + if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { + region.extents.x1 += dx; + region.extents.x2 += dx; + region.extents.y1 += dy; + region.extents.y2 += dy; + } + sna_pixmap_discard_shadow_damage(priv, ®ion); if (region_subsumes_pixmap(®ion, pixmap)) { DBG(("%s: discarding move-to-gpu READ for subsumed pixmap\n", __FUNCTION__)); hint = MOVE_WRITE; - } else { - if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { - region.extents.x1 += dx; - region.extents.x2 += dx; - region.extents.y1 += dy; - region.extents.y2 += dy; - } - sna_pixmap_discard_shadow_damage(priv, ®ion); } } diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index b62fda15..c5407990 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -1038,7 +1038,24 @@ sna_crtc_apply(xf86CrtcPtr crtc) return true; } -static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) +static bool overlap(const BoxRec *a, const BoxRec *b) +{ + if (a->x1 >= b->x2) + return false; + if (a->x2 <= b->x1) + return false; + + if (a->y1 >= b->y2) + return false; + if (a->y2 <= b->y1) + return false; + + return true; +} + +static bool wait_for_shadow(struct sna *sna, + struct sna_pixmap *priv, + unsigned flags) { PixmapPtr pixmap = priv->pixmap; DamagePtr damage; @@ -1059,20 +1076,25 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f if ((flags & __MOVE_SCANOUT) == 0) { while (!list_is_empty(&sna->mode.shadow_crtc)) { struct sna_crtc *crtc = - list_first_entry(&sna->mode.shadow_crtc, struct sna_crtc, shadow_link); - - DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n", - __FUNCTION__, - crtc->base->bounds.x1, - crtc->base->bounds.y1, - crtc->base->bounds.x2, - crtc->base->bounds.y2, - crtc->shadow_bo->handle)); - ret &= sna->render.copy_boxes(sna, GXcopy, - pixmap, crtc->shadow_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, - pixmap, priv->gpu_bo, 0, 0, - &crtc->base->bounds, 1, - 0); + list_first_entry(&sna->mode.shadow_crtc, + struct sna_crtc, + shadow_link); + if (overlap(&sna->mode.shadow_region.extents, + &crtc->base->bounds)) { + DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n", + __FUNCTION__, + crtc->base->bounds.x1, + crtc->base->bounds.y1, + crtc->base->bounds.x2, + crtc->base->bounds.y2, + crtc->shadow_bo->handle)); + + ret &= sna->render.copy_boxes(sna, GXcopy, + pixmap, crtc->shadow_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, + pixmap, priv->gpu_bo, 0, 0, + &crtc->base->bounds, 1, + 0); + } kgem_bo_destroy(&sna->kgem, crtc->shadow_bo); crtc->shadow_bo = NULL; @@ -1141,34 +1163,43 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f sna->mode.shadow_damage = damage; + RegionSubtract(&sna->mode.shadow_region, + &sna->mode.shadow_region, + &sna->mode.shadow_cancel); + while (!list_is_empty(&sna->mode.shadow_crtc)) { struct sna_crtc *crtc = list_first_entry(&sna->mode.shadow_crtc, struct sna_crtc, shadow_link); - RegionRec region; + if (overlap(&crtc->base->bounds, + &sna->mode.shadow_region.extents)) { + RegionRec region; - DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n", - __FUNCTION__, - crtc->base->bounds.x1, - crtc->base->bounds.y1, - crtc->base->bounds.x2, - crtc->base->bounds.y2, - crtc->shadow_bo->handle)); - ret = sna->render.copy_boxes(sna, GXcopy, - pixmap, crtc->shadow_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, - pixmap, bo, 0, 0, - &crtc->base->bounds, 1, - 0); + DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n", + __FUNCTION__, + crtc->base->bounds.x1, + crtc->base->bounds.y1, + crtc->base->bounds.x2, + crtc->base->bounds.y2, + crtc->shadow_bo->handle)); + + ret = sna->render.copy_boxes(sna, GXcopy, + pixmap, crtc->shadow_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, + pixmap, bo, 0, 0, + &crtc->base->bounds, 1, + 0); + + + region.extents = crtc->base->bounds; + region.data = NULL; + RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, ®ion); + } kgem_bo_destroy(&sna->kgem, crtc->shadow_bo); crtc->shadow_bo = NULL; list_del(&crtc->shadow_link); - - region.extents = crtc->base->bounds; - region.data = NULL; - RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, ®ion); } - if (flags & MOVE_READ && RegionNotEmpty(&sna->mode.shadow_region)) { + if (RegionNotEmpty(&sna->mode.shadow_region)) { DBG(("%s: copying existing GPU damage: %dx(%d, %d), (%d, %d)\n", __FUNCTION__, region_num_rects(&sna->mode.shadow_region), sna->mode.shadow_region.extents.x1, @@ -1198,6 +1229,7 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f sna_dri2_pixmap_update_bo(sna, pixmap, bo); done: + RegionEmpty(&sna->mode.shadow_cancel); RegionEmpty(&sna->mode.shadow_region); sna->mode.shadow_dirty = false; @@ -1229,12 +1261,22 @@ bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv, RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, (RegionPtr)region); + RegionUnion(&sna->mode.shadow_cancel, + &sna->mode.shadow_cancel, + (RegionPtr)region); } else { DBG(("%s: discarding all damage %dx[(%d, %d], (%d, %d)]\n", region_num_rects(&sna->mode.shadow_region), sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1, sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2)); RegionEmpty(&sna->mode.shadow_region); + + RegionUninit(&sna->mode.shadow_cancel); + sna->mode.shadow_cancel.extents.x1 = 0; + sna->mode.shadow_cancel.extents.y1 = 0; + sna->mode.shadow_cancel.extents.x2 = sna->front->drawable.width; + sna->mode.shadow_cancel.extents.y2 = sna->front->drawable.height; + sna->mode.shadow_cancel.data = NULL; } return RegionNil(&sna->mode.shadow_region); @@ -5172,6 +5214,7 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna) sna->mode.max_crtc_height = res->max_height; RegionEmpty(&sna->mode.shadow_region); + RegionEmpty(&sna->mode.shadow_cancel); list_init(&sna->mode.shadow_crtc); drmModeFreeResources(res); |