Commit ed9ff6f3 authored by Zhenyu Wang's avatar Zhenyu Wang

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.
parent f0ced5ed
......@@ -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);
......
......@@ -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;
};
......
......@@ -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;
......
......@@ -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,
};
......@@ -38,16 +38,6 @@
#define I915_NUM_XVMC_ATTRIBUTES 0x02
#define I915_XVMC_VALID 0x80000000
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;
......
......@@ -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,
......
......@@ -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;
}
/*
......
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment