mirror of
https://github.com/X11Libre/xserver.git
synced 2026-03-24 08:04:30 +00:00
Xvmc isn't using SHM for over 20 years now. There's still a code path for it
that could be enabled explicitly by manually setting HAS_XVMCSHM, but no
indication whatsoever that this ever has been done.
Considering that Xvmc in general already is obsolete for very long time now,
we can safely assume this code path is really dead and can be removed.
Fixes: 9a26d6f39e
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
800 lines
23 KiB
C
800 lines
23 KiB
C
|
|
#include <dix-config.h>
|
|
|
|
#include <string.h>
|
|
#include <X11/X.h>
|
|
#include <X11/Xfuncproto.h>
|
|
#include <X11/Xproto.h>
|
|
#include <X11/extensions/XvMC.h>
|
|
#include <X11/extensions/Xvproto.h>
|
|
#include <X11/extensions/XvMCproto.h>
|
|
|
|
#include "dix/dix_priv.h"
|
|
#include "dix/request_priv.h"
|
|
#include "dix/screen_hooks_priv.h"
|
|
#include "miext/extinit_priv.h"
|
|
#include "Xext/xvdix_priv.h"
|
|
|
|
#include "misc.h"
|
|
#include "os.h"
|
|
#include "dixstruct.h"
|
|
#include "resource.h"
|
|
#include "scrnintstr.h"
|
|
#include "extnsionst.h"
|
|
#include "servermd.h"
|
|
#include "xvmcext.h"
|
|
|
|
#define SERVER_XVMC_MAJOR_VERSION 1
|
|
#define SERVER_XVMC_MINOR_VERSION 1
|
|
|
|
#define DR_CLIENT_DRIVER_NAME_SIZE 48
|
|
#define DR_BUSID_SIZE 48
|
|
|
|
static DevPrivateKeyRec XvMCScreenKeyRec;
|
|
static Bool XvMCInUse;
|
|
|
|
int XvMCReqCode;
|
|
int XvMCEventBase;
|
|
|
|
static RESTYPE XvMCRTContext;
|
|
static RESTYPE XvMCRTSurface;
|
|
static RESTYPE XvMCRTSubpicture;
|
|
|
|
typedef struct {
|
|
int num_adaptors;
|
|
XvMCAdaptorPtr adaptors;
|
|
char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE];
|
|
char busID[DR_BUSID_SIZE];
|
|
int major;
|
|
int minor;
|
|
int patchLevel;
|
|
} XvMCScreenRec, *XvMCScreenPtr;
|
|
|
|
#define XVMC_GET_PRIVATE(pScreen) \
|
|
(XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, &XvMCScreenKeyRec))
|
|
|
|
static int
|
|
XvMCDestroyContextRes(void *data, XID id)
|
|
{
|
|
XvMCContextPtr pContext = (XvMCContextPtr) data;
|
|
|
|
pContext->refcnt--;
|
|
|
|
if (!pContext->refcnt) {
|
|
XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
|
|
|
|
(*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext) (pContext);
|
|
free(pContext);
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
XvMCDestroySurfaceRes(void *data, XID id)
|
|
{
|
|
XvMCSurfacePtr pSurface = (XvMCSurfacePtr) data;
|
|
XvMCContextPtr pContext = pSurface->context;
|
|
XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
|
|
|
|
(*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface) (pSurface);
|
|
free(pSurface);
|
|
|
|
XvMCDestroyContextRes((void *) pContext, pContext->context_id);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
XvMCDestroySubpictureRes(void *data, XID id)
|
|
{
|
|
XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr) data;
|
|
XvMCContextPtr pContext = pSubpict->context;
|
|
XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
|
|
|
|
(*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture) (pSubpict);
|
|
free(pSubpict);
|
|
|
|
XvMCDestroyContextRes((void *) pContext, pContext->context_id);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcXvMCQueryVersion(ClientPtr client)
|
|
{
|
|
xvmcQueryVersionReply reply = {
|
|
.major = SERVER_XVMC_MAJOR_VERSION,
|
|
.minor = SERVER_XVMC_MINOR_VERSION
|
|
};
|
|
|
|
/* REQUEST(xvmcQueryVersionReq); */
|
|
REQUEST_SIZE_MATCH(xvmcQueryVersionReq);
|
|
|
|
if (client->swapped) {
|
|
swapl(&reply.major);
|
|
swapl(&reply.minor);
|
|
}
|
|
|
|
return X_SEND_REPLY_SIMPLE(client, reply);
|
|
}
|
|
|
|
static int
|
|
ProcXvMCListSurfaceTypes(ClientPtr client)
|
|
{
|
|
XvPortPtr pPort;
|
|
XvMCScreenPtr pScreenPriv;
|
|
XvMCAdaptorPtr adaptor = NULL;
|
|
|
|
REQUEST(xvmcListSurfaceTypesReq);
|
|
REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq);
|
|
|
|
VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
|
|
|
|
if (XvMCInUse) { /* any adaptors at all */
|
|
ScreenPtr pScreen = pPort->pAdaptor->pScreen;
|
|
|
|
if ((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */
|
|
for (int i = 0; i < pScreenPriv->num_adaptors; i++) {
|
|
if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
|
|
adaptor = &(pScreenPriv->adaptors[i]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE };
|
|
|
|
int num_surfaces = (adaptor) ? adaptor->num_surfaces : 0;
|
|
for (int i = 0; i < num_surfaces; i++) {
|
|
XvMCSurfaceInfoPtr surface = adaptor->surfaces[i];
|
|
|
|
/* write xvmcSurfaceInfo */
|
|
x_rpcbuf_write_CARD32(&rpcbuf, surface->surface_type_id);
|
|
x_rpcbuf_write_CARD16(&rpcbuf, surface->chroma_format);
|
|
x_rpcbuf_write_CARD16(&rpcbuf, 0);
|
|
x_rpcbuf_write_CARD16(&rpcbuf, surface->max_width);
|
|
x_rpcbuf_write_CARD16(&rpcbuf, surface->max_height);
|
|
x_rpcbuf_write_CARD16(&rpcbuf, surface->subpicture_max_width);
|
|
x_rpcbuf_write_CARD16(&rpcbuf, surface->subpicture_max_height);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, surface->mc_type);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, surface->flags);
|
|
}
|
|
|
|
xvmcListSurfaceTypesReply reply = {
|
|
.num = num_surfaces,
|
|
};
|
|
|
|
if (client->swapped) {
|
|
swapl(&reply.num);
|
|
}
|
|
|
|
return X_SEND_REPLY_WITH_RPCBUF(client, reply, rpcbuf);
|
|
}
|
|
|
|
static int
|
|
ProcXvMCCreateContext(ClientPtr client)
|
|
{
|
|
XvPortPtr pPort;
|
|
CARD32 *data = NULL;
|
|
int dwords = 0;
|
|
int result, adapt_num = -1;
|
|
ScreenPtr pScreen;
|
|
XvMCContextPtr pContext;
|
|
XvMCScreenPtr pScreenPriv;
|
|
XvMCAdaptorPtr adaptor = NULL;
|
|
XvMCSurfaceInfoPtr surface = NULL;
|
|
|
|
REQUEST(xvmcCreateContextReq);
|
|
REQUEST_SIZE_MATCH(xvmcCreateContextReq);
|
|
|
|
VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
|
|
|
|
pScreen = pPort->pAdaptor->pScreen;
|
|
|
|
if (!XvMCInUse) /* no XvMC adaptors */
|
|
return BadMatch;
|
|
|
|
if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */
|
|
return BadMatch;
|
|
|
|
for (int i = 0; i < pScreenPriv->num_adaptors; i++) {
|
|
if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
|
|
adaptor = &(pScreenPriv->adaptors[i]);
|
|
adapt_num = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (adapt_num < 0) /* none this port */
|
|
return BadMatch;
|
|
|
|
for (int i = 0; i < adaptor->num_surfaces; i++) {
|
|
if (adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
|
|
surface = adaptor->surfaces[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* adaptor doesn't support this suface_type_id */
|
|
if (!surface)
|
|
return BadMatch;
|
|
|
|
if ((stuff->width > surface->max_width) ||
|
|
(stuff->height > surface->max_height))
|
|
return BadValue;
|
|
|
|
if (!(pContext = calloc(1, sizeof(XvMCContextRec)))) {
|
|
return BadAlloc;
|
|
}
|
|
|
|
pContext->pScreen = pScreen;
|
|
pContext->adapt_num = adapt_num;
|
|
pContext->context_id = stuff->context_id;
|
|
pContext->surface_type_id = stuff->surface_type_id;
|
|
pContext->width = stuff->width;
|
|
pContext->height = stuff->height;
|
|
pContext->flags = stuff->flags;
|
|
pContext->refcnt = 1;
|
|
|
|
result = (*adaptor->CreateContext) (pPort, pContext, &dwords, &data);
|
|
|
|
if (result != Success) {
|
|
free(pContext);
|
|
return result;
|
|
}
|
|
if (!AddResource(pContext->context_id, XvMCRTContext, pContext)) {
|
|
free(data);
|
|
return BadAlloc;
|
|
}
|
|
|
|
x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE };
|
|
x_rpcbuf_write_CARD32s(&rpcbuf, data, dwords);
|
|
free(data);
|
|
|
|
xvmcCreateContextReply reply = {
|
|
.width_actual = pContext->width,
|
|
.height_actual = pContext->height,
|
|
.flags_return = pContext->flags
|
|
};
|
|
|
|
if (client->swapped) {
|
|
swaps(&reply.width_actual);
|
|
swaps(&reply.height_actual);
|
|
swapl(&reply.flags_return);
|
|
}
|
|
|
|
return X_SEND_REPLY_WITH_RPCBUF(client, reply, rpcbuf);
|
|
}
|
|
|
|
static int
|
|
ProcXvMCDestroyContext(ClientPtr client)
|
|
{
|
|
void *val;
|
|
int rc;
|
|
|
|
REQUEST(xvmcDestroyContextReq);
|
|
REQUEST_SIZE_MATCH(xvmcDestroyContextReq);
|
|
|
|
rc = dixLookupResourceByType(&val, stuff->context_id, XvMCRTContext,
|
|
client, DixDestroyAccess);
|
|
if (rc != Success)
|
|
return rc;
|
|
|
|
FreeResource(stuff->context_id, X11_RESTYPE_NONE);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcXvMCCreateSurface(ClientPtr client)
|
|
{
|
|
CARD32 *data = NULL;
|
|
int dwords = 0;
|
|
int result;
|
|
XvMCContextPtr pContext;
|
|
XvMCSurfacePtr pSurface;
|
|
XvMCScreenPtr pScreenPriv;
|
|
|
|
REQUEST(xvmcCreateSurfaceReq);
|
|
REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq);
|
|
|
|
result = dixLookupResourceByType((void **) &pContext, stuff->context_id,
|
|
XvMCRTContext, client, DixUseAccess);
|
|
if (result != Success)
|
|
return result;
|
|
|
|
pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
|
|
|
|
if (!(pSurface = calloc(1, sizeof(XvMCSurfaceRec))))
|
|
return BadAlloc;
|
|
|
|
pSurface->surface_id = stuff->surface_id;
|
|
pSurface->surface_type_id = pContext->surface_type_id;
|
|
pSurface->context = pContext;
|
|
|
|
result =
|
|
(*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface) (pSurface,
|
|
&dwords,
|
|
&data);
|
|
|
|
if (result != Success) {
|
|
free(pSurface);
|
|
return result;
|
|
}
|
|
if (!AddResource(pSurface->surface_id, XvMCRTSurface, pSurface)) {
|
|
free(data);
|
|
return BadAlloc;
|
|
}
|
|
|
|
x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE };
|
|
x_rpcbuf_write_CARD32s(&rpcbuf, data, dwords);
|
|
free(data);
|
|
|
|
xvmcCreateSurfaceReply reply = { 0 };
|
|
|
|
pContext->refcnt++;
|
|
|
|
return X_SEND_REPLY_WITH_RPCBUF(client, reply, rpcbuf);
|
|
}
|
|
|
|
static int
|
|
ProcXvMCDestroySurface(ClientPtr client)
|
|
{
|
|
void *val;
|
|
int rc;
|
|
|
|
REQUEST(xvmcDestroySurfaceReq);
|
|
REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq);
|
|
|
|
rc = dixLookupResourceByType(&val, stuff->surface_id, XvMCRTSurface,
|
|
client, DixDestroyAccess);
|
|
if (rc != Success)
|
|
return rc;
|
|
|
|
FreeResource(stuff->surface_id, X11_RESTYPE_NONE);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcXvMCCreateSubpicture(ClientPtr client)
|
|
{
|
|
Bool image_supported = FALSE;
|
|
CARD32 *data = NULL;
|
|
int result, dwords = 0;
|
|
XvMCContextPtr pContext;
|
|
XvMCSubpicturePtr pSubpicture;
|
|
XvMCScreenPtr pScreenPriv;
|
|
XvMCAdaptorPtr adaptor;
|
|
XvMCSurfaceInfoPtr surface = NULL;
|
|
|
|
REQUEST(xvmcCreateSubpictureReq);
|
|
REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq);
|
|
|
|
result = dixLookupResourceByType((void **) &pContext, stuff->context_id,
|
|
XvMCRTContext, client, DixUseAccess);
|
|
if (result != Success)
|
|
return result;
|
|
|
|
pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
|
|
|
|
adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]);
|
|
|
|
/* find which surface this context supports */
|
|
for (int i = 0; i < adaptor->num_surfaces; i++) {
|
|
if (adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id) {
|
|
surface = adaptor->surfaces[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!surface)
|
|
return BadMatch;
|
|
|
|
/* make sure this surface supports that xvimage format */
|
|
if (!surface->compatible_subpictures)
|
|
return BadMatch;
|
|
|
|
for (int i = 0; i < surface->compatible_subpictures->num_xvimages; i++) {
|
|
if (surface->compatible_subpictures->xvimage_ids[i] ==
|
|
stuff->xvimage_id) {
|
|
image_supported = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!image_supported)
|
|
return BadMatch;
|
|
|
|
/* make sure the size is OK */
|
|
if ((stuff->width > surface->subpicture_max_width) ||
|
|
(stuff->height > surface->subpicture_max_height))
|
|
return BadValue;
|
|
|
|
if (!(pSubpicture = calloc(1, sizeof(XvMCSubpictureRec))))
|
|
return BadAlloc;
|
|
|
|
pSubpicture->subpicture_id = stuff->subpicture_id;
|
|
pSubpicture->xvimage_id = stuff->xvimage_id;
|
|
pSubpicture->width = stuff->width;
|
|
pSubpicture->height = stuff->height;
|
|
pSubpicture->num_palette_entries = 0; /* overwritten by DDX */
|
|
pSubpicture->entry_bytes = 0; /* overwritten by DDX */
|
|
pSubpicture->component_order[0] = 0; /* overwritten by DDX */
|
|
pSubpicture->component_order[1] = 0;
|
|
pSubpicture->component_order[2] = 0;
|
|
pSubpicture->component_order[3] = 0;
|
|
pSubpicture->context = pContext;
|
|
|
|
result =
|
|
(*pScreenPriv->adaptors[pContext->adapt_num].
|
|
CreateSubpicture) (pSubpicture, &dwords, &data);
|
|
|
|
if (result != Success) {
|
|
free(pSubpicture);
|
|
return result;
|
|
}
|
|
if (!AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture)) {
|
|
free(data);
|
|
return BadAlloc;
|
|
}
|
|
|
|
x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE };
|
|
x_rpcbuf_write_CARD32s(&rpcbuf, data, dwords);
|
|
free(data);
|
|
|
|
xvmcCreateSubpictureReply reply = {
|
|
.width_actual = pSubpicture->width,
|
|
.height_actual = pSubpicture->height,
|
|
.num_palette_entries = pSubpicture->num_palette_entries,
|
|
.entry_bytes = pSubpicture->entry_bytes,
|
|
.component_order[0] = pSubpicture->component_order[0],
|
|
.component_order[1] = pSubpicture->component_order[1],
|
|
.component_order[2] = pSubpicture->component_order[2],
|
|
.component_order[3] = pSubpicture->component_order[3]
|
|
};
|
|
|
|
if (client->swapped) {
|
|
swaps(&reply.width_actual);
|
|
swaps(&reply.height_actual);
|
|
swaps(&reply.num_palette_entries);
|
|
swaps(&reply.entry_bytes);
|
|
}
|
|
|
|
pContext->refcnt++;
|
|
|
|
return X_SEND_REPLY_WITH_RPCBUF(client, reply, rpcbuf);
|
|
}
|
|
|
|
static int
|
|
ProcXvMCDestroySubpicture(ClientPtr client)
|
|
{
|
|
void *val;
|
|
int rc;
|
|
|
|
REQUEST(xvmcDestroySubpictureReq);
|
|
REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq);
|
|
|
|
rc = dixLookupResourceByType(&val, stuff->subpicture_id, XvMCRTSubpicture,
|
|
client, DixDestroyAccess);
|
|
if (rc != Success)
|
|
return rc;
|
|
|
|
FreeResource(stuff->subpicture_id, X11_RESTYPE_NONE);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcXvMCListSubpictureTypes(ClientPtr client)
|
|
{
|
|
XvPortPtr pPort;
|
|
XvMCScreenPtr pScreenPriv;
|
|
ScreenPtr pScreen;
|
|
XvMCAdaptorPtr adaptor = NULL;
|
|
XvMCSurfaceInfoPtr surface = NULL;
|
|
XvImagePtr pImage;
|
|
|
|
REQUEST(xvmcListSubpictureTypesReq);
|
|
REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq);
|
|
|
|
VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
|
|
|
|
pScreen = pPort->pAdaptor->pScreen;
|
|
|
|
if (!dixPrivateKeyRegistered(&XvMCScreenKeyRec))
|
|
return BadMatch; /* No XvMC adaptors */
|
|
|
|
if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
|
|
return BadMatch; /* None this screen */
|
|
|
|
for (int i = 0; i < pScreenPriv->num_adaptors; i++) {
|
|
if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
|
|
adaptor = &(pScreenPriv->adaptors[i]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!adaptor)
|
|
return BadMatch;
|
|
|
|
for (int i = 0; i < adaptor->num_surfaces; i++) {
|
|
if (adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
|
|
surface = adaptor->surfaces[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!surface)
|
|
return BadMatch;
|
|
|
|
int num = (surface->compatible_subpictures ?
|
|
surface->compatible_subpictures->num_xvimages : 0);
|
|
|
|
x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE };
|
|
|
|
if (num) {
|
|
for (int i = 0; i < num; i++) {
|
|
pImage = NULL;
|
|
for (int j = 0; j < adaptor->num_subpictures; j++) {
|
|
if (surface->compatible_subpictures->xvimage_ids[i] ==
|
|
adaptor->subpictures[j]->id) {
|
|
pImage = adaptor->subpictures[j];
|
|
break;
|
|
}
|
|
}
|
|
if (!pImage) {
|
|
return BadImplementation;
|
|
}
|
|
|
|
/* xvImageFormatInfo */
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->id);
|
|
x_rpcbuf_write_CARD8(&rpcbuf, pImage->type);
|
|
x_rpcbuf_write_CARD8(&rpcbuf, pImage->byte_order);
|
|
x_rpcbuf_write_CARD16(&rpcbuf, 0); /* pad1 */
|
|
x_rpcbuf_write_CARD8s(&rpcbuf, (CARD8*)pImage->guid, 16);
|
|
x_rpcbuf_write_CARD8(&rpcbuf, pImage->bits_per_pixel);
|
|
x_rpcbuf_write_CARD8(&rpcbuf, pImage->num_planes);
|
|
x_rpcbuf_write_CARD16(&rpcbuf, 0); /* pad2 */
|
|
x_rpcbuf_write_CARD8(&rpcbuf, pImage->depth);
|
|
x_rpcbuf_write_CARD8(&rpcbuf, 0); /* pad3 */
|
|
x_rpcbuf_write_CARD16(&rpcbuf, 0); /* pad4 */
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->red_mask);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->green_mask);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->blue_mask);
|
|
x_rpcbuf_write_CARD8(&rpcbuf, pImage->format);
|
|
x_rpcbuf_write_CARD8(&rpcbuf, 0); /* pad5 */
|
|
x_rpcbuf_write_CARD16(&rpcbuf, 0); /* pad6 */
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->y_sample_bits);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->u_sample_bits);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->v_sample_bits);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->horz_y_period);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->horz_u_period);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->horz_v_period);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->vert_y_period);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->vert_u_period);
|
|
x_rpcbuf_write_CARD32(&rpcbuf, pImage->vert_v_period);
|
|
x_rpcbuf_write_CARD8s(&rpcbuf, (CARD8*)pImage->component_order, 32);
|
|
x_rpcbuf_write_CARD8(&rpcbuf, pImage->scanline_order);
|
|
x_rpcbuf_write_CARD8(&rpcbuf, 0); /* pad7 */
|
|
x_rpcbuf_write_CARD16(&rpcbuf, 0); /* pad8 */
|
|
x_rpcbuf_write_CARD32(&rpcbuf, 0); /* pad9 */
|
|
x_rpcbuf_write_CARD32(&rpcbuf, 0); /* pad10 */
|
|
}
|
|
}
|
|
|
|
xvmcListSubpictureTypesReply reply = {
|
|
.num = num,
|
|
};
|
|
|
|
if (client->swapped) {
|
|
swapl(&reply.num);
|
|
}
|
|
|
|
return X_SEND_REPLY_WITH_RPCBUF(client, reply, rpcbuf);
|
|
}
|
|
|
|
static int
|
|
ProcXvMCGetDRInfo(ClientPtr client)
|
|
{
|
|
XvPortPtr pPort;
|
|
ScreenPtr pScreen;
|
|
XvMCScreenPtr pScreenPriv;
|
|
|
|
REQUEST(xvmcGetDRInfoReq);
|
|
REQUEST_SIZE_MATCH(xvmcGetDRInfoReq);
|
|
|
|
VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
|
|
|
|
pScreen = pPort->pAdaptor->pScreen;
|
|
pScreenPriv = XVMC_GET_PRIVATE(pScreen);
|
|
|
|
int nameLen = strlen(pScreenPriv->clientDriverName) + 1;
|
|
int busIDLen = strlen(pScreenPriv->busID) + 1;
|
|
|
|
x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE };
|
|
x_rpcbuf_write_CARD8s(&rpcbuf, (CARD8*)pScreenPriv->clientDriverName, nameLen);
|
|
x_rpcbuf_write_CARD8s(&rpcbuf, (CARD8*)pScreenPriv->busID, busIDLen);
|
|
|
|
xvmcGetDRInfoReply reply = {
|
|
.major = pScreenPriv->major,
|
|
.minor = pScreenPriv->minor,
|
|
.patchLevel = pScreenPriv->patchLevel,
|
|
.nameLen = nameLen,
|
|
.busIDLen = busIDLen,
|
|
.isLocal = 1
|
|
};
|
|
|
|
/*
|
|
* Read back to the client what she has put in the shared memory
|
|
* segment she prepared for us.
|
|
*/
|
|
if (client->swapped) {
|
|
swapl(&reply.major);
|
|
swapl(&reply.minor);
|
|
swapl(&reply.patchLevel);
|
|
swapl(&reply.nameLen);
|
|
swapl(&reply.busIDLen);
|
|
swapl(&reply.isLocal);
|
|
}
|
|
|
|
return X_SEND_REPLY_WITH_RPCBUF(client, reply, rpcbuf);
|
|
}
|
|
|
|
static int
|
|
ProcXvMCDispatch(ClientPtr client)
|
|
{
|
|
if (!(client->local))
|
|
return BadImplementation;
|
|
|
|
REQUEST(xReq);
|
|
switch (stuff->data)
|
|
{
|
|
case xvmc_QueryVersion:
|
|
return ProcXvMCQueryVersion(client);
|
|
case xvmc_ListSurfaceTypes:
|
|
return ProcXvMCListSurfaceTypes(client);
|
|
case xvmc_CreateContext:
|
|
return ProcXvMCCreateContext(client);
|
|
case xvmc_DestroyContext:
|
|
return ProcXvMCDestroyContext(client);
|
|
case xvmc_CreateSurface:
|
|
return ProcXvMCCreateSurface(client);
|
|
case xvmc_DestroySurface:
|
|
return ProcXvMCDestroySurface(client);
|
|
case xvmc_CreateSubpicture:
|
|
return ProcXvMCCreateSubpicture(client);
|
|
case xvmc_DestroySubpicture:
|
|
return ProcXvMCDestroySubpicture(client);
|
|
case xvmc_ListSubpictureTypes:
|
|
return ProcXvMCListSubpictureTypes(client);
|
|
case xvmc_GetDRInfo:
|
|
return ProcXvMCGetDRInfo(client);
|
|
default:
|
|
return BadRequest;
|
|
}
|
|
}
|
|
|
|
void
|
|
XvMCExtensionInit(void)
|
|
{
|
|
ExtensionEntry *extEntry;
|
|
|
|
if (!dixPrivateKeyRegistered(&XvMCScreenKeyRec))
|
|
return;
|
|
|
|
if (!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes,
|
|
"XvMCRTContext")))
|
|
return;
|
|
|
|
if (!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes,
|
|
"XvMCRTSurface")))
|
|
return;
|
|
|
|
if (!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes,
|
|
"XvMCRTSubpicture")))
|
|
return;
|
|
|
|
extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors,
|
|
ProcXvMCDispatch, ProcXvMCDispatch,
|
|
NULL, StandardMinorOpcode);
|
|
|
|
if (!extEntry)
|
|
return;
|
|
|
|
XvMCReqCode = extEntry->base;
|
|
XvMCEventBase = extEntry->eventBase;
|
|
SetResourceTypeErrorValue(XvMCRTContext,
|
|
extEntry->errorBase + XvMCBadContext);
|
|
SetResourceTypeErrorValue(XvMCRTSurface,
|
|
extEntry->errorBase + XvMCBadSurface);
|
|
SetResourceTypeErrorValue(XvMCRTSubpicture,
|
|
extEntry->errorBase + XvMCBadSubpicture);
|
|
}
|
|
|
|
static void XvMCScreenClose(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused)
|
|
{
|
|
XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
|
|
free(pScreenPriv);
|
|
dixSetPrivate(&pScreen->devPrivates, &XvMCScreenKeyRec, NULL);
|
|
dixScreenUnhookClose(pScreen, XvMCScreenClose);
|
|
}
|
|
|
|
int
|
|
XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt)
|
|
{
|
|
XvMCScreenPtr pScreenPriv;
|
|
|
|
if (!dixRegisterPrivateKey(&XvMCScreenKeyRec, PRIVATE_SCREEN, 0))
|
|
return BadAlloc;
|
|
|
|
if (!(pScreenPriv = calloc(1, sizeof(XvMCScreenRec))))
|
|
return BadAlloc;
|
|
|
|
dixSetPrivate(&pScreen->devPrivates, &XvMCScreenKeyRec, pScreenPriv);
|
|
|
|
dixScreenHookClose(pScreen, XvMCScreenClose);
|
|
|
|
pScreenPriv->num_adaptors = num;
|
|
pScreenPriv->adaptors = pAdapt;
|
|
pScreenPriv->clientDriverName[0] = 0;
|
|
pScreenPriv->busID[0] = 0;
|
|
pScreenPriv->major = 0;
|
|
pScreenPriv->minor = 0;
|
|
pScreenPriv->patchLevel = 0;
|
|
|
|
XvMCInUse = TRUE;
|
|
|
|
return Success;
|
|
}
|
|
|
|
XvImagePtr
|
|
XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
|
|
{
|
|
XvImagePtr pImage = NULL;
|
|
ScreenPtr pScreen = pPort->pAdaptor->pScreen;
|
|
XvMCScreenPtr pScreenPriv;
|
|
XvMCAdaptorPtr adaptor = NULL;
|
|
|
|
if (!dixPrivateKeyRegistered(&XvMCScreenKeyRec))
|
|
return NULL;
|
|
|
|
if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
|
|
return NULL;
|
|
|
|
for (int i = 0; i < pScreenPriv->num_adaptors; i++) {
|
|
if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
|
|
adaptor = &(pScreenPriv->adaptors[i]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!adaptor)
|
|
return NULL;
|
|
|
|
for (int i = 0; i < adaptor->num_subpictures; i++) {
|
|
if (adaptor->subpictures[i]->id == id) {
|
|
pImage = adaptor->subpictures[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return pImage;
|
|
}
|
|
|
|
int
|
|
xf86XvMCRegisterDRInfo(ScreenPtr pScreen, const char *name,
|
|
const char *busID, int major, int minor, int patchLevel)
|
|
{
|
|
XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
|
|
|
|
strlcpy(pScreenPriv->clientDriverName, name, DR_CLIENT_DRIVER_NAME_SIZE);
|
|
strlcpy(pScreenPriv->busID, busID, DR_BUSID_SIZE);
|
|
pScreenPriv->major = major;
|
|
pScreenPriv->minor = minor;
|
|
pScreenPriv->patchLevel = patchLevel;
|
|
return Success;
|
|
}
|