summaryrefslogtreecommitdiff
path: root/src/xvmc
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyu.z.wang@intel.com>2007-12-25 08:32:47 +0800
committerZhenyu Wang <zhenyu.z.wang@intel.com>2007-12-25 08:32:47 +0800
commited9ff6f30fff33fe2d60715f1b503047f8e1ef01 (patch)
tree844a6d6b72b3a6af3a6d76c63933913e552187fb /src/xvmc
parentf0ced5edaeec3e7741828eab728417843326d56f (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.
Diffstat (limited to 'src/xvmc')
-rw-r--r--src/xvmc/i915_xvmc.c76
-rw-r--r--src/xvmc/intel_xvmc.c141
-rw-r--r--src/xvmc/intel_xvmc.h17
3 files changed, 161 insertions, 73 deletions
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