exa: use PixmapDestroy hook

Wrapping ScreenRec's function pointers is problematic for many reasons,
so use the new pixmap destroy notify hook instead.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2024-10-04 17:56:04 +02:00
parent 60dd47abda
commit f39bbe58d6
5 changed files with 52 additions and 94 deletions

View File

@ -743,6 +743,11 @@ static void exaCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unuse
dixScreenUnhookClose(pScreen, exaCloseScreen);
/* doesn't matter which one actually was registered */
dixScreenUnhookPixmapDestroy(pScreen, exaPixmapDestroy_classic);
dixScreenUnhookPixmapDestroy(pScreen, exaPixmapDestroy_driver);
dixScreenUnhookPixmapDestroy(pScreen, exaPixmapDestroy_mixed);
if (ps && ps->Glyphs == exaGlyphs)
exaGlyphsFini(pScreen);
@ -755,8 +760,6 @@ static void exaCloseScreen(CallbackListPtr *pcbl, ScreenPtr pScreen, void *unuse
unwrap(pExaScr, pScreen, GetSpans);
if (pExaScr->SavedCreatePixmap)
unwrap(pExaScr, pScreen, CreatePixmap);
if (pExaScr->SavedDestroyPixmap)
unwrap(pExaScr, pScreen, DestroyPixmap);
if (pExaScr->SavedModifyPixmapHeader)
unwrap(pExaScr, pScreen, ModifyPixmapHeader);
unwrap(pExaScr, pScreen, CopyWindow);
@ -958,8 +961,9 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
}
if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) {
if (pExaScr->info->flags & EXA_MIXED_PIXMAPS) {
dixScreenHookPixmapDestroy(pScreen, exaPixmapDestroy_mixed);
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_mixed);
wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_mixed);
wrap(pExaScr, pScreen, ModifyPixmapHeader,
exaModifyPixmapHeader_mixed);
wrap(pExaScr, pScreen, SharePixmapBacking, exaSharePixmapBacking_mixed);
@ -972,8 +976,9 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
}
else {
dixScreenHookPixmapDestroy(pScreen, exaPixmapDestroy_driver);
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver);
wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
wrap(pExaScr, pScreen, ModifyPixmapHeader,
exaModifyPixmapHeader_driver);
pExaScr->do_migration = NULL;
@ -984,8 +989,9 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
}
}
else {
dixScreenHookPixmapDestroy(pScreen, exaPixmapDestroy_classic);
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic);
wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_classic);
wrap(pExaScr, pScreen, ModifyPixmapHeader,
exaModifyPixmapHeader_classic);
pExaScr->do_migration = exaDoMigration_classic;

View File

@ -206,42 +206,26 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height,
return ret;
}
Bool
exaDestroyPixmap_classic(PixmapPtr pPixmap)
void exaPixmapDestroy_classic(CallbackListPtr *pcbl, ScreenPtr pScreen, PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaPixmapPriv(pPixmap);
if (!pExaPixmap) // we're called on an error path
return;
ExaScreenPriv(pScreen);
Bool ret = TRUE;
exaDestroyPixmap(pPixmap);
if (pPixmap->refcnt == 1) {
ExaPixmapPriv(pPixmap);
if (!pExaPixmap) // we're called on an error path
goto out;
exaDestroyPixmap(pPixmap);
if (pExaPixmap->area) {
DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
(void *) pPixmap->drawable.id,
ExaGetPixmapPriv(pPixmap)->area->offset,
pPixmap->drawable.width, pPixmap->drawable.height));
/* Free the offscreen area */
exaOffscreenFree(pPixmap->drawable.pScreen, pExaPixmap->area);
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
pPixmap->devKind = pExaPixmap->sys_pitch;
}
RegionUninit(&pExaPixmap->validSys);
RegionUninit(&pExaPixmap->validFB);
if (pExaPixmap->area) {
DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
(void *) pPixmap->drawable.id,
ExaGetPixmapPriv(pPixmap)->area->offset,
pPixmap->drawable.width, pPixmap->drawable.height));
/* Free the offscreen area */
exaOffscreenFree(pPixmap->drawable.pScreen, pExaPixmap->area);
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
pPixmap->devKind = pExaPixmap->sys_pitch;
}
out:
// restore original (screen driver's) DestroyPixmap() handler and call it
swap(pExaScr, pScreen, DestroyPixmap);
dixDestroyPixmap(pPixmap, 0);
swap(pExaScr, pScreen, DestroyPixmap);
return ret;
RegionUninit(&pExaPixmap->validSys);
RegionUninit(&pExaPixmap->validFB);
}
Bool

View File

@ -185,33 +185,19 @@ exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height,
return ret;
}
Bool
exaDestroyPixmap_driver(PixmapPtr pPixmap)
void exaPixmapDestroy_driver(CallbackListPtr *pcbl, ScreenPtr pScreen, PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaScreenPriv(pScreen);
Bool ret = TRUE;
if (pPixmap->refcnt == 1) {
ExaPixmapPriv(pPixmap);
if (!pExaPixmap) // we're called on an error path
goto out;
ExaPixmapPriv(pPixmap);
if (!pExaPixmap) // we're called on an error path
return;
exaDestroyPixmap(pPixmap);
exaDestroyPixmap(pPixmap);
if (pExaPixmap->driverPriv)
pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
pExaPixmap->driverPriv = NULL;
}
out:
// restore original (screen driver's) DestroyPixmap() handler and call it
swap(pExaScr, pScreen, DestroyPixmap);
dixDestroyPixmap(pPixmap, 0);
swap(pExaScr, pScreen, DestroyPixmap);
return ret;
if (pExaPixmap->driverPriv)
pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
pExaPixmap->driverPriv = NULL;
}
Bool

View File

@ -239,42 +239,28 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
return ret;
}
Bool
exaDestroyPixmap_mixed(PixmapPtr pPixmap)
void exaPixmapDestroy_mixed(CallbackListPtr *pcbl, ScreenPtr pScreen, PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaScreenPriv(pScreen);
Bool ret = TRUE;
if (pPixmap->refcnt == 1) {
ExaPixmapPriv(pPixmap);
if (!pExaPixmap)
goto out; // we're called on an error path
ExaPixmapPriv(pPixmap);
if (!pExaPixmap) // we're called on an error path
return;
exaDestroyPixmap(pPixmap);
exaDestroyPixmap(pPixmap);
if (pExaScr->deferred_mixed_pixmap == pPixmap)
pExaScr->deferred_mixed_pixmap = NULL;
if (pExaScr->deferred_mixed_pixmap == pPixmap)
pExaScr->deferred_mixed_pixmap = NULL;
if (pExaPixmap->driverPriv)
pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
pExaPixmap->driverPriv = NULL;
if (pExaPixmap->driverPriv)
pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
pExaPixmap->driverPriv = NULL;
if (pExaPixmap->pDamage) {
free(pExaPixmap->sys_ptr);
pExaPixmap->sys_ptr = NULL;
pExaPixmap->pDamage = NULL;
}
if (pExaPixmap->pDamage) {
free(pExaPixmap->sys_ptr);
pExaPixmap->sys_ptr = NULL;
pExaPixmap->pDamage = NULL;
}
out:
// restore original (screen driver's) DestroyPixmap() handler and call it
swap(pExaScr, pScreen, DestroyPixmap);
dixDestroyPixmap(pPixmap, 0);
swap(pExaScr, pScreen, DestroyPixmap);
return ret;
}
Bool

View File

@ -155,7 +155,6 @@ typedef struct {
GetImageProcPtr SavedGetImage;
GetSpansProcPtr SavedGetSpans;
CreatePixmapProcPtr SavedCreatePixmap;
DestroyPixmapProcPtr SavedDestroyPixmap;
CopyWindowProcPtr SavedCopyWindow;
ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
BitmapToRegionProcPtr SavedBitmapToRegion;
@ -589,8 +588,7 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height,
int depth, int bitsPerPixel, int devKind,
void *pPixData);
Bool
exaDestroyPixmap_classic(PixmapPtr pPixmap);
void exaPixmapDestroy_classic(CallbackListPtr *pcbl, ScreenPtr pScreen, PixmapPtr pPixmap);
Bool
exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap);
@ -607,8 +605,7 @@ exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height,
int depth, int bitsPerPixel, int devKind,
void *pPixData);
Bool
exaDestroyPixmap_driver(PixmapPtr pPixmap);
void exaPixmapDestroy_driver(CallbackListPtr *pcbl, ScreenPtr pScreen, PixmapPtr pPixmap);
Bool
exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap);
@ -624,8 +621,7 @@ Bool
exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
int bitsPerPixel, int devKind, void *pPixData);
Bool
exaDestroyPixmap_mixed(PixmapPtr pPixmap);
void exaPixmapDestroy_mixed(CallbackListPtr *pcbl, ScreenPtr pScreen, PixmapPtr pPixmap);
Bool
exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap);