From 195a51353c3af7bd253227da5f759f06cea01f73 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 9 Apr 2013 19:13:46 +0100 Subject: 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 --- src/compat-api.h | 1 + src/sna/sna.h | 6 + src/sna/sna_accel.c | 2 + 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, 654 insertions(+), 514 deletions(-) (limited to 'src') diff --git a/src/compat-api.h b/src/compat-api.h index 6d147c74..d80b7fe1 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 ee3f821d..79ac1adc 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 #include #include +#include #include @@ -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 6a9fb1d8..0e4d8fe2 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 @@ -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 1cfba5b6..a29661c4 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 6d067c76..eb4f8463 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 2e7144ec..e1b289d4 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 55aa8546..15a7844a 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 8b0d2cdf..a6469a01 100644 --- a/src/sna/sna_video_hwmc.h +++ b/src/sna/sna_video_hwmc.h @@ -40,7 +40,7 @@ #ifdef _SNA_XVMC_SERVER_ #include -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 459541c8..6d852752 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 a749d1ef..06b278e5 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 8278606c..29f4d9d4 100644 --- a/src/sna/sna_video_textured.c +++ b/src/sna/sna_video_textured.c @@ -34,29 +34,21 @@ #include #include -#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; } -- cgit v1.2.3