After a much heated discussion about how to fix the horrible resizing and performance bug with FGLRX and KDE4, no one knew where to start looking. The X team had to do a little digging; the KDE4 team needed to change somethings; the FGLRX warehouse needed to get their shit together and listen to the users… bla bla bla the flame wars raged on, fingers were pointed, and nothing ever got done.

That is, nothing got done until a lone user piped up with a workaround. Here is what he wrote in the comments of that blog post:

Hi, I have been pissed off by this problem a long time and assumed it was ATI’s fault. Tonight I made one last effort before ordering a Nvidia graphics card. And I was successful.

I am running catalyst 9.8 using a Radeon 3850 and have had this re-size/maximize problem as long as long as I have used KDE4. To solve the problem I needed to modify a file in xorg-server. in the code directory it is called ./composite/compalloc.c. Here I commented out most of a function called compNewPixmap. Everything below these lines:

pPixmap->screen_x = x;
pPixmap->screen_y = y;

all the way down to (but not including) the last line:

return pPixmap;

After this I am running KDE4 with all desktop effects that I want and without any lag in resizing/maximizing.
I am running Gentoo, so I just updated the xorg-server source package file and put it back into the source repository, rebuilt the manifest and emerged it again. Voila!

Voila indeed. The patch he’s talking about looks like this (thanks to this Russian blog I can’t read):

--- composite/compalloc.c.orig  2009-09-08 02:54:28.657143479 +0700                              
+++ composite/compalloc.c       2009-09-08 02:55:42.835357653 +0700                              
@@ -484,64 +484,6 @@                                                                             
     pPixmap->screen_x = x;                                                                      
     pPixmap->screen_y = y;                                                                      
 
-    if (pParent->drawable.depth == pWin->drawable.depth)                                        
-    {                                                                                           
-       GCPtr   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);                                                                 
-       }                                                                                        
-    }                                                                                           
-    else                                                                                        
-    {                                                                                           
-       PictFormatPtr   pSrcFormat = compWindowFormat (pParent);                                 
-       PictFormatPtr   pDstFormat = compWindowFormat (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);
-    }
     return pPixmap;
 }

This patch works like a charm. All of the FGLRX resizing/maximizing bugs disappear. Not only that, but things like clicking on the K menu are suddenly a lot faster… KDE4 doesn’t seem laggy and now has the performance I’ve expected all along. The effects look great, and my transparent terminal is a delight.

There is, however, a bit of garbage that shows up occasionally, and perhaps there’s a good use for the code that was removed in the patch. Why is it only FGLRX that benefits from removing this code? I don’t know much about XOrg internals, but I’m guessing it has to do with some sort of sometimes-required allocation that causes a readback in the FGLRX driver but not in other drivers. What’s the deal? Is fixing this problem as simple as committing this patch and then fixing the garbage error? Or is the code that was removed necessary, and really the problem lays with FGLRX? What to do at this point?

September 7, 2009 · [Print]

18 Comments to “Fast Compositing with KDE4 and FGLRX”

  1. Alex says:

    I suspect the root cause is in FGLRX. Judging by the patch you posted, it seems that the sole purpose of the removed code is to prevent the garbage you mentioned. So, the cause of the performance problems is probably an improper implementation of the CopyArea or CompositePicture (or perhaps CreatePicture) operation in FGLRX.

  2. Simon Edwards says:

    This is the hated “back fill” problem that affects FGLRX. It has been discussed on Phoronix a few times. for example this thread:

    http://www.phoronix.com/forums/showthread.php?p=90703

    There are also packages floating around for various distributions. For example:

    http://k3mist.com/linux/ati-proprietary-fglrx-minimizemaximize-fix-for-jaunty-904/

  3. Peter says:

    With this :

    http://aur.archlinux.org/packages.php?ID=26687

    the fglrx users on Archlinux seem to be OK with the resizing (it’s not an already built package, it’s a PKGBUILD + patches. PKGBUILD’s on Archlinux are like .spec files on Redhat/Fedora)

    But, it’s not Xorg server’s problem. Since ALL the other drivers don’t have a problem with that, but only fglrx, it is fglrx’s problem.

  4. Beat Wolf says:

    Whoever is at fault, i hope you can pinpoint to the exact problem, perhaps by reading line by line of the patch. Because currently X performance is one of the biggest linux problems, and nobody really seems to do anything.
    so even though i don’t have a ati card i wish you good luck :-)

  5. aroedl says:

    This blog post changed my life! Ever since I’m using KDE4, I quit resizing windows, because it was soooo slow. This patch makes all the difference. Thanks!

  6. aroedl says:

    By the way: the CPU load of X went down from about 40 per cent to 5-10 per cent.

  7. Damnshock says:

    Are you all sure it does *not* work for other drivers? I’m here running on an intel gm945 and the resize performance is horribly slow…

    Has anyone tried it?

  8. TooTea says:

    Hey, but this isn’t anything new under the sun! The “no backfill” patch (exactly the one you’re talking about) has been with us for ages (it was also included in stock Ubuntu Xorg, IIRC), e.g. here http://cvs.fedoraproject.org/viewvc/rpms/xorg-x11-server/F-9/xserver-1.4.99-dont-backfill-bg-none.patch?revision=1.1&view=markup

  9. warnec says:

    Perhaps this can work for nvidia as well? ;) (Just hoping)

    http://forum.kde.org/viewtopic.php?f=111&t=77049

  10. [...] Fast Compositing with KDE4 and FGLRX After a much heated discussion about how to fix the horrible resizing and performance bug with FGLRX and KDE4, no one knew where to start looking. The X team had to do a little digging; the KDE4 team needed to change somethings; the FGLRX warehouse needed to get their shit together and listen to the users… bla bla bla the flame wars raged on, fingers were pointed, and nothing ever got done. [...]

  11. razum2um says:

    “The patch he’s talking about looks like this”

    Ye. I had read that comment, about this (done for ages) in Ubuntu&Arch and couldn’t understand, where’s patch, so wrote it myself.

    BUT when you are using KDE-decorator style like auroae it still “twitches”. Sad.

    (sorry for my English ;)

  12. dummy says:

    Does QT 4.6 solve the Problem??

    Smooth and solid resizing on X11 :
    http://labs.trolltech.com/blogs/2009/06/10/smooth-and-solid-resizing-on-x11

  13. @dummy
    I tried out the binaries on that page, and they did not fix the problem.

  14. Shlomi Fish says:

    Hi!

    Will this work with the radeonhd driver, which is what I am using, too?

    Regards,

    – Shlomi Fish

  15. Timo Schmid says:

    Thanks so much for this trick.
    You just made my day.

  16. Dixan Xhaiden says:

    IS there something similar for “Gnome” ?! :(

  17. [...] internet natrafiłem na dwa wpisy na blogu Geek Ideas. Autor prosi czytelników o pomoc w znalezieniu powodu takiego stanu rzeczy. [...]

Leave a Reply