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 [email protected]. 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 <[email protected]>
Reviewed--by: Bob Paauwe <[email protected]>
---
 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

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to