[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'ubuntu'



 debian/changelog                                            |   11 
 debian/patches/series                                       |    1 
 debian/patches/sna-flush-scanout-cache-after-resizing.patch |  228 ++++++++++++
 3 files changed, 240 insertions(+)

New commits:
commit 30fce9c04afb32c5d060d7040d8e28d7de12228b
Author: Bryce Harrington <bryce@canonical.com>
Date:   Fri Apr 19 21:27:20 2013 -0700

    Add sna-flush-scanout-cache-after-resizing.patch

diff --git a/debian/changelog b/debian/changelog
index 6c2e6f1..be1fca2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+xserver-xorg-video-intel (2:2.21.6-0ubuntu4) raring-proposed; urgency=low
+
+  [Chris Arges]
+  * Add sna-flush-scanout-cache-after-resizing.patch: Flush the scanout
+    cache after resizing the display.  Fixes a problem that occurs
+    e.g. when unplugging an external display, suspend/resume, etc. by
+    ensuring the scanout cache is properly sized.
+    (LP: #1157678)
+
+ -- Bryce Harrington <bryce@ubuntu.com>  Fri, 19 Apr 2013 11:12:14 -0700
+
 xserver-xorg-video-intel (2:2.21.6-0ubuntu3) raring-proposed; urgency=low
 
   * rules: Drop --enable-valgrind for now (causes FTBS).
diff --git a/debian/patches/series b/debian/patches/series
index 23ed8a4..df7cb15 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1,2 @@
 0002-Update-manpage-for-new-accelmethod-option.patch
+sna-flush-scanout-cache-after-resizing.patch
diff --git a/debian/patches/sna-flush-scanout-cache-after-resizing.patch b/debian/patches/sna-flush-scanout-cache-after-resizing.patch
new file mode 100644
index 0000000..bb4928f
--- /dev/null
+++ b/debian/patches/sna-flush-scanout-cache-after-resizing.patch
@@ -0,0 +1,228 @@
+From e083fbdc3f2025f4ccc199070e2488afc5afb2a7 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Fri, 12 Apr 2013 11:01:08 +0100
+Subject: [PATCH] sna: Flush the scanout cache after resizing the display
+
+And ensure that any new scanout allocations make the requested size.
+
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+(cherry picked from commit 9dae6f9f1f169c228929185a8bd94e82afe92574)
+
+Conflicts:
+
+	src/sna/kgem.h
+---
+ src/sna/kgem.c        |   88 ++++++++++++++++++++++++++++++++++++-------------
+ src/sna/kgem.h        |    3 ++
+ src/sna/sna_display.c |   23 ++++++++-----
+ 3 files changed, 83 insertions(+), 31 deletions(-)
+
+diff --git a/src/sna/kgem.c b/src/sna/kgem.c
+index 4136ce9..cb2dea7 100644
+--- a/src/sna/kgem.c
++++ b/src/sna/kgem.c
+@@ -1601,6 +1601,17 @@ inline static void kgem_bo_remove_from_active(struct kgem *kgem,
+ 	assert(list_is_empty(&bo->vma));
+ }
+ 
++static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
++{
++	struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy;
++
++	DBG(("%s: size=%d, offset=%d, parent used=%d\n",
++	     __FUNCTION__, bo->size.bytes, bo->delta, io->used));
++
++	if (ALIGN(bo->delta + bo->size.bytes, UPLOAD_ALIGNMENT) == io->used)
++		io->used = bo->delta;
++}
++
+ static void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo)
+ {
+ 	assert(bo->scanout);
+@@ -1625,15 +1636,31 @@ static void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo)
+ 		bo->reusable = false;
+ }
+ 
+-static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
++static bool check_scanout_size(struct kgem *kgem,
++			       struct kgem_bo *bo,
++			       int width, int height)
+ {
+-	struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy;
++	struct drm_mode_fb_cmd info;
+ 
+-	DBG(("%s: size=%d, offset=%d, parent used=%d\n",
+-	     __FUNCTION__, bo->size.bytes, bo->delta, io->used));
++	assert(bo->scanout);
+ 
+-	if (ALIGN(bo->delta + bo->size.bytes, UPLOAD_ALIGNMENT) == io->used)
+-		io->used = bo->delta;
++	VG_CLEAR(info);
++	info.fb_id = bo->delta;
++
++	if (drmIoctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info))
++		return false;
++
++	gem_close(kgem->fd, info.handle);
++
++	if (width != info.width || height != info.height) {
++		DBG(("%s: not using scanout %d (%dx%d), want (%dx%d)\n",
++		     __FUNCTION__,
++		     info.fb_id, info.width, info.height,
++		     width, height))
++		return false;
++	}
++
++	return true;
+ }
+ 
+ static void kgem_bo_move_to_scanout(struct kgem *kgem, struct kgem_bo *bo)
+@@ -2769,6 +2796,31 @@ void kgem_purge_cache(struct kgem *kgem)
+ 	kgem->need_purge = false;
+ }
+ 
++void kgem_clean_scanout_cache(struct kgem *kgem)
++{
++	while (!list_is_empty(&kgem->scanout)) {
++		struct kgem_bo *bo;
++
++		bo = list_first_entry(&kgem->scanout, struct kgem_bo, list);
++		if (__kgem_busy(kgem, bo->handle))
++			break;
++
++		list_del(&bo->list);
++		kgem_bo_clear_scanout(kgem, bo);
++		__kgem_bo_destroy(kgem, bo);
++	}
++}
++
++void kgem_clean_large_cache(struct kgem *kgem)
++{
++	while (!list_is_empty(&kgem->large_inactive)) {
++		kgem_bo_free(kgem,
++			     list_first_entry(&kgem->large_inactive,
++					      struct kgem_bo, list));
++
++	}
++}
++
+ bool kgem_expire_cache(struct kgem *kgem)
+ {
+ 	time_t now, expire;
+@@ -2791,22 +2843,8 @@ bool kgem_expire_cache(struct kgem *kgem)
+ 		free(rq);
+ 	}
+ 
+-	while (!list_is_empty(&kgem->large_inactive)) {
+-		kgem_bo_free(kgem,
+-			     list_first_entry(&kgem->large_inactive,
+-					      struct kgem_bo, list));
+-
+-	}
+-
+-	while (!list_is_empty(&kgem->scanout)) {
+-		bo = list_first_entry(&kgem->scanout, struct kgem_bo, list);
+-		if (__kgem_busy(kgem, bo->handle))
+-			break;
+-
+-		list_del(&bo->list);
+-		kgem_bo_clear_scanout(kgem, bo);
+-		__kgem_bo_destroy(kgem, bo);
+-	}
++	kgem_clean_large_cache(kgem);
++	kgem_clean_scanout_cache(kgem);
+ 
+ 	expire = 0;
+ 	list_for_each_entry(bo, &kgem->snoop, list) {
+@@ -2960,6 +2998,9 @@ void kgem_cleanup_cache(struct kgem *kgem)
+ 						     struct kgem_bo, list));
+ 	}
+ 
++	kgem_clean_large_cache(kgem);
++	kgem_clean_scanout_cache(kgem);
++
+ 	while (!list_is_empty(&kgem->snoop))
+ 		kgem_bo_free(kgem,
+ 			     list_last_entry(&kgem->snoop,
+@@ -3571,6 +3612,9 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
+ 			if (size > num_pages(bo) || num_pages(bo) > 2*size)
+ 				continue;
+ 
++			if (!check_scanout_size(kgem, bo, width, height))
++				continue;
++
+ 			if (bo->tiling != tiling ||
+ 			    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
+ 				if (!gem_set_tiling(kgem->fd, bo->handle,
+diff --git a/src/sna/kgem.h b/src/sna/kgem.h
+index f2b1c98..8f24d8b 100644
+--- a/src/sna/kgem.h
++++ b/src/sna/kgem.h
+@@ -682,6 +682,9 @@ bool kgem_expire_cache(struct kgem *kgem);
+ void kgem_purge_cache(struct kgem *kgem);
+ void kgem_cleanup_cache(struct kgem *kgem);
+ 
++void kgem_clean_scanout_cache(struct kgem *kgem);
++void kgem_clean_large_cache(struct kgem *kgem);
++
+ #if HAS_DEBUG_FULL
+ void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch);
+ #else
+diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
+index 0d32086..ba9bf79 100644
+--- a/src/sna/sna_display.c
++++ b/src/sna/sna_display.c
+@@ -103,6 +103,14 @@ static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc)
+ 	return crtc->driver_private;
+ }
+ 
++static bool sna_mode_has_pending_events(struct sna *sna)
++{
++	struct pollfd pfd;
++	pfd.fd = sna->kgem.fd;
++	pfd.events = POLLIN;
++	return poll(&pfd, 1, 0) == 1;
++}
++
+ #define BACKLIGHT_CLASS "/sys/class/backlight"
+ 
+ /* Enough for 10 digits of backlight + '\n' + '\0' */
+@@ -2601,6 +2609,11 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
+ 
+ 	screen->DestroyPixmap(old_front);
+ 
++	while (sna_mode_has_pending_events(sna))
++		sna_mode_wakeup(sna);
++
++	kgem_clean_scanout_cache(&sna->kgem);
++
+ 	return TRUE;
+ }
+ 
+@@ -2743,14 +2756,6 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
+ 	return true;
+ }
+ 
+-static Bool sna_mode_has_pending_events(struct sna *sna)
+-{
+-	struct pollfd pfd;
+-	pfd.fd = sna->kgem.fd;
+-	pfd.events = POLLIN;
+-	return poll(&pfd, 1, 0) == 1;
+-}
+-
+ void
+ sna_mode_close(struct sna *sna)
+ {
+@@ -2761,7 +2766,7 @@ sna_mode_close(struct sna *sna)
+ 	 * check that the fd is readable before attempting to read the next
+ 	 * event from drm.
+ 	 */
+-	if (sna_mode_has_pending_events(sna))
++	while (sna_mode_has_pending_events(sna))
+ 		sna_mode_wakeup(sna);
+ 
+ 	for (i = 0; i < xf86_config->num_crtc; i++)
+-- 
+1.7.9.5
+


Reply to: