[PATCH] composite: Don't bother copying the pixmap for ForgetGravity windows (v2)

Aaron Plattner aplattner at nvidia.com
Thu Apr 23 14:13:54 PDT 2015


Does this cause flickering when resizing windows and the compositor 
reads the new window pixmap before the app has a chance to respond to 
the events?

On 04/23/2015 01:24 PM, Jasper St. Pierre wrote:
> 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 <ajax at redhat.com>
> Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
> ---
>   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;
>   }

-- 
Aaron


More information about the xorg-devel mailing list