xserver/composite compalloc.c, 1.9, 1.10 compinit.c, 1.14, 1.15 compint.h, 1.9, 1.10 compwindow.c, 1.12, 1.13
Keith Packard <xserver-commit-u7BhqnqprCWvj1b/[email protected]> Tue, 8 Feb 2005 14:39:26 -0800 (PST)
| Newsgroups | gmane.comp.freedesktop.xserver.cvs |
|---|---|
| Message-ID | <[email protected]> |
Committed by: keithp Update of /cvs/xserver/xserver/composite In directory gabe:/tmp/cvs-serv18301/composite Modified Files: compalloc.c compinit.c compint.h compwindow.c Log Message: 2005-02-08 Keith Packard <[email protected]> * composite/compalloc.c: (compRedirectWindow), (compNewPixmap), (compAllocPixmap), (compFreePixmap), (compReallocPixmap): * composite/compinit.c: (compCloseScreen), (compInstallColormap), (compAddAlternateVisuals), (compScreenInit): * composite/compint.h: * composite/compwindow.c: (compRepaintBorder), (compSetPixmapVisitWindow), (compCheckRedirect), (compPositionWindow), (compCopyWindow), (compSetRedirectBorderClip), (compWindowUpdateAutomatic): Avoid telling DDX about colormaps for synthetic visuals Fix border repainting on resize. Change pixmap allocation around * damageext/damageext.c: (DamageExtReport), (ProcDamageCreate), (ProcDamageSubtract): * dix/colormap.c: (CopyFree), (AllocColor), (AllocDirect): * fb/fbcmap.c: (fbInitVisuals): Change where the 'alpha bits' live in visuals. * include/regionstr.h: * include/scrnintstr.h: * mi/misprite.c: * miext/damage/damage.c: (getDrawableDamageRef), (damageDamageRegion), (damageCreateGC), (damageCopyArea), (damageCopyPlane), (damageRemoveDamage), (damageInsertDamage), (damageDestroyPixmap), (damageSetWindowPixmap), (DamageSetup), (DamageCreate), (DamageRegister), (DamageUnregister), (DamageDestroy), (DamageSubtract), (DamageEmpty): * miext/damage/damage.h: * miext/damage/damagestr.h: * miext/shadow/shadow.c: (shadowSetup): Check for NULL pCompositeClip in damage code. Call SourceValidate for self CopyArea/CopyPlane Change damageInsertDamage API so it doesn't require a pixmap Index: compalloc.c =================================================================== RCS file: /cvs/xserver/xserver/composite/compalloc.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- compalloc.c 11 Jun 2004 00:00:53 -0000 1.9 +++ compalloc.c 8 Feb 2005 22:39:20 -0000 1.10 @@ -91,6 +91,7 @@ compDestroyDamage, DamageReportNonEmpty, FALSE, + pWin->drawable.pScreen, pWin); if (!cw->damage) { @@ -101,7 +102,7 @@ if (wasMapped) UnmapWindow (pWin, FALSE); - REGION_INIT (pScreen, &cw->borderClip, NullBox, 0); + REGION_NULL (pScreen, &cw->borderClip); cw->update = CompositeRedirectAutomatic; cw->clients = 0; cw->oldx = COMP_ORIGIN_INVALID; @@ -417,24 +418,58 @@ return Success; } -Bool -compAllocPixmap (WindowPtr pWin) +static PixmapPtr +compNewPixmap (WindowPtr pWin, int x, int y, int w, int h) { ScreenPtr pScreen = pWin->drawable.pScreen; + WindowPtr pParent = pWin->parent; PixmapPtr pPixmap; - int bw = (int) pWin->borderWidth; - int x, y, w, h; - CompWindowPtr cw = GetCompWindow (pWin); + GCPtr pGC; - x = pWin->drawable.x - bw; - y = pWin->drawable.y - bw; - w = pWin->drawable.width + (bw << 1); - h = pWin->drawable.height + (bw << 1); pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth); + if (!pPixmap) - return FALSE; + return 0; + pPixmap->screen_x = x; pPixmap->screen_y = y; + + pGC = GetScratchGC (pWin->drawable.depth, pScreen); + + /* + * Copy bits from the parent into the new pixmap so that it will + * have "reasonable" contents in case for background None areas. + */ + if (pGC) + { + XID val = IncludeInferiors; + + ValidateGC(&pPixmap->drawable, pGC); + dixChangeGC (serverClient, pGC, GCSubwindowMode, &val, NULL); + (*pGC->ops->CopyArea) (&pParent->drawable, + &pPixmap->drawable, + pGC, + x - pParent->drawable.x, + y - pParent->drawable.y, + w, h, 0, 0); + FreeScratchGC (pGC); + } + return pPixmap; +} + +Bool +compAllocPixmap (WindowPtr pWin) +{ + int bw = (int) pWin->borderWidth; + int x = pWin->drawable.x - bw; + int y = pWin->drawable.y - bw; + int w = pWin->drawable.width + (bw << 1); + int h = pWin->drawable.height + (bw << 1); + PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h); + CompWindowPtr cw = GetCompWindow (pWin); + + if (!pPixmap) + return FALSE; pWin->redirectDraw = TRUE; compSetPixmap (pWin, pPixmap); cw->oldx = COMP_ORIGIN_INVALID; @@ -459,6 +494,7 @@ { DamageUnregister (&pWin->drawable, cw->damage); cw->damageRegistered = FALSE; + DamageEmpty (cw->damage); } /* * Move the parent-constrained border clip region back into @@ -488,42 +524,22 @@ PixmapPtr pNew; CompWindowPtr cw = GetCompWindow (pWin); int pix_x, pix_y; - unsigned int pix_w, pix_h; + int pix_w, pix_h; assert (cw && pWin->redirectDraw); + cw->oldx = pOld->screen_x; + cw->oldy = pOld->screen_y; pix_x = draw_x - bw; pix_y = draw_y - bw; pix_w = w + (bw << 1); pix_h = h + (bw << 1); - cw->oldx = pOld->screen_x; - cw->oldy = pOld->screen_y; - if (pix_w != pOld->drawable.width || - pix_h != pOld->drawable.height) + if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height) { - GCPtr pGC; - - pNew = (*pScreen->CreatePixmap) (pScreen, pix_w, pix_h, pWin->drawable.depth); + pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h); if (!pNew) return FALSE; cw->pOldPixmap = pOld; compSetPixmap (pWin, pNew); - /* - * Copy new bits to align at same place on the screen. CopyWindow - * calls will patch up any differences - */ - pGC = GetScratchGC (pNew->drawable.depth, pScreen); - if (pGC) - { - ValidateGC(&pNew->drawable, pGC); - (*pGC->ops->CopyArea) (&pOld->drawable, - &pNew->drawable, - pGC, - pWin->drawable.x - draw_x, - pWin->drawable.y - draw_y, - pix_w, pix_h, - 0, 0); - FreeScratchGC (pGC); - } } else { Index: compinit.c =================================================================== RCS file: /cvs/xserver/xserver/composite/compinit.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- compinit.c 4 Jun 2004 16:10:50 -0000 1.14 +++ compinit.c 8 Feb 2005 22:39:20 -0000 1.15 @@ -40,6 +40,7 @@ pScreen->CloseScreen = cs->CloseScreen; pScreen->BlockHandler = cs->BlockHandler; + pScreen->InstallColormap = cs->InstallColormap; pScreen->ReparentWindow = cs->ReparentWindow; pScreen->MoveWindow = cs->MoveWindow; pScreen->ResizeWindow = cs->ResizeWindow; @@ -60,6 +61,23 @@ } static void +compInstallColormap (ColormapPtr pColormap) +{ + VisualPtr pVisual = pColormap->pVisual; + ScreenPtr pScreen = pColormap->pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + int a; + + for (a = 0; a < NUM_COMP_ALTERNATE_VISUALS; a++) + if (pVisual->vid == cs->alternateVisuals[a]) + return; + pScreen->InstallColormap = cs->InstallColormap; + (*pScreen->InstallColormap) (pColormap); + cs->InstallColormap = pScreen->InstallColormap; + pScreen->InstallColormap = compInstallColormap; +} + +static void compScreenUpdate (ScreenPtr pScreen) { CompScreenPtr cs = GetCompScreen (pScreen); @@ -126,7 +144,9 @@ } CompAlternateVisual; static CompAlternateVisual altVisuals[NUM_COMP_ALTERNATE_VISUALS] = { +#if COMP_INCLUDE_RGB24_VISUAL { 24, PICT_r8g8b8 }, +#endif { 32, PICT_a8r8g8b8 }, }; @@ -164,10 +184,6 @@ continue; /* - * Ok, create a visual id for this format - */ - cs->alternateVisuals[numAlternate] = FakeClientID (0); - /* * Allocate vid list for this depth */ vids[numAlternate] = xalloc (sizeof (VisualID)); @@ -235,6 +251,7 @@ DepthPtr depth = depths[alt]; PictFormatPtr pPictFormat = pPictFormats[alt]; VisualPtr visual = &visuals[numVisuals + alt]; + unsigned long alphaMask; /* * Initialize the visual @@ -249,19 +266,19 @@ pPictFormat->direct.green); visual->blueMask = (((unsigned long) pPictFormat->direct.blueMask) << pPictFormat->direct.blue); + alphaMask = (((unsigned long) pPictFormat->direct.alphaMask) << + pPictFormat->direct.alpha); visual->offsetRed = pPictFormat->direct.red; visual->offsetGreen = pPictFormat->direct.green; visual->offsetBlue = pPictFormat->direct.blue; - visual->alphaMask = (((unsigned long) pPictFormat->direct.alphaMask) << - pPictFormat->direct.alpha); - visual->offsetAlpha = pPictFormat->direct.alpha; /* - * follow GLX and set nplanes to just the bits - * used for the RGB value, not A + * Include A bits in this (unlike GLX which includes only RGB) + * This lets DIX compute suitable masks for colormap allocations */ visual->nplanes = Ones (visual->redMask | visual->greenMask | - visual->blueMask); + visual->blueMask | + alphaMask); /* * find widest component */ @@ -358,6 +375,9 @@ cs->ReparentWindow = pScreen->ReparentWindow; pScreen->ReparentWindow = compReparentWindow; + cs->InstallColormap = pScreen->InstallColormap; + pScreen->InstallColormap = compInstallColormap; + cs->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = compBlockHandler; Index: compint.h =================================================================== RCS file: /cvs/xserver/xserver/composite/compint.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- compint.h 21 May 2004 03:32:27 -0000 1.9 +++ compint.h 8 Feb 2005 22:39:20 -0000 1.10 @@ -49,6 +49,12 @@ #include <X11/extensions/compositeproto.h> #include <assert.h> +/* + * enable this for debugging + + #define COMPOSITE_DEBUG + */ + typedef struct _CompClientWindow { struct _CompClientWindow *next; XID id; @@ -75,9 +81,15 @@ CompClientWindowPtr clients; } CompSubwindowsRec, *CompSubwindowsPtr; -extern int CompPixmapPrivateIndex; +#ifndef COMP_INCLUDE_RGB24_VISUAL +#define COMP_INCLUDE_RGB24_VISUAL 0 +#endif +#if COMP_INCLUDE_RGB24_VISUAL #define NUM_COMP_ALTERNATE_VISUALS 2 +#else +#define NUM_COMP_ALTERNATE_VISUALS 1 +#endif typedef struct _CompScreen { PositionWindowProcPtr PositionWindow; @@ -101,16 +113,17 @@ */ ReparentWindowProcPtr ReparentWindow; + /* + * Colormaps for new visuals better not get installed + */ + InstallColormapProcPtr InstallColormap; + ScreenBlockHandlerProcPtr BlockHandler; CloseScreenProcPtr CloseScreen; Bool damaged; XID alternateVisuals[NUM_COMP_ALTERNATE_VISUALS]; } CompScreenRec, *CompScreenPtr; -#define HasCompRedirect(w) (wPixmap(w) != wPixmap(w->parent)) -#define wScreen(w) ((w)->drawable.pScreen) -#define wPixmap(w) (*(wScreen(w)->GetWindowPixmap) (w)) - extern int CompScreenPrivateIndex; extern int CompWindowPrivateIndex; extern int CompSubwindowsPrivateIndex; @@ -181,11 +194,11 @@ * compwindow.c */ -#ifdef NDEBUG -#define compCheckTree(s) -#else +#ifdef COMPOSITE_DEBUG void compCheckTree (ScreenPtr pScreen); +#else +#define compCheckTree(s) #endif void Index: compwindow.c =================================================================== RCS file: /cvs/xserver/xserver/composite/compwindow.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- compwindow.c 21 May 2004 03:32:27 -0000 1.12 +++ compwindow.c 8 Feb 2005 22:39:20 -0000 1.13 @@ -27,7 +27,7 @@ #endif #include "compint.h" -#ifndef NDEBUG +#ifdef COMPOSITE_DEBUG static int compCheckWindow (WindowPtr pWin, pointer data) { @@ -69,6 +69,23 @@ PixmapPtr pPixmap; } CompPixmapVisitRec, *CompPixmapVisitPtr; +static Bool +compRepaintBorder (ClientPtr pClient, pointer closure) +{ + WindowPtr pWindow = LookupWindow ((XID) closure, pClient); + + if (pWindow) + { + RegionRec exposed; + + REGION_NULL(pScreen, &exposed); + REGION_SUBTRACT(pScreen, &exposed, &pWindow->borderClip, &pWindow->winSize); + (*pWindow->drawable.pScreen->PaintWindowBorder)(pWindow, &exposed, PW_BORDER); + REGION_UNINIT(pScreen, &exposed); + } + return TRUE; +} + static int compSetPixmapVisitWindow (WindowPtr pWindow, pointer data) { @@ -85,6 +102,9 @@ */ SetWinSize (pWindow); SetBorderSize (pWindow); + if (HasBorder (pWindow)) + QueueWorkProc (compRepaintBorder, serverClient, + (pointer) pWindow->drawable.id); return WT_WALKCHILDREN; } @@ -103,7 +123,10 @@ compCheckRedirect (WindowPtr pWin) { CompWindowPtr cw = GetCompWindow (pWin); - Bool should = pWin->viewable && (cw != NULL); + Bool should; + + should = pWin->realized && (pWin->drawable.class != InputOnly) && + (cw != NULL); if (should != pWin->redirectDraw) { @@ -128,8 +151,10 @@ * compCheckRedirect (pWin); */ +#ifdef COMPOSITE_DEBUG if (pWin->redirectDraw != (pWin->viewable && (GetCompWindow(pWin) != NULL))) abort (); +#endif if (pWin->redirectDraw) { PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); @@ -468,7 +493,7 @@ dy = ptOldOrg.y - pWin->drawable.y; REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); - REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0); + REGION_NULL (pWin->drawable.pScreen, &rgnDst); REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); @@ -587,7 +612,7 @@ CompWindowPtr cw = GetCompWindow (pWin); RegionRec damage; - REGION_INIT (pScreen, &damage, NullBox, 0); + REGION_NULL (pScreen, &damage); /* * Align old border clip with new border clip */ @@ -648,7 +673,6 @@ ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pParent = pWin->parent; PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin); - PixmapPtr pDstPixmap = (*pScreen->GetWindowPixmap) (pParent); PictFormatPtr pSrcFormat = compWindowFormat (pWin); PictFormatPtr pDstFormat = compWindowFormat (pWin->parent); int error; @@ -658,33 +682,55 @@ 0, 0, serverClient, &error); - PicturePtr pDstPicture = CreatePicture (0, &pDstPixmap->drawable, + XID subwindowMode = IncludeInferiors; + PicturePtr pDstPicture = CreatePicture (0, &pParent->drawable, pDstFormat, - 0, 0, + CPSubwindowMode, + &subwindowMode, serverClient, &error); - + + /* + * First move the region from window to screen coordinates + */ REGION_TRANSLATE (pScreen, pRegion, - pSrcPixmap->screen_x, pSrcPixmap->screen_y); + pWin->drawable.x, pWin->drawable.y); + + /* + * Clip against the "real" border clip + */ REGION_INTERSECT (pScreen, pRegion, pRegion, &cw->borderClip); + + /* + * Now translate from screen to dest coordinates + */ REGION_TRANSLATE (pScreen, pRegion, - -pSrcPixmap->screen_x, -pSrcPixmap->screen_y); + -pParent->drawable.x, -pParent->drawable.y); - SetPictureClipRegion (pSrcPicture, 0, 0, pRegion); + /* + * Clip the picture + */ + SetPictureClipRegion (pDstPicture, 0, 0, pRegion); + /* + * And paint + */ CompositePicture (PictOpSrc, pSrcPicture, 0, pDstPicture, - 0, - 0, - 0, 0, - pSrcPixmap->screen_x - pDstPixmap->screen_x, - pSrcPixmap->screen_y - pDstPixmap->screen_y, + 0, 0, /* src_x, src_y */ + 0, 0, /* msk_x, msk_y */ + pSrcPixmap->screen_x - pParent->drawable.x, + pSrcPixmap->screen_y - pParent->drawable.y, pSrcPixmap->drawable.width, pSrcPixmap->drawable.height); FreePicture (pSrcPicture, 0); FreePicture (pDstPicture, 0); + /* + * Empty the damage region. This has the nice effect of + * rendering the translations above harmless + */ DamageEmpty (cw->damage); }