Fast Remote Desktop on the Raspberry Pi

I love network computing, so I decided to improve it with a slice of Pi.

Given that I’m very familiar with RDP and use it routinely (I’m prone to set up sessions across the Atlantic Ocean to this Linode, where I keep a copy of the Android SDK and a few extra things that I can access from my iPad), I’ve been searching for a way to use it properly on the Raspberry Pi — i.e., speedily and with the minimum amount of hassle.

Raspbian includes rdesktop and a couple of other clients, but they all require X11 — which at this point in time lacks hardware acceleration and is more of a hindrance than help.

However, FreeRDP includes a DirectFB client that is almost completely functional and that is vastly more performant than anything using X11 on the Pi — and considering that RDP updates are essentially highly optimized bitmap transfers, accessing the frame buffer directly is probably faster than trying to run those updates by the GPU.

So even though it would be nice to have accelerated X, it likely won’t be as fast as DirectFB. The only thing that’s likely to be somewhat faster is a fully native OpenGL ES implementation, but I haven’t found one yet (I’d love to be proven wrong on this, though, for the sake of completeness).

Building the client

After digging around a bit, I came up with the following recipe for setting it up using the latest stable tarball as of this writing1:

# note that this assumes that you've already installed 
# build-essential, cmake and things like libssl-dev, 
# libdirectfb-dev, X11 development files, etc.

wget https://github.com/downloads/FreeRDP/FreeRDP/freerdp-1.0.1.tar.gz
tar -zjvf freerdp-1.0.1.tar.gz
cd freerdp-1.0.1/

# you might want to add -DCMAKE_INSTALL_PREFIX=~/freerdp the first time 
# around so binaries and libraries stay in your home dir

# Generate makefiles
cmake -DCMAKE_BUILD_TYPE=Release  -DWITH_FFMPEG=OFF -DWITH_XINERAMA=OFF \
-DWITH_XCURSOR=OFF -DWITH_DIRECTFB=ON

cd client/DirectFB/
make

# optionally
sudo make install

If cmake fails along the way simply apt-get the required libraries. When you’re done, you’ll have a dfreerdp executable that you can invoke with something like:

dfreerdp -g 1920x1080 -f servername

Granting Permissions

However, nothing’s quite that simple. For starters, dfreerdp will need access to a number of system devices (like /dev/fb0), so you’ll have to run it as sudo until you grant access to all required devices2 via udev:

cat /etc/udev/rules.d/99-input.rules
# reboot after changing these
SUBSYSTEM=="input", GROUP="input", MODE="0660"
KERNEL=="tty[0-9]*", GROUP="root", MODE="0666"
KERNEL=="mice", MODE="0666"
KERNEL=="fb0", OWNER="root", MODE="0660"

And even then, you’d better make triply sure that all your graphics settings are correct - the Raspberry Pi lacks default directfbrc and complete fb.modes files, so there’s plenty more to do:

Massaging the Frame Buffer

First, begin by making sure /boot/config.txt sets the framebuffer size properly (here’s my settings — I prefer 16 bit mode since it’s more responsive, and set the hardware depth accordingly to minimize overhead):

framebuffer_width=1920
framebuffer_height=1080
framebuffer_depth=16
# for other stuff
gpu_mem=128

Then you have to make sure that /etc/fb.modes lists valid modes for your monitor (I’m using a 1920x1080 LCD panel, and tend to work in TV-equivalent resolutions):

# 50 Hz
mode "1280x720-50"
   # D: 61.80 MHz, H: 37.50 kHz, V: 50.00 Hz
   geometry 1280 720 1280 720 32
   timings 16181 218 110 20 5 40 5
endmode

# 60 Hz 
mode "1280x720-60"
   # D: 74.25 MHz, H: 45.00 kHz, V: 60.00 Hz
   geometry 1280 720 1280 720 16
   timings 13468 220 110 20 5 40 5
endmode

mode "1920x1080-24p"
   geometry 1920 1080 1920 1080 32
   timings 13468 148 638 36 4 44 5
endmode

And, finally, you need to set /etc/directfbrc to:

system=fbdev
autoflip-window
desktop-buffer-mode=auto
vt-switching
graphics-vt
no-deinit-check
no-motion-compression
no-translucent-windows
memcpy=arm
mode=1920x1080
depth=16
dma
hardware
# for the moment, we need DirectFB's own cursor sprite
cursor

You can learn more about these settings by reading the man page, if you’re so inclined.

Running it

Some experimentation may be in order (especially regarding keymaps, that bane of every remote user), but I think you’ll find this to be speedier and pleasanter than other remote desktop solutions for the Raspberry Pi — I’m using it against a native xrdp server, and it’s good enough to scroll a full-screen web browser without hassle (and much, much faster than anything you could possibly run locally on the Pi).

As usual, lowering your resolution will make a very significant difference — I find 1280x720 to be almost as good as sitting at my server console, but prefer 1920x1080 for researching and coding.

Right now the only (minor) hassle I’ve come across is the lack of dynamic cursors in the DirectFB client, but I’m hoping the FreeRDP folk will eventually get around to it.


  1. Judging from the Github repo, there were a few recent changes that add a bunch of dependencies — none of which we actually need for running the DirectFB client. Still, you might want to check out the build instructions just the same. 

  2. Note that the pi user is already a member of the video group — so if you’re using another username, make sure you sudo usermod -a -G video username to add yourself to it.