kdrive: glamor_xv: Don't leak X-Video memory and textures

Clears a few KB of leaks from asan

xf86 has similar issues

Signed-off-by: stefan11111 <stefan11111github@gmail.com>
This commit is contained in:
stefan11111 2026-08-22 14:25:11 +03:00 • committed by Enrico Weigelt
commit 8b4ab8b697
4 changed files with 63 additions and 24 deletions

View file

@ -968,6 +968,7 @@ extern int glamor_xv_num_images;
void glamor_xv_init_port(glamor_port_private *port_priv);
void glamor_xv_stop_video(glamor_port_private *port_priv);
void glamor_xv_free_port_data(glamor_port_private *port_priv);
int glamor_xv_set_port_attribute(glamor_port_private *port_priv,
Atom attribute, INT32 value);
int glamor_xv_get_port_attribute(glamor_port_private *port_priv,

View file

@ -265,7 +265,7 @@ glamor_xv_stop_video(glamor_port_private *port_priv)
{
}
static void
void
glamor_xv_free_port_data(glamor_port_private *port_priv)
{
int i;
@ -278,6 +278,11 @@ glamor_xv_free_port_data(glamor_port_private *port_priv)
}
RegionUninit(&port_priv->clip);
RegionNull(&port_priv->clip);
if (port_priv->xv_prog.prog) {
glDeleteProgram(port_priv->xv_prog.prog);
port_priv->xv_prog.prog = 0;
}
}
int
@ -652,19 +657,8 @@ glamor_xv_put_image(glamor_port_private *port_priv,
s2offset = s3offset = srcPitch2 = 0;
if (!glamor_xv_can_reuse_port(port_priv, id, width, height)) {
int i;
glamor_xv_free_port_data(port_priv);
if (port_priv->xv_prog.prog) {
glDeleteProgram(port_priv->xv_prog.prog);
port_priv->xv_prog.prog = 0;
}
for (i = 0; i < 3; i++)
if (port_priv->src_pix[i])
glamor_destroy_pixmap(port_priv->src_pix[i]);
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:

View file

@ -27,11 +27,15 @@
#include "kxv.h"
#include "glamor_priv.h"
#include "dix/screen_hooks_priv.h"
#include <X11/extensions/Xv.h>
#include "fourcc.h"
#define NUM_FORMATS 4
static DevPrivateKeyRec KdGlamorXVScreenPrivateKey;
static KdVideoFormatRec Formats[NUM_FORMATS] = {
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}, {30, TrueColor}
};
@ -102,12 +106,25 @@ kd_glamor_xv_put_image(KdScreenInfo *screen,
id, buf, width, height, sync, clipBoxes);
}
void
static void
kd_glamor_xv_close_screen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unused)
{
KdVideoAdaptorRec *adaptor = dixGetPrivate(&pScreen->devPrivates, &KdGlamorXVScreenPrivateKey);
for (int i = 0; i < adaptor->nPorts; i++) {
glamor_xv_free_port_data(adaptor->pPortPrivates[i].ptr);
}
free(adaptor->pPortPrivates[0].ptr);
free(adaptor->pPortPrivates);
free(adaptor);
dixScreenUnhookClose(pScreen, kd_glamor_xv_close_screen);
}
Bool
kd_glamor_xv_init(ScreenPtr screen)
{
KdVideoAdaptorRec *adaptor;
glamor_port_private *port_privates;
int i;
KdVideoAdaptorRec *adaptor = NULL;
glamor_port_private *port_privates = NULL;
GLint max_size = 0;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
if (max_size <= 0) {
@ -124,7 +141,10 @@ kd_glamor_xv_init(ScreenPtr screen)
glamor_xv_core_init(screen);
adaptor = XNFcallocarray(1, sizeof(*adaptor));
adaptor = calloc(1, sizeof(*adaptor));
if (!adaptor) {
goto fail;
}
adaptor->name = "GLAMOR Textured Video";
adaptor->type = XvWindowMask | XvInputMask | XvImageMask;
@ -136,11 +156,17 @@ kd_glamor_xv_init(ScreenPtr screen)
adaptor->nFormats = NUM_FORMATS;
adaptor->nPorts = 16; /* Some absurd number */
port_privates = XNFcallocarray(adaptor->nPorts,
sizeof(glamor_port_private));
adaptor->pPortPrivates = XNFcallocarray(adaptor->nPorts,
sizeof(glamor_port_private *));
for (i = 0; i < adaptor->nPorts; i++) {
port_privates = calloc(adaptor->nPorts,
sizeof(glamor_port_private));
if (!port_privates) {
goto fail;
}
adaptor->pPortPrivates = calloc(adaptor->nPorts,
sizeof(glamor_port_private *));
if (!adaptor->pPortPrivates) {
goto fail;
}
for (int i = 0; i < adaptor->nPorts; i++) {
adaptor->pPortPrivates[i].ptr = &port_privates[i];
glamor_xv_init_port(&port_privates[i]);
}
@ -158,5 +184,23 @@ kd_glamor_xv_init(ScreenPtr screen)
adaptor->PutImage = kd_glamor_xv_put_image;
adaptor->QueryImageAttributes = kd_glamor_xv_query_image_attributes;
KdXVScreenInit(screen, adaptor, 1);
if (!KdXVScreenInit(screen, adaptor, 1) ||
!dixRegisterPrivateKey(&KdGlamorXVScreenPrivateKey, PRIVATE_SCREEN, 0)) {
goto fail;
}
dixSetPrivate(&screen->devPrivates, &KdGlamorXVScreenPrivateKey, adaptor);
dixScreenHookClose(screen, kd_glamor_xv_close_screen);
return TRUE;
fail:
if (adaptor->pPortPrivates) {
for (int i = 0; i < adaptor->nPorts; i++) {
glamor_xv_free_port_data(adaptor->pPortPrivates[i].ptr);
}
free(adaptor->pPortPrivates);
}
free(port_privates);
free(adaptor);
return FALSE;
}

View file

@ -197,7 +197,7 @@ typedef struct _KdXVWindowRec {
#ifdef GLAMOR
/* Must not be called before glamor is fully initialized */
void kd_glamor_xv_init(ScreenPtr screen);
Bool kd_glamor_xv_init(ScreenPtr screen);
#endif
#endif /* _XVDIX_H_ */