[Intel-gfx] [PATCH v4 DDX] sna/video sprite patch: support for multiple xv ports

Michael Hadley michaelx.hadley at intel.com
Thu Mar 31 13:08:03 UTC 2016


The current driver exposes only a single adaptor port so that only one
xv video can be played on sprite at a time. This change will allow
available hardware sprites to be used.

v4: re-formatted code, renamed sprite_disable_unlock() to sprite_unlock()
    to be clearer. Also moved the sprite locking mechanism from
    sprite_disable() to sna_crtc_sprite_unlock(), seperating the logic
    between both functions and isolating them to their specific purposes.

v3: updated patch from lornax.mcneill at intel.com. removed/added
    whitespace, re-formatted code, removed redundent variable allocation.

v2: removed/added whitespace, check for NULL return from calloc
    made requested changes to simplify code (not exactly as requested
    due to struct sprite being 'private' to sna_display.c).

Signed-off-by: Michael Hadley <michaelx.hadley at intel.com>
Reviewed--by: Bob Paauwe <bob.j.paauwe at intel.com>
---
 src/sna/sna.h                |   7 +-
 src/sna/sna_display.c        | 201 ++++++++++++++++++++++++++++++++++++-------
 src/sna/sna_video.h          |   2 +
 src/sna/sna_video_sprite.c   | 146 ++++++++++++++++++-------------
 src/sna/sna_video_textured.c |   2 +-
 5 files changed, 260 insertions(+), 98 deletions(-)

diff --git a/src/sna/sna.h b/src/sna/sna.h
index e5ca906..0fce602 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -608,8 +608,11 @@ 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, uint32_t rotation, DrawablePtr draw);
+extern uint32_t sna_crtc_num_sprites(xf86CrtcPtr crtc);
+extern bool sna_crtc_drawable_to_sprite_id(xf86CrtcPtr crtc, DrawablePtr draw, uint32_t *id);
+extern bool sna_crtc_sprite_lock(xf86CrtcPtr crtc, DrawablePtr draw);
+extern void sna_crtc_sprite_unlock(xf86CrtcPtr crtc, DrawablePtr draw);
 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 6ceb515..9495845 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -221,7 +221,15 @@ struct sna_crtc {
 			uint32_t supported;
 			uint32_t current;
 		} rotation;
-	} primary, sprite;
+	} primary;
+
+	struct sprite {
+		struct plane plane;
+		DrawablePtr locked_to; /* drawable the sprite was grabbed for */
+		struct xorg_list link;
+	} sprite; /* TODO way to suppress anonymous struct warning "declaration does not declare anything" without ming? */
+
+	struct xorg_list sprites; /* sprites that can be displayed on this crtc */
 
 	uint32_t mode_serial, flip_serial;
 
@@ -438,10 +446,111 @@ static inline uint32_t fb_id(struct kgem_bo *bo)
 	return bo->delta;
 }
 
-uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc)
+uint32_t sna_crtc_num_sprites(xf86CrtcPtr crtc)
+{
+	struct sna_crtc *sna_crtc;
+	struct sprite *sp = NULL;
+	uint32_t num_sprites = 0;
+
+	sna_crtc = to_sna_crtc(crtc);
+
+	xorg_list_for_each_entry(sp, &sna_crtc->sprites, link) {
+		num_sprites++;
+	}
+
+	DBG(("%s: %d sprites\n", __FUNCTION__, num_sprites));
+
+	return num_sprites;
+}
+
+/*
+ * return the sprite attached to the specified crtc
+ * and locked to the specified drawable if there is one.
+ */
+static struct sprite * sna_crtc_drawable_to_sprite(xf86CrtcPtr crtc, DrawablePtr draw)
 {
+	struct sna_crtc *sna_crtc;
+	struct sprite *sp = NULL;
+
+	sna_crtc = to_sna_crtc(crtc);
+
+	xorg_list_for_each_entry(sp, &sna_crtc->sprites, link) {
+		if (sp->locked_to == draw) {
+			return sp;
+		}
+	}
+	return NULL;
+}
+
+/*
+ * gets the sprite id for the sprite attached to the specified crtc
+ * and locked to the specified drawable if there is one.
+ */
+bool sna_crtc_drawable_to_sprite_id(xf86CrtcPtr crtc, DrawablePtr draw, uint32_t *sprite_id)
+{
+	struct sprite *sp = sna_crtc_drawable_to_sprite(crtc, draw);
+
+	if (sp) {
+		*sprite_id = sp->plane.id;
+		return true;
+	}
+	return false;
+}
+
+static void sprite_disable(struct sprite *sp, struct sna *sna)
+{
+	struct local_mode_set_plane s;
+
+	DBG(("%s: unlocking sprite %d\n", __FUNCTION__, sp->plane.id));
+	memset(&s, 0, sizeof(s));
+	s.plane_id = sp->plane.id;
+	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
+		xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "failed to disable plane\n");
+}
+
+/*
+ * If there's a sprite on this crtc using the specified drawable, then unlock
+ * it and disable the sprite
+ */
+void sna_crtc_sprite_unlock(xf86CrtcPtr crtc, DrawablePtr draw)
+{
+	struct sna_crtc *sna_crtc;
+	struct sprite *sp = NULL;
+	struct sna *sna = to_sna(crtc->scrn);
+
+	sna_crtc = to_sna_crtc(crtc);
 	assert(to_sna_crtc(crtc));
-	return to_sna_crtc(crtc)->sprite.id;
+
+	if (sp = sna_crtc_drawable_to_sprite(crtc, draw)) {
+		sprite_disable(sp, sna);
+		sp->locked_to = NULL;
+	}
+}
+
+/*
+ * Lock one of this crtc's sprites to this drawable
+ * if haven't already and there is one available  */
+bool sna_crtc_sprite_lock(xf86CrtcPtr crtc, DrawablePtr draw)
+{
+	struct sna_crtc *sna_crtc;
+	struct sprite *sp = NULL;
+
+	sna_crtc = to_sna_crtc(crtc);
+	assert(to_sna_crtc(crtc));
+
+	sp = sna_crtc_drawable_to_sprite(crtc, draw);
+	if (!sp) {
+		xorg_list_for_each_entry(sp, &sna_crtc->sprites, link) {
+			if (!sp->locked_to) {
+				DBG(("%s: locking sprite %d\n", __FUNCTION__, sp->plane.id));
+				sp->locked_to = draw;
+				return true;
+			}
+		}
+		DBG(("%s: No free sprites\n", __FUNCTION__));
+		return false;
+	}
+	return true;
 }
 
 bool sna_crtc_is_transformed(xf86CrtcPtr crtc)
@@ -1239,17 +1348,20 @@ 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, uint32_t rotation, DrawablePtr draw)
 {
-	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));
+	struct sprite *sp = NULL;
 
-	return rotation_set(to_sna(crtc->scrn),
-			    &to_sna_crtc(crtc)->sprite,
-			    rotation_reduce(&to_sna_crtc(crtc)->sprite, rotation));
+	sp = sna_crtc_drawable_to_sprite(crtc, draw);
+	if (sp) {
+		DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n",
+				__FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc),
+				sp->plane.id, rotation));
+		if (!rotation_set(to_sna(crtc->scrn),
+				&sp->plane, rotation_reduce(&sp->plane, rotation)))
+			return FALSE;
+       }
+	return true;
 }
 
 #if HAS_DEBUG_FULL
@@ -1645,7 +1757,6 @@ static bool wait_for_shadow(struct sna *sna,
 			RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, &region);
 		}
 
-		crtc->client_bo->active_scanout--;
 		kgem_bo_destroy(&sna->kgem, crtc->client_bo);
 		crtc->client_bo = NULL;
 		list_del(&crtc->shadow_link);
@@ -1871,8 +1982,7 @@ static void sna_crtc_disable_override(struct sna *sna, struct sna_crtc *crtc)
 	if (crtc->client_bo == NULL)
 		return;
 
-	assert(crtc->client_bo->refcnt >= crtc->client_bo->active_scanout);
-	crtc->client_bo->active_scanout--;
+	assert(crtc->client_bo->refcnt > crtc->client_bo->active_scanout);
 
 	if (!crtc->transform) {
 		DrawableRec tmp;
@@ -2985,10 +3095,15 @@ sna_crtc_gamma_set(xf86CrtcPtr crtc,
 static void
 sna_crtc_destroy(xf86CrtcPtr crtc)
 {
+	struct sprite *sp = NULL, *tmp = NULL;
 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 
 	if (sna_crtc == NULL)
 		return;
+	
+	xorg_list_for_each_entry_safe( sp, tmp, &sna_crtc->sprites, link) {
+		free(sp);
+	}
 
 	free(sna_crtc);
 	crtc->driver_private = NULL;
@@ -3212,9 +3327,20 @@ 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;
-			break;
+			{
+				struct sprite *s = calloc(1, sizeof( struct sprite ));
+
+				if (s) {
+					s->locked_to = NULL;
+					s->plane = details;
+					xorg_list_append(&s->link, &crtc->sprites);
+				} else {
+					DBG(("%s: Could not allocate memory for sprite \n",
+							__FUNCTION__));
+				}
+
+				break;
+			}
 		}
 	}
 
@@ -3225,10 +3351,14 @@ sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc)
 static void
 sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
 {
+	struct sprite *sp = NULL;
+	
 	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;
+	xorg_list_for_each_entry(sp, &crtc->sprites, link) {
+		sp->plane.rotation = crtc->primary.rotation;
+	}
 }
 
 static void
@@ -3281,14 +3411,16 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
 		return true;
 	}
 
+	xorg_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",
-	     __FUNCTION__, id, get_pipe.pipe,
-	     sna_crtc->primary.id, sna_crtc->primary.rotation.supported, sna_crtc->primary.rotation.current,
-	     sna_crtc->sprite.id, sna_crtc->sprite.rotation.supported, sna_crtc->sprite.rotation.current));
+	
+	DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x,"
+			" current-rotation=%x\n", __FUNCTION__, id, get_pipe.pipe,
+			sna_crtc->primary.id, sna_crtc->primary.rotation.supported,
+			sna_crtc->primary.rotation.current));
 
 	list_init(&sna_crtc->shadow_link);
 
@@ -7977,6 +8109,7 @@ static bool
 sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
 {
 	struct local_mode_set_plane s;
+	struct sprite *sp = NULL;
 
 	if (crtc->primary.id == 0)
 		return false;
@@ -7986,8 +8119,9 @@ 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);
+	xorg_list_for_each_entry(sp, &crtc->sprites, link) {
+		sprite_disable(sp, sna);
+	}
 
 	__sna_crtc_disable(sna, crtc);
 	return true;
@@ -8010,13 +8144,17 @@ void sna_mode_reset(struct sna *sna)
 	assert(sna->mode.front_active == 0);
 
 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
+		struct sprite *sp = NULL;
 		struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]);
 
 		assert(sna_crtc != NULL);
 
 		/* Force the rotation property to be reset on next use */
 		rotation_reset(&sna_crtc->primary);
-		rotation_reset(&sna_crtc->sprite);
+		
+		xorg_list_for_each_entry(sp, &sna_crtc->sprites, link) {
+			rotation_reset(&sp->plane);
+		}
 	}
 
 	/* VT switching, likely to be fbcon so make the backlight usable */
@@ -8403,14 +8541,12 @@ void sna_shadow_set_crtc(struct sna *sna,
 
 	if (sna_crtc->client_bo != bo) {
 		if (sna_crtc->client_bo) {
-			assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout);
-			sna_crtc->client_bo->active_scanout--;
+			assert(sna_crtc->client_bo->refcnt > sna_crtc->client_bo->active_scanout);
 			kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
 		}
 
 		sna_crtc->client_bo = kgem_bo_reference(bo);
-		sna_crtc->client_bo->active_scanout++;
-		assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout);
+		assert(sna_crtc->client_bo->refcnt > sna_crtc->client_bo->active_scanout);
 		sna_crtc_damage(crtc);
 	}
 
@@ -8465,8 +8601,7 @@ void sna_shadow_unset_crtc(struct sna *sna,
 	if (sna_crtc->client_bo == NULL)
 		return;
 
-	assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout);
-	sna_crtc->client_bo->active_scanout--;
+	assert(sna_crtc->client_bo->refcnt > sna_crtc->client_bo->active_scanout);
 	kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
 	sna_crtc->client_bo = NULL;
 	list_del(&sna_crtc->shadow_link);
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index b278991..24ce4fc 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -133,6 +133,8 @@ void sna_video_textured_setup(struct sna *sna, ScreenPtr screen);
 void sna_video_destroy_window(WindowPtr win);
 void sna_video_close(struct sna *sna);
 
+int sna_video_textured_put_image(ddPutImage_ARGS);
+
 XvAdaptorPtr sna_xv_adaptor_alloc(struct sna *sna);
 int sna_xv_fixup_formats(ScreenPtr screen,
 			 XvFormatPtr formats,
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index ae08ef7..a30528f 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -77,7 +77,6 @@ static const XvAttributeRec attribs[] = {
 static int sna_video_sprite_stop(ddStopVideo_ARGS)
 {
 	struct sna_video *video = port->devPriv.ptr;
-	struct local_mode_set_plane s;
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(video->sna->scrn);
 	int i;
 
@@ -90,11 +89,7 @@ static int sna_video_sprite_stop(ddStopVideo_ARGS)
 		if (video->bo[pipe] == NULL)
 			continue;
 
-		memset(&s, 0, sizeof(s));
-		s.plane_id = sna_crtc_to_sprite(crtc);
-		if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
-			xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
-				   "failed to disable plane\n");
+		sna_crtc_sprite_unlock(crtc, draw);
 
 		if (video->bo[pipe])
 			kgem_bo_destroy(&video->sna->kgem, video->bo[pipe]);
@@ -216,6 +211,7 @@ sna_video_sprite_show(struct sna *sna,
 		      struct sna_video *video,
 		      struct sna_video_frame *frame,
 		      xf86CrtcPtr crtc,
+		      DrawablePtr draw,
 		      BoxPtr dstBox)
 {
 	struct local_mode_set_plane s;
@@ -224,7 +220,12 @@ sna_video_sprite_show(struct sna *sna,
 	/* XXX handle video spanning multiple CRTC */
 
 	VG_CLEAR(s);
-	s.plane_id = sna_crtc_to_sprite(crtc);
+	
+	if(!sna_crtc_drawable_to_sprite_id(crtc, draw, &s.plane_id)) {
+		ERR(("%s: no sprite for this drawable\n", __FUNCTION__));
+		return false;
+	}
+
 
 #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)
@@ -417,14 +418,11 @@ static int sna_video_sprite_put_image(ddPutImage_ARGS)
 		RegionIntersect(&reg, &reg, &clip);
 		if (RegionNil(&reg)) {
 off:
-			assert(pipe < ARRAY_SIZE(video->bo));
 			if (video->bo[pipe]) {
-				struct local_mode_set_plane s;
-				memset(&s, 0, sizeof(s));
-				s.plane_id = sna_crtc_to_sprite(crtc);
-				if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
-					xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
-						   "failed to disable plane\n");
+				DBG(("%s: unlock sprite as no longer intersects\n",
+						__FUNCTION__));
+				/* image no longer on sprite plane, unlock sprite */
+				sna_crtc_sprite_unlock(crtc, draw);
 				video->bo[pipe] = NULL;
 			}
 			continue;
@@ -443,6 +441,26 @@ off:
 		if (!ret)
 			goto off;
 
+		if (!sna_crtc_sprite_lock(crtc, draw)) {
+			xf86DrvMsg(sna->scrn->scrnIndex,
+					X_ERROR, "failed to get a sprite plane,"
+					" fallback to textured \n");
+			#if XORG_XV_VERSION < 2
+				(void)sna_video_sprite_stop(client, port, draw);
+				return sna_video_textured_put_image(client, draw, port,
+								gc, src_x, src_y, src_w, src_h,
+								drw_x, drw_y, drw_w, drw_h, format,
+								buf, sync, width, height);
+			#else
+				(void)sna_video_sprite_stop(port, draw);
+				return sna_video_textured_put_image(draw, port, gc,
+								src_x, src_y,
+								src_w, src_h, drw_x, drw_y, drw_w,
+								drw_h, format, buf,
+								sync, width, height);
+			#endif
+		}
+
 		frame.src.x1 = x1 >> 16;
 		frame.src.y1 = y1 >> 16;
 		frame.src.x2 = (x2 + 0xffff) >> 16;
@@ -460,8 +478,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, crtc->rotation, draw)) {
+			sna_crtc_set_sprite_rotation(crtc, RR_Rotate_0, draw);
 			rotation = crtc->rotation;
 		}
 		sna_video_frame_set_rotation(video, &frame, rotation);
@@ -507,7 +525,7 @@ off:
 		}
 
 		ret = Success;
-		if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst)) {
+		if (!sna_video_sprite_show(sna, video, &frame, crtc, draw, &dst)) {
 			DBG(("%s: failed to show video frame\n", __FUNCTION__));
 			ret = BadAlloc;
 		}
@@ -594,45 +612,44 @@ 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 uint32_t sna_video_num_sprites(struct sna *sna)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
-	int i;
+	int i, n = 0;
 
 	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])) {
-			DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_pipe(config->crtc[i])));
-			return false;
-		}
+		n += sna_crtc_num_sprites(config->crtc[i]);
 	}
 
-	DBG(("%s: yes\n", __FUNCTION__));
-	return true;
+	DBG(("%s: %d sprites\n", __FUNCTION__, n));
+	return n;
 }
 
 void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 {
 	XvAdaptorPtr adaptor;
 	struct sna_video *video;
-	XvPortPtr port;
+	uint32_t i, nports = 0;
+
+	nports = sna_video_num_sprites(sna);
 
-	if (!sna_video_has_sprites(sna))
+	if (!nports)
 		return;
 
 	adaptor = sna_xv_adaptor_alloc(sna);
 	if (!adaptor)
 		return;
 
-	video = calloc(1, sizeof(*video));
-	port = calloc(1, sizeof(*port));
-	if (video == NULL || port == NULL) {
+	video = calloc(nports, sizeof(*video));
+	adaptor->pPorts = calloc(nports, sizeof(XvPortRec));
+	if (video == NULL || adaptor->pPorts == NULL) {
 		free(video);
-		free(port);
+		free(adaptor->pPorts);
 		sna->xv.num_adaptors--;
 		return;
 	}
@@ -674,36 +691,41 @@ 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->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 < nports; ++i) {
+		struct sna_video *v = &video[i];
+		XvPortPtr port = &adaptor->pPorts[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 = v;
+
+		v->sna = sna;
+		v->alignment = 64;
+		v->color_key = sna_video_sprite_color_key(sna);
+		v->color_key_changed = ~0;
+		v->has_color_key = true;
+		v->brightness = -19;    /* (255/219) * -16 */
+		v->contrast = 75;       /* 255/219 * 64 */
+		v->saturation = 146;    /* 128/112 * 128 */
+		v->desired_crtc = NULL;
+		v->gamma5 = 0xc0c0c0;
+		v->gamma4 = 0x808080;
+		v->gamma3 = 0x404040;
+		v->gamma2 = 0x202020;
+		v->gamma1 = 0x101010;
+		v->gamma0 = 0x080808;
+		RegionNull(&v->clip);
+		v->SyncToVblank = 1;
+	}
+
+	adaptor->base_id = adaptor->pPorts[0].id;
+	adaptor->nPorts = nports;
 
 	xvColorKey = MAKE_ATOM("XV_COLORKEY");
 	xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index f5b7e98..baf7c91 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -138,7 +138,7 @@ sna_video_textured_best_size(ddQueryBestSize_ARGS)
  * drawable is some Drawable, which might not be the screen in the case of
  * compositing.  It's a new argument to the function in the 1.1 server.
  */
-static int
+int
 sna_video_textured_put_image(ddPutImage_ARGS)
 {
 	struct sna_video *video = port->devPriv.ptr;
-- 
1.9.3



More information about the Intel-gfx mailing list