From: Ville Syrjälä <[email protected]>

Use CopyArea in compWindowUpdateAutomatic if the window and parent
depths match. It appears EXA Composite op can already switch to
a straight copy when the conditions are right, but non-EXA drivers
would fall back to software rendering.

Signed-off-by: Ville Syrjälä <[email protected]>
---
v3: New patch

 composite/compwindow.c |   95 +++++++++++++++++++++++++++++++-----------------
 1 files changed, 61 insertions(+), 34 deletions(-)

diff --git a/composite/compwindow.c b/composite/compwindow.c
index 2440f18..2913961 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -659,22 +659,7 @@ compWindowUpdateAutomatic (WindowPtr pWin)
     ScreenPtr      pScreen = pWin->drawable.pScreen;
     WindowPtr      pParent = pWin->parent;
     PixmapPtr      pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
-    PictFormatPtr   pSrcFormat = compWindowFormat (pWin);
-    PictFormatPtr   pDstFormat = compWindowFormat (pWin->parent);
-    int                    error;
     RegionPtr      pRegion = DamageRegion (cw->damage);
-    PicturePtr     pSrcPicture = CreatePicture (0, &pSrcPixmap->drawable,
-                                                pSrcFormat,
-                                                0, 0,
-                                                serverClient,
-                                                &error);
-    XID                    subwindowMode = IncludeInferiors;
-    PicturePtr     pDstPicture = CreatePicture (0, &pParent->drawable,
-                                                pDstFormat,
-                                                CPSubwindowMode,
-                                                &subwindowMode,
-                                                serverClient,
-                                                &error);
 
     /*
      * First move the region from window to screen coordinates
@@ -693,26 +678,68 @@ compWindowUpdateAutomatic (WindowPtr pWin)
     RegionTranslate(pRegion,
                      -pParent->drawable.x, -pParent->drawable.y);
 
-    /*
-     * Clip the picture
-     */
-    SetPictureClipRegion (pDstPicture, 0, 0, pRegion);
+    if (pWin->drawable.depth == pParent->drawable.depth) {
+       GCPtr pGC = GetScratchGC (pParent->drawable.depth, pScreen);
+
+       if (pGC) {
+           ChangeGCVal val;
+           RegionPtr pClip = RegionCreate(NullBox, 0);
+           RegionCopy(pClip, pRegion);
+           (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
+           val.val = IncludeInferiors;
+           ChangeGC (NullClient, pGC, GCSubwindowMode, &val);
+           ValidateGC(&pParent->drawable, pGC);
+
+           (*pGC->ops->CopyArea) (&pSrcPixmap->drawable,
+                                  &pParent->drawable,
+                                  pGC,
+                                  0, 0,
+                                  pSrcPixmap->drawable.width,
+                                  pSrcPixmap->drawable.height,
+                                  pSrcPixmap->screen_x - pParent->drawable.x,
+                                  pSrcPixmap->screen_y - pParent->drawable.y);
+
+           FreeScratchGC (pGC);
+       }
+    } else {
+           PictFormatPtr   pSrcFormat = compWindowFormat (pWin);
+           PictFormatPtr   pDstFormat = compWindowFormat (pParent);
+           int             error;
+           PicturePtr      pSrcPicture = CreatePicture (0, 
&pSrcPixmap->drawable,
+                                                        pSrcFormat,
+                                                        0, 0,
+                                                        serverClient,
+                                                        &error);
+           XID             subwindowMode = IncludeInferiors;
+           PicturePtr      pDstPicture = CreatePicture (0, &pParent->drawable,
+                                                        pDstFormat,
+                                                        CPSubwindowMode,
+                                                        &subwindowMode,
+                                                        serverClient,
+                                                        &error);
+
+           /*
+            * Clip the picture
+            */
+           SetPictureClipRegion (pDstPicture, 0, 0, pRegion);
+
+           /*
+            * And paint
+            */
+           CompositePicture (PictOpSrc,
+                             pSrcPicture,
+                             0,
+                             pDstPicture,
+                             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);
+    }
 
-    /*
-     * And paint
-     */
-    CompositePicture (PictOpSrc,
-                     pSrcPicture,
-                     0,
-                     pDstPicture,
-                     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
-- 
1.7.2.2

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to