Monday, September 22, 2014

Using EGL with GTK+

I recently needed to port some code from GTK+ OpenGL code from GLX to EGL and I couldn't find any examples of how to do this. So to seed the Internet here is what I found out.

This is the simplest example I could make to show how to do this. In real life you probably want to do a lot more error checking. This will only work with X11; for other systems you will need to use equivalent methods in gdk/gdkwayland.h etc. For anything modern you should probably use OpenGL ES instead of OpenGL - to do this you'll need to change the attributes to eglChooseConfig and use EGL_OPENGL_ES_API in eglBindAPI.

Compile with:
gcc -g -Wall egl.c -o egl `pkg-config --cflags --libs gtk+-3.0 gdk-x11-3.0` -lEGL -lGL

#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <EGL/egl.h>
#include <GL/gl.h>

static EGLDisplay *egl_display;
static EGLSurface *egl_surface;
static EGLContext *egl_context;

static void realize_cb (GtkWidget *widget)
    EGLConfig egl_config;
    EGLint n_config;
    EGLint attributes[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
                            EGL_NONE };

    egl_display = eglGetDisplay ((EGLNativeDisplayType) gdk_x11_display_get_xdisplay (gtk_widget_get_display (widget)));
    eglInitialize (egl_display, NULL, NULL);
    eglChooseConfig (egl_display, attributes, &egl_config, 1, &n_config);
    eglBindAPI (EGL_OPENGL_API);
    egl_surface = eglCreateWindowSurface (egl_display, egl_config, gdk_x11_window_get_xid (gtk_widget_get_window (widget)), NULL);
    egl_context = eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, NULL);

static gboolean draw_cb (GtkWidget *widget)
    eglMakeCurrent (egl_display, egl_surface, egl_surface, egl_context);

    glViewport (0, 0, gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget));

    glClearColor (0, 0, 0, 1);

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho (0, 100, 0, 100, 0, 1);

    glBegin (GL_TRIANGLES);
    glColor3f (1, 0, 0);
    glVertex2f (50, 10);
    glColor3f (0, 1, 0);
    glVertex2f (90, 90);
    glColor3f (0, 0, 1);
    glVertex2f (10, 90);
    glEnd ();

    eglSwapBuffers (egl_display, egl_surface);

    return TRUE;

int main (int argc, char **argv)
    GtkWidget *w;

    gtk_init (&argc, &argv);

    w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_double_buffered (GTK_WIDGET (w), FALSE);
    g_signal_connect (G_OBJECT (w), "realize", G_CALLBACK (realize_cb), NULL);
    g_signal_connect (G_OBJECT (w), "draw", G_CALLBACK (draw_cb), NULL);

    gtk_widget_show (w);

    gtk_main ();

    return 0;

Thursday, June 19, 2014

GTK+ applications in Unity 8 (Mir)

Ryan Lortie and I have been tinkering away with making getting GTK+ applications to run in Unity 8 and as you can see below it works!

This shows me running the Unity 8 preview session. Simple Scan shows up as an option and can be launched and perform a scan.

This is only a first start, and there's still lots of work to be done. In particular:

  • Applications need to set X-Ubuntu-Touch=true in their .desktop files to show in Unity 8.
  • Application icons from the gnome theme do not show (bug).
  • GTK+ applications don't go fullscreen (bug).
  • No cursors changes (bug).
  • We only support single window applications because we can't place/focus the subwindows yet (bug). We're currently faking menus and tooltips by drawing them onto the same surface.

If you are using Ubuntu 14.10 you can install the packages for this from a PPA:

$ sudo apt-add-repository ppa:ubuntu-desktop/gtk-mir
$ sudo apt-get update
$ sudo apt-get upgrade

The PPA contains a version of GTK+ with Mir support, fixes for libraries that assume you are running in X and a few select applications patched so they show in Unity 8.

The Mir backend currently on the wip/mir branch in the GTK+ git repository. We will keep developing it there until it is complete enough to propose into GTK+ master. We have updated jhbuild to support Mir so we can easily build and test this backend going forward.

Friday, May 09, 2014

One of the most useful tools I use is This shows statistics for the crash reports that are sent from users machines. Before I would trawl through Launchpad trying to work out which crash reports were more significant. Now we have numbers to see what's important.

Here is a graph showing the crash reports received for the last six releases over the last year:
Some interesting things from the graph:

  • We get more crash reports on weekdays than weekends (see the ripple in the 12.04 and 12.10 lines which otherwise seem quite stable).
  • Apparently people stop using Ubuntu development releases around Christmas (huge dip in the middle of the Ubuntu 14.04 line). Stable releases are unaffected.
  • You can see a step in crash reports for the 14.04 beta release (March). Looks like there was an outage then too as every release has a dip in reports before.
  • It looks like as soon as 14.04 was released (April) there's been a rapid migration from 13.10 users to 14.04 so there is now probably less than half the number of 13.10 users there were before.
  • If you look closely you can also see a slight decrease in crash reports from 12.04 after the 14.04 release, so people are migrating LTS to LTS.
  • I guess the 12.10 users love it because they don't seem to have started migrating at all.
  • We get a huge number of crash reports from release days and these very smoothly drop off over approximately three months. I guess this is due to the bugs being fixed and the users slowly updating.
  • Sorry, I don't get the vertical axis any more than you do other than to say "bigger means more crash reports" (bug). The X axis also show months from 2013/2014 (bug).
  • Not sure why the left hand side is so high - have we really reduced crash reports that much?

Sunday, March 23, 2014

Why the display server doesn't matter

Display servers are the component in the display stack that seems to hog a lot of the limelight. I think this is a bit of a mistake, as it's actually probably the least important component, at least to a user.

In the modern display stack there are five main components:
  • Hardware
  • Driver
  • Display Server / Shell
  • Toolkit / Platform API
  • Applications
The hardware we have no control over. We just get to pick which hardware to buy. The driver we have more control over - drivers range from completely closed source to fully open source. There's a tug of war between the hardware manufacturers who are used to being closed (like their hardware) and the open source community which wants to be able to modify / fix the drivers.

For (too) many years we've lived with the X display server in the open source world. But now we are moving into next generation display servers (as Apple and Microsoft did many years ago). At the moment there are two new classes of contender for X replacement, Mir and a set of Wayland based compositors (e.g. weston, mutter-wayland etc).

Applications use toolkits and platform APIs to access graphical functionality. There are plenty of toolkits out there (e.g. GTK+, Qt) and existing libraries are growing more broad, consistent and stable to be considered as a complete platform API (which is great for developers).

If you read the Internet you would think the most important part in this new world is the display server. But actually it's just a detail that doesn't matter that much.
  • Applications access the display server via a toolkit. All the successful toolkits support multiple backends because there's more than one OS out there today. In general you can take a GTK+ application and run it in Windows and everything just works.
  • The hardware and drivers are becoming more and more generic. Video cards used to have very specialised functionality and OpenGL used to provide only a fixed function function. Now video cards are basically massively parallel processors (see OpenCL) and OpenGL is a means of passing shaders and buffer contents.
The result of this is the display server doesn't matter much to applications because we have pretty good toolkits that already hide all this information from us. And it doesn't matter much to drivers as they're providing much the same operations to anything that uses them (i.e. buffer management and passing shaders around).

So what does matter now?
  • It does matter that we have open drivers. Because there will be different things exercising them we need to be able to fix drivers when display server B hits a bug but A doesn't. We saw this working with Mir on Android drivers. Since these drivers are only normally used by SurfaceFlinger there are odd bugs if you do things differently. Filing a bug report is no substitute to being able to read and fix the driver yourself.
  • The shell matters a lot more. We're moving on from the WIMP paradigm. We have multiple form factors now. The shell expresses what an application can do and different shells are likely to vary in what they allow.
I hope I've given some insight into the complex world of display stacks and shown we have plenty of room for innovation in the middle without causing major problems to the bits that matter to users. 

Tuesday, March 12, 2013

Ubuntu GNOME

Thanks to the hard work of Jeremy Bicha and others Ubuntu GNOME is now an official Ubuntu flavour. Flavours get some infrastructure and support benefits such as ISO creation that make it easier to release and support.

More information on Mir

With the recent announcement of Mir there's been some concern about what this means for Ubuntu and the wider Linux ecosystem. Christopher Halse Rogers who is on the Mir team has written some excellent posts covering some of the major questions: why Mir and not Wayland/Weston, what does this mean for other desktops on Ubuntu and what does this mean for Linux graphics drivers.

Well worth the read.

Tuesday, March 05, 2013


Today we go public with the Ubuntu graphics stack for the post X world. Since the beginning Ubuntu has relied on the X server to support the user experience and while it has worked generally well; it’s time for something new. My team is working on a big new component for this - Mir. Mir is a graphics technology that allows us to implement user experience we want for Ubuntu across all devices we support.

In many ways, Mir will be completely transparent to the user. Applications that use toolkits (e.g. Qt, GTK+) will not need to be recompiled. Unity will still look like Unity. We will support legacy X applications for the foreseeable future.

This is a big task. A lot of work has already been done and there’s a lot more to go. We’re aiming to do incremental improvements, and you can find more about this on the Wiki page and in the blueprints. You can help. From today our project is public, it’s GPL licensed and you’re welcome to use the source and propose changes.

It’s exciting times, and I hope you enjoy the results of this work!

Thursday, January 10, 2013

Vala support for Protocol Buffers

Recently I was playing around with Protocol Buffers, a data interchange format from Google. In the past I have spent quite a bit of time working with ASN.1 which is a similar format that has been around for many years. Protocol buffers seem to me to be a nice distillation of the useful parts of efficient data interchange and a welcome relief to the enormous size of the ASN.1 specifications.

With Vala being my favourite super-productive language I felt the need to add support to it. Solution: protobuf-vala.

Let's see it in action. Say you have the following protocol in rating.proto:

message Rating {
  required string thing = 1;
  required uint32 n_stars = 2 [default = 3];
  optional string comment = 3;

Run it through the protocol buffer compiler with:

$ protoc rating.proto --vala_out=.

This will create a Vala file rating.pb.vala with a class like this:

public class Rating

  string thing;
  uint32 n_stars;
  string comment;

You can use this class to encode a rating, e.g. for storing to a file or sending over a network protocol:

var rating = new Rating ();
rating.thing = "Vala";
rating.comment = "Vala is super awesome!";
rating.n_stars = 5;
var buffer = new Protobuf.EncodeBuffer ();
rating.encode (buffer);
do_something_with_data (;

And decode it:

var data = get_data_from_somewhere ();
var buffer = new Protobuf.DecodeBuffer (data);
var rating = new Rating ();
rating.decode (buffer);
stderr.printf ("%s is %d stars\n", rating.thing, rating.n_stars);

That's pretty much it!

If you're using Ubuntu (12.04 LTS, 12.10 or 13.04) then you can install Vala protocol buffer support with:

$ sudo apt-add-repository ppa:protobuf-vala-team/ppa
$ sudo apt-get update
$ sudo apt-get install protobuf-compiler-vala libprotobuf-vala-dev

Have fun!