diff options
Diffstat (limited to 'src/xvmc')
-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 |
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 |