What controls which OpenGL version is used

I reinstalled ubuntu from scratch (now on 24.04 dev). On Ubuntu 23.10, my application showed OpenGL version 4.6 (nvidia latest driver, glxinfo show the same). Now my application now shows 3.2.(which is not enough for geometry shaders, apparently). I tried gtk_gl_area_set_required_version but that made sure nothing works. Is there a way for me to control how GL is initiated when using GTK4?
Or, is there a way to enable GL extension?

The GL driver controls the version of GL that GTK gets. GTK always asks for the maximum supported version, and at least OpenGL 3.2.

But the driver supports 4.6, which it reports to other applications, why do I get 3.2? The NVIDIA drivers used to return 4.6 before the upgrade. But what you are saying is that this is somehow in the hands of the driver and I should look for some setup there?

You probably also upgraded GTK and the rest of the OS, not just the driver; you could try restoring an older version of the driver, nonetheless, to eliminate one option.

In any case, yes: the driver is the thing that decides which version of the GL context is getting reported. Some drivers always return the latest versions; others require an explicit version; others return the minimum version. If selecting the version with GtkGLArea does not work, feel free to open an issue; specify the version of GTK and of the nVidia driver you are using; and attach a minimal, self-contained example that exhibits the bug.

I realized now that the glGetString (GL_VERSION) call returned not the GL version, it returned:

OpenGL version OpenGL ES 3.2 NVIDIA 535.161.07

I changed the driver just to check. Sorry for the confusion, but I am still confused why I get the ES and not the full version. Guess it’s not the driver version but something else.

Right, that’s GTK4’s latest renderer asking for OpenGL ES, and that one stops at 3.2.

If you want to use OpenGL then you need:

The GL context is quite a rabbit hole. I tried to go down that path by connecting the create context signal (because the docs say one what to do all that before realize) but I never could get anything to work. Too many unknowns.
Is there a description somewhere I could try to follow?

This is years old code that I am looking into, but I now see that I had set

<property name="use-es">False</property>
and now I also added:
<property name="allowed-apis">1</property>

use-es property obviously had no effect (maybe it had before when it used to work).
allowed-apis does have an affect. The application won’t create a context at all.
Otherwise, setting the property seemed to be a simple solution but instead, it prevents
the context to be created entirely.

That must mean that my driver actually does not offer a full OpenGL context (which I think
it actually does). Has this behavior been changed recently? Like in a point release?

code that I’ve tried some time ago and it worked with GTK+OpenGL looks like (in init part):

GtkWidget *plot = gtk_gl_area_new();
g_return_val_if_fail(GTK_IS_GL_AREA(plot), NULL);
g_signal_connect(plot, "realize",   G_CALLBACK(init_plot), &res);
g_signal_connect(plot, "unrealize", G_CALLBACK(free_plot), &res);
g_signal_connect(plot, "render",    G_CALLBACK(draw_plot), &res);

static void init_plot(GtkGLArea *area, gpointer data) {
  if (!GTK_IS_GL_AREA(area)) return;
  if (gtk_gl_area_get_error(area)) return;

static void free_plot(GtkGLArea *area, gpointer data) {

static gboolean draw_plot(GtkGLArea *area, GdkGLContext *context, gpointer data) {
  if (!GTK_IS_GL_AREA(area) || !GDK_IS_GL_CONTEXT(context)) return false;

It has worked with 4.6 (Core Profile) Mesa. The only specific thing that I remember it’s necessary ‘epoxy’ bindings for GTK in my case.

I have all that. I have over 5000 lines of OpenGL specific code that no longer works on Linux/Ubuntu due to the upgrade and I don’t understand why I no longer can use the GL-4 core profile. It still works in windows but debugging sucks on that platform (and I don’t have the tools I wrote to be able to use ASAN) which is why I have to figure this out on Linux. Used to work and I don’t know why.
Anyway, thanks for the epoxy reference. I somehow lived with the glew library which appears not to be necessary. However, the problem remains. glxinfo | grep -i version gives me:

OpenGL core profile version string: 4.6.0 NVIDIA 545.29.06
OpenGL core profile shading language version string: 4.60 NVIDIA
OpenGL version string: 4.6.0 NVIDIA 545.29.06
OpenGL shading language version string: 4.60 NVIDIA
OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 545.29.06
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20
    GL_EXT_shader_group_vote, GL_EXT_shader_implicit_conversions,

I’ve been working on Ubuntu23.10 with GL4, the last time when I saw Ubuntu24.04 it was too beta to be used. Supposedly 24.04+GTK+GL will be ready at time when 24.04 is officially released.

p.s. for curiosity’s sake: made tests with the latest tagged GTK (4.14.1) by switching GL<->GLES back and forth, it works. And yes, it looks like default is changed from GL to GLES if they’re both present.

Thank you for the info. As I wrote earlier, I cannot even select the GL profile.
I obviously made a mistake thinking that 24.04 was close to a usable state. Will have to wait till May until I try to develop on Linux again. Today, there was a 643 package update today (and not the first one during the last week) with 82 packages that could not be upgraded due to inconsistencies (and that all in a fresh install I did a few days ago). I guess I needed that lesson. How Canonical are supposed to make a LTS form this in 25 days is beyond my imagination.
I tried to compile GTK4 from source but could not install the required -dev packages due to package inconsistencies. Been on Unix since 83 and linux since 95. This is probably the worst year in terms of user experience (I guess relative to expectations).

I cannot even select the GL profile.

is the second bit on for the allowed API in your case? If on, try to toggle to off

// #if GTK_CHECK_VERSION(4, 12, 0)
#define GL_API_SETGET(area, api) if (GTK_IS_GL_AREA(area)) { \
  g_print("< GL API: %d\n", gtk_gl_area_get_allowed_apis(area)); \
  gtk_gl_area_set_allowed_apis(area, api); \
  g_print("> GL API: %d\n", gtk_gl_area_get_allowed_apis(area)); \
// #endif
  GtkWidget *area = gtk_gl_area_new();
  g_return_val_if_fail(GTK_IS_GL_AREA(area), NULL);
  g_signal_connect(area, "realize",   G_CALLBACK(init_plot), &data);
  g_signal_connect(area, "unrealize", G_CALLBACK(free_plot), &data);
  g_signal_connect(area, "render",    G_CALLBACK(draw_plot), &data);

This often an issue I have with the docs, how to interpret:

property allowed-apis: Gdk.GLAPI [ read, write ]

What I usually do is to find the values for that particular enum and in the xml file use those. Probably not the way to go about it, but in my .ui file I have,

<property name="allowed-apis">1</property>
based on

  GDK_GL_API_GL   = 1 << 0,

And with this setting I cannot even get a OpenGL context at all. If I set allowed-apis to 2, then I (obviously) get the ES profile which I have no use for.

in the xml file

no idea how it works with xml in a declarative way, with std api it works in my case, you could check it out

FWIW, I donwgraded to 23.10 which includes gtk-4.12 and the driver is nvidia-535 and here it works. My application returns

Shading language version 4.60 NVIDIA
OpenGL version 4.6.0 NVIDIA 535.161.07

and combinations of the lines below work as one would expect.

<property name="use-es">0</property>
<property name="allowed-apis">1</property>

gtk-4.14 smells fishy to me but I am obviously not 100% sure. It is possible that when I (eventually) upgrade to 4.14 things continue to work but I cannot do that atm.

The above code I’ve tried on Ubuntu23.10 with compiled GTK-4.14.1 (GLIB-2.80.0) and GL-4.6 core profile, can say that std api works. Only difference that I spotted: 4.12 has GL default, 4.14 goes with GLES default.

Btw, have you tested that combination of XML settings works on GTK-4.12? (for example by switching to GLES from default GL).

Yes, I did play around but good that you asked.
When I set either (or both) of:
<property name="use-es">1</property>
<property name="allowed-apis">2</property>

gtk_gl_area_make_current will result in gtk_gl_area_get_error returning true and so now, instead, it looks as if I cannot get ES even if I wanted to (which I don’t but it’s interesting still). And all this with the same code that could not get OpenGL 4.6 before the downgrade (from 4.14).

it looks as if I cannot get ES even if I wanted to.
all this with the same code that could not get OpenGL 4.6 before the downgrade.

What does gtk_gl_area_get_allowed_apis() return in your case? (for GTK-4.12 and later). And you can still test gtk_gl_area_set_allowed_apis().