Speed up PyGTK and Cairo by reusing images

As you might have read in this blog, I own a Neo FreeRunner since one year ago. I have used it far less than I should have, mostly because it’s a wonderful toy, but a lousy phone. The hardware is fine, although externally quite a bit less sexy than other smartphones such as the iPhone. The software, however, is not very mature. Being as open as it is, different Linux-centric distros have been developed for it, but I haven’t been able to find one that converts the Neo into an everyday use phone.

But let’s cut the rant, and stick to the issue: that the Neo is a nice playground for a computer geek. Following my desire to play, I installed Debian on it. Next, I decided to make some GUI programs for it, such a screen locker. I found Zedlock, a program written in Python, using GTK+ and Cairo. Basically, Zedlock paints a lock on the screen, and refuses to disappear until you paint a big “Z” on the screen with your finger. Well, that’s what it’s supposed to do, because the 0.1 version available at the Openmoko wiki is not functional. However, with Zedlock I found just what I wanted: a piece of software capable of doing really cool graphical things on the screen of my Neo, while being simple enough for me to understand.

Using Zedlock as a base, I am starting to have real fun programming GUIs, but a problem has quickly arisen: their response is slow. My programs, as all GUIs, draw an image on the screen, and react to tapping in certain places (that is, buttons) by doing things that require that the image on the screen be modified and repainted. This repainting, done as in Zedlock, is too slow. To speed things up, I googled the issue, and found a StackOverflow question that suggested the obvious route: to cache the images. Let’s see how I did it, and how it turned out.

Material

You can download the three Python scripts, plus two sample PNGs, from: http://isilanes.org/pub/blog/pygtk/.

Version 0

You can download this program here. Its main loop follows:

C = Canvas()

# Main window:
C.win = gtk.Window()
C.win.set_default_size(C.width, C.height)

# Drawing area:
C.canvas = gtk.DrawingArea()
C.win.add(C.canvas)
C.canvas.connect('expose_event', C.expose_win)

C.regenerate_base()

# Repeat drawing of bg:
try:
  C.times = int(sys.argv[1])
except:
  C.times = 1

gobject.idle_add(C.regenerate_base)
C.win.show_all()

# Main loop:
gtk.main()

As you can see, it generates a GTK+ window (line 04), with a DrawingArea inside (line 08), and then executes the regenerate_base() function every time the main loop is idle (line 20). Canvas() is a class whose structure is not relevant for the discussion here. It basically holds all variables and relevant functions. The regenerate_base() function follows:

def regenerate_base(self):
    
    # Base Cairo Destination surface:
    self.DestSurf = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.width, self.height)
    self.target   = cairo.Context(self.DestSurf)
  
    # Background:
    if self.bg == 'bg1.png':
      self.bg = 'bg2.png'
    else:
      self.bg = 'bg1.png'

    self.i += 1

    image       = cairo.ImageSurface.create_from_png(self.bg)
    buffer_surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.width, self.height)
    buffer      = cairo.Context(buffer_surf)
    buffer.set_source_surface(image, 0,0)
    buffer.paint()
  
    self.target.set_source_surface(buffer_surf, 0, 0)
    self.target.paint()
  
    # Redraw interface:
    self.win.queue_draw()

    if self.i > self.times:
      sys.exit()

    return True

As you can see, it paints the whole window with a PNG file (lines 15-25), choosing alternately bg1.png and bg2.png each time it is called (lines 07-11). Since the re-painting is done every time the main event loop is idle, it just means that images are painted to screen as fast as possible. After a given amount of re-paintings, the script exits.

You can run the code above by placing two suitable PNGs (480×640 pixels) in the same directory as the above code. If an integer argument is given to the script, it re-paints the window that many times, then exits (default, just once). You can time this script by executing, e.g.:

% /usr/bin/time -f %e ./p0.py 1000

Version 1

You can download this version here.

The first difference with p1.py is that the regenerate_base() function has been separated into the first part (generate_base()), which is executed only once at program startup (see below), and all the rest, which is executed every time the background is changed.

def generate_base(self):

    # Base Cairo Destination surface:
    self.DestSurf = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.width, self.height)
    self.target   = cairo.Context(self.DestSurf)

The main difference, though, is that two new functions are introduced:

  def mk_iface(self):

    if not self.bg in self.buffers:
      self.buffers[self.bg] = self.generate_buffer(self.bg)

    self.target.set_source_surface(self.buffers[self.bg], 0, 0)
    self.target.paint()

  def generate_buffer(self, fn):

    image       = cairo.ImageSurface.create_from_png(fn)
    buffer_surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.width, self.height)
    buffer      = cairo.Context(buffer_surf)
    buffer.set_source_surface(image, 0,0)
    buffer.paint()
  
    # Return buffer surface:
    return buffer_surf

The function mk_iface() is called within regenerate_base(), and draws the background. However, the actual generation of the background image (the Cairo surface) is done in the second function, generate_buffer(), and only happens once per each background (i.e., twice in total), because mk_iface() reuses previously generated (and cached) surfaces.

Version 2

You can download this version here.

The difference with Revision 1 is that I eliminated some apparently redundant procedures for creating surfaces upon surfaces. As a result, the generate_base() function disappears again. I get rid of the DestSurf and C.target variables, so the mk_iface() and expose_win() functions end up as follows:

  def mk_iface(self):

    if not self.bg in self.buffers:
      self.buffers[self.bg] = self.generate_buffer(self.bg)

    buffer = self.canvas.window.cairo_create()
    buffer.set_source_surface(self.buffers[self.bg],0,0)
    buffer.paint()

  def expose_win(self, drawing_area, event):

    nm = 'bg1.png'

    if not nm in self.buffers:
      self.buffers[nm] = self.generate_buffer(nm)

    ctx = drawing_area.window.cairo_create()
    ctx.set_source_surface(self.buffers[nm], 0, 0)
    ctx.paint()

A side effect is that I can get also rid of the forced redraws of self.win.queue_draw().

Results

I have run the three versions above, varying the C.times variable, i.e., making a varying number of reprints. The command used (actually inside a script) would be something like the one mentioned above:

% /usr/bin/time -f %e ./p0.py 1000

The following table sumarizes the results for Flanders and Maude (see my computers), a desktop P4 and my Neo FreeRunner, respectively. All times in seconds.

Flanders
Repaints Version 0 Version 1 Version 2
1 0.26 0.43 0.33
4 0.48 0.40 0.42
16 0.99 0.43 0.40
64 2.77 0.76 0.56
256 9.09 1.75 1.15
1024 37.03 6.26 3.44
Maude
Repaints Version 0 Version 1 Version 2
1 4.17 4.70 5.22
4 8.16 6.35 6.41
16 21.58 14.17 12.28
64 75.14 44.43 35.76
256 288.11 165.58 129.56
512 561.78 336.58 254.73

Data in the tables above has been fitted to a linear equation, of the form t = A + B n, where n is the number of repaints. In that equation, parameter A would represent a startup time, whereas B represents the time taken by each repaint. The linear fits are quite good, and the values for the parameters are given in the following tables (units are milliseconds, and milliseconds/repaint):

Flanders
Parameter Version 0 Version 1 Version 2
A 291 366 366
B 36 6 3
Maude
Parameter Version 0 Version 1 Version 2
A 453 3218 4530
B 1092 648 487

Darn it! I have mixed feelings for the results. In the desktop computer (Flanders), the gains are huge, but hardly noticeable. Cacheing the images (Version 1) makes for a 6x speedup, whereas Version 2 gives another twofold increase in speed (a total of 12x speedup!). However, from a user’s point of view, a 36 ms refresh is just as immediate as a 6 ms refresh.

On the other hand, on the Neo, the gains are less spectacular: the total gain in speed for Version 2 is a mere 2x. Anyway, half-a-second repaints instead of one-second ones are noticeable, so there’s that.

And at least I had fun and learned in the process! :^)

Comments (2)

First impressions with Arch Linux

I have been considering for some time trying some Linux distro that would be a little faster than [[Ubuntu (operating system)|Ubuntu]]. I made the switch from [[Debian]] to Ubuntu some time ago, and I must say that I am very pleased with it, despite it being a bit bloated and slow. Ubuntu is really user-friendly. This term is often despised among geeks, but it does have a huge value. Often times a distro will disguise poor dependency-handling, lack of package tuning and absence of wise defaults as not having “fallen” for user-friendliness and “allowing the user do whatever she feels like”.

However comfortable Ubuntu might be, my inner geek wanted to get his hands a little bit dirtier with configurations, and obtain a more responsive OS in return. And that’s where [[Arch Linux]] fits in. Arch Linux is regarded as one of the fastest Linux distros, at least among the ones based on [[executable|binary]] [[Software package (installation)|packages]], not [[source code]]. Is this fame deserved? Well, in my short experience, it seem to be.

First off, let us clarify what one means with a “faster” Linux distro. There are as I see it, broadly speaking, three things that can be faster or slower in the users’ interaction with a computer. The first one, and very often cited one, is the [[booting|boot]] (and shutdown) time. Any period of time between a user deciding to use the computer and being able to do so is wasted time (from the user’s point of view). Many computers stay on for long periods of time, but for a home user, short booting times are a must. A second speed-related item would be the startup time of applications. Booting would be a sub-section of this, if we consider the OS/[[kernel (computing)|kernel]] as an “app”, but I refer here to user apps such as an e-mail client or text editor. Granted, most start within seconds at most, many below one second or apparently “instantly”, but some others are renowned for their slugginess ([[OpenOffice.org]], [[Firefox]] and [[Amarok (software)|Amarok]] come to mind). Even the not-very-slow apps that take a few seconds can become irritating if used with some frequency. The third speed-related item would be the execution of long-running CPU-intensive software, such as audio/video coding or scientific computation.

Of the three issues mentioned, it should be made clear that the third one (execution of CPU-intensive tasks) is seldom affected at all by the “speed” of the OS. Or it shouldn’t be. Of course having the latest versions of the libraries used by the CPU-intensive software should make a difference, but I doubt that encoding a video with [[MEncoder]] is any faster in [[Gentoo Linux|Gentoo]] than Ubuntu (for the same version of mencoder and libraries). However, the first two (booting and start up of apps) are different from OS to OS.

Booting

I did some timings in Ubuntu and Arch, both in the same (dual boot) machine. I measured the time from [[GRUB]] to [[GNOME Display Manager|GDM]], and then the time from GDM to a working [[desktop environment]] ([[GNOME]] in both). The exact data might not be that meaningful, as some details could be different from one installation to the other (different choice of firewall, or (minimally) different autostarted apps in the DE). But the big numbers are significant: where Ubuntu takes slightly below 1 minute to GDM, and around half a minute to GNOME, Arch takes below 20 seconds and 10 seconds, respectively.

App start up

Of the three applications mentioned, OpenOffice.org and Firefox start faster in Arch than in Ubuntu. I wrote down the numbers, but don’t have them now. Amarok, on the other hand, took equally long to start (some infamous 35 seconds) in both OSs. It is worth mentioning that all of them start up faster the second and successive times, and that the Ubuntu/Arch differences between second starts is correspondingly smaller (because both are fast). Still Arch is a bit faster (except for Amarok).

ABS, or custom compilation

But the benefits of Arch don’t end in a faster boot, or a more responsive desktop (which it has). Arch Linux makes it really easy to compile and install any custom package the user wants, and I decided to take advantage of it. With Debian/Ubuntu, you can download the source code of a package quite easily, but the compilation is more or less left to you, and the installation is different from that of a “official” package. With Arch, generating a package from the source is quite easy, and then installing it with [[Pacman (package manager)|Pacman]] is trivial. For more info, refer to the Arch wiki entry for ABS.

I first compiled MEncoder (inside the mplayer package), and found out that the compiled version made no difference with respect to the stock binary package. I should have known that, because I say so in this very post, don’t I? However, one always thinks that he can compile a package “better”, so I tried it (and failed to get any improvement).

On the other hand, when I recompiled Amarok, I did get a huge boost in speed. A simple custom compilation produced an Amarok that took only 15 seconds to start up, less than half of the vanilla binary distributed with Arch (I measured the 15 seconds even after rebooting, which rules out any “second time is faster” effect).

Is it hard to use?

Leaving the speed issue aside, one of the possible drawbacks of a geekier Linux distro is that it could be harder to use. Arch is, indeed, but not much. A seasoned Linux user should hardly find any difficulty to install and configure Arch. It is certainly not for beginners, but it is not super-hard either.

One of the few gripes I have with it regards the installation of a graphical environment. As it turns out, installing a DE such as GNOME does not trigger the installation of any [[X Window System]], such as [[X.org Server]], as dependencies are set only for really vital things. Well, that’s not too bad, Arch is not assuming I want something until I tell it I do. Fine. Then, when I do install Xorg, the tools for configuring it are a bit lacking. I am so spoiled by the automagic configurations in Ubuntu, where you are presented a full-fledged desktop with almost no decision on your side, that I miss a magic script that will make X “just work”. Anyway, I can live with that. But some thing that made me feel like giving up was that after following all the instruction in the really nice Arch Wiki, I was unable to start X (it would start as a black screen, then freeze, and I could only get out by rebooting the computer). The problem was that I have a [[Nvidia]] graphics card, and I needed the (proprietary) drivers. OK, of course I need them, but the default vesa driver should work as well!! In Ubuntu one can get a lower resolution, non-3D effect, desktop with the default vesa driver. Then the proprietary Nvidia drivers allow for more eye-candy and fanciness. But not in Arch. When I decided to skip the test with vesa, and download the proprietary drivers, the X server started without any problem.

Conclusions

I am quite happy with Arch so far. Yes, one has to work around some rough edges, but it is a nice experience as well, because one learns more than with other too user-friendly distros. I think Arch Linux is a very nice distro that is worth using, and I recommend it to any Linux user willing to learn and “get hands dirty”.

Comments (3)

John maddog Hall and OpenMoko at DebConf9 in Cáceres, Spain

The annual [[Debian]] developers meeting, DebConf is being held this year in Cáceres (Spain), from July 23 to 30. Apart from just promoting the event, I am posting this to mention that the Spanish OpenMoko distributor Tuxbrain will participate, and sell discounted [[Neo FreeRunner]] phones. As a masochistic proud owner of one such phone, I feel compelled to spread the word (and help infect other people with [[FLOSS]] virii).

You can read a post about it in the debconf-announce and debian-devel-announce lists, made by Martin Krafft. Also, Tuxbrain responsible David Samblas uploaded a video of maddog Hall promoting the event:

Comments

LaTeX input in Inkscape 0.46

I use [[Inkscape]] to do many of the drawings for my articles and talks, and have come across an irritating problem: I could not include [[LaTeX]] formulas on it. I have googled a bit about it, and the first match already led me to a bug report, where a comment by Kees Cook gives a fix that I quote below:

% cd /usr/share/inkscape/extensions
% curl -s 'http://launchpadlibrarian.net/12978623/eqtexsvg.py.patch' | sudo patch -p0

The bug affects (and the patch fixes) Inkscape 0.46 on [[Ubuntu]] Hardy Heron and [[Debian]] Lenny (that I know of).

Comments (2)

Linux e-mail clients rant

I am really disappointed at the [[e-mail client|MUA]] offer I am finding for by Debian box. I have tried [[KMail]], [[Mozilla Thunderbird|Thunderbird]], [[Evolution (software)|Evolution]] and [[Claws Mail]], and all of them fail at some point. All four errors are different, and all of them almost total showstoppers.

Note: I access my e-mail through Gmail [[IMAP]]. I don’t really care if these MUAs are good at [[POP3]] or whatever. I want good IMAP.

KMail 1.9.9

The [[GUI]] is nice, has all features I want, everything OK… It’s just that browsing the remote folders is hopelessly slow. I can brush my teeth in the time it takes to delete a message, and I don’t want to go into what I can do in the time it takes to move a message from one folder to another one.

Apparently this could be fixed in KMail2, which will come with KDE4. The problem is that I want it fixed now.

Thunderbird 2.0.0.14

This one is also very good in general. Actually, its problem is not due to itself. Its probably due to some bad interaction with [[X.org]] or something: everything works fine, but starting up and subsequent rendering/deleting of the window itself is really slow. If I minimize and maximize it back, it takes ages to reappear. I have this problem with TB and Firefox (actually Icedove and Iceweasel in Debian), and with no other program.

Evolution 2.22

Again, almost everything is fine. Almost. The single problem is that if the “To” and/or “From” fields in the message list contain non-ASCII characters, they appear garbled. Nowhere else does this happen. Even other fields, such as “Subject” can contain accents or ñ with no problem, as can the text body.

This would be a cosmetic issue I could live with, but there are two problems I can not tolerate: I do not want these errors to appear in the messages I send when replying to garbled messages, and more importantly, I have sometimes had recipient lists containing non-ASCII characters mangled. I don’t want to click “Reply all” and end up sending the message to only 3 of the 10 recipients.

This problem will supposedly be fixed in version 2.23.

Claws-mail 3.4.0

Again and again, almost everthing is right. Now messages can contain non-ASCII chars anywhere, browsing folders is fast, manipulating/drawing/erasing the program window is fast… BUT, replying to a message, regardless of the settings one chooses, does not include the original message quoted. This seems a minor error. It isn’t.

The thing that bugs me most is that I can not understand how these problems happen with [[free software]] packages. If you take KMail, Evolution and Claws, each one has a single error that the other two have already fixed… Couldn’t they just copy each other? That is precisely the whole point of free software.

Couldn’t KMail browse/scan/manipulate the IMAP folders with the efficient method Evolution and/or Claws use?

Couldn’t Evolution display the message fields with the error-free method KMail and Claws use?

Couldn’t Claws quote the original message as anyone else in the Universe does?

If only the three errors where not spread among the three MUAs, there would be one that I could use!

Comments (14)

Flash: better without Flash

Remember my previous post about a problem with Flash in Firefox/Iceweasel? Now the second part.

After following my own instructions, I ended up with a Flash instalation that could play YouTube videos correctly, but some other Flash animations would not work. By chance, my computer at work would reproduce any Flash animation just fine, so… why would that be?

To find out the reason, I have compared what Flash-related packages I have installed in Homer (my computer at work) and Heracles (the one at home). The result is quite surprising:

Homer[~]: aptitude search flash
p   flashplayer-mozilla       - Macromedia Flash Player
p   flashrom                  - Universal flash programming utility
p   flashybrid                - automates use of a flash disk as the root filesystem
p   libflash-dev              - GPL Flash (SWF) Library - development files
p   libflash-mozplugin        - GPL Flash (SWF) Library - Mozilla-compatible plugin
p   libflash-swfplayer        - GPL Flash (SWF) Library - stand-alone player
p   libflash0c2               - GPL Flash (SWF) Library - shared library
p   libroxen-flash2           - Flash2 module for the Roxen Challenger web server
p   m16c-flash                - Flash programmer for Renesas M16C and R8C microcontrollers
p   vrflash                   - tool to flash kernels and romdisks to Agenda VR
Homer[~]: aptitude search swf
p   libflash-swfplayer        - GPL Flash (SWF) Library - stand-alone player
p   libswf-perl               - Ming (SWF) module for Perl
p   libswfdec-0.5-4           - SWF (Macromedia Flash) decoder library
p   libswfdec-0.5-4-dbg       - SWF (Macromedia Flash) decoder library
p   libswfdec-0.5-dev         - SWF (Macromedia Flash) decoder library
v   libswfdec-dev             -
p   pyvnc2swf                 - screen recording tool to SWF movie
v   swf-player                -
p   swfdec-mozilla            - Mozilla plugin for SWF files (Macromedia Flash)
p   swfmill                   - xml2swf and swf2xml processor

Yes, Flash works perfectly at Homer because it has no package installed with swf or flash in their name! And I don’t have any Gnash package installed, either. I removed all swf/flash-related packages on Heracles, and now Flash works perfectly in my home computer too.

Comments (11)

Flash player problem in Debian Lenny: “This SWF file is known to trigger bugs in the swfdec decoder.”

[Update: read a more recent post]

I have recently come accross this problem, and I am posting the solution I just found. The problem is the following: when trying to watch any online flash animation with Iceweasel on my Debian Lenny (e.g. in YouTube), instead of the video, I got a grey window, with the following black letters on it:

This SWF file is known to trigger bugs in the swfdec decoder. Playback is cancelled.

This bug can be followed in this August 2007 thread at donarmstrong.com. I am amazed why it didn’t affect me sooner than this week, but oh well…

The steps that fixed the issue for me where to install two packages. I am not 100% sure the first one was needed, though. I first installed the package flashplayer-mozilla, which uninstalled flashplugin-nonfree as a side effect. This step alone fixed nothing.

The second step was to actually read the donarmstrong.com bug report, and see that it says that “This is fixed in swfdec-0.4.2 […]”. Great! I did a aptitude search swf, and found out that Lenny has libswfdec-0.5-4, and a swfdec-mozilla that depends on it. I installed the latter, which obviously also installed the former, plus it removed swf-player and libswfdec0.3.

After that, I opened Iceweasel again, and now flash works!

Comments (2)

Compiz Fusion on an integrated Intel 865G graphics chip under Debian Lenny

This YouTube video shows Compiz Fusion running on my work computer. It has a fairly decent CPU (P4 3.00GHz), but no “useless” things like sound cards or (more relevant for this issue) graphics card. The only thing it has is an Intel 82865G graphics chip integrated in the motherboard. We are talking about an integrated chip (not dedicated graphics card) released in May 2003.

Judge the performance for yourself (take into account that the actual performance is higher, since the recording program to make the video also uses up some resources):

Comments (7)

Compiz Fusion under Debian Lenny on my home desktop

I recently wrote (actually, my last post, 12 days ago), a howto of sorts with my experience installing Compiz Fusion on my laptop. Yesterday I came back from my vacations, and repeated the feat with my destop computer at home.

The setup is quite different:

CPU: AMD Athlon 2800+
Graphics: nVidia FX 5700 (256MB)

And the effort is also quite different: it took me much less! Partially, this was because of my previous exprerience, but mainly the reason is that the graphics card here is nVidia. Yes, let the world know that ATI cards suck on Linux.

The problem is that ATI cards need XGL to have Compiz running, but nVidia cards make use of AIGLX natively, so the installation has only two steps: (1) installing the nVidia driver, and (2) installing the Compiz Fusion packages.

Installing the latest nVidia driver

As with the ATI card in my laptop, I decided to use the proprietary drivers from the nVidia site. The choice-making interface is so similar, actually, to that of ATI. I had to go Graphics Driver->GeForce FX series->Linux x86->Go!, and download this installer.

BIG WARNING: before actually installing anything, remove a previous installation of the nVidia drivers, if you installed them “the Debian way”. For that, do:

% aptitude purge nvidia-glx

I have a friend who did not do so and… Ok, ok, it happened to me. If you do not do the above, everything seems to work fine, but everytime you reboot the X server will crash, and you might get incredibly annoyed by that.

To perform the installation, simply run, as root:

% sh path-to-file/NVIDIA-Linux-x86-100.14.11-pkg1.run

Then, just modify your xorg.conf file to contain the following:

Section "ServerLayout"
  Identifier     "Default Layout"
  Screen       "Default Screen" 0 0
  InputDevice    "Generic Keyboard"
  InputDevice    "Configured Mouse"
  Option         "AIGLX" "true"
EndSection

...

Section "Extensions"
  Option         "RENDER" "true"
  Option         "Composite" "Enable"
  Option         "DAMAGE" "true"
EndSection

Installing Compiz Fusion packages

The procedure is exactly the same covered in my previous post. In short:

1) Add the Shame repository to your /etc/apt/sources.list:

deb http://download.tuxfamily.org/shames/debian-sid/desktopfx/unstable/ ./

2) Get the signature for the repo:

% gpg --keyserver pgpkeys.mit.edu --recv-key 11F6E468
% gpg -a --export 11F6E468

3) Update and install:

% aptitude update
% aptitude install compiz-fusion-all --a

Any time you want to run Compiz, just execute:

% compiz --replace -c emerald

Shorter than the ATI thing, uh?

Comments

Compiz Fusion under Debian Lenny on my laptop

I have a previous post with what I’ve done to my laptop, and in that post it’s not mentioned, but I managed (quite a while ago) to make Beryl work under Ubuntu Dapper Drake. Dapper is getting older, but I am not having good experiences installing Edgy and Feisty on the laptop. I have managed to install Debian Etch with no problem, but the wireless driver was not working properly (for me, a showstopper) until Lenny.

So now I have a Debian Lenny partition, plus three other: the original WinXP, the Ubuntu Dapper I am still using as “main” OS, and a Fedora 7 I installed just because it came in a DVD with a magazine I bought for a train trip I had not brought any reading material with me :^)

Since I am on vacation, and I have plenty of time (although I don’t want to spend all of it on my comp), I decided to give Compiz Fusion a try, mostly after seeing what it its capable of.

First things first, the specs of my laptop are:

Fujitsu-Siemes Amilo PI1536
CPU: Intel Core 2 Duo T7200 2×2.0GHz
RAM: 2x1Gb
HD: 120Gb SATA
Display: 15.4 WXGA
Graphics: ATI Mobility Radeon X1400 (128Mb dedicated/512Mb shared)

The only relevant parts above are that it has an ATI graphics card (which, under Linux, sucks), and that it has Core 2 CPUs, which are amd64-capable (which is both great, for performance, and sucks, for drivers and software compatibilities). So, my second step was:

Installation of ATI drivers

If you want to take the best out of your ATI card, you have to tell your X.org graphics server to use the fglrx driver, and not the default vesa one. You can install this driver from the official Debian repositories, but for me those packages (fglrx-driver and related ones) didn’t do it.

So, I googled a bit, and followed the most widespread recommendation: to install the latest non-free (sigh) driver from the ATI site. For that, I chose the options: Linux x86_64 -> Mobility Radeon -> Mobility Radeon X1400 -> Go, reaching this page, and downloading this 38MB binary (for the record, the 32bit version of the drivers is exactly the same .run file).

Next, I followed the remaining information in this excelent thread in linuxquestions.org. Namely, I downloaded the needed packages (the code is copy-paste-able):

% aptitude install module-assistant build-essential dh-make debhelper debconf libstdc++5 linux-headers-$(uname -r) ia32-libs

Beware that the ia32-libs packages is not mentioned in the linuxquestions.org thread (assuming that you already have it installed), but it is required.

Next, run the ATI binary inside a dedicated directory (I did it as root, but it is not compulsory):

% mkdir /root/fglrx
% cd /root/fglrx
% mv wherever-I-downloaded-it/ati-driver-installer-8.32.5-x86.x86_64.run .
% chmod +x ati-driver-installer-8.32.5-x86.x86_64.run
% ./ati-driver-installer-8.32.5-x86.x86_64.run --buildpkg Debian/lenny
% rm or mv the .run file wherever you want

This generates a bunch of .debs in the /root/fglrx dir. Next, install them, and compile the driver (for this, you do need to be root):

% dpkg -i fglrx-*.deb
% cd /usr/src
% m-a prepare
% m-a a-i fglrx

The linuxquestion.org thread mentions modifying the /etc/X11/xorg.conf file in two ways. First, disable compositing, adding:

Section "Extensions"
Option "Composite" "Disable"
EndSection

to it, and then running:

% aticonfig --initial
% aticonfig --overlay-type=Xv

For me, both were superfluous, because I made a copy of my Ubuntu xorg.conf, and them made minimal changes (if at all). However, the first change (disabling compositing) was straightforward wrong. If I want to use Compiz Fusion, I need to have it. Relevant excerpts from my xorg.conf:

Section "Module"
  Load  "i2c"
  Load  "bitmap"
  Load  "ddc"
  Load  "dri"
  Load  "extmod"
  Load  "freetype"
  Load  "glx"
  Load  "int10"
  Load  "type1"
  Load  "vbe"
EndSection

...

Section "Device"
  Identifier  "aticonfig-Device[0]"
  Driver      "fglrx"
  Option      "VideoOverlay" "on"
  Option      "OpenGLOverlay" "off"
EndSection

...

Section "Screen"
  Identifier "aticonfig-Screen[0]"
  Device     "aticonfig-Device[0]"
  Monitor    "aticonfig-Monitor[0]"
  DefaultDepth     24
  SubSection "Display"
    Viewport   0 0
    Depth     24
    Modes    "1280x800" "800x600" "640x480"
  EndSubSection
EndSection

...

Section "DRI"
  Mode         0666
EndSection

Section "Extensions"
  Option "Composite" "1"
EndSection

After all this fuss, and to ensure you have it all running OK, try to insert the module as root:

% modprobe fglrx

Then, make sure it loads everytime you reboot (include it in /etc/modules if necessary, but it shouldn’t be).

Next, reload the X server, and check that now it is running the fglrx driver, by doing the following (as user is fine):

% fglrxinfo

It should display something like the following:

display: :0.0 screen: 0
OpenGL vendor string: ATI Technologies Inc.
OpenGL renderer string: ATI Mobility Radeon X1400
OpenGL version string: 2.0.6650 (8.39.4)

If, instead, it says something about mesa3d, it didn’t work.

Now, the second step is…

Installing Xgl

With the standard X.org server we have a problem. We can load the fglrx driver, but we can not activate compositing (see last three lines of my xorg.conf file above). If we activate compositing in the xorg.conf file, the ATI driver will not be loaded (don’t ask me why, it just seems to happen). If we deactivate compositing, the ATI driver gets loaded, but without compositing, we can not use Compiz.

The solution is to install Xgl which is an X server (or, I think, a kind of layer that runs on top of the X.org server) that allows for the above trick. There seem to be two “ways” of getting proper compositing: Xgl and AIGLX. The general agreement on the net seems to be that the latter is “better”, but only the former seems to work with ATI cards (read the “AIGLX with AMD (ex-ATI) Proprietary Drivers” section in the AIGLX Wikipedia article, because it hits the problem dead-on). With Xgl I can make use of the fglrx driver and have compositing at the same time.

We are lucky here, because there are Debian repositories for Xgl. I found out about them in this howto in tuxmachines.org. Most of the info there is mostly… ehem… useless (for me), but reading it I found a repo for Xgl. I just have to add the following line to my /etc/apt/sources.list (beware that the original mention in the tuxmachines.org page says “binary-i386”, and I had to change it to “binary-amd64”):

deb http://www5.autistici.org/debian-xgl/debian/ binary-amd64/

I then had to do aptitude update, and I (of course) got an error telling me that some signatures couldn’t be verified (read my own article about secure APT and/or the wonderful Debian wiki to know more). I think the key is 11F6E468, and it corresponds to Francesco Cecconi (mantainer of the repo). It is downloadable from pgpkeys.mit.edu (follow instructions on my previous post, or the ones in the Debian wiki). If you want, do not skip reading the parent page of the repository.

After the keys are OK, it’s just a matter of doing (as root):

% aptitude update
% aptitude install xgl

Now you are done installing, but will have to actually use Xgl. This gave me some headaches, not because I didn’t know where to put things, but because I didn’t know exactly what to put. I read, and followed, the instructions in freedesktop.org, and (after all, the blog seems to be useful for someone: myself) a previous post of my own.

I am using GDM, so my final setup was the following: first generate a suitable entry in the GDM menu, by creating a file named /usr/share/xsessions/xfce4-xgl.desktop (or whatever, but in the same dir, and ending in “.desktop”), and putting the following inside:

[Desktop Entry]
Encoding=UTF-8
Name=Xfce-Xgl
Exec=/usr/local/bin/startxgl_xfce
Icon=Type=Application

The string after “Name=” is the one that will appear in the GDM menu, and the one after “Exec=” what will be executed when selecting that entry.

Next, we have to create the string we promise above (/usr/local/bin/startxgl_xfce), and put the following inside:

# Start the Xgl server:
Xgl -fullscreen :0 -ac -accel glx:pbuffer -accel xv:pbuffer -fp /usr/share/X11/fonts/misc & sleep 5 && DISPLAY=:0
# Start Xfce:
exec xfce4-session

As you can see, I am telling Xgl to load a font (with -fp) that was giving me headaches, because the server would die saying that the font was missing when I didn’t include that option. Your mileage may vary.

Now, everytime we select the entry labeled “Xfce-Xgl” in the GDM menu, we will have the Xgl server running.

Installing Compiz Fusion packages

I think the aforementioned autistici.org repo has compiz packages, as well as the default Debian Lenny repos. But net consensus seems to be that they are not the way to go. Everyone praises two repositories: Treviño’s and Shame’s. I chose the latter, adding the following line to my /etc/apt/sources.list:

deb http://download.tuxfamily.org/shames/debian-sid/desktopfx/unstable/ ./

I think I went through the same chores as above for key verification, Shame’s key being A42A6CF5.

After that, I installed the following package (it installs all of the needed packages):

% aptitude install compiz-fusion-all

After that, and inside my “Xfce-Xgl” session, I just did the following, as some googling revealed:

% compiz --replace

But… it didn’t work :^( It complained in the following manner:

Fatal: Failed test: texture_from_pixmap support
Checks indicate that it's impossible to start compiz on your system.

I found a lot of pages, threads and howtos in the net stumbling upon this same problem (for example, this one at ubuntuforums.org), but none with the answer. Really. None. The most enlightening tips where the use of the -v, -h and --help switches for compiz. The first one requests verbose output, the second one help about “short” options, and the third one help about the “long” options. With the latter I discovered the --force-fglrx switch, which saved the day! Yes, I now use the following command to start Compiz:

% compiz --replace -c emerald --force-fglrx

I have two things to say at that point. First: this Compiz Fusion is visually astonishing! It is full of great ideas, and has a lot of settings to play with. The second thing is not so nice: some glitches are present. For example, my Konsole windows get transparent background for no reason, and the refresh is horrible (when text reaches the bottom on the terminal, it starts to overwrite itself. One must hide and un-hide the window for proper refreshing, which is unacceptable). The latter also affects other windows, which, all in all, makes it unsuitable for much comfort.

However, Compiz Fusion is new, hot and experimental. I love playing with it, but right now it can not be relied upon. On the bright side, in the three days from my installation, the packages have been updated three times! I suppose some aptitude upgrade cycles will fix the issues eventually.

And that’s it, dear reader.

Comments (6)

« Previous entries Next Page » Next Page »