diff options
author | Zhenyu Wang <zhenyu.z.wang@intel.com> | 2007-12-25 08:32:47 +0800 |
---|---|---|
committer | Zhenyu Wang <zhenyu.z.wang@intel.com> | 2007-12-25 08:32:47 +0800 |
commit | ed9ff6f30fff33fe2d60715f1b503047f8e1ef01 (patch) | |
tree | 844a6d6b72b3a6af3a6d76c63933913e552187fb | |
parent | f0ced5edaeec3e7741828eab728417843326d56f (diff) |
xvmc: consolidate put surface interfaces
Make surface list track like context list, and move
generic PutSurface code out of i915. So MC driver just
needs to fill specific the command params, and we can
get one single type of intel xvmc command to issue,
ddx driver's put_image_size got removed.
Fix last commit with missing XvMCContext assignment.
Fix priv_data free with apropriate X11 XFree.
-rw-r--r-- | src/i830_hwmc.c | 6 | ||||
-rw-r--r-- | src/i830_hwmc.h | 12 | ||||
-rw-r--r-- | src/i830_video.c | 2 | ||||
-rw-r--r-- | src/i915_hwmc.c | 21 | ||||
-rw-r--r-- | src/i915_hwmc.h | 10 | ||||
-rw-r--r-- | src/xvmc/i915_xvmc.c | 76 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.c | 141 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.h | 17 |
8 files changed, 180 insertions, 105 deletions
diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c index 189c2e56..acb89e61 100644 --- a/src/i830_hwmc.c +++ b/src/i830_hwmc.c @@ -114,12 +114,6 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen) return TRUE; } -int intel_xvmc_put_image_size(ScrnInfoPtr pScrn) -{ - return (*xvmc_driver->put_image_size)(pScrn); -} - - Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h index 073fe441..3464d016 100644 --- a/src/i830_hwmc.h +++ b/src/i830_hwmc.h @@ -57,6 +57,17 @@ struct _intel_xvmc_common { struct hwmc_buffer batchbuffer; }; +/* Intel private XvMC command to DDX driver */ +struct intel_xvmc_command { + unsigned int command; + unsigned int ctxNo; + unsigned int srfNo; + unsigned int subPicNo; + unsigned int flags; + unsigned int real_id; + unsigned int pad[6]; +}; + #ifdef _INTEL_XVMC_SERVER_ #include <xf86xvmc.h> @@ -70,7 +81,6 @@ struct intel_xvmc_driver { /* more items for xvmv surface manage? */ Bool (*init)(ScrnInfoPtr, XF86VideoAdaptorPtr); void (*fini)(ScrnInfoPtr); - int (*put_image_size)(ScrnInfoPtr); void* devPrivate; }; diff --git a/src/i830_video.c b/src/i830_video.c index 1f82ce44..967fda92 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2552,7 +2552,7 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn, #ifdef INTEL_XVMC case FOURCC_XVMC: *h = (*h + 1) & ~1; - size = intel_xvmc_put_image_size(pScrn); + size = sizeof(struct intel_xvmc_command); if (pitches) pitches[0] = size; break; diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c index e41d148d..a8daf3e6 100644 --- a/src/i915_hwmc.c +++ b/src/i915_hwmc.c @@ -766,24 +766,24 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, { I830Ptr pI830 = I830PTR(pScrn); I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; - I915XvMCCommandBuffer *i915XvMCData = (I915XvMCCommandBuffer *)buf; + struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf; int ret; if (pI830->XvMCEnabled) { if (FOURCC_XVMC == id) { - switch (i915XvMCData->command) { + switch (xvmc_cmd->command) { case INTEL_XVMC_COMMAND_DISPLAY: - if ((i915XvMCData->srfNo >= I915_XVMC_MAX_SURFACES) || - !pXvMC->surfaces[i915XvMCData->srfNo] || - !pXvMC->sfprivs[i915XvMCData->srfNo]) { + if ((xvmc_cmd->srfNo >= I915_XVMC_MAX_SURFACES) || + !pXvMC->surfaces[xvmc_cmd->srfNo] || + !pXvMC->sfprivs[xvmc_cmd->srfNo]) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] i915 put image: Invalid parameters!\n"); return 1; } buf = pI830->FbBase + - pXvMC->sfprivs[i915XvMCData->srfNo]->surface->offset; - id = i915XvMCData->real_id; + pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset; + id = xvmc_cmd->real_id; pI830->IsXvMCSurface = 1; break; default: @@ -799,12 +799,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, return ret; } -static int i915_xvmc_put_image_size(ScrnInfoPtr pScrn) -{ - return sizeof(I915XvMCCommandBuffer); -} - - static Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt) { I915XvMCPtr pXvMC; @@ -872,5 +866,4 @@ struct intel_xvmc_driver i915_xvmc_driver = { .flag = XVMC_I915_MPEG2_MC, .init = i915_xvmc_init, .fini = i915_xvmc_fini, - .put_image_size = i915_xvmc_put_image_size, }; diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h index 9da37475..0141fb25 100644 --- a/src/i915_hwmc.h +++ b/src/i915_hwmc.h @@ -40,16 +40,6 @@ typedef struct { - unsigned int command; - unsigned int ctxNo; - unsigned int srfNo; - unsigned int subPicNo; - int real_id; -} I915XvMCCommandBuffer; - - -typedef struct -{ struct _intel_xvmc_common comm; unsigned int ctxno; /* XvMC private context reference number */ struct hwmc_buffer sis; diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c index 44ccdc11..10b60ce2 100644 --- a/src/xvmc/i915_xvmc.c +++ b/src/xvmc/i915_xvmc.c @@ -1636,7 +1636,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context XVMC_INFO("\tExpected %d, got %d", (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count); _xvmc_destroy_context(display, context); - free(priv_data); + XFree(priv_data); context->privData = NULL; return BadValue; } @@ -1684,7 +1684,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset; /* Must free the private data we were passed from X */ - free(priv_data); + XFree(priv_data); priv_data = NULL; pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address; @@ -1741,6 +1741,14 @@ static Status i915_xvmc_mc_create_surface(Display *display, XVMC_DBG("%s\n", __FUNCTION__); + if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) { + XVMC_ERR("_xvmc_create_surface() returned incorrect data size!"); + XVMC_INFO("\tExpected %d, got %d", + (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count); + _xvmc_destroy_surface(display, surface); + XFree(priv_data); + return BadAlloc; + } PPTHREAD_MUTEX_LOCK(); surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface)); @@ -1761,25 +1769,14 @@ static Status i915_xvmc_mc_create_surface(Display *display, pI915Surface->privSubPic = NULL; pI915Surface->srf.map = NULL; - if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) { - XVMC_ERR("_xvmc_create_surface() returned incorrect data size!"); - XVMC_INFO("\tExpected %d, got %d", - (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count); - _xvmc_destroy_surface(display, surface); - free(priv_data); - free(pI915Surface); - surface->privData = NULL; - PPTHREAD_MUTEX_UNLOCK(); - return BadAlloc; - } - tmpComm = (I915XvMCCreateSurfaceRec *)priv_data; pI915Surface->srfNo = tmpComm->srfno; pI915Surface->srf.handle = tmpComm->srf.handle; pI915Surface->srf.offset = tmpComm->srf.offset; pI915Surface->srf.size = tmpComm->srf.size; - free(priv_data); + + XFree(priv_data); if (drmMap(xvmc_driver->fd, pI915Surface->srf.handle, @@ -1894,7 +1891,6 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, XVMC_ERR("Can't find intel xvmc context\n"); return BadValue; } - XVMC_DBG("intel ctx found\n"); /* P Frame Test */ if (!past_surface) { @@ -2043,18 +2039,11 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface, unsigned short srcw, unsigned short srch, short destx, short desty, unsigned short destw, unsigned short desth, - int flags) + int flags, struct intel_xvmc_command *data) { i915XvMCContext *pI915XvMC; i915XvMCSurface *pI915Surface; i915XvMCSubpicture *pI915SubPic; - I915XvMCCommandBuffer buf; - - // drawableInfo *drawInfo; - Status ret; - - if (!display || !surface) - return BadValue; if (!(pI915Surface = surface->privData)) return (error_base + XvMCBadSurface); @@ -2064,37 +2053,14 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface, PPTHREAD_MUTEX_LOCK(); - if (!pI915XvMC->haveXv) { - pI915XvMC->xvImage = - XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC, - (char *)&buf, pI915Surface->width, pI915Surface->height); - pI915XvMC->gc = XCreateGC(display, draw, 0, 0); - pI915XvMC->haveXv = 1; - } - - pI915XvMC->draw = draw; - pI915XvMC->xvImage->data = (char *)&buf; - - buf.command = INTEL_XVMC_COMMAND_DISPLAY; - buf.ctxNo = pI915XvMC->ctxno; - buf.srfNo = pI915Surface->srfNo; + data->command = INTEL_XVMC_COMMAND_DISPLAY; + data->ctxNo = pI915XvMC->ctxno; + data->srfNo = pI915Surface->srfNo; pI915SubPic = pI915Surface->privSubPic; - buf.subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo); - buf.real_id = FOURCC_YV12; + data->subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo); + data->real_id = FOURCC_YV12; + data->flags = flags; - XLockDisplay(display); - - if ((ret = XvPutImage(display, pI915XvMC->port, draw, pI915XvMC->gc, - pI915XvMC->xvImage, srcx, srcy, srcw, srch, - destx, desty, destw, desth))) { - XUnlockDisplay(display); - PPTHREAD_MUTEX_UNLOCK(); - - return ret; - } - - XSync(display, 0); - XUnlockDisplay(display); PPTHREAD_MUTEX_UNLOCK(); return 0; @@ -2236,7 +2202,7 @@ Status i915_xvmc_create_subpict(Display *display, XvMCContext *context, XLockDisplay(display); _xvmc_destroy_subpicture(display, subpicture); XUnlockDisplay(display); - free(priv_data); + XFree(priv_data); free(pI915Subpicture); subpicture->privData = NULL; PPTHREAD_MUTEX_UNLOCK(); @@ -2248,7 +2214,7 @@ Status i915_xvmc_create_subpict(Display *display, XvMCContext *context, pI915Subpicture->srf.handle = tmpComm->srf.handle; pI915Subpicture->srf.offset = tmpComm->srf.offset; pI915Subpicture->srf.size = tmpComm->srf.size; - free(priv_data); + XFree(priv_data); if (drmMap(pI915XvMC->fd, pI915Subpicture->srf.handle, diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c index fead3a4d..0ce3cc2d 100644 --- a/src/xvmc/intel_xvmc.c +++ b/src/xvmc/intel_xvmc.c @@ -84,7 +84,7 @@ static void intel_xvmc_free_context(XID id) intel_xvmc_context_ptr pre = p; while(p) { - if (p->context->context_id == id) { + if (p->context && p->context->context_id == id) { if (p == xvmc_driver->ctx_list) xvmc_driver->ctx_list = p->next; else @@ -95,9 +95,10 @@ static void intel_xvmc_free_context(XID id) p = p->next; } - if (p) + if (p) { free(p); - xvmc_driver->num_ctx--; + xvmc_driver->num_ctx--; + } } intel_xvmc_context_ptr intel_xvmc_find_context(XID id) @@ -105,13 +106,69 @@ intel_xvmc_context_ptr intel_xvmc_find_context(XID id) intel_xvmc_context_ptr p = xvmc_driver->ctx_list; while(p) { - if (p->context->context_id == id) + if (p->context && p->context->context_id == id) return p; p = p->next; } return NULL; } +static intel_xvmc_surface_ptr intel_xvmc_new_surface(Display *dpy) +{ + intel_xvmc_surface_ptr ret; + + ret = (intel_xvmc_surface_ptr)calloc(1, sizeof(intel_xvmc_surface_t)); + if (!ret) + return NULL; + + if (!xvmc_driver->surf_list) + ret->next = NULL; + else + ret->next = xvmc_driver->surf_list; + xvmc_driver->surf_list = ret; + xvmc_driver->num_surf++; + + ret->image = NULL; + ret->gc_init = FALSE; + + return ret; + +} + +static void intel_xvmc_free_surface(XID id) +{ + intel_xvmc_surface_ptr p = xvmc_driver->surf_list; + intel_xvmc_surface_ptr pre = p; + + while(p) { + if (p->surface && p->surface->surface_id == id) { + if (p == xvmc_driver->surf_list) + xvmc_driver->surf_list = p->next; + else + pre->next = p->next; + break; + } + pre = p; + p = p->next; + } + + if (p) { + free(p); + xvmc_driver->num_surf--; + } +} + +intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id) +{ + intel_xvmc_surface_ptr p = xvmc_driver->surf_list; + + while(p) { + if (p->surface && p->surface->surface_id == id) + return p; + p = p->next; + } + return NULL; +} /* * Function: XvMCCreateContext * Description: Create a XvMC context for the given surface parameters. @@ -207,7 +264,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, case XVMC_I965_MPEG2_VLD: default: XVMC_ERR("unimplemented xvmc type %d", comm->type); - free(priv_data); + XFree(priv_data); priv_data = NULL; return BadValue; } @@ -231,32 +288,33 @@ Status XvMCCreateContext(Display *display, XvPortID port, XVMC_ERR("Intel XvMC context create fail\n"); return BadAlloc; } + intel_ctx->context = context; ret = uniDRIQueryDirectRenderingCapable(display, screen, &isCapable); if (!ret || !isCapable) { XVMC_ERR("Direct Rendering is not available on this system!"); - free(priv_data); + XFree(priv_data); return BadValue; } if (!uniDRIOpenConnection(display, screen, &xvmc_driver->hsarea, &curBusID)) { XVMC_ERR("Could not open DRI connection to X server!"); - free(priv_data); + XFree(priv_data); return BadValue; } strncpy(xvmc_driver->busID, curBusID, 20); xvmc_driver->busID[20] = '\0'; - free(curBusID); + XFree(curBusID); /* Open DRI Device */ if((xvmc_driver->fd = drmOpen("i915", NULL)) < 0) { XVMC_ERR("DRM Device could not be opened."); //(xvmc_driver->fini)(); xvmc_driver = NULL; - free(priv_data); + XFree(priv_data); return BadValue; } @@ -267,7 +325,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, if (!uniDRIAuthConnection(display, screen, magic)) { XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions."); xvmc_driver = NULL; - free(priv_data); + XFree(priv_data); return BadAlloc; } @@ -278,7 +336,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, xvmc_driver->sarea_size, &xvmc_driver->sarea_address) < 0) { XVMC_ERR("Unable to map DRI SAREA.\n"); xvmc_driver = NULL; - free(priv_data); + XFree(priv_data); return BadAlloc; } pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address; @@ -290,7 +348,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, context->context_id, &intel_ctx->hw_context)) { XVMC_ERR("Could not create DRI context."); - free(priv_data); + XFree(priv_data); context->privData = NULL; drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size); return BadAlloc; @@ -301,7 +359,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data); if (ret) { XVMC_ERR("driver create context failed\n"); - free(priv_data); + XFree(priv_data); drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size); return ret; } @@ -367,6 +425,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su Status ret; int priv_count; CARD32 *priv_data; + intel_xvmc_surface_ptr intel_surf = NULL; if (!display || !context) return XvMCBadContext; @@ -374,12 +433,28 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su if (!surface) return XvMCBadSurface; + intel_surf = intel_xvmc_new_surface(display); + if (!intel_surf) + return BadAlloc; + intel_surf->surface = surface; + if ((ret = _xvmc_create_surface(display, context, surface, &priv_count, &priv_data))) { XVMC_ERR("Unable to create XvMCSurface."); return ret; } + intel_surf->image = XvCreateImage(display, context->port, + FOURCC_XVMC, (char *)&intel_surf->data, surface->width, + surface->height); + if (!intel_surf->image) { + XVMC_ERR("Can't create XvImage for surface\n"); + _xvmc_destroy_surface(display, surface); + intel_xvmc_free_surface(surface->surface_id); + return BadAlloc; + } + intel_surf->image->data = (char *)&intel_surf->data; + ret = (xvmc_driver->create_surface)(display, context, surface, priv_count, priv_data); if (ret) { @@ -396,9 +471,20 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su */ Status XvMCDestroySurface(Display *display, XvMCSurface *surface) { + intel_xvmc_surface_ptr intel_surf; + if (!display || !surface) return XvMCBadSurface; + intel_surf = intel_xvmc_find_surface(surface->surface_id); + if (!intel_surf) + return XvMCBadSurface; + + XFree(intel_surf->image); + if (intel_surf->gc_init) + XFreeGC(display, intel_surf->gc); + intel_xvmc_free_surface(surface->surface_id); + (xvmc_driver->destroy_surface)(display, surface); _xvmc_destroy_surface(display, surface); @@ -559,19 +645,42 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface, unsigned short destw, unsigned short desth, int flags) { - Status ret; + Status ret = Success; + XvMCContext *context; + intel_xvmc_context_ptr intel_ctx; + intel_xvmc_surface_ptr intel_surf; if (!display || !surface) return XvMCBadSurface; + intel_ctx = intel_xvmc_find_context(surface->context_id); + intel_surf = intel_xvmc_find_surface(surface->surface_id); + if (!intel_ctx || !intel_surf) + return XvMCBadSurface; + context = intel_ctx->context; + + if (intel_surf->gc_init == FALSE) { + intel_surf->gc = XCreateGC(display, draw, 0, NULL); + intel_surf->gc_init = TRUE; + } else if (draw != intel_surf->last_draw) { + XFreeGC(display, intel_surf->gc); + intel_surf->gc = XCreateGC(display, draw, 0, NULL); + } + intel_surf->last_draw = draw; + + /* fill intel_surf->data */ ret = (xvmc_driver->put_surface)(display, surface, draw, srcx, srcy, - srcw, srch, destx, desty, destw, desth, flags); + srcw, srch, destx, desty, destw, desth, flags, &intel_surf->data); if (ret) { XVMC_ERR("put surface fail\n"); return ret; } - return Success; + ret = XvPutImage(display, context->port, draw, intel_surf->gc, + intel_surf->image, srcx, srcy, srcw, srch, destx, desty, + destw, desth); + + return ret; } /* diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h index 19c5f4cd..8ebb14bf 100644 --- a/src/xvmc/intel_xvmc.h +++ b/src/xvmc/intel_xvmc.h @@ -88,7 +88,7 @@ extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context); extern Status _xvmc_create_surface(Display *dpy, XvMCContext *context, XvMCSurface *surface, int *priv_count, - uint **priv_data); + CARD32 **priv_data); extern Status _xvmc_destroy_surface(Display *dpy, XvMCSurface *surface); @@ -105,6 +105,16 @@ typedef struct _intel_xvmc_context { struct _intel_xvmc_context *next; } intel_xvmc_context_t, *intel_xvmc_context_ptr; +typedef struct _intel_xvmc_surface { + XvMCSurface *surface; + XvImage *image; + GC gc; + Bool gc_init; + Drawable last_draw; + struct intel_xvmc_command data; + struct _intel_xvmc_surface *next; +} intel_xvmc_surface_t, *intel_xvmc_surface_ptr; + typedef struct _intel_xvmc_drm_map { drm_handle_t handle; unsigned long offset; @@ -150,6 +160,8 @@ typedef struct _intel_xvmc_driver { int num_ctx; intel_xvmc_context_ptr ctx_list; + int num_surf; + intel_xvmc_surface_ptr surf_list; void *private; @@ -185,7 +197,7 @@ typedef struct _intel_xvmc_driver { unsigned short srcw, unsigned short srch, short destx, short desty, unsigned short destw, unsigned short desth, - int flags); + int flags, struct intel_xvmc_command *data); Status (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat); @@ -240,5 +252,6 @@ static inline const char* intel_xvmc_decoder_string(int flag) } extern intel_xvmc_context_ptr intel_xvmc_find_context(XID id); +extern intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id); #endif |