xf86-video-intel: 3 commits - src/sna/sna_display.c src/sna/sna.h src/sna/sna_video.h src/sna/sna_video_sprite.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Jun 20 11:03:22 UTC 2016


 src/sna/sna.h              |    5 +-
 src/sna/sna_display.c      |   81 ++++++++++++++++++++++++++++++------
 src/sna/sna_video.h        |    2 
 src/sna/sna_video_sprite.c |  100 +++++++++++++++++++++++++--------------------
 4 files changed, 128 insertions(+), 60 deletions(-)

New commits:
commit ebc5e9c3b2241be69bee7b96bd63ef00dacf816c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jun 20 11:44:23 2016 +0100

    sna/video: Create one XvAdapter for each sprite plane
    
    The caveat here is that the sprite plane must be available on all CRTCs
    so that the availability of the XvAdapter is not dependent upon output
    configuration or Window placement.
    
    Based on a patch by Michael Hadley <michaelx.hadley at intel.com>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 033781e..64bf498 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -611,6 +611,7 @@ static inline void sna_present_vblank_handler(struct drm_event_vblank *event) {
 static inline void sna_present_cancel_flip(struct sna *sna) { }
 #endif
 
+extern unsigned sna_crtc_count_sprites(xf86CrtcPtr crtc);
 extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, unsigned idx, uint32_t rotation);
 extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx);
 extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 2f54ff1..a22d94e 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -445,6 +445,18 @@ static inline uint32_t fb_id(struct kgem_bo *bo)
 	return bo->delta;
 }
 
+unsigned sna_crtc_count_sprites(xf86CrtcPtr crtc)
+{
+	struct plane *sprite;
+	unsigned count;
+
+	count = 0;
+	list_for_each_entry(sprite, &to_sna_crtc(crtc)->sprites, link)
+		count++;
+
+	return count;
+}
+
 static struct plane *lookup_sprite(struct sna_crtc *crtc, unsigned idx)
 {
 	struct plane *sprite;
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index a302b5d..1a2b1c8 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -654,6 +654,7 @@ static int sna_video_sprite_color_key(struct sna *sna)
 static int sna_video_has_sprites(struct sna *sna)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	unsigned min;
 	int i;
 
 	DBG(("%s: num_crtc=%d\n", __FUNCTION__, sna->mode.num_real_crtc));
@@ -661,15 +662,17 @@ static int sna_video_has_sprites(struct sna *sna)
 	if (sna->mode.num_real_crtc == 0)
 		return 0;
 
+	min = -1;
 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
-		if (!sna_crtc_to_sprite(config->crtc[i], 0)) {
-			DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_pipe(config->crtc[i])));
-			return 0;
-		}
+		unsigned count =  sna_crtc_count_sprites(config->crtc[i]);
+		DBG(("%s: %d sprites found on pipe %d\n", __FUNCTION__,
+		     count, sna_crtc_pipe(config->crtc[i])));
+		if (count < min)
+			min = count;
 	}
 
-	DBG(("%s: yes\n", __FUNCTION__));
-	return 1;
+	DBG(("%s: min=%d\n", __FUNCTION__, min));
+	return min;
 }
 
 void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
commit 52c9d7ca2467bc273a8ef3c61c1b690ac56caa74
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jun 20 11:40:04 2016 +0100

    sna/video: Prepare for multiple sprite ports
    
    Allocate an array of XvAdapters, one for each sprite plane on a CRTC.
    
    Based on a patch by Michael Hadley <michaelx.hadley at intel.com>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index b278991..39cb725 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -72,6 +72,8 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 struct sna_video {
 	struct sna *sna;
 
+	int idx; /* XXX expose struct plane instead? */
+
 	int brightness;
 	int contrast;
 	int saturation;
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index 17b272c..a302b5d 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -91,7 +91,7 @@ static int sna_video_sprite_stop(ddStopVideo_ARGS)
 			continue;
 
 		memset(&s, 0, sizeof(s));
-		s.plane_id = sna_crtc_to_sprite(crtc, 0);
+		s.plane_id = sna_crtc_to_sprite(crtc, video->idx);
 		if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
 			xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
 				   "failed to disable plane\n");
@@ -224,7 +224,7 @@ sna_video_sprite_show(struct sna *sna,
 	/* XXX handle video spanning multiple CRTC */
 
 	VG_CLEAR(s);
-	s.plane_id = sna_crtc_to_sprite(crtc, 0);
+	s.plane_id = sna_crtc_to_sprite(crtc, video->idx);
 
 #define DRM_I915_SET_SPRITE_COLORKEY 0x2b
 #define LOCAL_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct local_intel_sprite_colorkey)
@@ -422,7 +422,7 @@ off:
 			if (video->bo[pipe]) {
 				struct local_mode_set_plane s;
 				memset(&s, 0, sizeof(s));
-				s.plane_id = sna_crtc_to_sprite(crtc, 0);
+				s.plane_id = sna_crtc_to_sprite(crtc, video->idx);
 				if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
 					xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
 						   "failed to disable plane\n");
@@ -461,8 +461,8 @@ off:
 
 		/* if sprite can't handle rotation natively, store it for the copy func */
 		rotation = RR_Rotate_0;
-		if (!sna_crtc_set_sprite_rotation(crtc, 0, crtc->rotation)) {
-			sna_crtc_set_sprite_rotation(crtc, 0, RR_Rotate_0);
+		if (!sna_crtc_set_sprite_rotation(crtc, video->idx, crtc->rotation)) {
+			sna_crtc_set_sprite_rotation(crtc, video->idx, RR_Rotate_0);
 			rotation = crtc->rotation;
 		}
 		sna_video_frame_set_rotation(video, &frame, rotation);
@@ -651,7 +651,7 @@ static int sna_video_sprite_color_key(struct sna *sna)
 	return color_key & ((1 << scrn->depth) - 1);
 }
 
-static bool sna_video_has_sprites(struct sna *sna)
+static int sna_video_has_sprites(struct sna *sna)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
 	int i;
@@ -659,17 +659,17 @@ static bool sna_video_has_sprites(struct sna *sna)
 	DBG(("%s: num_crtc=%d\n", __FUNCTION__, sna->mode.num_real_crtc));
 
 	if (sna->mode.num_real_crtc == 0)
-		return false;
+		return 0;
 
 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
 		if (!sna_crtc_to_sprite(config->crtc[i], 0)) {
 			DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_pipe(config->crtc[i])));
-			return false;
+			return 0;
 		}
 	}
 
 	DBG(("%s: yes\n", __FUNCTION__));
-	return true;
+	return 1;
 }
 
 void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
@@ -677,16 +677,18 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 	XvAdaptorPtr adaptor;
 	struct sna_video *video;
 	XvPortPtr port;
+	int count, i;
 
-	if (!sna_video_has_sprites(sna))
+	count = sna_video_has_sprites(sna);
+	if (!count)
 		return;
 
 	adaptor = sna_xv_adaptor_alloc(sna);
 	if (!adaptor)
 		return;
 
-	video = calloc(1, sizeof(*video));
-	port = calloc(1, sizeof(*port));
+	video = calloc(count, sizeof(*video));
+	port = calloc(count, sizeof(*port));
 	if (video == NULL || port == NULL) {
 		free(video);
 		free(port);
@@ -731,36 +733,43 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 	adaptor->ddPutImage = sna_video_sprite_put_image;
 	adaptor->ddQueryImageAttributes = sna_video_sprite_query;
 
-	adaptor->nPorts = 1;
+	adaptor->nPorts = count;
 	adaptor->pPorts = port;
 
-	adaptor->base_id = port->id = FakeClientID(0);
-	AddResource(port->id, XvGetRTPort(), port);
-	port->pAdaptor = adaptor;
-	port->pNotify =  NULL;
-	port->pDraw =  NULL;
-	port->client =  NULL;
-	port->grab.client =  NULL;
-	port->time = currentTime;
-	port->devPriv.ptr = video;
-
-	video->sna = sna;
-	video->alignment = 64;
-	video->color_key = sna_video_sprite_color_key(sna);
-	video->color_key_changed = ~0;
-	video->has_color_key = true;
-	video->brightness = -19;	/* (255/219) * -16 */
-	video->contrast = 75;	/* 255/219 * 64 */
-	video->saturation = 146;	/* 128/112 * 128 */
-	video->desired_crtc = NULL;
-	video->gamma5 = 0xc0c0c0;
-	video->gamma4 = 0x808080;
-	video->gamma3 = 0x404040;
-	video->gamma2 = 0x202020;
-	video->gamma1 = 0x101010;
-	video->gamma0 = 0x080808;
-	RegionNull(&video->clip);
-	video->SyncToVblank = 1;
+	for (i = 0; i < count; i++) {
+		port->id = FakeClientID(0);
+		AddResource(port->id, XvGetRTPort(), port);
+		port->pAdaptor = adaptor;
+		port->pNotify =  NULL;
+		port->pDraw =  NULL;
+		port->client =  NULL;
+		port->grab.client =  NULL;
+		port->time = currentTime;
+		port->devPriv.ptr = video;
+
+		video->sna = sna;
+		video->idx = i;
+		video->alignment = 64;
+		video->color_key = sna_video_sprite_color_key(sna);
+		video->color_key_changed = ~0;
+		video->has_color_key = true;
+		video->brightness = -19;	/* (255/219) * -16 */
+		video->contrast = 75;	/* 255/219 * 64 */
+		video->saturation = 146;	/* 128/112 * 128 */
+		video->desired_crtc = NULL;
+		video->gamma5 = 0xc0c0c0;
+		video->gamma4 = 0x808080;
+		video->gamma3 = 0x404040;
+		video->gamma2 = 0x202020;
+		video->gamma1 = 0x101010;
+		video->gamma0 = 0x080808;
+		RegionNull(&video->clip);
+		video->SyncToVblank = 1;
+
+		port++;
+		video++;
+	}
+	adaptor->base_id = adaptor->pPorts[0].id;
 
 	xvColorKey = MAKE_ATOM("XV_COLORKEY");
 	xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");
commit 00a3adaf43640b9aaa84b8cb98c1f2f227686689
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jun 20 11:24:43 2016 +0100

    sna: Record all sprite planes reported by the kernel
    
    In the following patches, we wish to expose them all to userspace. First
    we have to enumerate them, and make sure they all behave as expected.
    
    Based on a patch by Michael Hadley <michaelx.hadley at intel.com>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index fdfefe1..033781e 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -611,8 +611,8 @@ static inline void sna_present_vblank_handler(struct drm_event_vblank *event) {
 static inline void sna_present_cancel_flip(struct sna *sna) { }
 #endif
 
-extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation);
-extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc);
+extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, unsigned idx, uint32_t rotation);
+extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx);
 extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc);
 
 #define CRTC_VBLANK 0x3
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 0cf2bdb..2f54ff1 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -221,7 +221,9 @@ struct sna_crtc {
 			uint32_t supported;
 			uint32_t current;
 		} rotation;
-	} primary, sprite;
+		struct list link;
+	} primary;
+	struct list sprites;
 
 	uint32_t mode_serial, flip_serial;
 
@@ -443,10 +445,25 @@ static inline uint32_t fb_id(struct kgem_bo *bo)
 	return bo->delta;
 }
 
-uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc)
+static struct plane *lookup_sprite(struct sna_crtc *crtc, unsigned idx)
 {
+	struct plane *sprite;
+
+	list_for_each_entry(sprite, &crtc->sprites, link)
+		if (idx-- == 0)
+			return sprite;
+
+	return NULL;
+}
+
+uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx)
+{
+	struct plane *sprite;
+
 	assert(to_sna_crtc(crtc));
-	return to_sna_crtc(crtc)->sprite.id;
+
+	sprite = lookup_sprite(to_sna_crtc(crtc), idx);
+	return sprite ? sprite->id : 0;
 }
 
 bool sna_crtc_is_transformed(xf86CrtcPtr crtc)
@@ -1253,17 +1270,23 @@ rotation_reset(struct plane *p)
 	p->rotation.current = 0;
 }
 
-bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation)
+bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc,
+				  unsigned idx,
+				  uint32_t rotation)
 {
+	struct plane *sprite;
 	assert(to_sna_crtc(crtc));
 	DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n",
 	     __FUNCTION__,
 	     sna_crtc_id(crtc), sna_crtc_pipe(crtc),
 	     to_sna_crtc(crtc)->sprite.id, rotation));
 
-	return rotation_set(to_sna(crtc->scrn),
-			    &to_sna_crtc(crtc)->sprite,
-			    rotation_reduce(&to_sna_crtc(crtc)->sprite, rotation));
+	sprite = lookup_sprite(to_sna_crtc(crtc), idx);
+	if (!sprite)
+		return false;
+
+	return rotation_set(to_sna(crtc->scrn), sprite,
+			    rotation_reduce(sprite, rotation));
 }
 
 #if HAS_DEBUG_FULL
@@ -3005,10 +3028,14 @@ static void
 sna_crtc_destroy(xf86CrtcPtr crtc)
 {
 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct plane *sprite, *sn;
 
 	if (sna_crtc == NULL)
 		return;
 
+	list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
+		free(sprite);
+
 	free(sna_crtc);
 	crtc->driver_private = NULL;
 }
@@ -3158,6 +3185,17 @@ static int plane_details(struct sna *sna, struct plane *p)
 	return type;
 }
 
+static void add_sprite_plane(struct sna_crtc *crtc,
+			     struct plane *details)
+{
+	struct plane *sprite = malloc(sizeof(*sprite));
+	if (!sprite)
+		return;
+
+	memcpy(sprite, details, sizeof(*sprite));
+	list_add(&sprite->link, &crtc->sprites);
+}
+
 static void
 sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc)
 {
@@ -3231,8 +3269,7 @@ sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc)
 			break;
 
 		case DRM_PLANE_TYPE_OVERLAY:
-			if (crtc->sprite.id == 0)
-				crtc->sprite = details;
+			add_sprite_plane(crtc, &details);
 			break;
 		}
 	}
@@ -3247,7 +3284,6 @@ sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
 	crtc->rotation = RR_Rotate_0;
 	crtc->primary.rotation.supported = RR_Rotate_0;
 	crtc->primary.rotation.current = RR_Rotate_0;
-	crtc->sprite.rotation = crtc->primary.rotation;
 }
 
 static void
@@ -3299,8 +3335,8 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
 		return true;
 	}
 
+	list_init(&sna_crtc->sprites);
 	sna_crtc_init__rotation(sna, sna_crtc);
-
 	sna_crtc_find_planes(sna, sna_crtc);
 
 	DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x, sprite id=%x: supported-rotations=%x, current-rotation=%x\n",
@@ -8084,6 +8120,7 @@ static bool
 sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
 {
 	struct local_mode_set_plane s;
+	struct plane *plane;
 
 	if (crtc->primary.id == 0)
 		return false;
@@ -8093,8 +8130,10 @@ sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
 		return false;
 
-	s.plane_id = crtc->sprite.id;
-	(void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s);
+	list_for_each_entry(plane, &crtc->sprites, link) {
+		s.plane_id = plane->id;
+		(void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s);
+	}
 
 	__sna_crtc_disable(sna, crtc);
 	return true;
@@ -8118,12 +8157,14 @@ void sna_mode_reset(struct sna *sna)
 
 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
 		struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]);
+		struct plane *plane;
 
 		assert(sna_crtc != NULL);
 
 		/* Force the rotation property to be reset on next use */
 		rotation_reset(&sna_crtc->primary);
-		rotation_reset(&sna_crtc->sprite);
+		list_for_each_entry(plane, &sna_crtc->sprites, link)
+			rotation_reset(plane);
 	}
 
 	/* VT switching, likely to be fbcon so make the backlight usable */
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index 1498707..17b272c 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -91,7 +91,7 @@ static int sna_video_sprite_stop(ddStopVideo_ARGS)
 			continue;
 
 		memset(&s, 0, sizeof(s));
-		s.plane_id = sna_crtc_to_sprite(crtc);
+		s.plane_id = sna_crtc_to_sprite(crtc, 0);
 		if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
 			xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
 				   "failed to disable plane\n");
@@ -224,7 +224,7 @@ sna_video_sprite_show(struct sna *sna,
 	/* XXX handle video spanning multiple CRTC */
 
 	VG_CLEAR(s);
-	s.plane_id = sna_crtc_to_sprite(crtc);
+	s.plane_id = sna_crtc_to_sprite(crtc, 0);
 
 #define DRM_I915_SET_SPRITE_COLORKEY 0x2b
 #define LOCAL_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct local_intel_sprite_colorkey)
@@ -422,7 +422,7 @@ off:
 			if (video->bo[pipe]) {
 				struct local_mode_set_plane s;
 				memset(&s, 0, sizeof(s));
-				s.plane_id = sna_crtc_to_sprite(crtc);
+				s.plane_id = sna_crtc_to_sprite(crtc, 0);
 				if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
 					xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
 						   "failed to disable plane\n");
@@ -461,8 +461,8 @@ off:
 
 		/* if sprite can't handle rotation natively, store it for the copy func */
 		rotation = RR_Rotate_0;
-		if (!sna_crtc_set_sprite_rotation(crtc, crtc->rotation)) {
-			sna_crtc_set_sprite_rotation(crtc, RR_Rotate_0);
+		if (!sna_crtc_set_sprite_rotation(crtc, 0, crtc->rotation)) {
+			sna_crtc_set_sprite_rotation(crtc, 0, RR_Rotate_0);
 			rotation = crtc->rotation;
 		}
 		sna_video_frame_set_rotation(video, &frame, rotation);
@@ -662,7 +662,7 @@ static bool sna_video_has_sprites(struct sna *sna)
 		return false;
 
 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
-		if (!sna_crtc_to_sprite(config->crtc[i])) {
+		if (!sna_crtc_to_sprite(config->crtc[i], 0)) {
 			DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_pipe(config->crtc[i])));
 			return false;
 		}


More information about the xorg-commit mailing list