xf86-video-intel: 8 commits - src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_dri2.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Sat Dec 20 05:49:49 PST 2014


 src/sna/sna.h         |    4 ++
 src/sna/sna_accel.c   |   21 +++++++----
 src/sna/sna_display.c |   93 ++++++++++++++++++++++++++++++++++++++++----------
 src/sna/sna_dri2.c    |   64 +++++++++++++++++++++++++---------
 4 files changed, 141 insertions(+), 41 deletions(-)

New commits:
commit 01ce7efe73538047abd38bbbb95fc4012ebeb9b4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 20 13:36:50 2014 +0000

    sna: Fix Drawable offsets prior to performing shadow discard
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 5920769..baf5f60 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2704,6 +2704,13 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
 	}
 
+	assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL || (flags & MOVE_WRITE) == 0);
+
+	if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
+		DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy));
+		RegionTranslate(region, dx, dy);
+	}
+
 	if (priv->move_to_gpu) {
 		DBG(("%s: applying move-to-gpu override\n", __FUNCTION__));
 		if ((flags & MOVE_READ) == 0)
@@ -2714,13 +2721,6 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		}
 	}
 
-	assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL || (flags & MOVE_WRITE) == 0);
-
-	if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
-		DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy));
-		RegionTranslate(region, dx, dy);
-	}
-
 	if (operate_inplace(priv, flags) &&
 	    region_inplace(sna, pixmap, region, priv, flags) &&
 	    sna_pixmap_create_mappable_gpu(pixmap, false)) {
commit c27e6306e86797553351a71e2917a9b1158ec388
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 20 12:46:52 2014 +0000

    sna/dri2: Check for implicit flushing after updating a Pixmap buffer
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 430c99e..e5c4d53 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -432,6 +432,8 @@ sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo)
 
 	DBG(("%s: adding flush hint to handle=%d\n", __FUNCTION__, bo->handle));
 	bo->flush = true;
+	if (bo->exec)
+		sna->kgem.flush = 1;
 	assert(sna_pixmap(pixmap)->flush);
 
 	/* XXX DRI2InvalidateDrawable(&pixmap->drawable); */
commit 5c16a4ec9b59123336483238ee6017db5491e255
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 20 09:38:41 2014 +0000

    sna: Skip allocation of new TearFree buffer if not actually flipping
    
    After showing the new front buffer, we have to avoid writing to the back
    buffer whilst the flip is still pending (as it may still be being shown
    by the display). To do this we check if there are any outstanding flips,
    and reallocate if so. However, with a CRTC override, we may just be
    flipping that one CRTC and not the current TearFree back buffer and in
    that case we can avoid the reallocation.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index e9fecef..4b218b7 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -127,6 +127,7 @@ struct sna_crtc {
 	bool shadow;
 	bool fallback_shadow;
 	bool transform;
+	bool flip_pending;
 	uint8_t id;
 	uint8_t pipe;
 
@@ -1100,6 +1101,7 @@ static bool wait_for_shadow(struct sna *sna,
 	PixmapPtr pixmap = priv->pixmap;
 	DamagePtr damage;
 	struct kgem_bo *bo, *tmp;
+	int flip_active;
 	bool ret = true;
 
 	DBG(("%s: flags=%x, flips=%d, handle=%d, shadow=%d\n",
@@ -1156,17 +1158,32 @@ static bool wait_for_shadow(struct sna *sna,
 	damage = sna->mode.shadow_damage;
 	sna->mode.shadow_damage = NULL;
 
-	if (sna->mode.flip_active) {
+	flip_active = sna->mode.flip_active;
+	if (flip_active) {
+		struct sna_crtc *crtc;
+		list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link)
+			flip_active -= crtc->flip_pending;
+		DBG(("%s: %d flips still pending, shadow flip_active=%d\n",
+		     __FUNCTION__, sna->mode.flip_active, flip_active));
+	}
+	if (flip_active) {
 		/* raw cmd to avoid setting wedged in the middle of an op */
 		drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0);
 		sna->kgem.need_throttle = false;
 
-		while (sna->mode.flip_active && sna_mode_wakeup(sna))
-			;
+		while (flip_active && sna_mode_wakeup(sna)) {
+			struct sna_crtc *crtc;
+
+			flip_active = sna->mode.flip_active;
+			list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link)
+				flip_active -= crtc->flip_pending;
+		}
+		DBG(("%s: after waiting %d flips outstanding, flip_active=%d\n",
+		     __FUNCTION__, sna->mode.flip_active, flip_active));
 	}
 
 	bo = sna->mode.shadow;
-	if (sna->mode.flip_active) {
+	if (flip_active) {
 		bo = kgem_create_2d(&sna->kgem,
 				    pixmap->drawable.width,
 				    pixmap->drawable.height,
@@ -5372,6 +5389,7 @@ retry_flip:
 			crtc->flip_bo = kgem_bo_reference(bo);
 			crtc->flip_bo->active_scanout++;
 			crtc->flip_serial = crtc->mode_serial;
+			crtc->flip_pending = true;
 			sna->mode.flip_active++;
 		}
 
@@ -7259,6 +7277,7 @@ disable1:
 				sna_crtc->flip_bo = bo;
 				sna_crtc->flip_bo->active_scanout++;
 				sna_crtc->flip_serial = sna_crtc->mode_serial;
+				sna_crtc->flip_pending = true;
 
 				sna_crtc->client_bo = kgem_bo_reference(sna_crtc->bo);
 			} else {
@@ -7400,6 +7419,7 @@ fixup_flip:
 			crtc->flip_bo = kgem_bo_reference(flip_bo);
 			crtc->flip_bo->active_scanout++;
 			crtc->flip_serial = crtc->mode_serial;
+			crtc->flip_pending = true;
 
 			{
 				struct drm_i915_gem_busy busy = { flip_bo->handle };
@@ -7482,6 +7502,7 @@ again:
 				crtc->swap.tv_sec = vbl->tv_sec;
 				crtc->swap.tv_usec = vbl->tv_usec;
 				crtc->swap.msc = msc64(crtc, vbl->sequence);
+				crtc->flip_pending = false;
 
 				assert(crtc->flip_bo);
 				assert(crtc->flip_bo->active_scanout);
commit 9b3b591476cc52cc285a8a1f02462db37d5e10c2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 19 12:25:30 2014 +0000

    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 <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 3116f11..18425e3 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 c31c68f..e9fecef 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, &region);
+				}
 			}
 		}
 
@@ -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 75e85a3..430c99e 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;
 
commit 391b50c81decd208c47c109217b2c882c064ac69
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 19 11:11:38 2014 +0000

    sna/dri2: Report changes in pitch when swapping bo
    
    As we have relaxed the pitch restriction between front/back buffers when
    swapping, we need to make sure that any change is also reported back
    along with the change in front/back names.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index c1b4e16..c31c68f 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1736,7 +1736,7 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
 	}
 
 	if (sna->flags & SNA_TEAR_FREE && to_sna_crtc(crtc)->slave_pixmap) {
-		DBG(("%s: tear-free shadow required\n", __FUNCTION__));
+		DBG(("%s: TearFree shadow required\n", __FUNCTION__));
 		return true;
 	}
 
@@ -6998,7 +6998,7 @@ void sna_mode_redisplay(struct sna *sna)
 			damage.extents = crtc->bounds;
 			damage.data = NULL;
 			RegionIntersect(&damage, &damage, region);
-			if (RegionNotEmpty(&damage)) {
+			if (!box_empty(&damage.extents)) {
 				struct kgem_bo *bo = NULL;
 
 				DBG(("%s: fallback intersects pipe=%d [(%d, %d), (%d, %d)]\n",
@@ -7138,7 +7138,13 @@ void sna_mode_redisplay(struct sna *sna)
 		damage.data = NULL;
 
 		RegionIntersect(&damage, &damage, region);
-		if (RegionNotEmpty(&damage)) {
+		DBG(("%s: crtc[%d] damage? %d[%d]: %dx[(%d, %d), (%d, %d)]\n",
+		     __FUNCTION__, i,
+		     !box_empty(&damage.extents), RegionNotEmpty(&damage),
+		     region_num_rects(&damage),
+		     damage.extents.x1, damage.extents.y1,
+		     damage.extents.x2, damage.extents.y2));
+		if (!box_empty(&damage.extents)) {
 			if (sna->flags & SNA_TEAR_FREE) {
 				struct drm_mode_crtc_page_flip arg;
 				struct kgem_bo *bo;
@@ -7242,7 +7248,7 @@ disable1:
 		struct drm_mode_crtc_page_flip arg;
 		uint32_t fb = 0;
 
-		DBG(("%s: flipping tear-free outputs, current scanout handle=%d [active?=%d], new handle=%d [active=%d]\n",
+		DBG(("%s: flipping TearFree outputs, current scanout handle=%d [active?=%d], new handle=%d [active=%d]\n",
 		     __FUNCTION__, old->handle, old->active_scanout, new->handle, new->active_scanout));
 
 		assert(new != old);
@@ -7314,7 +7320,7 @@ fixup_shadow:
 				continue;
 
 			if (flip_bo->pitch != crtc->bo->pitch || (y << 16 | x)  != crtc->offset) {
-				DBG(("%s: changing pitch (%d == %d) or offset (%x == %x)\n",
+				DBG(("%s: changing pitch (new %d =?= old %d) or offset (new %x =?= old %x)\n",
 				     __FUNCTION__,
 				     flip_bo->pitch, crtc->bo->pitch,
 				     y << 16 | x, crtc->offset));
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 7ea210d..75e85a3 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -427,6 +427,7 @@ sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo)
 	kgem_bo_destroy(&sna->kgem, private->bo);
 
 	buffer->name = kgem_bo_flink(&sna->kgem, bo);
+	buffer->pitch = bo->pitch;
 	private->bo = ref(bo);
 
 	DBG(("%s: adding flush hint to handle=%d\n", __FUNCTION__, bo->handle));
@@ -1471,6 +1472,7 @@ sna_dri2_flip(struct sna_dri2_event *info)
 	struct kgem_bo *bo = get_private(info->back)->bo;
 	struct kgem_bo *tmp_bo;
 	uint32_t tmp_name;
+	int tmp_pitch;
 
 	DBG(("%s(type=%d)\n", __FUNCTION__, info->type));
 
@@ -1494,13 +1496,16 @@ sna_dri2_flip(struct sna_dri2_event *info)
 
 	tmp_bo = get_private(info->front)->bo;
 	tmp_name = info->front->name;
+	tmp_pitch = info->front->pitch;
 
 	set_bo(info->sna->front, bo);
 
 	info->front->name = info->back->name;
+	info->front->pitch = info->back->pitch;
 	get_private(info->front)->bo = bo;
 
 	info->back->name = tmp_name;
+	info->back->pitch = tmp_pitch;
 	get_private(info->back)->bo = tmp_bo;
 	mark_stale(info->back);
 
commit ada97d27250aa09b1a27d5f6640fea011fade997
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 19 09:43:33 2014 +0000

    sna/dri2: Look for preferred CRTC for visible portion of the window
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index bd5e26d..7ea210d 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1230,19 +1230,13 @@ draw_target_seq(DrawablePtr draw, uint64_t msc)
 static xf86CrtcPtr
 sna_dri2_get_crtc(DrawablePtr draw)
 {
-	struct sna *sna = to_sna_from_drawable(draw);
-	BoxRec box;
-
 	if (draw->type == DRAWABLE_PIXMAP)
 		return NULL;
 
-	box.x1 = draw->x;
-	box.y1 = draw->y;
-	box.x2 = box.x1 + draw->width;
-	box.y2 = box.y1 + draw->height;
-
 	/* Make sure the CRTC is valid and this is the real front buffer */
-	return sna_covering_crtc(sna, &box, NULL);
+	return sna_covering_crtc(to_sna_from_drawable(draw),
+				 &((WindowPtr)draw)->clipList.extents,
+				 NULL);
 }
 
 static void
commit 6f99bbe67e6e70d5b24611c7afa0dffc5632aaab
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 19 08:37:07 2014 +0000

    sna/dri2: Prevent NULL pointer dereference of Window private
    
    In case we receive quick successive calls to DRI2GetBuffers on the same
    Window, we need to check that the private exists before dereferencing
    it.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 8f8baef..bd5e26d 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -234,7 +234,11 @@ dri2_chain(DrawablePtr d)
 	assert(priv != NULL);
 	return priv->chain;
 }
-inline static DRI2BufferPtr dri2_window_get_front(WindowPtr win) { return dri2_window(win)->front; }
+inline static DRI2BufferPtr dri2_window_get_front(WindowPtr win)
+{
+	struct dri2_window *priv = dri2_window(win);
+	return priv ? priv->front : NULL;
+}
 #else
 inline static void *dri2_window_get_front(WindowPtr win) { return NULL; }
 #endif
commit fdd7508e53043f82f9cf422fc968c6574334a667
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Dec 19 07:59:24 2014 +0000

    sna/dri2: Decouple Window cache on Pixmap changes
    
    If the Pixmap for a Window is changed (i.e. Composite
    redirection/unredirection), we also need to decouple any associated DRI2
    front buffer for the Pixmap (e.g. used for single CRTC flipping).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 3e16f7e..3116f11 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -539,6 +539,7 @@ bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen);
 void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event);
 void sna_dri2_vblank_handler(struct drm_event_vblank *event);
 void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo);
+void sna_dri2_decouple_window(WindowPtr win);
 void sna_dri2_destroy_window(WindowPtr win);
 void sna_dri2_close(struct sna *sna, ScreenPtr pScreen);
 #else
@@ -546,6 +547,7 @@ static inline bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen) { return fa
 static inline void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event) { }
 static inline void sna_dri2_vblank_handler(struct drm_event_vblank *event) { }
 static inline void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo) { }
+static inline void sna_dri2_decouple_window(WindowPtr win) { }
 static inline void sna_dri2_destroy_window(WindowPtr win) { }
 static inline void sna_dri2_close(struct sna *sna, ScreenPtr pScreen) { }
 #endif
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index c702187..5920769 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -17593,6 +17593,13 @@ sna_get_window_pixmap(WindowPtr window)
 static void
 sna_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
 {
+	DBG(("%s: window=%ld, old pixmap=%ld new pixmap=%ld\n",
+	     __FUNCTION__, window->drawable.id,
+	     get_window_pixmap(window) ? get_window_pixmap(window)->drawable.serialNumber : 0,
+	     pixmap->drawable.serialNumber));
+
+	sna_dri2_decouple_window(window);
+
 	*(PixmapPtr *)__get_private(window, sna_window_key) = pixmap;
 }
 
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index d0760fc..8f8baef 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -446,10 +446,11 @@ sna_dri2_create_buffer(DrawablePtr draw,
 	uint32_t size;
 	int bpp;
 
-	DBG(("%s pixmap=%ld, (attachment=%d, format=%d, drawable=%dx%d)\n",
+	DBG(("%s pixmap=%ld, (attachment=%d, format=%d, drawable=%dx%d), window?=%d\n",
 	     __FUNCTION__,
 	     get_drawable_pixmap(draw)->drawable.serialNumber,
-	     attachment, format, draw->width, draw->height));
+	     attachment, format, draw->width, draw->height,
+	     draw->type != DRAWABLE_PIXMAP));
 
 	pixmap = NULL;
 	size = (uint32_t)draw->height << 16 | draw->width;
@@ -464,11 +465,12 @@ sna_dri2_create_buffer(DrawablePtr draw,
 		if (buffer) {
 			private = get_private(buffer);
 
-			DBG(("%s: reusing front buffer attachment, win=%lu %dx%d, pixmap=%ld %dx%d, handle=%d, name=%d\n",
+			DBG(("%s: reusing front buffer attachment, win=%lu %dx%d, pixmap=%ld [%ld] %dx%d, handle=%d, name=%d\n",
 			     __FUNCTION__,
 			     draw->type != DRAWABLE_PIXMAP ? (long)draw->id : (long)0,
 			     draw->width, draw->height,
 			     pixmap->drawable.serialNumber,
+			     private->pixmap->drawable.serialNumber,
 			     pixmap->drawable.width,
 			     pixmap->drawable.height,
 			     private->bo->handle, buffer->name));
@@ -1400,19 +1402,37 @@ sna_dri2_add_event(struct sna *sna, DrawablePtr draw, ClientPtr client)
 	return info;
 }
 
+void sna_dri2_decouple_window(WindowPtr win)
+{
+	struct dri2_window *priv;
+
+	priv = dri2_window(win);
+	if (priv == NULL)
+		return;
+
+	DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id));
+
+	if (priv->front) {
+		struct sna *sna = to_sna_from_drawable(&win->drawable);
+		assert(priv->crtc);
+		sna_shadow_unset_crtc(sna, priv->crtc);
+		_sna_dri2_destroy_buffer(sna, priv->front);
+		priv->front = NULL;
+	}
+}
+
 void sna_dri2_destroy_window(WindowPtr win)
 {
-	struct sna *sna;
 	struct dri2_window *priv;
 
 	priv = dri2_window(win);
 	if (priv == NULL)
 		return;
 
-	DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.serialNumber));
-	sna = to_sna_from_drawable(&win->drawable);
+	DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id));
 
 	if (priv->front) {
+		struct sna *sna = to_sna_from_drawable(&win->drawable);
 		assert(priv->crtc);
 		sna_shadow_unset_crtc(sna, priv->crtc);
 		_sna_dri2_destroy_buffer(sna, priv->front);
@@ -3120,6 +3140,7 @@ out_complete:
 }
 #else
 void sna_dri2_destroy_window(WindowPtr win) { }
+void sna_dri2_decouple_window(WindowPtr win) { }
 #endif
 
 static bool has_i830_dri(void)


More information about the xorg-commit mailing list