Tuesday, February 19, 2013

How to program DirectFB in C# on Raspberry PI (and other embedded devices / SoCs)

Raspberry PI is a very popular and extremely affordable ARM based computer. Among other things, it runs several flavors of Linux, including Debian (called Raspbian in R-Pi world.) Lots of interest in R-Pi world revolves around its graphics and how to unleash its power the easy way (which is not necessarily the right one.) For example, this post  raises an interesting question - how to access kernel's framebuffer via DirectFB in C# (mono.) I've been studying DirectFB for a few days now, and even though C is my language of choice, I have some experience in C#, so I decided to accept the challenge. Here is what I did:

1. Install mono runtime and c sharp compiler
apt-get install mono-runtime mono-mcs

2. Install directfb package for development
apt-get install libdirectfb-dev

3. Build and run directfb example drawing a single line. This is needed to test that DirectFB works properly on Raspberry PI. I copied the sample code into the line.c file, then compiled as follows.
Note that in order to run this successfully, your account needs to have read/write rights to the /dev/fb0 device (userspace interface to the kernel's framebuffer.) Alternatively, you can drop to the root shell.
If everything's fine, you should see a horizontal line on  a black background.    

4. Now it's time to try the same in C#. The obvious option is P/Invoke. If I were to develop a C# library for DirectFB, I would (have to) replicate all DirectFB structures in C# code. This is however an overkill for a proof of concept, so here I am cutting corners. It's not the best approach, but definitely the fast one. So I create another shared library in C that wraps the needed set of DirectFB API calls and exposes them to the C# world in a much simpler way. These calls accept no parameters and return void, eliminating the need to replicate numerous DirectFB structures in C#. The corresponding files are dfbwrap.h and dfbwrap.c:


dfbwrap.c (compare this to the DirectFB line sample - they are almost identical)

The line below compiles and links it into libdfbwrap.so which we will use in our C# app:

5. Create and build C# app. I put my C# code into the client.cs:

This is a build command:

6. Finally, run the result (don't forget about proper access for your account to /dev/fb0 or drop to root shell)

If everything's fine, you'll see a square with red, green, blue, and white sides for 3 seconds.

DirectFB API has functions to draw a lot more primitives and also to render text which you can access the same way.