Commit Graph

83 Commits

Author SHA1 Message Date
Benjamin Otte
41cd0c6f13 gl: Fix initial EGL context creation on X11
After commit 447bc18c48 EGL on X11 broke.

But the handling of the GL context also was quite awkward because it was
unclear who was responsible for ensuring it got reset.

Change that by making gdk_gl_context_clear_current_if_surface() return
the context (with a reference because it might be the last reference) it
had unset, so that after changing EGL properties the code that caused
the clearing can re-make it current.

This moves the responsibility to the actual code that is dealing with
updating properties and frees the outer layers of code from that task.

And that means the X11 EGL code doesn't need to care and the code in the
Wayland backend that did care can be removed.

Related: !7662
Fixes: #6964 on X11
2024-08-29 01:31:47 +02:00
Benjamin Otte
523cd0dff7 glcontext: Add a surface_attached flag
GLContexts marked as surface_attached are always attached to the surface
in make_current().
Other contexts continue to only get attached to their surface between
begin_frame() and end_frame().

All our renderer use surface-attached contexts now.
Public API only gives out non-surface-attached contexts.

The benefit here is that we can now choose whenever we want to
call make_current() because it will not cause a re-make_current() if we
call it outside vs inside the begin/end_frame() region.

Or in other words: I want to call make_current() before begin_frame()
without a performance penalty, and now I can.
2024-08-10 01:40:45 +02:00
Benjamin Otte
96b800fa0c gl: Add buffer implementation using persistent mapping
If glBufferStorage() is available, we can replace our usage of
glBufferSubData() with persistently mapped storage via
glMappedBufferRange().

This has 1 disadvantage:

1. It's not supported everywhere, it requires GL 4.4 or
   GL_EXT_buffer_storage. But every GPU of the last 10 years should
   implement it. So we check for it and keep the old code.
   The old code can also be forced via GDK_GL_DISABLE=buffer-storage.

But it has 2 advantages:

1. It is what Vulkan does, so it unifies the two renderers' buffer
   handling.

2. It is a significant performance boost in use cases with large vertex
   buffers. Those are pretty rare, but do happen with lots of text at a
   small font size. An example would be a small font in a maximized VTE
   terminal or the overview in gnome-text-editor.

A custom benchmark tailored for this problem can be created with:

  tests/rendernode-create-tests 1000000 text.node

This creates a node file called "text.node" that draws 1 million text
nodes.
(Creating that test takes a minute or so. A smaller number may be useful
on less powerful hardware than my Intel Tigerlake laptop.)
The difference can then be compared via:

  tools/gtk4-rendernode-tool benchmark --runs=20 text.node
and
  GDK_GL_DISABLE=buffer-storage tools/gtk4-rendernode-tool benchmark --runs=20 text.node

For my laptop, the difference is:
before: 1.1s
after:  0.8s

Related: !7021
2024-03-16 20:55:26 +01:00
Benjamin Otte
f725bdad25 gl: Move GL_ARB_base_instance check
It's a GLContext feature check, not a GpuRenderer thing.

So put it there.
2024-03-16 13:52:28 +01:00
Benjamin Otte
4e453acd4f gl: Remove the BGRA feature
Nobody is using it anymore now that we have format tracking for all
formats.
2024-03-16 13:44:02 +01:00
Benjamin Otte
141769fb46 gl: Turn has_foo flags into GdkGLFeatures
The goal is to have it mirror GdkVulkanFeatures, and in particular
having an environment variable to turn individual flags off.
2024-03-16 13:44:02 +01:00
Matthias Clasen
6e8a70ada1 Drop gdk_gl_context_has_bgra
This private api turned out to be more problematic than useful,
and it isn't used anymore.
2024-01-21 08:29:33 -05:00
Benjamin Otte
5485d806c5 glcontext: Add gdk_gl_context_get_memory_flags()
Checks which features of a given memory format are supported by
the current GL implementation.

We check:
 * usable: Can be used as a texture with NEAREST filter
 * renderable: Can be used as a render target
 * filterable: Can be used with GL_LINEAR

In normal GL, all formats are all of these things, but GLES is a lot
more picky.

So far nobody uses this.
2023-12-11 07:33:26 +01:00
Benjamin Otte
cd7e1c1387 dmabuf: Modify gdk_gl_context_import_dmabuf()
Move a bunch of code - namely the target selection - into the function.

I want to use the same code in the NGL renderer, so no need to duplicate
it.
2023-11-07 05:12:57 +01:00
Matthias Clasen
6e236b9459 Revert "gl context: Check for more GL extensions"
This reverts commit b8b5835fc6.
2023-10-29 14:44:46 -04:00
Matthias Clasen
8fb0ab2b43 gl context: Add private dmabuf API
Add API to import a dmabuf into a texture,
and to export a texture to a dmabuf.

All this is implemented using the relevant
EGL and GL extensions.
2023-10-22 16:39:24 -04:00
Matthias Clasen
b8b5835fc6 gl context: Check for more GL extensions
These will be used in future commits.
2023-10-22 16:39:24 -04:00
Matthias Clasen
b8ffceaebb glcontext: Add api to check for vertex arrays
Vertex arrays are available in GL and in GLES >= 3.

We don't check for the GLES extension that provided
vertex arrays in older GLES, since that requires
using different API.

This api avoids version checks all over the place.
2023-10-19 22:43:13 -04:00
Matthias Clasen
d55fa0dfef glcontext: Check for GL_EXT_texture_format_BGRA8888
Check for this GLES extension and add a private getter.
2023-10-19 13:55:18 -04:00
Benjamin Otte
e720008dca glcontext: Add gdk_gl_context_get_glsl_version_string()
This is in preparation for the new renderer.
2023-09-26 11:08:59 +02:00
Benjamin Otte
46e3454eb7 gl: Update tracked buffers from 2 to 4
With XWayland and direct scanout it is possible that some apps get into
a situation where more than 2 buffers are in flight and in that case we
want to be able to still track the change regions for those buffers.

Usually 3 buffers are in use, so we go one higher, just to be safe.
2023-05-24 21:44:43 +02:00
Benjamin Otte
7573a9d2a7 gl: Rewrite update area tracking code
Make it more generic. That way we could dynamically change the number of
buffers we track.

We don't do that yet though.
2023-05-24 21:44:29 +02:00
Matthias Clasen
5071e6154c glcontext: Add a way to check for GLsync 2023-04-27 06:54:49 +02:00
Benjamin Otte
5f833f1d31 glcontext: Compute matching version the simple way
Do it all in one function instead of requiring two different ones.
2023-04-27 02:13:32 +02:00
Benjamin Otte
34662fc4b0 egl: Make sure highest possible GL version is created
The EGL spec states:

    The context returned must be the specified version, or a later
    version which is backwards compatible with that version.
    Even if a later version is returned, the specified version
    must correspond to a defined version of the client API.

GTK has so far been relying on EGL implementations returning a
later version, because that is what Mesa does.
But ANGLE does not do that and only provides the minimum version, which
means Windows EGL has been forced to use a lower EGL version for no
reason.

So fix this and try versions in order from highest to lowest.
2023-04-27 02:13:32 +02:00
Benjamin Otte
3aefed39b1 glcontext: Use GdkGLVersion elsewhere
... and add a convenience API to generate GL versions from strings to
make the gdk_gl_context_check() API nicer.
2023-04-27 02:13:32 +02:00
Benjamin Otte
f86429177a gdk: Introduce GdkGLVersion
... and use it.

Makes the code simpler.
2023-04-27 02:13:32 +02:00
Marc-André Lureau
d69cdf6c05 gdk: drop libangle GLES minimum version
GLES 2.0 version is fine now with current gtk according to B. Otte.
Let's use the same minimum requirement for all implementations.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-17 04:50:17 +00:00
Marc-André Lureau
3cb2115212 gdk: drop unused vertex_array_object
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-04-17 04:50:17 +00:00
Matthias Clasen
4746ffc4eb Make fractional scaling for GL opt-in
Fractional scaling with the GL renderer is
experimental for now, so we disable it unless
GDK_DEBUG=gl-fractional is set.

This will give us time to work out the kinks.
2023-04-02 11:05:57 -04:00
Matthias Clasen
a1c5a806b3 Convert headers to #pragma once
The conversion was done by guard2one.
2023-03-31 15:11:10 -04:00
Benjamin Otte
c6cef6db52 gdk: Add private GLContext::is_current() check
... and use this check in gdk_gl_context_make_current() and
gdk_gl_context_get_current() to make sure the context really is still
current.

The context no longer being current can happen when external GL
implementations make their own contexts current in the same threads GDK
contexts are used in.
And that can happen for example by WebKit.

Theoretically, this should also allow external EGL code to run in X11
applications when GDK chooses to use GLX, but I didn't try it.

Fixes #5392
2023-02-02 04:23:51 +01:00
Benjamin Otte
45422f7b61 Merge branch 'gl-api-es-fix' into 'main'
glcontext: Respect ES API when getting gl version from shared context

Closes #4763

See merge request GNOME/gtk!4687
2022-06-04 20:26:58 +00:00
Pablo Correa Gómez
549a2b4c86
glcontext: Refactor realize function, fix interaction with shared context 2022-06-04 20:48:40 +02:00
Pablo Correa Gómez
8d175801d7
glcontext: Add internal get_clipped_version function
It is useful for backends to get user set preferences while
ensuring the correctness of the result, which will be always
greater or equal than the minimum version provided
2022-06-04 20:48:40 +02:00
Matthias Clasen
158963ff77 gdk: Check OES_vertex_half_float GLES extension
This will be checked in the GL renderer.
2022-05-05 13:21:25 -04:00
Christian Hergert
f9268e8137 gsk/gl: support non-standard default framebuffer
There are situations where our "default framebuffer" is not actually
zero, yet we still want to apply a scissor rect.

Generally, 0 is the default framebuffer. But on platforms where we need
to bind a platform-specific feature to a GL_FRAMEBUFFER, we might have a
default that is not 0. For example, on macOS we bind an IOSurfaceRef to
a GL_TEXTURE_RECTANGLE which then is assigned as the backing store for a
framebuffer. This is different than using gsk_gl_renderer_render_texture()
in that we don't want to incur an extra copy to the destination surface
nor do we even have a way to pass a texture_id into render_texture().
2022-02-22 12:01:24 -08:00
Benjamin Otte
2caab68be9 gl: Change gdk_gl_context_check_version()
Instead of just passing major/minor, pass them twice, once for GL and
once for GLES. This way, we don't need to check for GL and GLES
separately.

If something is supported unconditionally, passing 0/0 works fine.

That said, I'd like to group the arguments somehow, because otherwise
it's just a confusing list of numbers - but I have no idea how to do
that.
2021-12-25 15:07:44 +01:00
Benjamin Otte
c419799313 gl: Clear current when destroying current's surface
When destroying the EGLSurface or GLXDrawable of a GdkSurface, make sure
the current context is not still bound to it.

If it is, clear the current context.

Fixes #4554
2021-12-22 20:00:52 +01:00
Benjamin Otte
2601c39cb2 API: Add gdk_display_create_gl_context()
This is an alternative to gdk_surface_create_gl_context() when the
context is meant to only draw to textures.

This is useful in the testsuite or in GStreamer or with GLArea,
basically whenever we want to do GL stuff but don't need to actually
draw anything on screen.

A bunch of code will need to be updated to deal with context->surface
being NULL.
2021-10-20 20:31:33 +02:00
Benjamin Otte
7a50ebaa3f gdk: Move GdkMemoryFormat enum to gdktypes.h
It's used in too many places now.
2021-10-16 15:49:37 +02:00
Benjamin Otte
5199bebdb5 gl: Move texture uploading to the renderer
It does not belong in GdkGLContext, it's a renderer thing.
It's also the only user of that API.

Introduce gdk_gl_context_check_version() private API to make version
checks simpler.
2021-10-13 14:33:44 +02:00
Benjamin Otte
f584d4f500 gl: Check allowed APIs in realize()
Add gdk_gl_context_is_api_allowed() for backends and make them use it.

Finally, have them return the final API as the return value (or 0 on
error).

And then use that api instead of a use_es boolean flag.

Fixes #4221
2021-10-08 03:31:07 +02:00
Benjamin Otte
2ff1ea555f egl: Unify contexts
Unify the X11 and Wayland EGL contexts.

This is a bit ugly to implement, because I don't want to create an
interface and I can't make them inherit from the same object, because
one needs to inherit from X11GLContext and the other from
WaylandGLContext.

So we have to put the code in GdkGLContext and make sure non-EGL
contexts can't accidentally run it. This is rather easy because we can
just check for priv->egl_context != NULL.
2021-10-06 03:44:36 +02:00
Benjamin Otte
03cc603093 glcontext: Remove unused functionality
The recent changes made and unused function removals make these features
unused.
2021-10-06 03:44:36 +02:00
Benjamin Otte
64f10eff20 gdk: Remove unused gdk_gl_texture_quads() function
That function carried a lot of baggage.
2021-10-06 03:44:36 +02:00
Benjamin Otte
23acc993cc gdk: Make sure only one GL backend is used
Creative people managed to create an X11 display and a Wayland display
at once, thereby getting EGL and GLX involved in a fight to the death
over the ownership of the glFoo() symbolspace.

A way to force such a fight with available tools here is (on Wayland)
running something like:
GTK_INSPECTOR_DISPLAY=:1 GTK_DEBUG=interactive gtk4-demo

Related: xdg-desktop-portal-gnome#5
2021-09-24 01:59:37 +02:00
Benjamin Otte
e06e0e8555 gdk: Move GL context construction to GdkGLContext
Now that we have the display's context to hook into, we can use it to
construct other GL contexts and don't need a GdkSurface vfunc anymore.

This has the added benefit that backends can have different GdkGLContext
classes on the display and get new GLContexts generated from them, so
we get multiple GL backend support per GDK backend for free.

I originally wanted to make this a vfunc on GdkGLContextClass, but
it turns out all the abckends would just call g_object_new() anyway.
2021-07-22 16:27:32 +02:00
Benjamin Otte
9f1d6e1f44 gl: Move vfunc
Instead of
  Display::make_gl_context_current()
we now have
  GLContext::clear_current()
  GLContext::make_current()

This fits better with the backends (we can actually implement
clearCurrent on macOS now) and makes it easier to implement different GL
backends for backends (like EGL/GLX on X11).

We also pass a surfaceless boolean to make_current() so the calling code
can decide if a surface needs to be bound or not, because the backends
were all doing whatever, which was very counterproductive.
2021-07-22 16:27:32 +02:00
Benjamin Otte
c7320df0c9 gdk: Add gdk_gl_context_is_shared()
... and use it in the GL renderers.
2021-07-22 16:27:31 +02:00
Benjamin Otte
e4f0418003 gdk: Require EGL version 1.4 across the board
Mesa currently ships 1.5.
2021-07-22 16:23:56 +02:00
Christian Hergert
524fbc35a7 gl: remove unused texture_from_surface API
This is not used anywhere and only exists within the X11 backend. It
can be removed now.
2020-10-29 08:26:27 -07:00
Alexander Larsson
1001995d49 Correctly upload textures for GLES
GLES doesn't support the GL_BGRA +  GL_UNSIGNED_INT_24_8 hack that
we use on desktop OpenGL to upload textures directly in the cairo
pixel format. This adds the required conversions to all the places
that currently need it.

We also add a data_format to the internal gdk_gl_context_upload_texture()
function to make it clearer what the format are. Currently it is always
the cairo image surface format, but eventually we want to support other
formats so that we can avoid some of the unnecessary conversions we do.

Also, the current gdk_gl_context_upload_texture() code always converts
to a cairo format and uploads that like we did before. Later commits
will allow this to use other upload formats that gl supports to avoid
conversions.
2020-09-25 09:31:43 +02:00
Matthias Clasen
b3786b7b07 gdk: Slim down gdkinternals.h more
Move things to the private headers they belong in.
2020-08-14 07:45:53 -04:00
Chun-wei Fan
edc1c28236 GdkGLContext: Drop gdk_gl_context_has_[framebuffer_blit|frame_terminator]()
gdk_gl_context_has_framebuffer_blit() and gdk_gl_context_has_frame_terminator()
were only used by by GDK/Win32, and they do not provide performance advantages
in GTK master, so clean up the code a bit by dropping them.
2020-08-05 18:56:57 +08:00