diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 69d71bf108..b304faa60b 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -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, diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index b1c4198c52..796a9882ad 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -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: diff --git a/hw/kdrive/src/kd_glamor_xv.c b/hw/kdrive/src/kd_glamor_xv.c index a3e1f251b4..5a355c0ca9 100644 --- a/hw/kdrive/src/kd_glamor_xv.c +++ b/hw/kdrive/src/kd_glamor_xv.c @@ -27,11 +27,15 @@ #include "kxv.h" #include "glamor_priv.h" +#include "dix/screen_hooks_priv.h" + #include #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; } diff --git a/hw/kdrive/src/kxv.h b/hw/kdrive/src/kxv.h index e9f656de8c..0d570ad4af 100644 --- a/hw/kdrive/src/kxv.h +++ b/hw/kdrive/src/kxv.h @@ -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_ */