If a window has ForgetGravity in its bitGravity, that very likely means it will repaint on the ConfigureNotify / Expose event, and thus we don't have to copy the old pixmap into the new pixmap, we can simply leave it blank.
Preventing this copy is super simple to do and a big win on small devices where these blits can be expensive. A better approach would be to actually obey BitGravity correctly rather than assume NorthWestGravity always, but this is a big speedup for the common case. v2: Check all subwindows to make sure they are also ForgetGravity Cc: Adam Jackson <[email protected]> Signed-off-by: Jasper St. Pierre <[email protected]> --- composite/compalloc.c | 109 +++++++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/composite/compalloc.c b/composite/compalloc.c index 8daded0..40bf873 100644 --- a/composite/compalloc.c +++ b/composite/compalloc.c @@ -526,6 +526,21 @@ compUnredirectOneSubwindow(WindowPtr pParent, WindowPtr pWin) return Success; } +static Bool +needsPixmapCopy(WindowPtr pWin) +{ + WindowPtr pChild; + + if (pWin->bitGravity != ForgetGravity) + return TRUE; + + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) + if (needsPixmapCopy(pChild)) + return TRUE; + + return FALSE; +} + static PixmapPtr compNewPixmap(WindowPtr pWin, int x, int y, int w, int h) { @@ -542,54 +557,56 @@ compNewPixmap(WindowPtr pWin, int x, int y, int w, int h) pPixmap->screen_x = x; pPixmap->screen_y = y; - if (pParent->drawable.depth == pWin->drawable.depth) { - GCPtr pGC = GetScratchGC(pWin->drawable.depth, pScreen); - - if (pGC) { - ChangeGCVal val; - - val.val = IncludeInferiors; - ChangeGC(NullClient, pGC, GCSubwindowMode, &val); - ValidateGC(&pPixmap->drawable, pGC); - (*pGC->ops->CopyArea) (&pParent->drawable, - &pPixmap->drawable, - pGC, - x - pParent->drawable.x, - y - pParent->drawable.y, w, h, 0, 0); - FreeScratchGC(pGC); + if (needsPixmapCopy(pWin)) { + if (pParent->drawable.depth == pWin->drawable.depth) { + GCPtr pGC = GetScratchGC(pWin->drawable.depth, pScreen); + + if (pGC) { + ChangeGCVal val; + + val.val = IncludeInferiors; + ChangeGC(NullClient, pGC, GCSubwindowMode, &val); + ValidateGC(&pPixmap->drawable, pGC); + (*pGC->ops->CopyArea) (&pParent->drawable, + &pPixmap->drawable, + pGC, + x - pParent->drawable.x, + y - pParent->drawable.y, w, h, 0, 0); + FreeScratchGC(pGC); + } } - } - else { - PictFormatPtr pSrcFormat = PictureWindowFormat(pParent); - PictFormatPtr pDstFormat = PictureWindowFormat(pWin); - XID inferiors = IncludeInferiors; - int error; - - PicturePtr pSrcPicture = CreatePicture(None, - &pParent->drawable, - pSrcFormat, - CPSubwindowMode, - &inferiors, - serverClient, &error); - - PicturePtr pDstPicture = CreatePicture(None, - &pPixmap->drawable, - pDstFormat, - 0, 0, - serverClient, &error); - - if (pSrcPicture && pDstPicture) { - CompositePicture(PictOpSrc, - pSrcPicture, - NULL, - pDstPicture, - x - pParent->drawable.x, - y - pParent->drawable.y, 0, 0, 0, 0, w, h); + else { + PictFormatPtr pSrcFormat = PictureWindowFormat(pParent); + PictFormatPtr pDstFormat = PictureWindowFormat(pWin); + XID inferiors = IncludeInferiors; + int error; + + PicturePtr pSrcPicture = CreatePicture(None, + &pParent->drawable, + pSrcFormat, + CPSubwindowMode, + &inferiors, + serverClient, &error); + + PicturePtr pDstPicture = CreatePicture(None, + &pPixmap->drawable, + pDstFormat, + 0, 0, + serverClient, &error); + + if (pSrcPicture && pDstPicture) { + CompositePicture(PictOpSrc, + pSrcPicture, + NULL, + pDstPicture, + x - pParent->drawable.x, + y - pParent->drawable.y, 0, 0, 0, 0, w, h); + } + if (pSrcPicture) + FreePicture(pSrcPicture, 0); + if (pDstPicture) + FreePicture(pDstPicture, 0); } - if (pSrcPicture) - FreePicture(pSrcPicture, 0); - if (pDstPicture) - FreePicture(pDstPicture, 0); } return pPixmap; } -- 2.1.0 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
