diff options
-rw-r--r-- | src/sna/sna_video.h | 19 | ||||
-rw-r--r-- | src/sna/sna_video_overlay.c | 53 | ||||
-rw-r--r-- | src/sna/sna_video_sprite.c | 46 | ||||
-rw-r--r-- | src/sna/sna_video_textured.c | 37 |
4 files changed, 96 insertions, 59 deletions
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h index c0c023cf..2e7144ec 100644 --- a/src/sna/sna_video.h +++ b/src/sna/sna_video.h @@ -35,6 +35,20 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SNA_XVMC 1 #endif +/* + * Below, a dummy picture type that is used in XvPutImage + * only to do an overlay update. + * Introduced for the XvMC client lib. + * Defined to have a zero data size. + */ +#define XVMC_YUV { \ + FOURCC_XVMC, XvYUV, LSBFirst, \ + {'X', 'V', 'M', 'C', 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}, \ + 12, XvPlanar, 3, 0, 0, 0, 0, 8, 8, 8, 1, 2, 2, 1, 2, 2, \ + {'Y', 'V', 'U', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ + XvTopToBottom \ +} + struct sna_video { int brightness; int contrast; @@ -88,6 +102,11 @@ XF86VideoAdaptorPtr sna_video_textured_setup(struct sna *sna, ScreenPtr screen); #define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') +static inline int xvmc_passthrough(int id) +{ + return id == FOURCC_XVMC; +} + static inline int is_planar_fourcc(int id) { switch (id) { diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c index 3655b876..459541c8 100644 --- a/src/sna/sna_video_overlay.c +++ b/src/sna/sna_video_overlay.c @@ -91,12 +91,12 @@ static const XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = { {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"} }; -#define NUM_IMAGES 4 -static const XF86ImageRec Images[NUM_IMAGES] = { +static const XF86ImageRec Images[] = { XVIMAGE_YUY2, XVIMAGE_YV12, XVIMAGE_I420, XVIMAGE_UYVY, + XVMC_YUV }; /* kernel modesetting overlay functions */ @@ -515,15 +515,32 @@ sna_video_overlay_put_image(ScrnInfoPtr scrn, /* overlay can't handle rotation natively, store it for the copy func */ video->rotation = crtc->rotation; - frame.bo = sna_video_buffer(sna, 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)) { - DBG(("%s: failed to copy video data\n", __FUNCTION__)); - return BadAlloc; + if (xvmc_passthrough(id)) { + DBG(("%s: using passthough, name=%d\n", + __FUNCTION__, *(uint32_t *)buf)); + + frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf); + if (frame.bo == NULL) { + DBG(("%s: failed to open bo\n", __FUNCTION__)); + return BadAlloc; + } + + assert(kgem_bo_size(frame.bo) >= frame.size); + frame.image.x1 = 0; + frame.image.y1 = 0; + frame.image.x2 = frame.width; + frame.image.y2 = frame.height; + } else { + frame.bo = sna_video_buffer(sna, 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)) { + DBG(("%s: failed to copy video data\n", __FUNCTION__)); + return BadAlloc; + } } if (!sna_video_overlay_show @@ -533,7 +550,10 @@ sna_video_overlay_put_image(ScrnInfoPtr scrn, } frame.bo->domain = DOMAIN_NONE; - sna_video_buffer_fini(sna, video); + if (xvmc_passthrough(id)) + kgem_bo_destroy(&sna->kgem, frame.bo); + else + sna_video_buffer_fini(sna, video); /* update cliplist */ if (!REGION_EQUAL(scrn->pScreen, &video->clip, clip)) { @@ -572,6 +592,13 @@ sna_video_overlay_query_video_attributes(ScrnInfoPtr scrn, offsets[0] = 0; switch (id) { + case FOURCC_XVMC: + *h = (*h + 1) & ~1; + size = sizeof(uint32_t); + if (pitches) + pitches[0] = size; + break; + /* IA44 is for XvMC only */ case FOURCC_IA44: case FOURCC_AI44: @@ -689,7 +716,7 @@ XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna, memcpy(adaptor->pAttributes + NUM_ATTRIBUTES, GammaAttributes, sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES); - adaptor->nImages = NUM_IMAGES; + adaptor->nImages = ARRAY_SIZE(Images); adaptor->pImages = (XF86ImagePtr)Images; adaptor->PutVideo = NULL; adaptor->PutStill = NULL; diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c index 7737460b..a749d1ef 100644 --- a/src/sna/sna_video_sprite.c +++ b/src/sna/sna_video_sprite.c @@ -53,7 +53,7 @@ static Atom xvColorKey; static XF86VideoFormatRec xv_formats[] = { {15, TrueColor}, {16, TrueColor}, {24, TrueColor} }; -static XF86ImageRec xv_images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, }; +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} } }; @@ -314,15 +314,30 @@ static int sna_video_sprite_put_image(ScrnInfoPtr scrn, /* sprites can't handle rotation natively, store it for the copy func */ video->rotation = crtc->rotation; - frame.bo = sna_video_buffer(sna, video, &frame); - if (frame.bo == NULL) { - DBG(("%s: failed to allocate video bo\n", __FUNCTION__)); - return BadAlloc; - } + if (xvmc_passthrough(id)) { + DBG(("%s: using passthough, name=%d\n", + __FUNCTION__, *(uint32_t *)buf)); - if (!sna_video_copy_data(sna, video, &frame, buf)) { - DBG(("%s: failed to copy video data\n", __FUNCTION__)); - return BadAlloc; + frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf); + if (frame.bo == NULL) + return BadAlloc; + + assert(kgem_bo_size(frame.bo) >= frame.size); + frame.image.x1 = 0; + frame.image.y1 = 0; + frame.image.x2 = frame.width; + frame.image.y2 = frame.height; + } else { + frame.bo = sna_video_buffer(sna, 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)) { + DBG(("%s: failed to copy video data\n", __FUNCTION__)); + return BadAlloc; + } } if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst_box)) { @@ -330,7 +345,11 @@ static int sna_video_sprite_put_image(ScrnInfoPtr scrn, return BadAlloc; } - sna_video_buffer_fini(sna, video); + frame.bo->domain = DOMAIN_NONE; + if (xvmc_passthrough(id)) + kgem_bo_destroy(&sna->kgem, frame.bo); + else + sna_video_buffer_fini(sna, video); if (!REGION_EQUAL(scrn->pScreen, &video->clip, clip)) { REGION_COPY(scrn->pScreen, &video->clip, clip); @@ -356,6 +375,13 @@ static int sna_video_sprite_query_attrs(ScrnInfoPtr scrn, int id, offsets[0] = 0; switch (id) { + case FOURCC_XVMC: + *h = (*h + 1) & ~1; + size = sizeof(uint32_t); + if (pitches) + pitches[0] = size; + break; + case FOURCC_YUY2: default: size = *w << 1; diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c index d94dbd8f..ddde2494 100644 --- a/src/sna/sna_video_textured.c +++ b/src/sna/sna_video_textured.c @@ -69,44 +69,9 @@ static const XF86ImageRec Images[NUM_IMAGES] = { XVIMAGE_YV12, XVIMAGE_I420, XVIMAGE_UYVY, -#ifdef SNA_XVMC - { - /* - * Below, a dummy picture type that is used in XvPutImage - * only to do an overlay update. - * Introduced for the XvMC client lib. - * Defined to have a zero data size. - */ - FOURCC_XVMC, - XvYUV, - LSBFirst, - {'X', 'V', 'M', 'C', - 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, - 0x38, 0x9B, 0x71}, - 12, - XvPlanar, - 3, - 0, 0, 0, 0, - 8, 8, 8, - 1, 2, 2, - 1, 2, 2, - {'Y', 'V', 'U', - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - XvTopToBottom}, -#endif + XVMC_YUV, }; -static int xvmc_passthrough(int id) -{ -#ifdef SNA_XVMC - return id == FOURCC_XVMC; -#else - return 0; - (void)id; -#endif -} - static void sna_video_textured_stop(ScrnInfoPtr scrn, pointer data, Bool shutdown) |