summaryrefslogtreecommitdiff
path: root/src/xvmc
diff options
context:
space:
mode:
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