Commit 5f961f28 authored by Zhenyu Wang's avatar Zhenyu Wang

xvmc: move dri context handling to generic code

Use XvMCContext's context_id for dri context handling instead
of driver private id. Remove unnecessary field for i915 private
structs.
parent 73827e78
......@@ -501,7 +501,6 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset;
contextRec->corrdata.size = ctxpriv->mcCorrdata->size;
contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec);
contextRec->depth = pScrn->bitsPerPixel;
contextRec->deviceID = pI830DRI->deviceID;
pXvMC->ncontexts++;
......
......@@ -59,7 +59,6 @@ typedef struct
struct hwmc_buffer psc;
struct hwmc_buffer corrdata;/* Correction Data Buffer */
unsigned int sarea_priv_offset;
unsigned int depth;
int deviceID;
} I915XvMCCreateContextRec;
......
......@@ -1612,10 +1612,6 @@ static void i915_release_resource(Display *display, XvMCContext *context)
driDestroyHashContents(pI915XvMC->drawHash);
drmHashDestroy(pI915XvMC->drawHash);
XLockDisplay(display);
uniDRIDestroyContext(display, screen, pI915XvMC->id);
XUnlockDisplay(display);
free(pI915XvMC);
context->privData = NULL;
}
......@@ -1633,6 +1629,8 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
int isCapable;
int screen = DefaultScreen(display);
XVMC_DBG("i915_xvmc_mc_create_context\n");
if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
XVMC_INFO("\tExpected %d, got %d",
......@@ -1684,7 +1682,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
pI915XvMC->corrdata.size = tmpComm->corrdata.size;
pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
pI915XvMC->depth = tmpComm->depth;
/* Must free the private data we were passed from X */
free(priv_data);
......@@ -1692,27 +1689,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset);
ret = XMatchVisualInfo(display, screen,
(pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
&pI915XvMC->visualInfo);
if (!ret) {
XVMC_ERR("Could not find a matching TrueColor visual.");
free(pI915XvMC);
context->privData = NULL;
drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
return BadAlloc;
}
if (!uniDRICreateContext(display, screen,
pI915XvMC->visualInfo.visual, &pI915XvMC->id,
&pI915XvMC->hHWContext)) {
XVMC_ERR("Could not create DRI context.");
free(pI915XvMC);
context->privData = NULL;
drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
return BadAlloc;
}
if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
XVMC_ERR("Could not allocate drawable hash table.");
......@@ -1761,12 +1737,15 @@ static Status i915_xvmc_mc_create_surface(Display *display,
int priv_count;
uint *priv_data;
if (!display || !context || !display)
if (!display || !context)
return BadValue;
if (!(pI915XvMC = context->privData))
return (error_base + XvMCBadContext);
XVMC_DBG("%s\n", __FUNCTION__);
PPTHREAD_MUTEX_LOCK();
surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
......@@ -1823,6 +1802,7 @@ static Status i915_xvmc_mc_create_surface(Display *display,
pI915Surface->srf.handle,
pI915Surface->srf.size,
(drmAddress *)&pI915Surface->srf.map) != 0) {
XVMC_ERR("mapping surface memory failed!\n");
_xvmc_destroy_surface(display, surface);
free(pI915Surface);
surface->privData = NULL;
......@@ -1890,11 +1870,15 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
/* Current Macroblock Pointer */
XvMCMacroBlock *mb;
intel_xvmc_context_ptr intel_ctx;
i915XvMCSurface *privTarget = NULL;
i915XvMCSurface *privFuture = NULL;
i915XvMCSurface *privPast = NULL;
i915XvMCContext *pI915XvMC = NULL;
XVMC_DBG("%s\n", __FUNCTION__);
/* Check Parameters for validity */
if (!display || !context || !target_surface) {
XVMC_ERR("Invalid Display, Context or Target!");
......@@ -1926,6 +1910,13 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
return BadValue;
}
intel_ctx = intel_xvmc_find_context(context->context_id);
if (!intel_ctx) {
XVMC_ERR("Can't find intel xvmc context\n");
return BadValue;
}
XVMC_DBG("intel ctx found\n");
/* P Frame Test */
if (!past_surface) {
/* Just to avoid some ifs later. */
......@@ -1955,7 +1946,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
picture_coding_type = MPEG_B_PICTURE;
}
LOCK_HARDWARE(pI915XvMC->hHWContext);
LOCK_HARDWARE(intel_ctx->hw_context);
corrdata_ptr = pI915XvMC->corrdata.map;
corrdata_size = 0;
......@@ -2064,7 +2055,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
xvmc_driver->last_render = xvmc_driver->alloc.irq_emitted;
privTarget->last_render = xvmc_driver->last_render;
UNLOCK_HARDWARE(pI915XvMC->hHWContext);
UNLOCK_HARDWARE(intel_ctx->hw_context);
return 0;
}
......@@ -2093,14 +2084,7 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
return (error_base + XvMCBadSurface);
PPTHREAD_MUTEX_LOCK();
/*
if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
PPTHREAD_MUTEX_UNLOCK();
return BadAccess;
}
*/
if (!pI915XvMC->haveXv) {
pI915XvMC->xvImage =
XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC,
......@@ -2154,7 +2138,6 @@ static int i915_xvmc_mc_get_surface_status(Display *display,
if (!(pI915XvMC = pI915Surface->privContext))
return (error_base + XvMCBadSurface);
// LOCK_HARDWARE(pI915XvMC->hHWContext);
PPTHREAD_MUTEX_LOCK();
if (pI915Surface->last_flip) {
/* This can not happen */
......@@ -2184,7 +2167,6 @@ static int i915_xvmc_mc_get_surface_status(Display *display,
*stat |= XVMC_RENDERING;
}
// UNLOCK_HARDWARE(pI915XvMC->hHWContext);
PPTHREAD_MUTEX_UNLOCK();
return 0;
}
......@@ -2594,7 +2576,6 @@ Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture
if (!(pI915XvMC = pI915Subpicture->privContext))
return (error_base + XvMCBadSubpicture);
// LOCK_HARDWARE(pI915XvMC->hHWContext);
PPTHREAD_MUTEX_LOCK();
/* FIXME: */
if (pI915Subpicture->last_render &&
......@@ -2602,7 +2583,6 @@ Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture
*stat |= XVMC_RENDERING;
}
// UNLOCK_HARDWARE(pI915XvMC->hHWContext);
PPTHREAD_MUTEX_UNLOCK();
return Success;
}
......@@ -2610,14 +2590,16 @@ Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture
#endif
struct _intel_xvmc_driver i915_xvmc_mc_driver = {
.type = XVMC_I915_MPEG2_MC,
.init = i915_xvmc_mc_init,
.fini = i915_xvmc_mc_fini,
.create_context = i915_xvmc_mc_create_context,
.destroy_context = i915_xvmc_mc_destroy_context,
.create_surface = i915_xvmc_mc_create_surface,
.destroy_surface = i915_xvmc_mc_destroy_surface,
.render_surface = i915_xvmc_mc_render_surface,
.put_surface = i915_xvmc_mc_put_surface,
.get_surface_status = i915_xvmc_mc_get_surface_status,
.type = XVMC_I915_MPEG2_MC,
.num_ctx = 0,
.ctx_list = NULL,
.init = i915_xvmc_mc_init,
.fini = i915_xvmc_mc_fini,
.create_context = i915_xvmc_mc_create_context,
.destroy_context = i915_xvmc_mc_destroy_context,
.create_surface = i915_xvmc_mc_create_surface,
.destroy_surface = i915_xvmc_mc_destroy_surface,
.render_surface = i915_xvmc_mc_render_surface,
.put_surface = i915_xvmc_mc_put_surface,
.get_surface_status = i915_xvmc_mc_get_surface_status,
};
......@@ -56,7 +56,6 @@ typedef struct _i915XvMCContext {
unsigned int uvStride;
unsigned short ref;
volatile drmI830Sarea *sarea;
drm_context_t hHWContext; /* drmcontext; */
unsigned int sarea_priv_offset; /* Offset in sarea to private part */
unsigned int depth;
XvPortID port; /* Xv Port ID when displaying */
......@@ -66,8 +65,6 @@ typedef struct _i915XvMCContext {
* buffer transport to the X server */
GC gc; /* X GC needed for displaying */
Drawable draw; /* Drawable to undisplay from */
XID id;
XVisualInfo visualInfo;
void *drawHash;
int deviceID;
......
......@@ -59,6 +59,59 @@ void UNLOCK_HARDWARE(drm_context_t ctx)
PPTHREAD_MUTEX_UNLOCK();
}
static intel_xvmc_context_ptr intel_xvmc_new_context(Display *dpy)
{
intel_xvmc_context_ptr ret;
ret = (intel_xvmc_context_ptr)calloc(1, sizeof(intel_xvmc_context_t));
if (!ret)
return NULL;
if (!xvmc_driver->ctx_list)
ret->next = NULL;
else
ret->next = xvmc_driver->ctx_list;
xvmc_driver->ctx_list = ret;
xvmc_driver->num_ctx++;
return ret;
}
static void intel_xvmc_free_context(XID id)
{
intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
intel_xvmc_context_ptr pre = p;
while(p) {
if (p->id == id) {
if (p == xvmc_driver->ctx_list)
xvmc_driver->ctx_list = p->next;
else
pre->next = p->next;
break;
}
pre = p;
p = p->next;
}
if (p)
free(p);
xvmc_driver->num_ctx--;
}
intel_xvmc_context_ptr intel_xvmc_find_context(XID id)
{
intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
while(p) {
if (p->id == id)
return p;
p = p->next;
}
return NULL;
}
/*
* Function: XvMCCreateContext
* Description: Create a XvMC context for the given surface parameters.
......@@ -89,6 +142,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
int priv_count;
int isCapable;
int screen = DefaultScreen(display);
intel_xvmc_context_ptr intel_ctx;
/* Verify Obvious things first */
if (!display || !context)
......@@ -171,6 +225,15 @@ Status XvMCCreateContext(Display *display, XvPortID port,
xvmc_driver->batchbuffer.offset = comm->batchbuffer.offset;
xvmc_driver->batchbuffer.size = comm->batchbuffer.size;
/* assign local ctx info */
intel_ctx = intel_xvmc_new_context(display);
if (!intel_ctx) {
XVMC_ERR("Intel XvMC context create fail\n");
return BadAlloc;
}
/* context_id is alloc in _xvmc_create_context */
intel_ctx->id = context->context_id;
ret = uniDRIQueryDirectRenderingCapable(display, screen,
&isCapable);
if (!ret || !isCapable) {
......@@ -205,7 +268,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
if (!uniDRIAuthConnection(display, screen, magic)) {
XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions.");
//(xvmc_driver->fini)();
xvmc_driver = NULL;
free(priv_data);
return BadAlloc;
......@@ -217,7 +279,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
if (drmMap(xvmc_driver->fd, xvmc_driver->hsarea,
xvmc_driver->sarea_size, &xvmc_driver->sarea_address) < 0) {
XVMC_ERR("Unable to map DRI SAREA.\n");
//(xvmc_driver->fini)();
xvmc_driver = NULL;
free(priv_data);
return BadAlloc;
......@@ -226,6 +287,16 @@ Status XvMCCreateContext(Display *display, XvPortID port,
xvmc_driver->driHwLock = (drmLock *)&pSAREA->lock;
pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
if (!uniDRICreateContext(display, screen, NULL,
context->context_id,
&intel_ctx->hw_context)) {
XVMC_ERR("Could not create DRI context.");
free(priv_data);
context->privData = NULL;
drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
return BadAlloc;
}
/* call driver hook.
* driver hook should free priv_data after return if success.*/
ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data);
......@@ -264,22 +335,28 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
return ret;
}
uniDRIDestroyContext(display, screen, context->context_id);
intel_xvmc_free_context(context->context_id);
ret = _xvmc_destroy_context(display, context);
if (ret != Success) {
XVMC_ERR("_xvmc_destroy_context fail\n");
return ret;
}
uniDRICloseConnection(display, screen);
pthread_mutex_destroy(&xvmc_driver->ctxmutex);
if (xvmc_driver->num_ctx == 0) {
uniDRICloseConnection(display, screen);
pthread_mutex_destroy(&xvmc_driver->ctxmutex);
drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
if (xvmc_driver->fd >= 0)
drmClose(xvmc_driver->fd);
xvmc_driver->fd = -1;
if (xvmc_driver->fd >= 0)
drmClose(xvmc_driver->fd);
xvmc_driver->fd = -1;
intelFiniBatchBuffer();
intelFiniBatchBuffer();
}
return Success;
}
......
......@@ -99,6 +99,12 @@ extern Status _xvmc_create_subpicture(Display *dpy, XvMCContext *context,
extern Status _xvmc_destroy_subpicture(Display *dpy,
XvMCSubpicture *subpicture);
typedef struct _intel_xvmc_context {
XID id; /* context id to X system */
drm_context_t hw_context; /* context id to kernel drm */
struct _intel_xvmc_context *next;
} intel_xvmc_context_t, *intel_xvmc_context_ptr;
typedef struct _intel_xvmc_drm_map {
drm_handle_t handle;
unsigned long offset;
......@@ -142,6 +148,9 @@ typedef struct _intel_xvmc_driver {
int locked;
drmLock *driHwLock;
int num_ctx;
intel_xvmc_context_ptr ctx_list;
void *private;
/* XXX: remove? */
......@@ -229,4 +238,7 @@ static inline const char* intel_xvmc_decoder_string(int flag)
return "Unknown decoder";
}
}
extern intel_xvmc_context_ptr intel_xvmc_find_context(XID id);
#endif
......@@ -332,7 +332,7 @@ uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
Display *dpy;
int screen;
int configID;
XID *context;
XID context;
drm_context_t *hHWContext;
{
XExtDisplayInfo *info = find_display(dpy);
......@@ -348,8 +348,7 @@ uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
req->driReqType = X_XF86DRICreateContext;
req->visual = configID;
req->screen = screen;
*context = XAllocID(dpy);
req->context = *context;
req->context = context;
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
......@@ -368,10 +367,11 @@ uniDRICreateContext(dpy, screen, visual, context, hHWContext)
Display *dpy;
int screen;
Visual *visual;
XID *context;
XID context;
drm_context_t *hHWContext;
{
return uniDRICreateContextWithConfig(dpy, screen, visual->visualid,
return uniDRICreateContextWithConfig(dpy, screen,
visual ? visual->visualid : 0,
context, hHWContext);
}
......
......@@ -86,11 +86,13 @@ Bool uniDRIGetClientDriverName(Display * dpy, int screen,
int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
int *ddxDriverPatchVersion, char **clientDriverName);
/* XvMC context XID is alloced in _xvmc_create_context, so
* don't recreate here */
Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual,
XID * ptr_to_returned_context_id, drm_context_t * hHWContext);
XID context_id, drm_context_t * hHWContext);
Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID,
XID * ptr_to_returned_context_id, drm_context_t * hHWContext);
XID context_id, drm_context_t * hHWContext);
extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id);
......
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