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