xf86-video-intel: 4 commits - src/sna/sna_display.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Sun Apr 27 00:40:42 PDT 2014


 src/sna/sna.h         |    5 ++
 src/sna/sna_display.c |   94 ++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 77 insertions(+), 22 deletions(-)

New commits:
commit 11cc397cb1cded40f7ab43c1add3fd00b97c6bdc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 27 07:55:09 2014 +0100

    sna: Preallocate cursors
    
    We need to avoid all allocations within the signal handlers, so
    preallocate the cursor structs.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77975
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index fc73f7e..1e23ac1 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -298,6 +298,8 @@ struct sna {
 		unsigned max_size;
 		bool use_gtt;
 
+		int num_stash;
+		struct sna_cursor *stash;
 		void *scratch;
 	} cursor;
 
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index f3672e7..14446c7 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3105,17 +3105,14 @@ static struct sna_cursor *__sna_create_cursor(struct sna *sna)
 
 	__DBG(("%s(size=%d)\n", __FUNCTION__, size));
 
-	c = malloc(sizeof(*c));
-	if (c == NULL)
-		return NULL;
+	c = sna->cursor.stash;
+	assert(c);
 
 	size = size * size * 4;
 	c->alloc = ALIGN(size, 4096);
 	c->handle = gem_create(sna->kgem.fd, c->alloc);
-	if (c->handle == 0) {
-		free(c);
+	if (c->handle == 0)
 		return NULL;
-	}
 
 	/* Old hardware uses physical addresses, which the kernel
 	 * implements in an incoherent fashion requiring a pwrite.
@@ -3124,7 +3121,6 @@ static struct sna_cursor *__sna_create_cursor(struct sna *sna)
 		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
@@ -3135,6 +3131,9 @@ static struct sna_cursor *__sna_create_cursor(struct sna *sna)
 	c->serial = 0;
 	c->last_width = c->last_height = 0; /* all clear */
 
+	sna->cursor.num_stash--;
+	sna->cursor.stash = c->next;
+
 	c->next = sna->cursor.cursors;
 	sna->cursor.cursors = c;
 
@@ -3410,6 +3409,7 @@ sna_hide_cursors(ScrnInfoPtr scrn)
 {
 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 	struct sna *sna = to_sna(scrn);
+	struct sna_cursor *cursor, **prev;
 	int sigio, c;
 
 	__DBG(("%s\n", __FUNCTION__));
@@ -3438,14 +3438,22 @@ sna_hide_cursors(ScrnInfoPtr scrn)
 		sna_crtc->cursor = NULL;
 	}
 
-	while (sna->cursor.cursors) {
-		struct sna_cursor *cursor = sna->cursor.cursors;
-		sna->cursor.cursors = cursor->next;
+	for (prev = &sna->cursor.cursors; (cursor = *prev) != NULL; ) {
+		if (cursor->serial == sna->cursor.serial) {
+			prev = &cursor->next;
+			continue;
+		}
+
+		*prev = cursor->next;
 		if (cursor->image)
 			munmap(cursor->image, cursor->alloc);
 		gem_close(sna->kgem.fd, cursor->handle);
-		free(cursor);
+
+		cursor->next = sna->cursor.stash;
+		sna->cursor.stash = cursor;
+		sna->cursor.num_stash++;
 	}
+
 	sigio_unblock(sigio);
 }
 
@@ -3577,6 +3585,23 @@ static int __cursor_size(CursorPtr cursor)
 	return size;
 }
 
+static bool
+sna_cursor_preallocate(struct sna *sna)
+{
+	while (sna->cursor.num_stash < 0) {
+		struct sna_cursor *cursor = malloc(sizeof(*cursor));
+		if (!cursor)
+			return false;
+
+		cursor->next = sna->cursor.stash;
+		sna->cursor.stash = cursor;
+
+		sna->cursor.num_stash++;
+	}
+
+	return true;
+}
+
 static Bool
 sna_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
 {
@@ -3598,6 +3623,9 @@ sna_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
 	if (sna->cursor.size > sna->cursor.max_size)
 		return FALSE;
 
+	if (!sna_cursor_preallocate(sna))
+		return FALSE;
+
 	sna->cursor.ref = cursor;
 	cursor->refcnt++;
 	sna->cursor.serial++;
@@ -3646,11 +3674,28 @@ sna_cursor_pre_init(struct sna *sna)
 			sna->cursor.max_size = 0;
 	}
 
+	sna->cursor.num_stash = -sna->mode.kmode->count_crtcs;
+
 	xf86DrvMsg(sna->scrn->scrnIndex, X_PROBED,
 		   "Using a maximum size of %dx%d for hardware cursors\n",
 		   sna->cursor.max_size, sna->cursor.max_size);
 }
 
+static void
+sna_cursor_close(struct sna *sna)
+{
+	sna->cursor.serial = 0;
+	sna_hide_cursors(sna->scrn);
+
+	while (sna->cursor.stash) {
+		struct sna_cursor *cursor = sna->cursor.stash;
+		sna->cursor.stash = cursor->next;
+		free(cursor);
+	}
+
+	sna->cursor.num_stash = -sna->mode.kmode->count_crtcs;
+}
+
 bool
 sna_cursors_init(ScreenPtr screen, struct sna *sna)
 {
@@ -4243,7 +4288,7 @@ sna_mode_close(struct sna *sna)
 	if (sna->flags & SNA_IS_HOSTED)
 		return;
 
-	sna_hide_cursors(sna->scrn);
+	sna_cursor_close(sna);
 
 	for (i = 0; i < config->num_crtc; i++) {
 		struct sna_crtc *crtc;
commit 9417f13cc4074ea6e5dad88e054337e93b461a4c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 27 07:55:09 2014 +0100

    sna: Preallocate pwrite scratch buffer for old fashioned cursor updates
    
    We need to avoid all allocations within the signal handlers, so
    preallocate the transfer buffer.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=77975
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index bd6eb49..fc73f7e 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -297,6 +297,8 @@ struct sna {
 
 		unsigned max_size;
 		bool use_gtt;
+
+		void *scratch;
 	} cursor;
 
 	struct sna_dri {
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 3ab81fc..f3672e7 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3221,10 +3221,7 @@ 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)
-			return NULL;
-
+		image = sna->cursor.scratch;
 		cursor->last_width = cursor->last_height = size;
 	}
 	if (width < cursor->last_width || height < cursor->last_height)
@@ -3291,8 +3288,6 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
 		pwrite.data_ptr = (uintptr_t)image;
 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite))
 			__DBG(("%s: cursor update (pwrite) failed: %d\n", errno));
-
-		free(image);
 	}
 
 	cursor->size = size;
@@ -3641,13 +3636,19 @@ sna_cursor_pre_init(struct sna *sna)
 		assert(sna->cursor.max_size == cap.value);
 #endif
 
-	xf86DrvMsg(sna->scrn->scrnIndex, X_PROBED,
-		   "Using a maximum size of %dx%d for hardware cursors\n",
-		   sna->cursor.max_size, sna->cursor.max_size);
-
 	sna->cursor.use_gtt = sna->kgem.gen >= 033;
 	DBG(("%s: cursor updates use_gtt?=%d\n",
 	     __FUNCTION__, sna->cursor.use_gtt));
+
+	if (!sna->cursor.use_gtt) {
+		sna->cursor.scratch = malloc(sna->cursor.max_size * sna->cursor.max_size * 4);
+		if (!sna->cursor.scratch)
+			sna->cursor.max_size = 0;
+	}
+
+	xf86DrvMsg(sna->scrn->scrnIndex, X_PROBED,
+		   "Using a maximum size of %dx%d for hardware cursors\n",
+		   sna->cursor.max_size, sna->cursor.max_size);
 }
 
 bool
commit 795cebf053e8457b998522ab7eea80b0819cb46b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 27 07:52:14 2014 +0100

    sna: Replace cursor gen test with feature flag
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 00b12e9..bd6eb49 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -296,6 +296,7 @@ struct sna {
 		int last_y;
 
 		unsigned max_size;
+		bool use_gtt;
 	} cursor;
 
 	struct sna_dri {
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index c452064..3ab81fc 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3120,7 +3120,7 @@ static struct sna_cursor *__sna_create_cursor(struct sna *sna)
 	/* Old hardware uses physical addresses, which the kernel
 	 * implements in an incoherent fashion requiring a pwrite.
 	 */
-	if (sna->kgem.gen >= 033) {
+	if (sna->cursor.use_gtt) {
 		c->image = gem_mmap(sna->kgem.fd, c->handle, c->alloc);
 		if (c->image == NULL) {
 			gem_close(sna->kgem.fd, c->handle);
@@ -3175,7 +3175,7 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
 	if (cursor && cursor->alloc < 4*size*size)
 		cursor = NULL;
 
-	if (sna->kgem.gen >= 033) { /* Don't allow phys cursor sharing */
+	if (sna->cursor.use_gtt) { /* Don't allow phys cursor sharing */
 		for (cursor = sna->cursor.cursors; cursor; cursor = cursor->next) {
 			if (cursor->serial == sna->cursor.serial && cursor->rotation == rotation) {
 				__DBG(("%s: reusing handle=%d, serial=%d, rotation=%d, size=%d\n",
@@ -3644,6 +3644,10 @@ sna_cursor_pre_init(struct sna *sna)
 	xf86DrvMsg(sna->scrn->scrnIndex, X_PROBED,
 		   "Using a maximum size of %dx%d for hardware cursors\n",
 		   sna->cursor.max_size, sna->cursor.max_size);
+
+	sna->cursor.use_gtt = sna->kgem.gen >= 033;
+	DBG(("%s: cursor updates use_gtt?=%d\n",
+	     __FUNCTION__, sna->cursor.use_gtt));
 }
 
 bool
commit 1b76a1f6fb046353b1e2f553dfcb03978807272d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 27 08:32:17 2014 +0100

    sna: Initialise cursors after checking for KMS
    
    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 b802cf7..c452064 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4168,8 +4168,6 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 	int num_fake = 0;
 	int i;
 
-	sna_cursor_pre_init(sna);
-
 	if (sna->flags & SNA_IS_HOSTED) {
 		sna_setup_provider(scrn);
 		return true;
@@ -4189,6 +4187,8 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 		assert(mode->kmode->count_crtcs);
 		assert(mode->kmode->count_connectors);
 
+		sna_cursor_pre_init(sna);
+
 		xf86CrtcConfigInit(scrn, &sna_mode_funcs);
 		XF86_CRTC_CONFIG_PTR(scrn)->xf86_crtc_notify = sna_crtc_config_notify;
 


More information about the xorg-commit mailing list