From 9b3b591476cc52cc285a8a1f02462db37d5e10c2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 19 Dec 2014 12:25:30 +0000 Subject: sna/dri2: Preserve the shadow CRTCs when copying to other areas In the Composite setup, if we are doing a DRI2 copy onto the front buffer, we are fully cognizant that the copy will not go onto the unredirected Windows of another Client. So we can preserve the shadow CRTC mapping for those Clients, and prevent ping-ponging between CRTC modes. Signed-off-by: Chris Wilson --- src/sna/sna.h | 2 ++ src/sna/sna_display.c | 48 +++++++++++++++++++++++++++++++++++++++--------- src/sna/sna_dri2.c | 6 ++++++ 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/sna/sna.h b/src/sna/sna.h index 3116f116..18425e30 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -428,6 +428,8 @@ extern void sna_mode_reset(struct sna *sna); extern int sna_mode_wakeup(struct sna *sna); extern void sna_mode_redisplay(struct sna *sna); extern void sna_shadow_set_crtc(struct sna *sna, xf86CrtcPtr crtc, struct kgem_bo *bo); +extern void sna_shadow_steal_crtcs(struct sna *sna, struct list *list); +extern void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list); extern void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc); extern bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv, const RegionRec *region); diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index c31c68f2..e9fecef7 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -1114,14 +1114,13 @@ static bool wait_for_shadow(struct sna *sna, if ((flags & MOVE_WRITE) == 0) { 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); + struct sna_crtc *crtc; + + list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) { if (overlap(&sna->mode.shadow_region.extents, &crtc->base->bounds)) { DrawableRec draw; + RegionRec region; draw.width = crtc->base->mode.HDisplay; draw.height = crtc->base->mode.VDisplay; @@ -1141,11 +1140,11 @@ static bool wait_for_shadow(struct sna *sna, &pixmap->drawable, priv->gpu_bo, 0, 0, &crtc->base->bounds, 1, 0); - } - kgem_bo_destroy(&sna->kgem, crtc->client_bo); - crtc->client_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); + } } } @@ -6915,6 +6914,37 @@ void sna_shadow_set_crtc(struct sna *sna, priv->move_to_gpu_data = sna; } +void sna_shadow_steal_crtcs(struct sna *sna, struct list *list) +{ + list_init(list); + while (!list_is_empty(&sna->mode.shadow_crtc)) { + RegionRec sub, *damage; + struct sna_crtc *crtc = + list_first_entry(&sna->mode.shadow_crtc, + struct sna_crtc, + shadow_link); + + damage = DamageRegion(sna->mode.shadow_damage); + sub.extents = crtc->base->bounds; + sub.data = NULL; + RegionSubtract(damage, damage, &sub); + + list_move(&crtc->shadow_link, list); + } +} + +void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list) +{ + while (!list_is_empty(list)) { + struct sna_crtc *crtc = + list_first_entry(list, + struct sna_crtc, + shadow_link); + assert(crtc->client_bo); + sna_shadow_set_crtc(sna, crtc->base, crtc->client_bo); + } +} + void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc) { diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 75e85a3c..430c99ec 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -1006,6 +1006,10 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, assert(dst_bo->refcnt); if (is_front(dst->attachment)) { struct sna_pixmap *priv; + struct list shadow; + + /* Preserve the CRTC shadow overrides */ + sna_shadow_steal_crtcs(sna, &shadow); flags = MOVE_WRITE | __MOVE_FORCE; if (clip.data) @@ -1020,6 +1024,8 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, DBG(("%s: updated FrontLeft dst_bo from handle=%d to handle=%d\n", __FUNCTION__, dst_priv->bo->handle, dst_bo->handle)); assert(dst_bo->refcnt); + + sna_shadow_unsteal_crtcs(sna, &shadow); } else { RegionRec target; -- cgit v1.2.3