[PATCH driver/intel] Allow copy_front() to fail and clean up gracefully if it does

Egbert Eich eich at freedesktop.org
Tue Sep 23 23:17:59 PDT 2014


From: Egbert Eich <eich at suse.de>

copy_front() calls sna_pixmap_force_to_gpu() which may fail. If we pretend
to have been successful and continue the caller sna_mode_resize() may finish
successfully pretending a mode change has succeeded which might leave a mode
behind which is unusable.
This patch makes copy_front() fail if sna_pixmap_force_to_gpu() fails which
allows sna_mode_resize() to detect this situation, clean up gracefully,
ie. destroy the newly created front pixmap and fail itself. This way an
application requesting such a mode will receive a proper XError while the
previous mode will be restored leaving the user with a usable mode.

Signed-off-by: Egbert Eich <eich at freedesktop.org>
---
 src/sna/sna_display.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 2a98fb9..25873c4 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4044,22 +4044,22 @@ void sna_mode_discover(struct sna *sna)
 	}
 }
 
-static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
+static Bool copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
 {
 	struct sna_pixmap *old_priv, *new_priv;
 
 	DBG(("%s\n", __FUNCTION__));
 
 	if (wedged(sna))
-		return;
+		return FALSE;
 
 	old_priv = sna_pixmap_force_to_gpu(old, MOVE_READ);
 	if (!old_priv)
-		return;
+		return FALSE;
 
 	new_priv = sna_pixmap_force_to_gpu(new, MOVE_WRITE);
 	if (!new_priv)
-		return;
+		return FALSE;
 
 	if (old_priv->clear) {
 		(void)sna->render.fill_one(sna, new, new_priv->gpu_bo,
@@ -4137,6 +4137,8 @@ static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
 	}
 
 	sna_damage_all(&new_priv->gpu_damage, new);
+
+	return TRUE;
 }
 
 static Bool
@@ -4182,7 +4184,10 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
 	assert(sna->mode.shadow_damage == NULL);
 	assert(sna->mode.shadow == NULL);
 
-	copy_front(sna, sna->front, new_front);
+	if (!copy_front(sna, sna->front, new_front)) {
+		screen->DestroyPixmap(new_front);
+		return FALSE;
+	}
 
 	screen->SetScreenPixmap(new_front);
 	assert(screen->GetScreenPixmap(screen) == new_front);
-- 
1.8.4.5



More information about the xorg-devel mailing list