[PATCH 6/5] On screen resize, clear the new buffer before displaying it

Michel Dänzer michel at daenzer.net
Wed Apr 22 02:45:19 PDT 2015


From: Michel Dänzer <michel.daenzer at amd.com>

Fixes garbage being intermittently visible during a screen resize.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=27757#c7
Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/drmmode_display.c        | 23 ++++++++++++++++++++---
 src/radeon.h                 |  1 +
 src/radeon_glamor_wrappers.c |  9 +++++++++
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 326d863..5af5900 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1766,6 +1766,9 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 	uint32_t tiling_flags = 0, base_align;
 	PixmapPtr ppix = screen->GetScreenPixmap(screen);
 	void *fb_shadow;
+	xRectangle rect;
+	Bool force;
+	GCPtr gc;
 
 	if (scrn->virtualX == width && scrn->virtualY == height)
 		return TRUE;
@@ -1909,6 +1912,23 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 	scrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
 #endif
 
+	if (info->use_glamor)
+		radeon_glamor_create_screen_resources(scrn->pScreen);
+
+	/* Clear new buffer */
+	gc = GetScratchGC(ppix->drawable.depth, scrn->pScreen);
+	force = info->accel_state->force;
+	info->accel_state->force = TRUE;
+	ValidateGC(&ppix->drawable, gc);
+	rect.x = 0;
+	rect.y = 0;
+	rect.width = width;
+	rect.height = height;
+	(*gc->ops->PolyFillRect)(&ppix->drawable, gc, 1, &rect);
+	FreeScratchGC(gc);
+	info->accel_state->force = force;
+	radeon_cs_flush_indirect(scrn);
+
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[i];
 
@@ -1919,9 +1939,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 				       crtc->rotation, crtc->x, crtc->y);
 	}
 
-	if (info->use_glamor)
-		radeon_glamor_create_screen_resources(scrn->pScreen);
-
 	if (old_fb_id)
 		drmModeRmFB(drmmode->fd, old_fb_id);
 	if (old_front)
diff --git a/src/radeon.h b/src/radeon.h
index cd03d53..7feed04 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -544,6 +544,7 @@ typedef struct {
 	CreateGCProcPtr SavedCreateGC;
 	RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int,
 				   int, int, int, int);
+	void (*SavedPolyFillRect)(DrawablePtr, GCPtr, int, xRectangle*);
 	CloseScreenProcPtr SavedCloseScreen;
 	GetImageProcPtr SavedGetImage;
 	GetSpansProcPtr SavedGetSpans;
diff --git a/src/radeon_glamor_wrappers.c b/src/radeon_glamor_wrappers.c
index db2e85f..7a57bc1 100644
--- a/src/radeon_glamor_wrappers.c
+++ b/src/radeon_glamor_wrappers.c
@@ -421,9 +421,17 @@ radeon_glamor_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC,
 			     int nrect, xRectangle *prect)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
+	RADEONInfoPtr info = RADEONPTR(scrn);
 	PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
 	struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
 
+	if ((info->accel_state->force || (priv && !priv->bo)) &&
+	    radeon_glamor_prepare_access_gpu(priv)) {
+		info->glamor.SavedPolyFillRect(pDrawable, pGC, nrect, prect);
+		radeon_glamor_finish_access_gpu_rw(info, priv);
+		return;
+	}
+
 	if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
 		if (radeon_glamor_prepare_access_gc(scrn, pGC)) {
 			fbPolyFillRect(pDrawable, pGC, nrect, prect);
@@ -622,6 +630,7 @@ radeon_glamor_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawabl
 
 	glamor_validate_gc(pGC, changes, pDrawable);
 	info->glamor.SavedCopyArea = pGC->ops->CopyArea;
+	info->glamor.SavedPolyFillRect = pGC->ops->PolyFillRect;
 
 	if (radeon_get_pixmap_private(get_drawable_pixmap(pDrawable)) ||
 	    (pGC->stipple && radeon_get_pixmap_private(pGC->stipple)) ||
-- 
2.1.4



More information about the xorg-driver-ati mailing list