Compare commits

...

4 Commits

Author SHA1 Message Date
Enrico Weigelt, metux IT consult b70b72077c Xext: xvmc: skip reply payload assembly when no data to send
Instead of trying to calloc() zero-size blocks when there's no actual payload
to send, skip the whole part. This also helps reducing analyzer noise.

Manpages of various BSDs don't tell whether it's safe to pass zero size
at all, so it's better not trying to do so.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-15 13:37:31 +02:00
Enrico Weigelt, metux IT consult 0fad1274f2 Xext: xvmc: simplify reply struct initialization
* use static initialization where possible
* put the lists into one one block, so they can be written in one pass
* simplify size computations

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-14 14:38:17 +02:00
Enrico Weigelt, metux IT consult 71ef8dbebc Xext: xvmc: use locally scoped counter variables
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-12 18:32:12 +02:00
Enrico Weigelt, metux IT consult 5ef75bc9ee Xext: xvmc: simplify dispatcher
The dispatcher functions are much more complex than they're usually are
(just switch/case statement). Bring them in line with the standard scheme
used in the Xserver, so further steps become easier.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-12 18:32:12 +02:00

View File

@ -112,7 +112,6 @@ ProcXvMCQueryVersion(ClientPtr client)
xvmcQueryVersionReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.major = SERVER_XVMC_MAJOR_VERSION,
.minor = SERVER_XVMC_MINOR_VERSION
};
@ -128,13 +127,8 @@ static int
ProcXvMCListSurfaceTypes(ClientPtr client)
{
XvPortPtr pPort;
int i;
XvMCScreenPtr pScreenPriv;
xvmcListSurfaceTypesReply rep;
xvmcSurfaceInfo info;
XvMCAdaptorPtr adaptor = NULL;
XvMCSurfaceInfoPtr surface;
int num_surfaces;
REQUEST(xvmcListSurfaceTypesReq);
REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq);
@ -145,7 +139,7 @@ ProcXvMCListSurfaceTypes(ClientPtr client)
ScreenPtr pScreen = pPort->pAdaptor->pScreen;
if ((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */
for (i = 0; i < pScreenPriv->num_adaptors; i++) {
for (int i = 0; i < pScreenPriv->num_adaptors; i++) {
if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
adaptor = &(pScreenPriv->adaptors[i]);
break;
@ -154,28 +148,36 @@ ProcXvMCListSurfaceTypes(ClientPtr client)
}
}
num_surfaces = (adaptor) ? adaptor->num_surfaces : 0;
rep = (xvmcListSurfaceTypesReply) {
int num_surfaces = (adaptor) ? adaptor->num_surfaces : 0;
xvmcSurfaceInfo *info = NULL;
if (num_surfaces) {
info = calloc(sizeof(xvmcSurfaceInfo), num_surfaces);
if (!info)
return BadAlloc;
for (int i = 0; i < num_surfaces; i++) {
XvMCSurfaceInfoPtr surface = adaptor->surfaces[i];
info[i].surface_type_id = surface->surface_type_id;
info[i].chroma_format = surface->chroma_format;
info[i].max_width = surface->max_width;
info[i].max_height = surface->max_height;
info[i].subpicture_max_width = surface->subpicture_max_width;
info[i].subpicture_max_height = surface->subpicture_max_height;
info[i].mc_type = surface->mc_type;
info[i].flags = surface->flags;
}
}
xvmcListSurfaceTypesReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.num = num_surfaces,
.length = bytes_to_int32(num_surfaces * sizeof(xvmcSurfaceInfo)),
.length = bytes_to_int32(sizeof(xvmcSurfaceInfo) * num_surfaces),
};
WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), &rep);
for (i = 0; i < num_surfaces; i++) {
surface = adaptor->surfaces[i];
info.surface_type_id = surface->surface_type_id;
info.chroma_format = surface->chroma_format;
info.max_width = surface->max_width;
info.max_height = surface->max_height;
info.subpicture_max_width = surface->subpicture_max_width;
info.subpicture_max_height = surface->subpicture_max_height;
info.mc_type = surface->mc_type;
info.flags = surface->flags;
WriteToClient(client, sizeof(xvmcSurfaceInfo), &info);
}
WriteToClient(client, sizeof(xvmcSurfaceInfo) * num_surfaces, info);
free(info);
return Success;
}
@ -186,13 +188,12 @@ ProcXvMCCreateContext(ClientPtr client)
XvPortPtr pPort;
CARD32 *data = NULL;
int dwords = 0;
int i, result, adapt_num = -1;
int result, adapt_num = -1;
ScreenPtr pScreen;
XvMCContextPtr pContext;
XvMCScreenPtr pScreenPriv;
XvMCAdaptorPtr adaptor = NULL;
XvMCSurfaceInfoPtr surface = NULL;
xvmcCreateContextReply rep;
REQUEST(xvmcCreateContextReq);
REQUEST_SIZE_MATCH(xvmcCreateContextReq);
@ -207,7 +208,7 @@ ProcXvMCCreateContext(ClientPtr client)
if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */
return BadMatch;
for (i = 0; i < pScreenPriv->num_adaptors; i++) {
for (int i = 0; i < pScreenPriv->num_adaptors; i++) {
if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
adaptor = &(pScreenPriv->adaptors[i]);
adapt_num = i;
@ -218,7 +219,7 @@ ProcXvMCCreateContext(ClientPtr client)
if (adapt_num < 0) /* none this port */
return BadMatch;
for (i = 0; i < adaptor->num_surfaces; i++) {
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;
@ -257,7 +258,7 @@ ProcXvMCCreateContext(ClientPtr client)
return BadAlloc;
}
rep = (xvmcCreateContextReply) {
xvmcCreateContextReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = dwords,
@ -303,7 +304,6 @@ ProcXvMCCreateSurface(ClientPtr client)
XvMCContextPtr pContext;
XvMCSurfacePtr pSurface;
XvMCScreenPtr pScreenPriv;
xvmcCreateSurfaceReply rep;
REQUEST(xvmcCreateSurfaceReq);
REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq);
@ -336,7 +336,7 @@ ProcXvMCCreateSurface(ClientPtr client)
return BadAlloc;
}
rep = (xvmcCreateSurfaceReply) {
xvmcCreateSurfaceReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = dwords
@ -377,11 +377,10 @@ ProcXvMCCreateSubpicture(ClientPtr client)
{
Bool image_supported = FALSE;
CARD32 *data = NULL;
int i, result, dwords = 0;
int result, dwords = 0;
XvMCContextPtr pContext;
XvMCSubpicturePtr pSubpicture;
XvMCScreenPtr pScreenPriv;
xvmcCreateSubpictureReply rep;
XvMCAdaptorPtr adaptor;
XvMCSurfaceInfoPtr surface = NULL;
@ -398,7 +397,7 @@ ProcXvMCCreateSubpicture(ClientPtr client)
adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]);
/* find which surface this context supports */
for (i = 0; i < adaptor->num_surfaces; i++) {
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;
@ -412,7 +411,7 @@ ProcXvMCCreateSubpicture(ClientPtr client)
if (!surface->compatible_subpictures)
return BadMatch;
for (i = 0; i < surface->compatible_subpictures->num_xvimages; i++) {
for (int i = 0; i < surface->compatible_subpictures->num_xvimages; i++) {
if (surface->compatible_subpictures->xvimage_ids[i] ==
stuff->xvimage_id) {
image_supported = TRUE;
@ -456,7 +455,7 @@ ProcXvMCCreateSubpicture(ClientPtr client)
return BadAlloc;
}
rep = (xvmcCreateSubpictureReply) {
xvmcCreateSubpictureReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = dwords,
@ -504,14 +503,11 @@ static int
ProcXvMCListSubpictureTypes(ClientPtr client)
{
XvPortPtr pPort;
xvmcListSubpictureTypesReply rep;
XvMCScreenPtr pScreenPriv;
ScreenPtr pScreen;
XvMCAdaptorPtr adaptor = NULL;
XvMCSurfaceInfoPtr surface = NULL;
xvImageFormatInfo info;
XvImagePtr pImage;
int i, j;
REQUEST(xvmcListSubpictureTypesReq);
REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq);
@ -526,7 +522,7 @@ ProcXvMCListSubpictureTypes(ClientPtr client)
if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
return BadMatch; /* None this screen */
for (i = 0; i < pScreenPriv->num_adaptors; i++) {
for (int i = 0; i < pScreenPriv->num_adaptors; i++) {
if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
adaptor = &(pScreenPriv->adaptors[i]);
break;
@ -536,7 +532,7 @@ ProcXvMCListSubpictureTypes(ClientPtr client)
if (!adaptor)
return BadMatch;
for (i = 0; i < adaptor->num_surfaces; i++) {
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;
@ -546,62 +542,70 @@ ProcXvMCListSubpictureTypes(ClientPtr client)
if (!surface)
return BadMatch;
rep = (xvmcListSubpictureTypesReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.num = 0
};
if (surface->compatible_subpictures)
rep.num = surface->compatible_subpictures->num_xvimages;
int num = (surface->compatible_subpictures ?
surface->compatible_subpictures->num_xvimages : 0);
rep.length = bytes_to_int32(rep.num * sizeof(xvImageFormatInfo));
xvImageFormatInfo *info = NULL;
if (num) {
info = calloc(sizeof(xvImageFormatInfo), num);
if (!info)
return BadAlloc;
WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), &rep);
for (i = 0; i < rep.num; i++) {
pImage = NULL;
for (j = 0; j < adaptor->num_subpictures; j++) {
if (surface->compatible_subpictures->xvimage_ids[i] ==
adaptor->subpictures[j]->id) {
pImage = adaptor->subpictures[j];
break;
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) {
free(info);
return BadImplementation;
}
}
if (!pImage)
return BadImplementation;
info.id = pImage->id;
info.type = pImage->type;
info.byte_order = pImage->byte_order;
memcpy(&info.guid, pImage->guid, 16);
info.bpp = pImage->bits_per_pixel;
info.num_planes = pImage->num_planes;
info.depth = pImage->depth;
info.red_mask = pImage->red_mask;
info.green_mask = pImage->green_mask;
info.blue_mask = pImage->blue_mask;
info.format = pImage->format;
info.y_sample_bits = pImage->y_sample_bits;
info.u_sample_bits = pImage->u_sample_bits;
info.v_sample_bits = pImage->v_sample_bits;
info.horz_y_period = pImage->horz_y_period;
info.horz_u_period = pImage->horz_u_period;
info.horz_v_period = pImage->horz_v_period;
info.vert_y_period = pImage->vert_y_period;
info.vert_u_period = pImage->vert_u_period;
info.vert_v_period = pImage->vert_v_period;
memcpy(&info.comp_order, pImage->component_order, 32);
info.scanline_order = pImage->scanline_order;
WriteToClient(client, sizeof(xvImageFormatInfo), &info);
info[i].id = pImage->id;
info[i].type = pImage->type;
info[i].byte_order = pImage->byte_order;
memcpy(&info[i].guid, pImage->guid, 16);
info[i].bpp = pImage->bits_per_pixel;
info[i].num_planes = pImage->num_planes;
info[i].depth = pImage->depth;
info[i].red_mask = pImage->red_mask;
info[i].green_mask = pImage->green_mask;
info[i].blue_mask = pImage->blue_mask;
info[i].format = pImage->format;
info[i].y_sample_bits = pImage->y_sample_bits;
info[i].u_sample_bits = pImage->u_sample_bits;
info[i].v_sample_bits = pImage->v_sample_bits;
info[i].horz_y_period = pImage->horz_y_period;
info[i].horz_u_period = pImage->horz_u_period;
info[i].horz_v_period = pImage->horz_v_period;
info[i].vert_y_period = pImage->vert_y_period;
info[i].vert_u_period = pImage->vert_u_period;
info[i].vert_v_period = pImage->vert_v_period;
memcpy(&info[i].comp_order, pImage->component_order, 32);
info[i].scanline_order = pImage->scanline_order;
}
}
xvmcListSubpictureTypesReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.num = num,
.length = bytes_to_int32(sizeof(info)),
};
WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), &rep);
WriteToClient(client, sizeof(xvImageFormatInfo) * num, info);
free(info);
return Success;
}
static int
ProcXvMCGetDRInfo(ClientPtr client)
{
xvmcGetDRInfoReply rep;
XvPortPtr pPort;
ScreenPtr pScreen;
XvMCScreenPtr pScreenPriv;
@ -618,21 +622,30 @@ ProcXvMCGetDRInfo(ClientPtr client)
pScreen = pPort->pAdaptor->pScreen;
pScreenPriv = XVMC_GET_PRIVATE(pScreen);
rep = (xvmcGetDRInfoReply) {
int nameLen = strlen(pScreenPriv->clientDriverName) + 1;
int busIDLen = strlen(pScreenPriv->busID) + 1;
// buffer holds two zero-terminated strings, padded to 4-byte ints
const size_t buflen = pad_to_int32(nameLen+busIDLen);
char *buf = calloc(1, buflen);
if (!buf)
return BadAlloc;
memcpy(buf, pScreenPriv->clientDriverName, nameLen);
memcpy(buf+nameLen, pScreenPriv->busID, busIDLen);
xvmcGetDRInfoReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.major = pScreenPriv->major,
.minor = pScreenPriv->minor,
.patchLevel = pScreenPriv->patchLevel,
.nameLen = bytes_to_int32(strlen(pScreenPriv->clientDriverName) + 1),
.busIDLen = bytes_to_int32(strlen(pScreenPriv->busID) + 1),
.nameLen = nameLen,
.busIDLen = busIDLen,
.length = bytes_to_int32(sizeof(buf)),
.isLocal = 1
};
rep.length = rep.nameLen + rep.busIDLen;
rep.nameLen <<= 2;
rep.busIDLen <<= 2;
/*
* Read back to the client what she has put in the shared memory
* segment she prepared for us.
@ -660,33 +673,40 @@ ProcXvMCGetDRInfo(ClientPtr client)
#endif /* HAS_XVMCSHM */
WriteToClient(client, sizeof(xvmcGetDRInfoReply), &rep);
if (rep.length) {
WriteToClient(client, rep.nameLen, pScreenPriv->clientDriverName);
WriteToClient(client, rep.busIDLen, pScreenPriv->busID);
}
WriteToClient(client, buflen, buf);
free(buf);
return Success;
}
int (*ProcXvMCVector[xvmcNumRequest]) (ClientPtr) = {
ProcXvMCQueryVersion,
ProcXvMCListSurfaceTypes,
ProcXvMCCreateContext,
ProcXvMCDestroyContext,
ProcXvMCCreateSurface,
ProcXvMCDestroySurface,
ProcXvMCCreateSubpicture,
ProcXvMCDestroySubpicture,
ProcXvMCListSubpictureTypes, ProcXvMCGetDRInfo};
static int
ProcXvMCDispatch(ClientPtr client)
{
REQUEST(xReq);
if (stuff->data < xvmcNumRequest)
return (*ProcXvMCVector[stuff->data]) (client);
else
return BadRequest;
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;
}
}
static int _X_COLD
@ -781,7 +801,6 @@ XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
ScreenPtr pScreen = pPort->pAdaptor->pScreen;
XvMCScreenPtr pScreenPriv;
XvMCAdaptorPtr adaptor = NULL;
int i;
if (!dixPrivateKeyRegistered(XvMCScreenKey))
return NULL;
@ -789,7 +808,7 @@ XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
if (!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
return NULL;
for (i = 0; i < pScreenPriv->num_adaptors; i++) {
for (int i = 0; i < pScreenPriv->num_adaptors; i++) {
if (pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
adaptor = &(pScreenPriv->adaptors[i]);
break;
@ -799,7 +818,7 @@ XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
if (!adaptor)
return NULL;
for (i = 0; i < adaptor->num_subpictures; i++) {
for (int i = 0; i < adaptor->num_subpictures; i++) {
if (adaptor->subpictures[i]->id == id) {
pImage = adaptor->subpictures[i];
break;