xf86-video-intel: 2 commits - src/compat-api.h src/sna/sna_accel.c src/sna/sna_driver.c src/sna/sna.h src/sna/sna_video.c src/sna/sna_video.h src/sna/sna_video_hwmc.c src/sna/sna_video_hwmc.h src/sna/sna_video_overlay.c src/sna/sna_video_sprite.c src/sna/sna_video_textured.c

Chris Wilson ickle at kemper.freedesktop.org
Tue May 21 03:15:02 PDT 2013


 src/compat-api.h             |    1 
 src/sna/sna.h                |    6 
 src/sna/sna_accel.c          |    4 
 src/sna/sna_driver.c         |    4 
 src/sna/sna_video.c          |  162 +++++++++++++-------
 src/sna/sna_video.h          |   44 ++++-
 src/sna/sna_video_hwmc.c     |   64 +++-----
 src/sna/sna_video_hwmc.h     |    2 
 src/sna/sna_video_overlay.c  |  344 ++++++++++++++++++++++---------------------
 src/sna/sna_video_sprite.c   |  282 ++++++++++++++++++++---------------
 src/sna/sna_video_textured.c |  257 +++++++++++++++-----------------
 11 files changed, 655 insertions(+), 515 deletions(-)

New commits:
commit 195a51353c3af7bd253227da5f759f06cea01f73
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Apr 9 19:13:46 2013 +0100

    sna/video: Convert to a pure Xv backend
    
    This is to enable feature work which requires access to Client state.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/compat-api.h b/src/compat-api.h
index 6d147c7..d80b7fe 100644
--- a/src/compat-api.h
+++ b/src/compat-api.h
@@ -128,6 +128,7 @@
 #define RegionNull(r) REGION_NULL(NULL, r)
 #define RegionNotEmpty(r) REGION_NOTEMPTY(NULL, r)
 #define RegionEmpty(r) REGION_EMPTY(NULL, r)
+#define RegionEqual(a, b) REGION_EQUAL(NULL, a, b)
 #define RegionDestroy(r) REGION_DESTROY(NULL, r)
 #else
 #define region_from_bitmap BitmapToRegion
diff --git a/src/sna/sna.h b/src/sna/sna.h
index ee3f821..79ac1ad 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -57,6 +57,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <glyphstr.h>
 #include <picturestr.h>
 #include <gcstruct.h>
+#include <xvdix.h>
 
 #include <pciaccess.h>
 
@@ -256,6 +257,11 @@ struct sna {
 		void *flip_pending;
 	} dri;
 
+	struct sna_xv {
+		XvAdaptorPtr adaptors;
+		int num_adaptors;
+	} xv;
+
 	unsigned int tiling;
 #define SNA_TILING_FB		0x1
 #define SNA_TILING_2D		0x2
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 6a9fb1d..0e4d8fe 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -32,6 +32,7 @@
 #include "intel_options.h"
 #include "sna.h"
 #include "sna_reg.h"
+#include "sna_video.h"
 #include "rop.h"
 
 #include <X11/fonts/font.h>
@@ -14479,6 +14480,7 @@ sna_unmap_window(WindowPtr win)
 static Bool
 sna_destroy_window(WindowPtr win)
 {
+	sna_video_destroy_window(win);
 	sna_dri_destroy_window(win);
 	return TRUE;
 }
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 1cfba5b..a29661c 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -916,7 +916,7 @@ sna_register_all_privates(void)
 		return FALSE;
 
 	if (!dixRegisterPrivateKey(&sna_window_key, PRIVATE_WINDOW,
-				   2*sizeof(void *)))
+				   3*sizeof(void *)))
 		return FALSE;
 #else
 	if (!dixRequestPrivate(&sna_pixmap_key, 3*sizeof(void *)))
@@ -928,7 +928,7 @@ sna_register_all_privates(void)
 	if (!dixRequestPrivate(&sna_glyph_key, sizeof(struct sna_glyph)))
 		return FALSE;
 
-	if (!dixRequestPrivate(&sna_window_key, 2*sizeof(void *)))
+	if (!dixRequestPrivate(&sna_window_key, 3*sizeof(void *)))
 		return FALSE;
 #endif
 
diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c
index 6d067c7..eb4f846 100644
--- a/src/sna/sna_video.c
+++ b/src/sna/sna_video.c
@@ -71,39 +71,38 @@ static inline void sna_video_xvmc_setup(struct sna *sna, ScreenPtr ptr)
 }
 #endif
 
-void sna_video_free_buffers(struct sna *sna, struct sna_video *video)
+void sna_video_free_buffers(struct sna_video *video)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(video->old_buf); i++) {
 		if (video->old_buf[i]) {
-			kgem_bo_destroy(&sna->kgem, video->old_buf[i]);
+			kgem_bo_destroy(&video->sna->kgem, video->old_buf[i]);
 			video->old_buf[i] = NULL;
 		}
 	}
 
 	if (video->buf) {
-		kgem_bo_destroy(&sna->kgem, video->buf);
+		kgem_bo_destroy(&video->sna->kgem, video->buf);
 		video->buf = NULL;
 	}
 }
 
 struct kgem_bo *
-sna_video_buffer(struct sna *sna,
-		 struct sna_video *video,
+sna_video_buffer(struct sna_video *video,
 		 struct sna_video_frame *frame)
 {
 	/* Free the current buffer if we're going to have to reallocate */
 	if (video->buf && __kgem_bo_size(video->buf) < frame->size)
-		sna_video_free_buffers(sna, video);
+		sna_video_free_buffers(video);
 
 	if (video->buf == NULL) {
 		if (video->tiled) {
-			video->buf = kgem_create_2d(&sna->kgem,
+			video->buf = kgem_create_2d(&video->sna->kgem,
 						    frame->width, frame->height, 32,
 						    I915_TILING_X, CREATE_EXACT);
 		} else {
-			video->buf = kgem_create_linear(&sna->kgem, frame->size,
+			video->buf = kgem_create_linear(&video->sna->kgem, frame->size,
 							CREATE_GTT_MAP);
 		}
 	}
@@ -111,8 +110,7 @@ sna_video_buffer(struct sna *sna,
 	return video->buf;
 }
 
-void sna_video_buffer_fini(struct sna *sna,
-			   struct sna_video *video)
+void sna_video_buffer_fini(struct sna_video *video)
 {
 	struct kgem_bo *bo;
 
@@ -189,8 +187,7 @@ sna_video_clip_helper(ScrnInfoPtr scrn,
 }
 
 void
-sna_video_frame_init(struct sna *sna,
-		     struct sna_video *video,
+sna_video_frame_init(struct sna_video *video,
 		     int id, short width, short height,
 		     struct sna_video_frame *frame)
 {
@@ -208,7 +205,7 @@ sna_video_frame_init(struct sna *sna,
 	align = video->alignment;
 #if SNA_XVMC
 	/* for i915 xvmc, hw requires 1kb aligned surfaces */
-	if (id == FOURCC_XVMC && sna->kgem.gen < 040 && align < 1024)
+	if (id == FOURCC_XVMC && video->sna->kgem.gen < 040 && align < 1024)
 		align = 1024;
 #endif
 
@@ -439,8 +436,7 @@ sna_copy_packed_data(struct sna_video *video,
 }
 
 bool
-sna_video_copy_data(struct sna *sna,
-		    struct sna_video *video,
+sna_video_copy_data(struct sna_video *video,
 		    struct sna_video_frame *frame,
 		    const uint8_t *buf)
 {
@@ -468,10 +464,10 @@ sna_video_copy_data(struct sna *sna,
 			    ALIGN(w >> 1, 4) == frame->pitch[0] &&
 			    ALIGN(w, 4) == frame->pitch[1]) {
 				if (frame->bo) {
-					kgem_bo_write(&sna->kgem, frame->bo,
+					kgem_bo_write(&video->sna->kgem, frame->bo,
 						      buf, frame->size);
 				} else {
-					frame->bo = kgem_create_buffer(&sna->kgem, frame->size,
+					frame->bo = kgem_create_buffer(&video->sna->kgem, frame->size,
 								       KGEM_BUFFER_WRITE | KGEM_BUFFER_WRITE_INPLACE,
 								       (void **)&dst);
 					if (frame->bo == NULL)
@@ -490,11 +486,11 @@ sna_video_copy_data(struct sna *sna,
 		} else {
 			if (frame->width*2 == frame->pitch[0]) {
 				if (frame->bo) {
-					kgem_bo_write(&sna->kgem, frame->bo,
+					kgem_bo_write(&video->sna->kgem, frame->bo,
 						      buf + (2U*frame->image.y1 * frame->width) + (frame->image.x1 << 1),
 						      2U*(frame->image.y2-frame->image.y1)*frame->width);
 				} else {
-					frame->bo = kgem_create_buffer(&sna->kgem, frame->size,
+					frame->bo = kgem_create_buffer(&video->sna->kgem, frame->size,
 								       KGEM_BUFFER_WRITE | KGEM_BUFFER_WRITE_INPLACE,
 								       (void **)&dst);
 					if (frame->bo == NULL)
@@ -513,11 +509,11 @@ sna_video_copy_data(struct sna *sna,
 
 	/* copy data, must use GTT so that we keep the overlay uncached */
 	if (frame->bo) {
-		dst = kgem_bo_map__gtt(&sna->kgem, frame->bo);
+		dst = kgem_bo_map__gtt(&video->sna->kgem, frame->bo);
 		if (dst == NULL)
 			return false;
 	} else {
-		frame->bo = kgem_create_buffer(&sna->kgem, frame->size,
+		frame->bo = kgem_create_buffer(&video->sna->kgem, frame->size,
 					       KGEM_BUFFER_WRITE | KGEM_BUFFER_WRITE_INPLACE,
 					       (void **)&dst);
 		if (frame->bo == NULL)
@@ -532,50 +528,108 @@ sna_video_copy_data(struct sna *sna,
 	return true;
 }
 
+XvAdaptorPtr sna_xv_adaptor_alloc(struct sna *sna)
+{
+	XvAdaptorPtr new_adaptors;
+
+	new_adaptors = realloc(sna->xv.adaptors,
+			       (sna->xv.num_adaptors+1)*sizeof(XvAdaptorRec));
+	if (new_adaptors == NULL)
+		return NULL;
+
+	if (sna->xv.num_adaptors && new_adaptors != sna->xv.adaptors) {
+		XvAdaptorPtr adaptor = new_adaptors;
+		int i = sna->xv.num_adaptors, j;
+		while (i--) {
+			for (j = 0; j < adaptor->nPorts; j++)
+				adaptor->pPorts[j].pAdaptor = adaptor;
+			adaptor++;
+		}
+	}
+
+	sna->xv.adaptors = new_adaptors;
+	return &sna->xv.adaptors[sna->xv.num_adaptors++];
+}
+
+int
+sna_xv_alloc_port(unsigned long port, XvPortPtr in, XvPortPtr *out)
+{
+	*out = in;
+	return Success;
+}
+
+int
+sna_xv_free_port(XvPortPtr port)
+{
+	return Success;
+}
+
+static int
+sna_xv_query_adaptors(ScreenPtr screen,
+		      XvAdaptorPtr *adaptors,
+		      int *num_adaptors)
+{
+	struct sna *sna = to_sna_from_screen(screen);
+
+	*num_adaptors = sna->xv.num_adaptors;
+	*adaptors = sna->xv.adaptors;
+	return Success;
+}
+
+static Bool
+sna_xv_close_screen(ScreenPtr screen)
+{
+	return TRUE;
+}
+
 void sna_video_init(struct sna *sna, ScreenPtr screen)
 {
-	XF86VideoAdaptorPtr *adaptors, *newAdaptors;
-	XF86VideoAdaptorPtr textured, overlay;
-	int num_adaptors;
-	int prefer_overlay =
-	    xf86ReturnOptValBool(sna->Options, OPTION_PREFER_OVERLAY, false);
+	XvScreenPtr xv;
 
-	if (!xf86LoaderCheckSymbol("xf86XVListGenericAdaptors"))
+	if (noXvExtension)
 		return;
 
-	adaptors = NULL;
-	num_adaptors = xf86XVListGenericAdaptors(sna->scrn, &adaptors);
-	newAdaptors = realloc(adaptors,
-			      (num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr));
-	if (newAdaptors == NULL) {
+	if (xf86LoaderCheckSymbol("xf86XVListGenericAdaptors")) {
+		XF86VideoAdaptorPtr *adaptors = NULL;
+		int num_adaptors = xf86XVListGenericAdaptors(sna->scrn, &adaptors);
+		if (num_adaptors)
+			xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
+				   "Ignoring generic xf86XV adaptors");
 		free(adaptors);
-		return;
 	}
-	adaptors = newAdaptors;
 
-	/* Set up textured video if we can do it at this depth and we are on
-	 * supported hardware.
-	 */
-	textured = sna_video_textured_setup(sna, screen);
-	overlay = sna_video_sprite_setup(sna, screen);
-	if (overlay == NULL)
-		overlay = sna_video_overlay_setup(sna, screen);
+	if (XvScreenInit(screen) != Success)
+		return;
 
-	if (overlay && prefer_overlay)
-		adaptors[num_adaptors++] = overlay;
+	xv = to_xv(screen);
+	xv->ddCloseScreen = sna_xv_close_screen;
+	xv->ddQueryAdaptors = sna_xv_query_adaptors;
 
-	if (textured)
-		adaptors[num_adaptors++] = textured;
+	sna_video_textured_setup(sna, screen);
+	sna_video_sprite_setup(sna, screen);
+	sna_video_overlay_setup(sna, screen);
 
-	if (overlay && !prefer_overlay)
-		adaptors[num_adaptors++] = overlay;
+	if (sna->xv.num_adaptors >= 2 &&
+	    xf86ReturnOptValBool(sna->Options, OPTION_PREFER_OVERLAY, false)) {
+		XvAdaptorRec tmp;
 
-	if (num_adaptors) {
-		if (xf86XVScreenInit(screen, adaptors, num_adaptors))
-			sna_video_xvmc_setup(sna, screen);
-	} else
-		xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
-			   "Disabling Xv because no adaptors could be initialized.\n");
+		tmp = sna->xv.adaptors[0];
+		sna->xv.adaptors[0] = sna->xv.adaptors[1];
+		sna->xv.adaptors[1] = tmp;
+	}
+
+	xv->nAdaptors = sna->xv.num_adaptors;
+	xv->pAdaptors = sna->xv.adaptors;
+
+	sna_video_xvmc_setup(sna, screen);
+}
+
+void sna_video_destroy_window(WindowPtr win)
+{
+	XvPortPtr port;
 
-	free(adaptors);
+	port = sna_window_get_port(win);
+	if (port)
+		port->pAdaptor->ddStopVideo(NULL, port, &win->drawable);
+	assert(sna_window_get_port(win) == NULL);
 }
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index 2e7144e..e1b289d 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -50,6 +50,8 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 }
 
 struct sna_video {
+	struct sna *sna;
+
 	int brightness;
 	int contrast;
 	int saturation;
@@ -95,10 +97,20 @@ struct sna_video_frame {
 	BoxRec src;
 };
 
+static inline XvScreenPtr to_xv(ScreenPtr screen)
+{
+	return dixLookupPrivate(&screen->devPrivates, XvGetScreenKey());
+}
+
 void sna_video_init(struct sna *sna, ScreenPtr screen);
-XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna, ScreenPtr screen);
-XF86VideoAdaptorPtr sna_video_sprite_setup(struct sna *sna, ScreenPtr screen);
-XF86VideoAdaptorPtr sna_video_textured_setup(struct sna *sna, ScreenPtr screen);
+void sna_video_overlay_setup(struct sna *sna, ScreenPtr screen);
+void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen);
+void sna_video_textured_setup(struct sna *sna, ScreenPtr screen);
+void sna_video_destroy_window(WindowPtr win);
+
+XvAdaptorPtr sna_xv_adaptor_alloc(struct sna *sna);
+int sna_xv_alloc_port(unsigned long port, XvPortPtr in, XvPortPtr *out);
+int sna_xv_free_port(XvPortPtr port);
 
 #define FOURCC_XVMC     (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
 
@@ -134,25 +146,33 @@ sna_video_clip_helper(ScrnInfoPtr scrn,
 		      RegionPtr reg);
 
 void
-sna_video_frame_init(struct sna *sna,
-		     struct sna_video *video,
+sna_video_frame_init(struct sna_video *video,
 		     int id, short width, short height,
 		     struct sna_video_frame *frame);
 
 struct kgem_bo *
-sna_video_buffer(struct sna *sna,
-		 struct sna_video *video,
+sna_video_buffer(struct sna_video *video,
 		 struct sna_video_frame *frame);
 
 bool
-sna_video_copy_data(struct sna *sna,
-		    struct sna_video *video,
+sna_video_copy_data(struct sna_video *video,
 		    struct sna_video_frame *frame,
 		    const uint8_t *buf);
 
-void sna_video_buffer_fini(struct sna *sna,
-			   struct sna_video *video);
+void sna_video_buffer_fini(struct sna_video *video);
+
+void sna_video_free_buffers(struct sna_video *video);
 
-void sna_video_free_buffers(struct sna *sna, struct sna_video *video);
+static inline XvPortPtr
+sna_window_get_port(WindowPtr window)
+{
+	return ((void **)__get_private(window, sna_window_key))[2];
+}
+
+static inline void
+sna_window_set_port(WindowPtr window, XvPortPtr port)
+{
+	((void **)__get_private(window, sna_window_key))[2] = port;
+}
 
 #endif /* SNA_VIDEO_H */
diff --git a/src/sna/sna_video_hwmc.c b/src/sna/sna_video_hwmc.c
index 55aa854..15a7844 100644
--- a/src/sna/sna_video_hwmc.c
+++ b/src/sna/sna_video_hwmc.c
@@ -196,66 +196,60 @@ static XvMCSurfaceInfoPtr surface_info_vld[] = {
 };
 
 /* check chip type and load xvmc driver */
-Bool sna_video_xvmc_setup(struct sna *sna,
-			  ScreenPtr screen)
+void sna_video_xvmc_setup(struct sna *sna, ScreenPtr screen)
 {
 	XvMCAdaptorRec *adaptors;
-	XvScreenPtr xv;
 	const char *name;
 	char bus[64];
-	int i, j;
+	int i;
+
+	if (!sna->xv.num_adaptors)
+		return;
 
 	if (!xf86LoaderCheckSymbol("XvMCScreenInit"))
-		return FALSE;
+		return;
 
 	/* Needs KMS support. */
 	if (sna->kgem.gen < 031)
-		return FALSE;
+		return;
 
 	/* Not implemented */
 	if (sna->kgem.gen >= 060)
-		return FALSE;
-
-	xv = dixLookupPrivate(&screen->devPrivates, XF86XvScreenKey);
+		return;
 
-	adaptors = calloc(xv->nAdaptors, sizeof(XvMCAdaptorRec));
+	adaptors = calloc(sna->xv.num_adaptors, sizeof(XvMCAdaptorRec));
 	if (adaptors == NULL)
-		return FALSE;
-
-	for (i = j = 0; i< xv->nAdaptors;i++) {
-		if (strncmp(xv->pAdaptors[i].name, "Intel(R)", 8))
-			continue;
+		return;
 
-		adaptors[j].xv_adaptor = &xv->pAdaptors[i];
+	for (i = 0; i< sna->xv.num_adaptors; i++) {
+		adaptors[i].xv_adaptor = &sna->xv.adaptors[i];
 
-		adaptors[j].num_subpictures = 0;
-		adaptors[j].subpictures = NULL;
-		adaptors[j].CreateContext = create_context;
-		adaptors[j].DestroyContext = destroy_context;
-		adaptors[j].CreateSurface = create_surface;
-		adaptors[j].DestroySurface = destroy_surface;
-		adaptors[j].CreateSubpicture = create_subpicture;
-		adaptors[j].DestroySubpicture = destroy_subpicture;
+		adaptors[i].num_subpictures = 0;
+		adaptors[i].subpictures = NULL;
+		adaptors[i].CreateContext = create_context;
+		adaptors[i].DestroyContext = destroy_context;
+		adaptors[i].CreateSurface = create_surface;
+		adaptors[i].DestroySurface = destroy_surface;
+		adaptors[i].CreateSubpicture = create_subpicture;
+		adaptors[i].DestroySubpicture = destroy_subpicture;
 
 		if (sna->kgem.gen >= 045) {
-			adaptors[j].num_surfaces = ARRAY_SIZE(surface_info_vld);
-			adaptors[j].surfaces = surface_info_vld;
+			adaptors[i].num_surfaces = ARRAY_SIZE(surface_info_vld);
+			adaptors[i].surfaces = surface_info_vld;
 		} else if (sna->kgem.gen >= 040) {
-			adaptors[j].num_surfaces = ARRAY_SIZE(surface_info_i965);
-			adaptors[j].surfaces = surface_info_i965;
+			adaptors[i].num_surfaces = ARRAY_SIZE(surface_info_i965);
+			adaptors[i].surfaces = surface_info_i965;
 		} else {
-			adaptors[j].num_surfaces = ARRAY_SIZE(surface_info_i915);
-			adaptors[j].surfaces = surface_info_i915;
+			adaptors[i].num_surfaces = ARRAY_SIZE(surface_info_i915);
+			adaptors[i].surfaces = surface_info_i915;
 		}
-
-		j++;
 	}
 
-	if (XvMCScreenInit(screen, j, adaptors) != Success) {
+	if (XvMCScreenInit(screen, i, adaptors) != Success) {
 		xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
 			   "[XvMC] Failed to initialize XvMC.\n");
 		free(adaptors);
-		return FALSE;
+		return;
 	}
 
 	sprintf(bus, "pci:%04x:%02x:%02x.%d",
@@ -275,6 +269,4 @@ Bool sna_video_xvmc_setup(struct sna *sna,
 	xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
 		   "[XvMC] %s driver initialized.\n",
 		   name);
-
-	return TRUE;
 }
diff --git a/src/sna/sna_video_hwmc.h b/src/sna/sna_video_hwmc.h
index 8b0d2cd..a6469a0 100644
--- a/src/sna/sna_video_hwmc.h
+++ b/src/sna/sna_video_hwmc.h
@@ -40,7 +40,7 @@
 
 #ifdef _SNA_XVMC_SERVER_
 #include <xf86xvmc.h>
-Bool sna_video_xvmc_setup(struct sna *sna, ScreenPtr screen);
+void sna_video_xvmc_setup(struct sna *sna, ScreenPtr screen);
 #endif
 
 #endif
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index 459541c..6d85275 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -57,41 +57,28 @@ static Atom xvSyncToVblank;
 #define IMAGE_MAX_WIDTH_LEGACY	1024
 #define IMAGE_MAX_HEIGHT_LEGACY	1088
 
-/* client libraries expect an encoding */
-static const XF86VideoEncodingRec DummyEncoding[1] = {
-	{
-	 0,
-	 "XV_IMAGE",
-	 IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
-	 {1, 1}
-	 }
-};
-
-#define NUM_FORMATS 3
-static const XF86VideoFormatRec Formats[NUM_FORMATS] = {
+static const XvFormatRec Formats[] = {
 	{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
 };
 
-#define NUM_ATTRIBUTES 5
-static const XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
+static const XvAttributeRec Attributes[] = {
 	{XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
 	{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
 	{XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
 	{XvSettable | XvGettable, 0, 1023, "XV_SATURATION"},
-	{XvSettable | XvGettable, -1, 1, "XV_PIPE"}
-};
+	{XvSettable | XvGettable, -1, 1, "XV_PIPE"},
+#define NUM_ATTRIBUTES 5
 
-#define GAMMA_ATTRIBUTES 6
-static const XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = {
 	{XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"},
 	{XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA1"},
 	{XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA2"},
 	{XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA3"},
 	{XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA4"},
 	{XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"}
+#define GAMMA_ATTRIBUTES 6
 };
 
-static const XF86ImageRec Images[] = {
+static const XvImageRec Images[] = {
 	XVIMAGE_YUY2,
 	XVIMAGE_YV12,
 	XVIMAGE_I420,
@@ -113,8 +100,7 @@ static bool sna_has_overlay(struct sna *sna)
 	return ret == 0 && has_overlay;
 }
 
-static bool sna_video_overlay_update_attrs(struct sna *sna,
-					   struct sna_video *video)
+static bool sna_video_overlay_update_attrs(struct sna_video *video)
 {
 	struct drm_intel_overlay_attrs attrs;
 
@@ -132,47 +118,39 @@ static bool sna_video_overlay_update_attrs(struct sna *sna,
 	attrs.gamma4 = video->gamma4;
 	attrs.gamma5 = video->gamma5;
 
-	return drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_OVERLAY_ATTRS, &attrs) == 0;
+	return drmIoctl(video->sna->kgem.fd, DRM_IOCTL_I915_OVERLAY_ATTRS, &attrs) == 0;
 }
 
-static void sna_video_overlay_off(struct sna *sna)
+static int sna_video_overlay_stop(ClientPtr client,
+				  XvPortPtr port,
+				  DrawablePtr draw)
 {
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna *sna = video->sna;
 	struct drm_intel_overlay_put_image request;
 
 	DBG(("%s()\n", __FUNCTION__));
 
-	request.flags = 0;
+	REGION_EMPTY(scrn->pScreen, &video->clip);
 
-	/* Not much we can do if the hardware dies before we turn it off! */
+	request.flags = 0;
 	(void)drmIoctl(sna->kgem.fd,
 		       DRM_IOCTL_I915_OVERLAY_PUT_IMAGE,
 		       &request);
-}
-
-static void sna_video_overlay_stop(ScrnInfoPtr scrn,
-				   pointer data,
-				   Bool shutdown)
-{
-	struct sna *sna = to_sna(scrn);
-	struct sna_video *video = data;
-
-	DBG(("%s()\n", __FUNCTION__));
 
-	REGION_EMPTY(scrn->pScreen, &video->clip);
-
-	if (!shutdown)
-		return;
-
-	sna_video_overlay_off(sna);
-	sna_video_free_buffers(sna, video);
+	sna_video_free_buffers(video);
+	sna_window_set_port((WindowPtr)draw, NULL);
+	return Success;
 }
 
 static int
-sna_video_overlay_set_port_attribute(ScrnInfoPtr scrn,
-				     Atom attribute, INT32 value, pointer data)
+sna_video_overlay_set_attribute(ClientPtr client,
+				XvPortPtr port,
+				Atom attribute,
+				INT32 value)
 {
-	struct sna *sna = to_sna(scrn);
-	struct sna_video *video = data;
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna *sna = video->sna;
 
 	if (attribute == xvBrightness) {
 		if ((value < -128) || (value > 127))
@@ -193,7 +171,7 @@ sna_video_overlay_set_port_attribute(ScrnInfoPtr scrn,
 		     video->saturation, (int)value));
 		video->saturation = value;
 	} else if (attribute == xvPipe) {
-		xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+		xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn);
 		if ((value < -1) || (value >= xf86_config->num_crtc))
 			return BadValue;
 		if (value < 0)
@@ -227,21 +205,23 @@ sna_video_overlay_set_port_attribute(ScrnInfoPtr scrn,
 		DBG(("%s: GAMMA\n", __FUNCTION__));
 	}
 
-	if (!sna_video_overlay_update_attrs(sna, data))
+	if (!sna_video_overlay_update_attrs(video))
 		return BadValue;
 
 	if (attribute == xvColorKey)
-		REGION_EMPTY(scrn->pScreen, &video->clip);
+		RegionEmpty(&video->clip);
 
 	return Success;
 }
 
 static int
-sna_video_overlay_get_port_attribute(ScrnInfoPtr scrn,
-				     Atom attribute, INT32 * value, pointer data)
+sna_video_overlay_get_attribute(ClientPtr client,
+				XvPortPtr port,
+				Atom attribute,
+				INT32 *value)
 {
-	struct sna *sna = to_sna(scrn);
-	struct sna_video *video = (struct sna_video *) data;
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna *sna = video->sna;
 
 	if (attribute == xvBrightness) {
 		*value = video->brightness;
@@ -251,7 +231,7 @@ sna_video_overlay_get_port_attribute(ScrnInfoPtr scrn,
 		*value = video->saturation;
 	} else if (attribute == xvPipe) {
 		int c;
-		xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+		xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn);
 		for (c = 0; c < xf86_config->num_crtc; c++)
 			if (xf86_config->crtc[c] == video->desired_crtc)
 				break;
@@ -280,15 +260,16 @@ sna_video_overlay_get_port_attribute(ScrnInfoPtr scrn,
 	return Success;
 }
 
-static void
-sna_video_overlay_query_best_size(ScrnInfoPtr scrn,
-				  Bool motion,
-				  short vid_w, short vid_h,
-				  short drw_w, short drw_h,
-				  unsigned int *p_w, unsigned int *p_h,
-				  pointer data)
+static int
+sna_video_overlay_best_size(ClientPtr client,
+			    XvPortPtr port,
+			    CARD8 motion,
+			    CARD16 vid_w, CARD16 vid_h,
+			    CARD16 drw_w, CARD16 drw_h,
+			    unsigned int *p_w, unsigned int *p_h)
 {
-	struct sna *sna = to_sna(scrn);
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna *sna = video->sna;
 	short max_w, max_h;
 
 	if (vid_w > (drw_w << 1) || vid_h > (drw_h << 1)){
@@ -311,6 +292,7 @@ sna_video_overlay_query_best_size(ScrnInfoPtr scrn,
 
 	*p_w = drw_w;
 	*p_h = drw_h;
+	return Success;
 }
 
 static void
@@ -462,21 +444,26 @@ sna_video_overlay_show(struct sna *sna,
 }
 
 static int
-sna_video_overlay_put_image(ScrnInfoPtr scrn,
-			    short src_x, short src_y,
-			    short drw_x, short drw_y,
-			    short src_w, short src_h,
-			    short drw_w, short drw_h,
-			    int id, unsigned char *buf,
-			    short width, short height,
-			    Bool sync, RegionPtr clip, pointer data,
-			    DrawablePtr drawable)
+sna_video_overlay_put_image(ClientPtr client,
+			    DrawablePtr draw,
+			    XvPortPtr port,
+			    GCPtr gc,
+			    INT16 src_x, INT16 src_y,
+			    CARD16 src_w, CARD16 src_h,
+			    INT16 drw_x, INT16 drw_y,
+			    CARD16 drw_w, CARD16 drw_h,
+			    XvImagePtr format,
+			    unsigned char *buf,
+			    Bool sync,
+			    CARD16 width, CARD16 height)
 {
-	struct sna *sna = to_sna(scrn);
-	struct sna_video *video = data;
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna *sna = video->sna;
 	struct sna_video_frame frame;
-	BoxRec dstBox;
 	xf86CrtcPtr crtc;
+	BoxRec dstBox;
+	RegionRec clip;
+	int ret;
 
 	DBG(("%s: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d), width %d, height %d\n",
 	     __FUNCTION__,
@@ -492,30 +479,43 @@ sna_video_overlay_put_image(ScrnInfoPtr scrn,
 	if (src_h >= (drw_h * 8))
 		drw_h = src_h / 7;
 
-	sna_video_frame_init(sna, video, id, width, height, &frame);
+	clip.extents.x1 = draw->x + drw_x;
+	clip.extents.y1 = draw->y + drw_y;
+	clip.extents.x2 = clip.extents.x1 + drw_w;
+	clip.extents.y2 = clip.extents.y1 + drw_h;
+	clip.data = NULL;
+
+	RegionIntersect(&clip, &clip, gc->pCompositeClip);
+	if (!RegionNotEmpty(&clip))
+		goto invisible;
+
+	DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n",
+	     __FUNCTION__,
+	     src_x, src_y, src_w, src_h,
+	     drw_x, drw_y, drw_w, drw_h,
+	     format->id, width, height, sync));
 
-	if (!sna_video_clip_helper(scrn,
-				   video,
-				   &frame,
-				   &crtc,
-				   &dstBox,
-				   src_x, src_y, drw_x, drw_y,
+	DBG(("%s: region %d:(%d, %d), (%d, %d)\n", __FUNCTION__,
+	     RegionNumRects(&clip),
+	     clip.extents.x1, clip.extents.y1,
+	     clip.extents.x2, clip.extents.y2));
+
+	sna_video_frame_init(video, format->id, width, height, &frame);
+
+	if (!sna_video_clip_helper(sna->scrn, video, &frame,
+				   &crtc, &dstBox,
+				   src_x, src_y, draw->x + drw_x, draw->y + drw_y,
 				   src_w, src_h, drw_w, drw_h,
-				   clip))
-		return Success;
+				   &clip))
+		goto invisible;
 
-	if (!crtc) {
-		/*
-		 * If the video isn't visible on any CRTC, turn it off
-		 */
-		sna_video_overlay_off(sna);
-		return Success;
-	}
+	if (!crtc)
+		goto invisible;
 
 	/* overlay can't handle rotation natively, store it for the copy func */
 	video->rotation = crtc->rotation;
 
-	if (xvmc_passthrough(id)) {
+	if (xvmc_passthrough(format->id)) {
 		DBG(("%s: using passthough, name=%d\n",
 		     __FUNCTION__, *(uint32_t *)buf));
 
@@ -531,46 +531,59 @@ sna_video_overlay_put_image(ScrnInfoPtr scrn,
 		frame.image.x2 = frame.width;
 		frame.image.y2 = frame.height;
 	} else {
-		frame.bo = sna_video_buffer(sna, video, &frame);
+		frame.bo = sna_video_buffer(video, &frame);
 		if (frame.bo == NULL) {
 			DBG(("%s: failed to allocate video bo\n", __FUNCTION__));
 			return BadAlloc;
 		}
 
-		if (!sna_video_copy_data(sna, video, &frame, buf)) {
+		if (!sna_video_copy_data(video, &frame, buf)) {
 			DBG(("%s: failed to copy video data\n", __FUNCTION__));
 			return BadAlloc;
 		}
 	}
 
-	if (!sna_video_overlay_show
+	ret = Success;
+	if (sna_video_overlay_show
 	    (sna, video, &frame, crtc, &dstBox, src_w, src_h, drw_w, drw_h)) {
+		if (!RegionEqual(&video->clip, &clip)) {
+			RegionCopy(&video->clip, &clip);
+			xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
+		}
+
+		sna_window_set_port((WindowPtr)draw, port);
+	} else {
 		DBG(("%s: failed to show video frame\n", __FUNCTION__));
-		return BadAlloc;
+		ret = BadAlloc;
 	}
 
 	frame.bo->domain = DOMAIN_NONE;
-	if (xvmc_passthrough(id))
+	if (xvmc_passthrough(format->id))
 		kgem_bo_destroy(&sna->kgem, frame.bo);
 	else
-		sna_video_buffer_fini(sna, video);
+		sna_video_buffer_fini(video);
 
-	/* update cliplist */
-	if (!REGION_EQUAL(scrn->pScreen, &video->clip, clip)) {
-		REGION_COPY(scrn->pScreen, &video->clip, clip);
-		xf86XVFillKeyHelperDrawable(drawable, video->color_key, clip);
-	}
+	return ret;
 
+invisible:
+	/*
+	 * If the video isn't visible on any CRTC, turn it off
+	 */
+	sna_video_overlay_stop(client, port, draw);
 	return Success;
 }
 
 static int
-sna_video_overlay_query_video_attributes(ScrnInfoPtr scrn,
-					 int id,
-					 unsigned short *w, unsigned short *h,
-					 int *pitches, int *offsets)
+sna_video_overlay_query(ClientPtr client,
+			XvPortPtr port,
+			XvImagePtr format,
+			unsigned short *w,
+			unsigned short *h,
+			int *pitches,
+			int *offsets)
 {
-	struct sna *sna = to_sna(scrn);
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna *sna = video->sna;
 	int size, tmp;
 
 	DBG(("%s: w is %d, h is %d\n", __FUNCTION__, *w, *h));
@@ -591,7 +604,7 @@ sna_video_overlay_query_video_attributes(ScrnInfoPtr scrn,
 	if (offsets)
 		offsets[0] = 0;
 
-	switch (id) {
+	switch (format->id) {
 	case FOURCC_XVMC:
 		*h = (*h + 1) & ~1;
 		size = sizeof(uint32_t);
@@ -666,69 +679,78 @@ static int sna_video_overlay_color_key(struct sna *sna)
 	return color_key & ((1 << scrn->depth) - 1);
 }
 
-XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna,
-					    ScreenPtr screen)
+void sna_video_overlay_setup(struct sna *sna, ScreenPtr screen)
 {
-	XF86VideoAdaptorPtr adaptor;
+	XvAdaptorPtr adaptor;
 	struct sna_video *video;
+	XvPortPtr port;
 
-	if (!sna_has_overlay(sna)) {
-		xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
-			   "Overlay video not supported on this hardware\n");
-		return NULL;
-	}
+	if (!sna_has_overlay(sna))
+		return;
 
 	DBG(("%s()\n", __FUNCTION__));
 
-	if (!(adaptor = calloc(1,
-			     sizeof(XF86VideoAdaptorRec) +
-			     sizeof(struct sna_video) +
-			     sizeof(DevUnion))))
-		return NULL;
+	adaptor = sna_xv_adaptor_alloc(sna);
+	if (adaptor == NULL)
+		return;
 
-	adaptor->type = XvWindowMask | XvInputMask | XvImageMask;
-	adaptor->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT */ ;
-	adaptor->name = "Intel(R) Video Overlay";
-	adaptor->nEncodings = 1;
-	adaptor->pEncodings = xnfalloc(sizeof(DummyEncoding));
-	memcpy(adaptor->pEncodings, DummyEncoding, sizeof(DummyEncoding));
-	if (sna->kgem.gen < 021) {
-		adaptor->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY;
-		adaptor->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY;
+	video = calloc(1, sizeof(*video));
+	port = calloc(1, sizeof(*port));
+	if (video == NULL || port == NULL) {
+		free(video);
+		free(port);
+		sna->xv.num_adaptors--;
+		return;
 	}
-	adaptor->nFormats = NUM_FORMATS;
-	adaptor->pFormats = (XF86VideoFormatPtr)Formats;
-	adaptor->nPorts = 1;
-	adaptor->pPortPrivates = (DevUnion *)&adaptor[1];
-
-	video = (struct sna_video *)&adaptor->pPortPrivates[1];
 
-	adaptor->pPortPrivates[0].ptr = video;
+	adaptor->type = XvInputMask | XvImageMask;
+	adaptor->pScreen = screen;
+	adaptor->name = "Intel(R) Video Overlay";
+	adaptor->nEncodings = 1;
+	adaptor->pEncodings = xnfalloc(sizeof(XvEncodingRec));
+	adaptor->pEncodings[0].id = 0;
+	adaptor->pEncodings[0].pScreen = screen;
+	adaptor->pEncodings[0].name = "XV_IMAGE";
+	adaptor->pEncodings[0].width = sna->kgem.gen < 021 ? IMAGE_MAX_WIDTH_LEGACY : IMAGE_MAX_WIDTH;
+	adaptor->pEncodings[0].height = sna->kgem.gen < 021 ? IMAGE_MAX_HEIGHT_LEGACY : IMAGE_MAX_HEIGHT;
+	adaptor->pEncodings[0].rate.numerator = 1;
+	adaptor->pEncodings[0].rate.denominator = 1;
+	adaptor->nFormats = ARRAY_SIZE(Formats);
+	adaptor->pFormats = Formats;
 	adaptor->nAttributes = NUM_ATTRIBUTES;
 	if (HAS_GAMMA(sna))
 		adaptor->nAttributes += GAMMA_ATTRIBUTES;
+	adaptor->pAttributes = Attributes;
+	adaptor->nImages = ARRAY_SIZE(Images);
+	adaptor->pImages = Images;
+	adaptor->ddAllocatePort = sna_xv_alloc_port;
+	adaptor->ddFreePort = sna_xv_free_port;
+	adaptor->ddPutVideo = NULL;
+	adaptor->ddPutStill = NULL;
+	adaptor->ddGetVideo = NULL;
+	adaptor->ddGetStill = NULL;
+	adaptor->ddStopVideo = sna_video_overlay_stop;
+	adaptor->ddSetPortAttribute = sna_video_overlay_set_attribute;
+	adaptor->ddGetPortAttribute = sna_video_overlay_get_attribute;
+	adaptor->ddQueryBestSize = sna_video_overlay_best_size;
+	adaptor->ddPutImage = sna_video_overlay_put_image;
+	adaptor->ddQueryImageAttributes = sna_video_overlay_query;
 
-	 adaptor->pAttributes =
-	    xnfalloc(sizeof(XF86AttributeRec) * adaptor->nAttributes);
-	/* Now copy the attributes */
-	memcpy(adaptor->pAttributes, Attributes, sizeof(XF86AttributeRec) * NUM_ATTRIBUTES);
-	if (HAS_GAMMA(sna))
-		memcpy(adaptor->pAttributes + NUM_ATTRIBUTES, GammaAttributes,
-		       sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES);
+	adaptor->nPorts = 1;
+	adaptor->pPorts = port;
 
-	adaptor->nImages = ARRAY_SIZE(Images);
-	adaptor->pImages = (XF86ImagePtr)Images;
-	adaptor->PutVideo = NULL;
-	adaptor->PutStill = NULL;
-	adaptor->GetVideo = NULL;
-	adaptor->GetStill = NULL;
-	adaptor->StopVideo = sna_video_overlay_stop;
-	adaptor->SetPortAttribute = sna_video_overlay_set_port_attribute;
-	adaptor->GetPortAttribute = sna_video_overlay_get_port_attribute;
-	adaptor->QueryBestSize = sna_video_overlay_query_best_size;
-	adaptor->PutImage = sna_video_overlay_put_image;
-	adaptor->QueryImageAttributes = sna_video_overlay_query_video_attributes;
+	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;
 	if (sna->kgem.gen >= 040)
 		/* Actually the alignment is 64 bytes, too. But the
 		 * stride must be at least 512 bytes. Take the easy fix
@@ -741,7 +763,6 @@ XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna,
 		video->alignment = 256;
 	else
 		video->alignment = 64;
-	video->textured = false;
 	video->color_key = sna_video_overlay_color_key(sna);
 	video->brightness = -19;	/* (255/219) * -16 */
 	video->contrast = 75;	/* 255/219 * 64 */
@@ -753,11 +774,8 @@ XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna,
 	video->gamma2 = 0x202020;
 	video->gamma1 = 0x101010;
 	video->gamma0 = 0x080808;
-
 	video->rotation = RR_Rotate_0;
-
-	/* gotta uninit this someplace */
-	REGION_NULL(screen, &video->clip);
+	RegionNil(&video->clip);
 
 	xvColorKey = MAKE_ATOM("XV_COLORKEY");
 	xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
@@ -776,7 +794,5 @@ XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna,
 		xvGamma5 = MAKE_ATOM("XV_GAMMA5");
 	}
 
-	sna_video_overlay_update_attrs(sna, video);
-
-	return adaptor;
+	sna_video_overlay_update_attrs(video);
 }
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index a749d1e..06b278e 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -50,43 +50,39 @@
 
 static Atom xvColorKey;
 
-static XF86VideoFormatRec xv_formats[] = {
-	{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
-};
-static XF86ImageRec xv_images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_YUV};
-static const XF86VideoEncodingRec xv_dummy_encoding[] = {
-	{ 0, "XV_IMAGE", IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, {1, 1} }
-};
-static XF86AttributeRec attribs[] = {
-	{XvSettable | XvGettable, 0, 0xffffff, "XV_COLORKEY"},
+static const XvFormatRec formats[] = { {15, TrueColor}, {16, TrueColor}, {24, TrueColor} };
+static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_YUV };
+static const XvAttributeRec attribs[] = {
+	{ XvSettable | XvGettable, 0, 0xffffff, "XV_COLORKEY" },
 };
 
-static void sna_video_sprite_off(struct sna *sna, struct sna_video *video)
+static int sna_video_sprite_stop(ClientPtr client,
+				 XvPortPtr port,
+				 DrawablePtr draw)
 {
+	struct sna_video *video = port->devPriv.ptr;
 	struct drm_mode_set_plane s;
 
 	if (video->plane == 0)
-		return;
+		return Success;
 
 	memset(&s, 0, sizeof(s));
 	s.plane_id = video->plane;
-	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s))
-		xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
+	if (drmIoctl(video->sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s))
+		xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
 			   "failed to disable plane\n");
 
 	video->plane = 0;
+	sna_window_set_port((WindowPtr)draw, NULL);
+	return Success;
 }
 
-static void sna_video_sprite_stop(ScrnInfoPtr scrn, pointer data, Bool shutdown)
-{
-	return sna_video_sprite_off(to_sna(scrn), data);
-}
-
-static int sna_video_sprite_set_attr(ScrnInfoPtr scrn,
-				     Atom attribute, INT32 value,
-				     pointer data)
+static int sna_video_sprite_set_attr(ClientPtr client,
+				     XvPortPtr port,
+				     Atom attribute,
+				     INT32 value)
 {
-	struct sna_video *video = data;
+	struct sna_video *video = port->devPriv.ptr;
 
 	if (attribute == xvColorKey) {
 		video->color_key_changed = true;
@@ -98,11 +94,12 @@ static int sna_video_sprite_set_attr(ScrnInfoPtr scrn,
 	return Success;
 }
 
-static int sna_video_sprite_get_attr(ScrnInfoPtr scrn,
-				     Atom attribute, INT32 *value,
-				     pointer data)
+static int sna_video_sprite_get_attr(ClientPtr client,
+				     XvPortPtr port,
+				     Atom attribute,
+				     INT32 *value)
 {
-	struct sna_video *video = data;
+	struct sna_video *video = port->devPriv.ptr;
 
 	if (attribute == xvColorKey)
 		*value = video->color_key;
@@ -112,21 +109,26 @@ static int sna_video_sprite_get_attr(ScrnInfoPtr scrn,
 	return Success;
 }
 
-static void sna_video_sprite_best_size(ScrnInfoPtr scrn, Bool motion,
-				       short vid_w, short vid_h,
-				       short drw_w, short drw_h,
-				       unsigned int *p_w, unsigned int *p_h,
-				       pointer data)
+static int sna_video_sprite_best_size(ClientPtr client,
+				      XvPortPtr port,
+				      CARD8 motion,
+				      CARD16 vid_w, CARD16 vid_h,
+				      CARD16 drw_w, CARD16 drw_h,
+				      unsigned int *p_w,
+				      unsigned int *p_h)
 {
-	struct sna *sna = to_sna(scrn);
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna *sna = video->sna;
 
-	if (sna->kgem.gen == 075) {
+	if (sna->kgem.gen >= 075) {
 		*p_w = vid_w;
 		*p_h = vid_h;
 	} else {
 		*p_w = drw_w;
 		*p_h = drw_h;
 	}
+
+	return Success;
 }
 
 static void
@@ -281,40 +283,64 @@ sna_video_sprite_show(struct sna *sna,
 	return true;
 }
 
-static int sna_video_sprite_put_image(ScrnInfoPtr scrn,
-				      short src_x, short src_y,
-				      short drw_x, short drw_y,
-				      short src_w, short src_h,
-				      short drw_w, short drw_h,
-				      int id, unsigned char *buf,
-				      short width, short height,
-				      Bool sync, RegionPtr clip, pointer data,
-				      DrawablePtr drawable)
+static int sna_video_sprite_put_image(ClientPtr client,
+				      DrawablePtr draw,
+				      XvPortPtr port,
+				      GCPtr gc,
+				      INT16 src_x, INT16 src_y,
+				      CARD16 src_w, CARD16 src_h,
+				      INT16 drw_x, INT16 drw_y,
+				      CARD16 drw_w, CARD16 drw_h,
+				      XvImagePtr format,
+				      unsigned char *buf,
+				      Bool sync,
+				      CARD16 width, CARD16 height)
 {
-	struct sna *sna = to_sna(scrn);
-	struct sna_video *video = data;
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna *sna = video->sna;
 	struct sna_video_frame frame;
 	xf86CrtcPtr crtc;
 	BoxRec dst_box;
-
-	sna_video_frame_init(sna, video, id, width, height, &frame);
-
-	if (!sna_video_clip_helper(scrn, video, &frame, &crtc, &dst_box,
-				   src_x, src_y, drw_x, drw_y,
+	RegionRec clip;
+	int ret;
+
+	clip.extents.x1 = draw->x + drw_x;
+	clip.extents.y1 = draw->y + drw_y;
+	clip.extents.x2 = clip.extents.x1 + drw_w;
+	clip.extents.y2 = clip.extents.y1 + drw_h;
+	clip.data = NULL;
+
+	RegionIntersect(&clip, &clip, gc->pCompositeClip);
+	if (!RegionNotEmpty(&clip))
+		goto invisible;
+
+	DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n",
+	     __FUNCTION__,
+	     src_x, src_y, src_w, src_h,
+	     drw_x, drw_y, drw_w, drw_h,
+	     format->id, width, height, sync));
+
+	DBG(("%s: region %d:(%d, %d), (%d, %d)\n", __FUNCTION__,
+	     RegionNumRects(&clip),
+	     clip.extents.x1, clip.extents.y1,
+	     clip.extents.x2, clip.extents.y2));
+
+	sna_video_frame_init(video, format->id, width, height, &frame);
+
+	if (!sna_video_clip_helper(sna->scrn, video, &frame,
+				   &crtc, &dst_box,
+				   src_x, src_y, draw->x + drw_x, draw->y + drw_y,
 				   src_w, src_h, drw_w, drw_h,
-				   clip))
-		return Success;
+				   &clip))
+		goto invisible;
 
-	if (!crtc || sna_crtc_to_plane(crtc) == 0) {
-		/* If the video isn't visible on any CRTC, turn it off */
-		sna_video_sprite_off(sna, video);
-		return Success;
-	}
+	if (!crtc || sna_crtc_to_plane(crtc) == 0)
+		goto invisible;
 
 	/* sprites can't handle rotation natively, store it for the copy func */
 	video->rotation = crtc->rotation;
 
-	if (xvmc_passthrough(id)) {
+	if (xvmc_passthrough(format->id)) {
 		DBG(("%s: using passthough, name=%d\n",
 		     __FUNCTION__, *(uint32_t *)buf));
 
@@ -328,40 +354,50 @@ static int sna_video_sprite_put_image(ScrnInfoPtr scrn,
 		frame.image.x2 = frame.width;
 		frame.image.y2 = frame.height;
 	} else {
-		frame.bo = sna_video_buffer(sna, video, &frame);
+		frame.bo = sna_video_buffer(video, &frame);
 		if (frame.bo == NULL) {
 			DBG(("%s: failed to allocate video bo\n", __FUNCTION__));
 			return BadAlloc;
 		}
 
-		if (!sna_video_copy_data(sna, video, &frame, buf)) {
+		if (!sna_video_copy_data(video, &frame, buf)) {
 			DBG(("%s: failed to copy video data\n", __FUNCTION__));
 			return BadAlloc;
 		}
 	}
 
+	ret = Success;
 	if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst_box)) {
 		DBG(("%s: failed to show video frame\n", __FUNCTION__));
-		return BadAlloc;
+		ret = BadAlloc;
+	} else {
+		if (!RegionEqual(&video->clip, &clip)) {
+			RegionCopy(&video->clip, &clip);
+			xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
+		}
+		sna_window_set_port((WindowPtr)draw, port);
 	}
 
 	frame.bo->domain = DOMAIN_NONE;
-	if (xvmc_passthrough(id))
+	if (xvmc_passthrough(format->id))
 		kgem_bo_destroy(&sna->kgem, frame.bo);
 	else
-		sna_video_buffer_fini(sna, video);
+		sna_video_buffer_fini(video);
 
-	if (!REGION_EQUAL(scrn->pScreen, &video->clip, clip)) {
-		REGION_COPY(scrn->pScreen, &video->clip, clip);
-		xf86XVFillKeyHelperDrawable(drawable, video->color_key, clip);
-	}
+	return ret;
 
-	return Success;
+invisible:
+	/* If the video isn't visible on any CRTC, turn it off */
+	return sna_video_sprite_stop(client, port, draw);
 }
 
-static int sna_video_sprite_query_attrs(ScrnInfoPtr scrn, int id,
-					unsigned short *w, unsigned short *h,
-					int *pitches, int *offsets)
+static int sna_video_sprite_query(ClientPtr client,
+				  XvPortPtr port,
+				  XvImagePtr format,
+				  unsigned short *w,
+				  unsigned short *h,
+				  int *pitches,
+				  int *offsets)
 {
 	int size;
 
@@ -374,7 +410,7 @@ static int sna_video_sprite_query_attrs(ScrnInfoPtr scrn, int id,
 	if (offsets)
 		offsets[0] = 0;
 
-	switch (id) {
+	switch (format->id) {
 	case FOURCC_XVMC:
 		*h = (*h + 1) & ~1;
 		size = sizeof(uint32_t);
@@ -413,58 +449,79 @@ static int sna_video_sprite_color_key(struct sna *sna)
 	return color_key & ((1 << scrn->depth) - 1);
 }
 
-XF86VideoAdaptorPtr sna_video_sprite_setup(struct sna *sna,
-					   ScreenPtr screen)
+void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 {
-	XF86VideoAdaptorPtr adaptor;
+	XvAdaptorPtr adaptor;
 	struct drm_mode_get_plane_res r;
 	struct sna_video *video;
+	XvPortPtr port;
 
 	memset(&r, 0, sizeof(struct drm_mode_get_plane_res));
 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &r))
-		return NULL;
+		return;
+
 	DBG(("%s: %d sprite planes\n", __FUNCTION__, r.count_planes));
 	if (r.count_planes == 0)
-		return NULL;
+		return;
 
-	adaptor = calloc(1,
-			 sizeof(XF86VideoAdaptorRec) +
-			 sizeof(struct sna_video) +
-			 sizeof(DevUnion));
+	adaptor = sna_xv_adaptor_alloc(sna);
 	if (!adaptor)
-		return NULL;
-
-	adaptor->type = XvWindowMask | XvInputMask | XvImageMask;
-	adaptor->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT */ ;
-	adaptor->name = "Intel(R) Video Sprite";
-	adaptor->nEncodings = ARRAY_SIZE(xv_dummy_encoding);
-	adaptor->pEncodings = xnfalloc(sizeof(xv_dummy_encoding));
-	memcpy(adaptor->pEncodings, xv_dummy_encoding, sizeof(xv_dummy_encoding));
-	adaptor->nFormats = ARRAY_SIZE(xv_formats);
-	adaptor->pFormats = xv_formats;
-	adaptor->nPorts = 1;
-	adaptor->pPortPrivates = (DevUnion *)&adaptor[1];
+		return;
 
-	video = (struct sna_video *)&adaptor->pPortPrivates[1];
-	adaptor->pPortPrivates[0].ptr = video;
+	video = calloc(1, sizeof(*video));
+	port = calloc(1, sizeof(*port));
+	if (video == NULL || port == NULL) {
+		free(video);
+		free(port);
+		sna->xv.num_adaptors--;
+		return;
+	}
 
+	adaptor->type = XvInputMask | XvImageMask;
+	adaptor->pScreen = screen;
+	adaptor->name = "Intel(R) Video Sprite";
+	adaptor->nEncodings = 1;
+	adaptor->pEncodings = xnfalloc(sizeof(XvEncodingRec));
+	adaptor->pEncodings[0].id = 0;
+	adaptor->pEncodings[0].pScreen = screen;
+	adaptor->pEncodings[0].name = "XV_IMAGE";
+	adaptor->pEncodings[0].width = IMAGE_MAX_WIDTH;
+	adaptor->pEncodings[0].height = IMAGE_MAX_HEIGHT;
+	adaptor->pEncodings[0].rate.numerator = 1;
+	adaptor->pEncodings[0].rate.denominator = 1;
+	adaptor->nFormats = ARRAY_SIZE(formats);
+	adaptor->pFormats = formats;
 	adaptor->nAttributes = ARRAY_SIZE(attribs);
 	adaptor->pAttributes = attribs;
+	adaptor->nImages = ARRAY_SIZE(images);
+	adaptor->pImages = images;
+	adaptor->ddAllocatePort = sna_xv_alloc_port;
+	adaptor->ddFreePort = sna_xv_free_port;
+	adaptor->ddPutVideo = NULL;
+	adaptor->ddPutStill = NULL;
+	adaptor->ddGetVideo = NULL;
+	adaptor->ddGetStill = NULL;
+	adaptor->ddStopVideo = sna_video_sprite_stop;
+	adaptor->ddSetPortAttribute = sna_video_sprite_set_attr;
+	adaptor->ddGetPortAttribute = sna_video_sprite_get_attr;
+	adaptor->ddQueryBestSize = sna_video_sprite_best_size;
+	adaptor->ddPutImage = sna_video_sprite_put_image;
+	adaptor->ddQueryImageAttributes = sna_video_sprite_query;
 
-	adaptor->nImages = ARRAY_SIZE(xv_images);
-	adaptor->pImages = xv_images;
-
-	adaptor->PutVideo = NULL;
-	adaptor->PutStill = NULL;
-	adaptor->GetVideo = NULL;
-	adaptor->GetStill = NULL;
-	adaptor->StopVideo = sna_video_sprite_stop;
-	adaptor->SetPortAttribute = sna_video_sprite_set_attr;
-	adaptor->GetPortAttribute = sna_video_sprite_get_attr;
-	adaptor->QueryBestSize = sna_video_sprite_best_size;
-	adaptor->PutImage = sna_video_sprite_put_image;
-	adaptor->QueryImageAttributes = sna_video_sprite_query_attrs;
-
+	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 = true;
@@ -478,18 +535,13 @@ XF86VideoAdaptorPtr sna_video_sprite_setup(struct sna *sna,
 	video->gamma2 = 0x202020;
 	video->gamma1 = 0x101010;
 	video->gamma0 = 0x080808;
-
 	video->rotation = RR_Rotate_0;
-
-	REGION_NULL(screen, &video->clip);
+	RegionNull(&video->clip);
 
 	xvColorKey = MAKE_ATOM("XV_COLORKEY");
-
-	return adaptor;
 }
 #else
-XF86VideoAdaptorPtr sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
+void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 {
-	return NULL;
 }
 #endif
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index 8278606..29f4d9d 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -34,29 +34,21 @@
 #include <xf86xv.h>
 #include <X11/extensions/Xv.h>
 
-#ifdef SNA_XVMC
-#define _SNA_XVMC_SERVER_
-#include "sna_video_hwmc.h"
-#endif
-
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true)
 
 static Atom xvBrightness, xvContrast, xvSyncToVblank;
 
-#define NUM_FORMATS 3
-static const XF86VideoFormatRec Formats[NUM_FORMATS] = {
+static const XvFormatRec Formats[] = {
 	{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
 };
 
-//#define NUM_TEXTURED_ATTRIBUTES 3
-#define NUM_TEXTURED_ATTRIBUTES 1
-static const XF86AttributeRec TexturedAttributes[] = {
+static const XvAttributeRec Attributes[] = {
 	{XvSettable | XvGettable, -1, 1, "XV_SYNC_TO_VBLANK"},
-	{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
-	{XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
+	//{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+	//{XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
 };
 
-static const XF86ImageRec Images[] = {
+static const XvImageRec Images[] = {
 	XVIMAGE_YUY2,
 	XVIMAGE_YV12,
 	XVIMAGE_I420,
@@ -64,30 +56,27 @@ static const XF86ImageRec Images[] = {
 	XVMC_YUV,
 };
 
-static void sna_video_textured_stop(ScrnInfoPtr scrn,
-				    pointer data,
-				    Bool shutdown)
+static int sna_video_textured_stop(ClientPtr client,
+				   XvPortPtr port,
+				   DrawablePtr draw)
 {
-	struct sna *sna = to_sna(scrn);
-	struct sna_video *video = data;
+	struct sna_video *video = port->devPriv.ptr;
 
 	DBG(("%s()\n", __FUNCTION__));
 
-	REGION_EMPTY(scrn->pScreen, &video->clip);
-
-	if (!shutdown)
-		return;
+	RegionUninit(&video->clip);
+	sna_video_free_buffers(video);
 
-	sna_video_free_buffers(sna, video);
+	return Success;
 }
 
 static int
-sna_video_textured_set_attribute(ScrnInfoPtr scrn,
+sna_video_textured_set_attribute(ClientPtr client,
+				 XvPortPtr port,
 				 Atom attribute,
-				 INT32 value,
-				 pointer data)
+				 INT32 value)
 {
-	struct sna_video *video = data;
+	struct sna_video *video = port->devPriv.ptr;
 
 	if (attribute == xvBrightness) {
 		if (value < -128 || value > 127)
@@ -111,12 +100,12 @@ sna_video_textured_set_attribute(ScrnInfoPtr scrn,
 }
 
 static int
-sna_video_textured_get_attribute(ScrnInfoPtr scrn,
+sna_video_textured_get_attribute(ClientPtr client,
+				 XvPortPtr port,
 				 Atom attribute,
-				 INT32 *value,
-				 pointer data)
+				 INT32 *value)
 {
-	struct sna_video *video = data;
+	struct sna_video *video = port->devPriv.ptr;
 
 	if (attribute == xvBrightness)
 		*value = video->brightness;
@@ -130,14 +119,14 @@ sna_video_textured_get_attribute(ScrnInfoPtr scrn,
 	return Success;
 }
 
-static void
-sna_video_textured_best_size(ScrnInfoPtr scrn,
-			     Bool motion,
-			     short vid_w, short vid_h,
-			     short drw_w, short drw_h,
+static int
+sna_video_textured_best_size(ClientPtr client,
+			     XvPortPtr port,
+			     CARD8 motion,
+			     CARD16 vid_w, CARD16 vid_h,
+			     CARD16 drw_w, CARD16 drw_h,
 			     unsigned int *p_w,
-			     unsigned int *p_h,
-			     pointer data)
+			     unsigned int *p_h)
 {
 	if (vid_w > (drw_w << 1))
 		drw_w = vid_w >> 1;
@@ -146,6 +135,8 @@ sna_video_textured_best_size(ScrnInfoPtr scrn,
 
 	*p_w = drw_w;
 	*p_h = drw_h;
+
+	return Success;
 }
 
 /*
@@ -162,40 +153,49 @@ sna_video_textured_best_size(ScrnInfoPtr scrn,
  * compositing.  It's a new argument to the function in the 1.1 server.
  */
 static int
-sna_video_textured_put_image(ScrnInfoPtr scrn,
-			     short src_x, short src_y,
-			     short drw_x, short drw_y,
-			     short src_w, short src_h,
-			     short drw_w, short drw_h,
-			     int id, unsigned char *buf,
-			     short width, short height,
-			     Bool sync, RegionPtr clip, pointer data,
-			     DrawablePtr drawable)
+sna_video_textured_put_image(ClientPtr client,
+			     DrawablePtr draw,
+			     XvPortPtr port,
+			     GCPtr gc,
+			     INT16 src_x, INT16 src_y,
+			     CARD16 src_w, CARD16 src_h,
+			     INT16 drw_x, INT16 drw_y,
+			     CARD16 drw_w, CARD16 drw_h,
+			     XvImagePtr format,
+			     unsigned char *buf,
+			     Bool sync,
+			     CARD16 width, CARD16 height)
 {
-	struct sna *sna = to_sna(scrn);
-	struct sna_video *video = data;
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna *sna = video->sna;
 	struct sna_video_frame frame;
-	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	PixmapPtr pixmap = get_drawable_pixmap(draw);
 	BoxRec dstBox;
+	RegionRec clip;
 	xf86CrtcPtr crtc;
 	bool flush = false;
 	bool ret;
 
+	clip.extents.x1 = draw->x + drw_x;
+	clip.extents.y1 = draw->y + drw_y;
+	clip.extents.x2 = clip.extents.x1 + drw_w;
+	clip.extents.y2 = clip.extents.y1 + drw_h;
+	clip.data = NULL;
+
+	RegionIntersect(&clip, &clip, gc->pCompositeClip);
+	if (!RegionNotEmpty(&clip))
+		return Success;
+
 	DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n",
 	     __FUNCTION__,
 	     src_x, src_y, src_w, src_h,
 	     drw_x, drw_y, drw_w, drw_h,
-	     id, width, height, sync));
+	     format->id, width, height, sync));
 
 	DBG(("%s: region %d:(%d, %d), (%d, %d)\n", __FUNCTION__,
-	     RegionNumRects(clip),
-	     clip->extents.x1, clip->extents.y1,
-	     clip->extents.x2, clip->extents.y2));
-
-	if (buf == 0) {
-		DBG(("%s: garbage video buffer\n", __FUNCTION__));
-		return BadAlloc;
-	}
+	     RegionNumRects(&clip),
+	     clip.extents.x1, clip.extents.y1,
+	     clip.extents.x2, clip.extents.y2));
 
 	if (!sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_WRITE)) {
 		DBG(("%s: attempting to render to a non-GPU pixmap\n",
@@ -203,16 +203,16 @@ sna_video_textured_put_image(ScrnInfoPtr scrn,
 		return BadAlloc;
 	}
 
-	sna_video_frame_init(sna, video, id, width, height, &frame);
+	sna_video_frame_init(video, format->id, width, height, &frame);
 
-	if (!sna_video_clip_helper(scrn, video, &frame,
+	if (!sna_video_clip_helper(sna->scrn, video, &frame,
 				   &crtc, &dstBox,
-				   src_x, src_y, drw_x, drw_y,
+				   src_x, src_y, drw_x + draw->x, drw_y + draw->y,
 				   src_w, src_h, drw_w, drw_h,
-				   clip))
+				   &clip))
 		return Success;
 
-	if (xvmc_passthrough(id)) {
+	if (xvmc_passthrough(format->id)) {
 		DBG(("%s: using passthough, name=%d\n",
 		     __FUNCTION__, *(uint32_t *)buf));
 
@@ -228,26 +228,26 @@ sna_video_textured_put_image(ScrnInfoPtr scrn,
 		frame.image.x2 = frame.width;
 		frame.image.y2 = frame.height;
 	} else {
-		if (!sna_video_copy_data(sna, video, &frame, buf)) {
+		if (!sna_video_copy_data(video, &frame, buf)) {
 			DBG(("%s: failed to copy frame\n", __FUNCTION__));
 			kgem_bo_destroy(&sna->kgem, frame.bo);
 			return BadAlloc;
 		}
 	}
 
-	if (crtc && video->SyncToVblank != 0 &&
+	if (crtc && sync && video->SyncToVblank != 0 &&
 	    sna_pixmap_is_scanout(sna, pixmap)) {
 		kgem_set_mode(&sna->kgem, KGEM_RENDER, sna_pixmap(pixmap)->gpu_bo);
 		flush = sna_wait_for_scanline(sna, pixmap, crtc,
-					      &clip->extents);
+					      &clip.extents);
 	}
 
 	ret = Success;
-	if (!sna->render.video(sna, video, &frame, clip, pixmap)) {
+	if (!sna->render.video(sna, video, &frame, &clip, pixmap)) {
 		DBG(("%s: failed to render video\n", __FUNCTION__));
 		ret = BadAlloc;
 	} else
-		DamageDamageRegion(drawable, clip);
+		DamageDamageRegion(draw, &clip);
 
 	kgem_bo_destroy(&sna->kgem, frame.bo);
 
@@ -257,14 +257,19 @@ sna_video_textured_put_image(ScrnInfoPtr scrn,
 	if (flush)
 		kgem_submit(&sna->kgem);
 
+	RegionUninit(&clip);
+
 	return ret;
 }
 
 static int
-sna_video_textured_query(ScrnInfoPtr scrn,
-			 int id,
-			 unsigned short *w, unsigned short *h,
-			 int *pitches, int *offsets)
+sna_video_textured_query(ClientPtr client,
+			 XvPortPtr port,
+			 XvImagePtr format,
+			 unsigned short *w,
+			 unsigned short *h,
+			 int *pitches,
+			 int *offsets)
 {
 	int size, tmp;
 
@@ -277,7 +282,7 @@ sna_video_textured_query(ScrnInfoPtr scrn,
 	if (offsets)
 		offsets[0] = 0;
 
-	switch (id) {
+	switch (format->id) {
 		/* IA44 is for XvMC only */
 	case FOURCC_IA44:
 	case FOURCC_AI44:
@@ -322,101 +327,93 @@ sna_video_textured_query(ScrnInfoPtr scrn,
 	return size;
 }
 
-XF86VideoAdaptorPtr sna_video_textured_setup(struct sna *sna,
-					     ScreenPtr screen)
+void sna_video_textured_setup(struct sna *sna, ScreenPtr screen)
 {
-	XF86VideoAdaptorPtr adaptor;
-	XF86AttributePtr attrs;
+	XvAdaptorPtr adaptor;
 	struct sna_video *video;
-	DevUnion *devUnions;
 	int nports = 16, i;
 
 	if (!sna->render.video) {
-		xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
+		xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
 			   "Textured video not supported on this hardware\n");
-		return NULL;
+		return;
 	}
 
 	if (wedged(sna)) {
 		xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
 			   "cannot enable XVideo whilst the GPU is wedged\n");
-		return NULL;
+		return;
 	}
 
-	adaptor = calloc(1, sizeof(XF86VideoAdaptorRec));
+	adaptor = sna_xv_adaptor_alloc(sna);
+	if (adaptor == NULL)
+		return;
+
 	video = calloc(nports, sizeof(struct sna_video));
-	devUnions = calloc(nports, sizeof(DevUnion));
-#if NUM_TEXTURED_ATTRIBUTES
-	attrs = calloc(NUM_TEXTURED_ATTRIBUTES, sizeof(XF86AttributeRec));
-	if (adaptor == NULL ||
-	    video == NULL ||
-	    devUnions == NULL ||
-	    attrs == NULL) {
-		free(adaptor);
-		free(video);
-		free(devUnions);
-		free(attrs);
-		return NULL;
-	}
-#else
-	if (adaptor == NULL || video == NULL || devUnions == NULL) {
-		free(adaptor);
-		free(video);
-		free(devUnions);
-		return NULL;
+	if ( video == NULL) {
+		sna->xv.num_adaptors--;
+		return;
 	}
-	attrs = NULL;
-#endif
 
-	adaptor->type = XvWindowMask | XvInputMask | XvImageMask;
-	adaptor->flags = 0;
+	adaptor->type = XvInputMask | XvImageMask;
+	adaptor->pScreen = screen;
 	adaptor->name = "Intel(R) Textured Video";
 	adaptor->nEncodings = 1;
-	adaptor->pEncodings = xnfalloc(sizeof(XF86VideoEncodingRec));
+	adaptor->pEncodings = xnfalloc(sizeof(XvEncodingRec));
 	adaptor->pEncodings[0].id = 0;
+	adaptor->pEncodings[0].pScreen = screen;
 	adaptor->pEncodings[0].name = "XV_IMAGE";
 	adaptor->pEncodings[0].width = sna->render.max_3d_size;
 	adaptor->pEncodings[0].height = sna->render.max_3d_size;
 	adaptor->pEncodings[0].rate.numerator = 1;
 	adaptor->pEncodings[0].rate.denominator = 1;
-	adaptor->nFormats = NUM_FORMATS;
-	adaptor->pFormats = (XF86VideoFormatPtr)Formats;
-	adaptor->nPorts = nports;
-	adaptor->pPortPrivates = devUnions;
-	adaptor->nAttributes = NUM_TEXTURED_ATTRIBUTES;
-	adaptor->pAttributes = attrs;
-	memcpy(attrs, TexturedAttributes,
-	       NUM_TEXTURED_ATTRIBUTES * sizeof(XF86AttributeRec));
+	adaptor->nFormats = ARRAY_SIZE(Formats);
+	adaptor->pFormats = Formats;
+	adaptor->nAttributes = ARRAY_SIZE(Attributes);
+	adaptor->pAttributes = Attributes;
 	adaptor->nImages = ARRAY_SIZE(Images);
-	adaptor->pImages = (XF86ImagePtr)Images;
-	adaptor->PutVideo = NULL;
-	adaptor->PutStill = NULL;
-	adaptor->GetVideo = NULL;
-	adaptor->GetStill = NULL;
-	adaptor->StopVideo = sna_video_textured_stop;
-	adaptor->SetPortAttribute = sna_video_textured_set_attribute;
-	adaptor->GetPortAttribute = sna_video_textured_get_attribute;
-	adaptor->QueryBestSize = sna_video_textured_best_size;
-	adaptor->PutImage = sna_video_textured_put_image;
-	adaptor->QueryImageAttributes = sna_video_textured_query;
+	adaptor->pImages = Images;
+	adaptor->ddAllocatePort = sna_xv_alloc_port;
+	adaptor->ddFreePort = sna_xv_free_port;
+	adaptor->ddPutVideo = NULL;
+	adaptor->ddPutStill = NULL;
+	adaptor->ddGetVideo = NULL;
+	adaptor->ddGetStill = NULL;
+	adaptor->ddStopVideo = sna_video_textured_stop;
+	adaptor->ddSetPortAttribute = sna_video_textured_set_attribute;
+	adaptor->ddGetPortAttribute = sna_video_textured_get_attribute;
+	adaptor->ddQueryBestSize = sna_video_textured_best_size;
+	adaptor->ddPutImage = sna_video_textured_put_image;
+	adaptor->ddQueryImageAttributes = sna_video_textured_query;
 
+	adaptor->nPorts = nports;
+	adaptor->pPorts = calloc(nports, sizeof(XvPortRec));
 	for (i = 0; i < nports; i++) {
 		struct sna_video *v = &video[i];
+		XvPortPtr port = &adaptor->pPorts[i];
 
+		v->sna = sna;
 		v->textured = true;
 		v->alignment = 4;
 		v->rotation = RR_Rotate_0;
 		v->SyncToVblank = 1;
 
-		/* gotta uninit this someplace, XXX: shouldn't be necessary for textured */
 		RegionNull(&v->clip);
 
-		adaptor->pPortPrivates[i].ptr = v;
+		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;
 	}
+	adaptor->base_id = adaptor->pPorts[0].id;
 
 	xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
 	xvContrast = MAKE_ATOM("XV_CONTRAST");
 	xvSyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK");
-
-	return adaptor;
 }
commit 8e42637050275945200797538a34c13c90b295cc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 21 11:13:03 2013 +0100

    sna: Re-enable read-read optimisations
    
    Coacher is optimistic that the issue is no longer reproducible on his
    machine - and whilst I do not understand the root cause, I am confident
    that the kernel code is correct as is our use.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=61628
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 6ed9e77..6a9fb1d 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -57,7 +57,7 @@
 #define FORCE_INPLACE 0
 #define FORCE_FALLBACK 0
 #define FORCE_FLUSH 0
-#define FORCE_FULL_SYNC 1 /* https://bugs.freedesktop.org/show_bug.cgi?id=61628 */
+#define FORCE_FULL_SYNC 0 /* https://bugs.freedesktop.org/show_bug.cgi?id=61628 */
 
 #define DEFAULT_TILING I915_TILING_X
 


More information about the xorg-commit mailing list