diff --git a/Xext/shm.c b/Xext/shm.c index c9efc092a..1b92e39c8 100644 --- a/Xext/shm.c +++ b/Xext/shm.c @@ -201,7 +201,11 @@ ShmCloseScreen(ScreenPtr pScreen) pScreen->CloseScreen = screen_priv->CloseScreen; dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL); free(screen_priv); - return (*pScreen->CloseScreen) (pScreen); + + if (!pScreen->CloseScreen) + return (*pScreen->CloseScreen) (pScreen); + + return TRUE; } static ShmScrPrivateRec * diff --git a/dix/main.c b/dix/main.c index 040dfd225..9b3e058b5 100644 --- a/dix/main.c +++ b/dix/main.c @@ -318,8 +318,8 @@ dix_main(int argc, char *argv[], char *envp[]) for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) { ScreenPtr pScreen = screenInfo.gpuscreens[i]; - dixFreeScreenSpecificPrivates(pScreen); (*pScreen->CloseScreen) (pScreen); + dixFreeScreenSpecificPrivates(pScreen); dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); free(pScreen); screenInfo.numGPUScreens = i; @@ -328,8 +328,8 @@ dix_main(int argc, char *argv[], char *envp[]) for (i = screenInfo.numScreens - 1; i >= 0; i--) { FreeGCperDepth(i); FreeDefaultStipple(i); - dixFreeScreenSpecificPrivates(screenInfo.screens[i]); (*screenInfo.screens[i]->CloseScreen) (screenInfo.screens[i]); + dixFreeScreenSpecificPrivates(screenInfo.screens[i]); dixFreePrivates(screenInfo.screens[i]->devPrivates, PRIVATE_SCREEN); free(screenInfo.screens[i]); screenInfo.numScreens = i; diff --git a/exa/exa.c b/exa/exa.c index 0422c615f..fc769fdb0 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -36,6 +36,8 @@ #include "exa.h" DevPrivateKeyRec exaScreenPrivateKeyRec; +DevPrivateKeyRec exaPixmapPrivateKeyRec; +DevPrivateKeyRec exaGcPrivateKeyRec; #ifdef MITSHM static ShmFuncs exaShmFuncs = { NULL, NULL }; @@ -888,6 +890,9 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo) return FALSE; } + memset(&exaGcPrivateKeyRec, 0, sizeof(exaGcPrivateKeyRec)); + memset(&exaPixmapPrivateKeyRec, 0, sizeof(exaPixmapPrivateKeyRec)); + pExaScr->info = pScreenInfo; dixSetPrivate(&pScreen->devPrivates, exaScreenPrivateKey, pExaScr); @@ -897,7 +902,7 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo) exaDDXDriverInit(pScreen); if (!dixRegisterScreenSpecificPrivateKey - (pScreen, &pExaScr->gcPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) { + (pScreen, &exaGcPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) { LogMessage(X_WARNING, "EXA(%d): Failed to allocate GC private\n", pScreen->myNum); return FALSE; @@ -946,7 +951,7 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo) */ if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) { if (!dixRegisterScreenSpecificPrivateKey - (pScreen, &pExaScr->pixmapPrivateKeyRec, PRIVATE_PIXMAP, + (pScreen, &exaPixmapPrivateKeyRec, PRIVATE_PIXMAP, sizeof(ExaPixmapPrivRec))) { LogMessage(X_WARNING, "EXA(%d): Failed to allocate pixmap private\n", diff --git a/exa/exa_priv.h b/exa/exa_priv.h index f9e166c66..d8878e4c6 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -209,19 +209,18 @@ typedef struct { RegionRec maskReg; PixmapPtr srcPix; PixmapPtr maskPix; - - DevPrivateKeyRec pixmapPrivateKeyRec; - DevPrivateKeyRec gcPrivateKeyRec; } ExaScreenPrivRec, *ExaScreenPrivPtr; extern DevPrivateKeyRec exaScreenPrivateKeyRec; +extern DevPrivateKeyRec exaPixmapPrivateKeyRec; +extern DevPrivateKeyRec exaGcPrivateKeyRec; #define exaScreenPrivateKey (&exaScreenPrivateKeyRec) #define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixGetPrivate(&(s)->devPrivates, exaScreenPrivateKey)) #define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s) -#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, &ExaGetScreenPriv(gc->pScreen)->gcPrivateKeyRec)) +#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, &exaGcPrivateKeyRec)) #define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc) /* @@ -272,7 +271,7 @@ extern DevPrivateKeyRec exaScreenPrivateKeyRec; #define EXA_PIXMAP_SCORE_PINNED 1000 #define EXA_PIXMAP_SCORE_INIT 1001 -#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &ExaGetScreenPriv((p)->drawable.pScreen)->pixmapPrivateKeyRec)) +#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &exaPixmapPrivateKeyRec)) #define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p) #define EXA_RANGE_PITCH (1 << 0) diff --git a/fb/fbscreen.c b/fb/fbscreen.c index 220a99511..eb9ee0452 100644 --- a/fb/fbscreen.c +++ b/fb/fbscreen.c @@ -26,19 +26,36 @@ #include "fb.h" +/* per-screen private data */ +static DevPrivateKeyRec fbScreenPrivKeyRec; + +#define fbScreenPrivKey (&fbScreenPrivKeyRec) + +typedef struct { + CloseScreenProcPtr CloseScreen; +} fbScreenRec, *fbScreenPtr; + +#define fbGetScreenPriv(s) ((fbScreenPtr)(dixLookupPrivate(&(s)->devPrivates, fbScreenPrivKey))) + Bool fbCloseScreen(ScreenPtr pScreen) { int d; DepthPtr depths = pScreen->allowedDepths; + fbScreenPtr pScreenPriv = fbGetScreenPriv(pScreen); fbDestroyGlyphCache(); for (d = 0; d < pScreen->numDepths; d++) free(depths[d].vids); free(depths); free(pScreen->visuals); - if (pScreen->devPrivate) - FreePixmap((PixmapPtr)pScreen->devPrivate); + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + free(pScreenPriv); + + if (pScreen->CloseScreen) + return (*pScreen->CloseScreen) (pScreen); + return TRUE; } @@ -97,8 +114,20 @@ fbSetupScreen(ScreenPtr pScreen, void *pbits, /* pointer to screen bitmap */ int dpiy, int width, /* pixel width of frame buffer */ int bpp) { /* bits per pixel for screen */ + fbScreenPtr pScreenPriv; + if (!fbAllocatePrivates(pScreen)) return FALSE; + + if (!dixRegisterPrivateKey(&fbScreenPrivKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + pScreenPriv = calloc(1, sizeof(fbScreenRec)); + if (!pScreenPriv) + return FALSE; + + dixSetPrivate(&pScreen->devPrivates, fbScreenPrivKey, pScreenPriv); + pScreen->defColormap = FakeClientID(0); if (bpp > 1) { /* let CreateDefColormap do whatever it wants for pixels */ @@ -156,6 +185,7 @@ fbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, int ndepths; int rootdepth; VisualID defaultVisual; + fbScreenPtr pScreenPriv = fbGetScreenPriv(pScreen); #ifdef FB_DEBUG int stride; @@ -184,6 +214,7 @@ fbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, defaultVisual, nvisuals, visuals)) return FALSE; /* overwrite miCloseScreen with our own */ + pScreenPriv->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = fbCloseScreen; return TRUE; } diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 632f2f28c..7390728fd 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -823,6 +823,11 @@ glamor_egl_close_screen(ScreenPtr screen) eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image); pixmap_priv->image = NULL; + if (glamor_egl->device_path) { + free(glamor_egl->device_path); + glamor_egl->device_path = NULL; + } + screen->CloseScreen = glamor_egl->saved_close_screen; return screen->CloseScreen(screen); @@ -971,7 +976,6 @@ static void glamor_egl_cleanup(struct glamor_egl_screen_private *glamor_egl) } if (glamor_egl->gbm) gbm_device_destroy(glamor_egl->gbm); - free(glamor_egl->device_path); free(glamor_egl); } diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 953e736e4..32e035ee9 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -111,6 +111,7 @@ typedef struct _DRI2Screen { unsigned int numDrivers; const char **driverNames; const char *deviceName; + const char *driverName; int fd; unsigned int lastSequence; int prime_id; @@ -1454,7 +1455,7 @@ dri2_probe_driver_name(ScreenPtr pScreen, DRI2InfoPtr info) #ifdef WITH_LIBDRM int i, j; char *driver = NULL; - drmDevicePtr dev; + drmDevicePtr dev = NULL; /* For non-PCI devices and drmGetDevice fail, just assume that * the 3D driver is named the same as the kernel driver. This is @@ -1472,6 +1473,7 @@ dri2_probe_driver_name(ScreenPtr pScreen, DRI2InfoPtr info) driver = strndup(version->name, version->name_len); drmFreeVersion(version); + drmFreeDevice(&dev); return driver; } @@ -1615,9 +1617,8 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) if (info->driverName) { ds->driverNames[0] = info->driverName; } else { - /* FIXME dri2_probe_driver_name() returns a strdup-ed string, - * currently this gets leaked */ - ds->driverNames[0] = ds->driverNames[1] = dri2_probe_driver_name(pScreen, info); + ds->driverName = dri2_probe_driver_name(pScreen, info); + ds->driverNames[0] = ds->driverNames[1] = ds->driverName; if (!ds->driverNames[0]) return FALSE; @@ -1673,6 +1674,7 @@ DRI2CloseScreen(ScreenPtr pScreen) if (ds->prime_id) prime_id_allocate_bitmask &= ~(1 << ds->prime_id); free(ds->driverNames); + free((char *)ds->driverName); free(ds); dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL); } diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c index af7db7ddc..73eeaef94 100644 --- a/hw/xfree86/drivers/modesetting/dri2.c +++ b/hw/xfree86/drivers/modesetting/dri2.c @@ -1063,6 +1063,7 @@ ms_dri2_screen_init(ScreenPtr screen) info.fd = ms->fd; info.driverName = NULL; /* Compat field, unused. */ info.deviceName = drmGetDeviceNameFromFd(ms->fd); + ms->drmmode.dri2_device_name = info.deviceName; info.version = 9; info.CreateBuffer = ms_dri2_create_buffer; @@ -1108,7 +1109,12 @@ ms_dri2_screen_init(ScreenPtr screen) void ms_dri2_close_screen(ScreenPtr screen) { + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + modesettingPtr ms = modesettingPTR(scrn); + DRI2CloseScreen(screen); + + free((char *)ms->drmmode.dri2_device_name); } #endif /* GLAMOR_HAS_GBM */ diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 68bdca8a8..6bb7ee05c 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -57,7 +57,6 @@ #include "xf86Crtc.h" #include "miscstruct.h" #include "dixstruct.h" -#include "xf86xv.h" #include #ifdef XSERVER_PLATFORM_BUS #include "xf86platformBus.h" @@ -2135,11 +2134,9 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv) #ifdef GLAMOR_HAS_GBM if (ms->drmmode.glamor) { - XF86VideoAdaptorPtr glamor_adaptor; - - glamor_adaptor = ms->glamor.xv_init(pScreen, 16); - if (glamor_adaptor != NULL) - xf86XVScreenInit(pScreen, &glamor_adaptor, 1); + ms->adaptor = ms->glamor.xv_init(pScreen, 16); + if (ms->adaptor != NULL) + xf86XVScreenInit(pScreen, &ms->adaptor, 1); else xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to initialize XV support.\n"); @@ -2327,6 +2324,11 @@ CloseScreen(ScreenPtr pScreen) PointPriv->spriteFuncs = ms->SpriteFuncs; } + if (ms->adaptor) { + free(ms->adaptor); + ms->adaptor = NULL; + } + if (pScrn->vtSema) { LeaveVT(pScrn); } @@ -2334,6 +2336,8 @@ CloseScreen(ScreenPtr pScreen) pScreen->CreateScreenResources = ms->createScreenResources; pScreen->BlockHandler = ms->BlockHandler; + xf86_cursors_fini(pScreen); + pScrn->vtSema = FALSE; pScreen->CloseScreen = ms->CloseScreen; return (*pScreen->CloseScreen) (pScreen); diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h index 74630cac4..aa4d8fddb 100644 --- a/hw/xfree86/drivers/modesetting/driver.h +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -181,6 +182,8 @@ typedef struct _modesettingRec { const char *(*egl_get_driver_name)(ScreenPtr); } glamor; #endif + + XF86VideoAdaptorPtr adaptor; } modesettingRec, *modesettingPtr; #define glamor_finish(screen) ms->glamor.finish(screen) diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 354e5b6a7..b6b163af0 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -3030,6 +3030,10 @@ drmmode_output_create_resources(xf86OutputPtr output) drmModePropertyPtr drmmode_prop; int i, j, err; + /* already created */ + if (drmmode_output->props) + return; + drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); if (!drmmode_output->props) @@ -3511,6 +3515,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r DRM_MODE_OBJECT_CONNECTOR); drmmode_prop_info_update(drmmode, drmmode_output->props_connector, DRMMODE_CONNECTOR__COUNT, props); + drmModeFreeObjectProperties(props); } else { drmmode_output->dpms_enum_id = koutput_get_prop_id(drmmode->fd, koutput, DRM_MODE_PROP_ENUM, diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index a82ae2609..a43832185 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -127,6 +127,8 @@ typedef struct { PixmapPtr fbcon_pixmap; + const char *dri2_device_name; + Bool dri2_flipping; Bool present_flipping; Bool flip_bo_import_failed; diff --git a/hw/xfree86/drivers/modesetting/pageflip.c b/hw/xfree86/drivers/modesetting/pageflip.c index 785c0d2d1..431602093 100644 --- a/hw/xfree86/drivers/modesetting/pageflip.c +++ b/hw/xfree86/drivers/modesetting/pageflip.c @@ -170,9 +170,11 @@ ms_pageflip_abort(void *data) ScrnInfoPtr scrn = xf86ScreenToScrn(screen); modesettingPtr ms = modesettingPTR(scrn); - if (flipdata->flip_count == 1) + if (flipdata->flip_count == 1) { flipdata->abort_handler(ms, flipdata->event); + drmModeRmFB(ms->fd, flipdata->old_fb_id); + } ms_pageflip_free(flip); } diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index da0aa7635..dc4f65635 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -305,8 +305,20 @@ xf86RotateCloseScreen(ScreenPtr screen) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int c; - /* This has already been destroyed when the root window was destroyed */ - xf86_config->rotation_damage = NULL; + if (xf86_config->rotation_damage) { + if (xf86_config->rotation_damage_registered) { + /* + * This has already been destroyed when the root window + * was destroyed + */ + xf86_config->rotation_damage_registered = FALSE; + } else { + /* Free damage structure */ + DamageDestroy(xf86_config->rotation_damage); + } + xf86_config->rotation_damage = NULL; + } + for (c = 0; c < xf86_config->num_crtc; c++) xf86RotateDestroy(xf86_config->crtc[c]); } diff --git a/mi/miscrinit.c b/mi/miscrinit.c index 8165d0f38..1fe8873f4 100644 --- a/mi/miscrinit.c +++ b/mi/miscrinit.c @@ -53,6 +53,17 @@ from The Open Group. * detail to the whole server. */ +/* per-screen private data */ +static DevPrivateKeyRec miScreenPrivKeyRec; + +#define miScreenPrivKey (&miScreenPrivKeyRec) + +typedef struct { + CloseScreenProcPtr CloseScreen; +} miScreenRec, *miScreenPtr; + +#define miGetScreenPriv(s) ((miScreenPtr)(dixLookupPrivate(&(s)->devPrivates, miScreenPrivKey))) + typedef struct { void *pbits; /* pointer to framebuffer */ int width; /* delta to add to a framebuffer addr to move one row down */ @@ -126,7 +137,18 @@ miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, static Bool miCloseScreen(ScreenPtr pScreen) { - return ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate)); + miScreenPtr pScreenPriv = miGetScreenPriv(pScreen); + + ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate)); + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + + free(pScreenPriv); + + if (pScreen->CloseScreen) + return (*pScreen->CloseScreen) (pScreen); + + return TRUE; } static Bool @@ -235,6 +257,17 @@ miScreenInit(ScreenPtr pScreen, void *pbits, /* pointer to screen bits */ VisualRec * visuals /* supported visuals */ ) { + miScreenPtr pScreenPriv; + + if (!dixRegisterPrivateKey(&miScreenPrivKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + pScreenPriv = calloc(1, sizeof(miScreenRec)); + if (!pScreenPriv) + return FALSE; + + dixSetPrivate(&pScreen->devPrivates, miScreenPrivKey, pScreenPriv); + pScreen->width = xsize; pScreen->height = ysize; pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10); @@ -259,6 +292,7 @@ miScreenInit(ScreenPtr pScreen, void *pbits, /* pointer to screen bits */ #ifdef MITSHM ShmRegisterFbFuncs(pScreen); #endif + pScreenPriv->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = miCloseScreen; } /* else CloseScreen */ diff --git a/miext/sync/misyncfd.c b/miext/sync/misyncfd.c index c2ad550c1..9d245a1d5 100644 --- a/miext/sync/misyncfd.c +++ b/miext/sync/misyncfd.c @@ -34,6 +34,7 @@ static DevPrivateKeyRec syncFdScreenPrivateKey; typedef struct _SyncFdScreenPrivate { SyncFdScreenFuncsRec funcs; + CloseScreenProcPtr CloseScreen; } SyncFdScreenPrivateRec, *SyncFdScreenPrivatePtr; static inline SyncFdScreenPrivatePtr sync_fd_screen_priv(ScreenPtr pScreen) @@ -66,6 +67,20 @@ miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence) return (*priv->funcs.GetFenceFd)(pDraw->pScreen, pFence); } +static Bool +miSyncFdCloseScreen(ScreenPtr pScreen) +{ + SyncFdScreenPrivatePtr priv = sync_fd_screen_priv(pScreen); + + pScreen->CloseScreen = priv->CloseScreen; + free(priv); + + if (pScreen->CloseScreen) + return (*pScreen->CloseScreen) (pScreen); + + return TRUE; +} + Bool miSyncFdScreenInit(ScreenPtr pScreen, const SyncFdScreenFuncsRec *funcs) { @@ -93,6 +108,9 @@ Bool miSyncFdScreenInit(ScreenPtr pScreen, priv->funcs = *funcs; + priv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = miSyncFdCloseScreen; + dixSetPrivate(&pScreen->devPrivates, &syncFdScreenPrivateKey, priv); return TRUE;