xf86-video-intel: src/sna/sna_display.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Apr 9 08:18:01 PDT 2014


 src/sna/sna_display.c |   53 +++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 42 insertions(+), 11 deletions(-)

New commits:
commit dba43d370b984e262f6fe5920b38b433f4bd392b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 9 16:11:26 2014 +0100

    sna: Use pwrite to update physical cursors
    
    Older hardware uses physical addresses for its cursor, which are
    implemented by the kernel in an incoherent fashion. Maybe with stolen
    support this would be different...
    
    Fixes regression on [845g, 945g] from
    commit 25ca8f136cef9e1bdf06967bf8e78c87b54ffce2
    Author: Chris Wilson <chris at chris-wilson.co.uk>
    Date:   Thu Mar 27 14:15:30 2014 +0000
    
        sna: Support variable sized cursors
    
    Reported-by: Knut Petersen <Knut_Petersen at t-online.de>
    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 664d42c..a9558d2 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3093,12 +3093,18 @@ static struct sna_cursor *__sna_create_cursor(struct sna *sna)
 		return NULL;
 	}
 
-	c->image = gem_mmap(sna->kgem.fd, c->handle, c->alloc);
-	if (c->image == NULL) {
-		gem_close(sna->kgem.fd, c->handle);
-		free(c);
-		return NULL;
-	}
+	/* Old hardware uses physical addresses, which the kernel
+	 * implements in an incoherent fashion requiring a pwrite.
+	 */
+	if (sna->kgem.gen >= 033) {
+		c->image = gem_mmap(sna->kgem.fd, c->handle, c->alloc);
+		if (c->image == NULL) {
+			gem_close(sna->kgem.fd, c->handle);
+			free(c);
+			return NULL;
+		}
+	} else
+		c->image = NULL;
 
 	__DBG(("%s: handle=%d, allocated %d\n", __FUNCTION__, c->handle, size));
 
@@ -3114,7 +3120,7 @@ static struct sna_cursor *__sna_create_cursor(struct sna *sna)
 static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
 {
 	struct sna_cursor *cursor;
-	uint32_t *src;
+	uint32_t *src, *image;
 	int width, height, size, x, y;
 	Rotation rotation;
 
@@ -3198,10 +3204,21 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
 		}
 	}
 
+	image = cursor->image;
+	if (image == NULL) {
+		image = malloc(4*size*size);
+		if (image == NULL) {
+			if (src != (uint32_t *)sna->cursor.ref->bits->argb)
+				free(src);
+			return NULL;
+		}
+
+		cursor->last_width = cursor->last_height = size;
+	}
 	if (width < cursor->last_width || height < cursor->last_height)
-		memset(cursor->image, 0, 4*size*size);
+		memset(image, 0, 4*size*size);
 	if (rotation == RR_Rotate_0) {
-		memcpy_blt(src, cursor->image, 32,
+		memcpy_blt(src, image, 32,
 			   width * 4, size * 4,
 			   0, 0,
 			   0, 0,
@@ -3217,10 +3234,23 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
 					pixel = src[yin * width + xin];
 				else
 					pixel = 0;
-				cursor->image[y * size + x] = pixel;
+				image[y * size + x] = pixel;
 			}
 	}
 
+	if (image != cursor->image) {
+		struct drm_i915_gem_pwrite pwrite;
+
+		VG_CLEAR(pwrite);
+		pwrite.handle = cursor->handle;
+		pwrite.offset = 0;
+		pwrite.size = 4*size*size;
+		pwrite.data_ptr = (uintptr_t)image;
+		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite);
+
+		free(image);
+	}
+
 	if (src != (uint32_t *)sna->cursor.ref->bits->argb)
 		free(src);
 
@@ -3365,7 +3395,8 @@ sna_hide_cursors(ScrnInfoPtr scrn)
 	while (sna->cursor.cursors) {
 		struct sna_cursor *cursor = sna->cursor.cursors;
 		sna->cursor.cursors = cursor->next;
-		munmap(cursor->image, cursor->alloc);
+		if (cursor->image)
+			munmap(cursor->image, cursor->alloc);
 		gem_close(sna->kgem.fd, cursor->handle);
 		free(cursor);
 	}


More information about the xorg-commit mailing list