According to EXT_color_buffer_half_float it should be renderable, but it
fails to glGenerateMipmap() with Mesa 23.3 so just pretend it's not
renderable until that is fixed.
Fixes CI from failing.
I naively assumed the EXT_color_buffer_float and
EXT_color_buffer_half_float extensions would mirror each other, but they
do not. The float extension explicitly excludes RGB32F from the
renderable formats.
Doing this in a way that is picked up by gobject-introspection
requires splitting off new enum members into separate doc
comments, which is a bit unfortunate.
Some dmabuf formats were added in Vulkan 1.3.
Note that this does not require the Vulkan drivers to be version 1.3 -
it just means compilation against libvulkan 1.3
This makes no sense by itself, but we want to create the EGLImage at
DmabufTexture construction so that we can actually reject dmabufs that
we can't create EGLImages for.
This will make it possible to bail when the stride limitation for AMD
GPUs hits.
Instead of having an add_formats() function, make the get_downloader()
function add the formats.
This allows putting the actual downloader in a different place from the
initialization code.
This is done without testing, just doing my best to map all the DRM
formats to VkFormats.
Once people start using them, they'll figure it out when it's wrong.
(Somebody needs to write a testsuite.)
When we use the builtin downloads via mmap(), it's a special case where
we don't need to initialize subsystems and query them for support. We
know what we can and can't do.
Also, we want to use these formats with the lowest priority but pick the
downloader first for supported formats, and queueing it in the
downloaders list doesn't reflect that. So don't do it.
Track fallback formats to use in the memoryformat directly instead of
using in the GL uploading code.
First of all, this allows sharing the code and ensuring all our
renderers use the same fallback mechanism.
But also, this allows tracking fallbacks per-format which is useful
because the fallback formats aren't really a tree. We want to make
FLOAT16 fall back to FLOAT32 when not available, but we also want
FLOAT32 fall back to FLOAT16.
By tracking the fallbacks per-format, we can achieve that.
Add gdk_memory_format_get_premultiplied() and
gdk_memory_format_get_straight() which return the matching
premultiplied/straight format.
Use this to pick the premultiplied format when uploading GL textures.
And remove the duplication in the dmabuf code, where we can now use
these functions instead of tracking both the premultiplied and straight
alpha versions.
Add an "RGBA" format that just maps to the swizzled version of the
default format.
This way, BGR gets mapped to RGB + swizzling first before trying to map
it to the default format for the depth.
The benefit here is that this format has the same memory width, so
uploading/downloading code can treat it equivalent to the original
format and there's no conversion neccessary later.
Now that we have gdk_gl_context_get_memory_flags() and code can use that
function, make the code do that.
Remove support checks from gdk_memory_format_gl_format().
This is an initial naive port that doesn't try to make use of the finer-grained
flags yet.
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.
If a subsurface is not below, it is visible no matter what the opaque
region is.
Also, we don't need to care about transparency in the subsurface if we
ignore it anyway. So this is a win-win.
We accept transparent subsurfaces for passthrough now, when they are
above the surface.
But we did not unset the opaque region to empty when the texture is
transprent.
That way, we can work with older libdrm versions.
The list was generated via a bit of sed and grep from the current
dmabuf-fourcc.h, which is why I put it into its own file and included
all the formats, no matter how old they are.
Add the matching GdkMemoryFormat for all dmabuf formats.
This way, we don't fall back to RGBA8 for 10- and 16-bit formats that we
don't support natively when EGL or Vulkan use them.
Also includes corrections for a few mixups.
Make this event behave like the other regular events, and emit
coordinates based on native surfaces. Fixes DnD over popovers
finding the correct coordinates.
This function takes an event, so the place(s) that do
not have one readily available can only pass NULL, so
the serial lookup will only work for the pointer.
Pass a device (plus optional sequence) to this function,
as these places do at least have the corresponding
GdkDevice at hand.
Fixes serial lookups for DnD, for other devices than
pointers (e.g. tablets, or touch).
Sadly, subsurface positioning is undefined in this case. We'll
trust the compositor to not mess up if the device coordinates
after applying the scale are integral, but otherwise, we'll
decline.
Instead, do it all in attach(), which becomes more and more like
ConfigureWindow. This is good, because it will let us take the
above-ness into account when making decisions about attaching.
There was one branch in the success case that turned it into a failure,
yet we were still reporting a success (and discarding the buffer).
Don't do that.
With the advent of dmabuf support, using GLES has become more
attractive, since we can use its external texture support to
support more dmabuf formats.
You can go back to the previous preference order by setting
GDK_DEBUG=gl-prefer-gl
The default keymap and keymap layouts are calculated on request.
If done once a surface is setup and listening at win32 events,
we may then enter in a recursive loop.
To avoid this, precalculate the keymap as soon as displays are open.
Fixes#6203Closes#6203
Add api to allow creating subsurfaces, attaching textures to them,
and changing the stacking order.
This is just the api, there is no implementation yet.
This is a backport of !1143 to gtk4.
SetClipboardViewer() API is obsolete is prone to clipboard chain breaks
from other applications.
Use recommended AddClipboardFormatListener() instead.
Fixes#442
Make sure all our dmabuf debug messages are display-scoped so the
inspector doesn't trigger them, use the same formatting throughout,
and improve consistency of wording here and there.
Getting this wrong matters, since we won't offload textures in
non-opaque formats. Found by Robert Mader. At the same time,
unify the two places we have for mapping from fourcc to memory
format.
It started out as busywork, but it does many separate things. If I could
start over, I'd take them apart into multiple commits:
1. Remove G_ENABLE_DEBUG around GDK_DEBUG_*() calls
This is not needed at all, the calls themselves take care of it.
2. Remove G_ENABLE_DEBUG around profiling code
This now enables profiling support in release builds.
3. Stop poking _gdk_debug_flags and use GDK_DEBUG_CHECK()
This was old code that was never updated.
4. Make !G_ENABLE_DEBUG turn off GDK_DEBUG_CHECK()
The code used to
#define GDK_DEBUG_CHECK(...) false
#define GDK_DEBUG(...)
which would compile away all the code inside those macros. This
means a lot of variable definitions and debug utility functions
would suddenly no longer be used and cause compiler errors.
Remove all the roadblocks we've put up to keep implicit modifiers
out. Our importing code already handles them as a signal that says
'No modifiers, please!'. Now we just hope for the best and pass
things along.
This is necessary since some drivers won't produce any explicit
modifiers.
We were confusingly printing "supported format" for dmabuf formats
that we end up not adding to our list of supported formats. Don't
do that, it is confusing. At the same time, we shuold print out
the linear formats we support via mmap.
Add an implementation of GdkDmabufDownloader that uses
gsk_renderer_render_texture + GL texture download.
Since gsk isn't threadsafe, we do the download in the main thread,
taking care to not disturb the current GL context of whatever is
going on there at the time.
And since gsk renderers are expensive to create, we cache it
in the display.
Note that gsk does not yet have any special support for
dmabuf textures, so for now, they will always get downloaded
and then reuploaded as GL textures.
Trying to use it is a programming error, applications should have code
that uses real modifiers.
Also add a check to the formatsbuilder so our code doesn't include the
invalid modifier by accident.
We don't really know how to deal with it, so better force applications
to figure out what to do.
When adding the formats of a downloader, allow them to return FALSE to
mean "This method is not supported", which is a useful way to opt out
when checking GL or Vulkan extensions and finding out that the desired
one isn't supported.
This seems to be what everyone does, so we should do it, too.
Previously it was assumed that an fd of -1 would mean reusing the
previous fd with a different offset, but that seems to be uncommon.
We did have 4 ordering variations of ARGB straight,
but only 3 premultiplied. Add the missing one.
Update all the places where we switch over memory formats.
1. Split out the download function from the mmap'ing of the plane(s)
2. Make the code mmap() all the planes
3. Determine size using lseek() as documented by libdrm, instead of
trying to guess it from the format.
4. Fix some bugs, like switcheroos of width and height
Tries to sanitize the dmabuf to conform to the values expected
by Vulkan/EGL which should also be the values expected by
Wayland compositors
We put these sanitized values into the GdkDmabufTexture, by
sanitizing the input from GdkDmabufTextureBuilder, which are
controlled by the callers.
Things we do here:
1. Disallow any dmabuf format that we do not know.
1. Treat the INVALID modifier the same as LINEAR.
2. Ignore all other modifiers.
3. Try and fix various inconsistencies between V4L and Mesa,
like NV12.
*** WARNING ***
This function is not absolutely perfect, you do not have a
perfect dmabuf afterwards.
In particular, it doesn't check sizes.
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.
Make gdk_memory_format_gl_format take the GdkGLContext,
instead of just a gles boolean. This will let us
check for extensions that may be needed for certain
formats.
Update all callers.
We always have a display - the default display - so there's no need to
accept NULL.
Plus, we need a display when building the texture, so accepthing NULL
wouldn't even make sense.
Includes update to defaultvalue test.
We are returning interned strings here, and
g-i seems to have trouble interpreting the const,
so lets help it out by being more explicit with
our annotations.
Fixes: #6167
GdkDmabuf is a struct encapsulating all the values of a dmabuf, so
nothing to see here.
GdkDmabufDownloader is a vtable for a thing that can download dmabufs.
For now only one implementation exists, so this just looks like a ton
of work for no benefit.
The only neat thing is that gdkdmabuftexture.c got a whole lot tidier.
Add a new debug flag for dmabuf-related information,
and use it in gdkdmabuftexture.c.
This will let us separate out dmabuf debug spew from
opengl debug spew.
These are the dmabuf formats that we can import
into a GL context as an EGLImage, and successfully
download.
We skip the GdkDisplay:dmabuf-formats property
in the default value tests, since the nominal
default value is NULL, but the actual value is
constructed on demand.
Add an implementation of GdkDmabufTexture.
For now, this implementation is rather minimal,
since we need a roundtrip through GL to convert
most nottrivial formats.
Add a builder for a new GdkTexture subclass that
wraps dmabuf buffers on Linux. For now, this is
just an API. The implementation will follow in
subsequent commits.
The C standard does not specify whether the underlying type of an enum
is signed or unsigned, and until C23 there was no way to control this
explicitly. GCC appears to make enums unsigned unless there is a
negative value among cases of the enum, in which case it becomes signed.
MSCV appears to make enums signed by default.
A bitfield of an enum type (which is not specificied in the C standard
either) behaves as if it was an instance of a numeric type with a
reduced value range. Specifically, a 'signed int val : 2;' bitfield will
have the possible values of -2, -1, 0, and 1, with the usual wraparound
behavior for the values that don't fit (although this too is
implementation-defined).
This causes the following issue, if we have:
typedef enum
{
GTK_ZERO,
GTK_ONE,
GTK_TWO
} GtkFoo;
struct _GtkBar
{
GtkFoo foo : 2;
};
and then assign bar.foo = GTK_TWO and read it back, it will have the
expected value of 2 (aka GTK_TWO) on GCC, but a value of -2 (not
matching any of the enum variants) on MSVC.
There does not seem to be any way to influence signedness of an enum
prior to C23, nor is there a 'unsigned GtkFoo foo : 2;' syntax. The only
remaining options seems to be never using enums in bitfields, which is
what this change implements.
In practice, this fixes GdkPipeIOStream crashing with an assertion when
trying to copy-paste in-app in MSVC builds on GTK.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Using "1 << x" means that we are shifting a signed 32bit integer, but we
want a gsize, which is an unsigned 64bit integer.
So now we don't overflow anymore if the array reaches a size of 2GB.
Gdk-Win32 uses GetClientRect() internally to query the surfaces coordinates,
but this API may fail in some transient contexts (observed when iconifying
a maximized window).
Check if the rect area is null, and don't update the surface position in
that case. This will keep the current surface size, until Win32 notifies
the new valid window state later.
This prevents using a nulled next_layout for toplevel size computation,
which would break widgets allocation once notified on gtk side.
Fixes#5724Closes#5724
At the moment of launching/activating an application, the
keyboard focus may be on a transient surface that quickly
disappears after activation. If this happens, and the
compositor handles surface destruction before the activated
application gets to reply, the activation request may be
deemed outdated, and the "demands attention" paths be taken.
Peek the toplevel from the focus surface, as that has larger
guarantees to remain valid for the whole duration of the
operation.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5820
We need to inist on the nonuniform access beuing available and that
requires Vulkan 1.2.
Also simplifies the descriptor indexing stuff, because that's all part
of Vulkan 1.2, too.
This function is deprecated, but we should still document it properly.
It appends, not prepends. This is clear enough from its implementation,
but also we have practical experience with WebKit in:
https://github.com/WebKit/WebKit/pull/8663
Matthias prefers to avoid the prepend, append, start, and end
terminology altogether.
Texture downloads can be initiated due to the weirdest reasons - and if
they cause a GL context to be changed, it'd be basically unpredictable
when the GL context changes.
An example is the Cairo renderer - if it needs to draw a GL texture, it
will download it.
Now that no longer changes the GL context.
The protocol spec isn't clear about the relationship
between the capability enum and the uint in the capability
event.
Fix things to use the same relationship as mutter.
This is implemented using a new xdg_toplevel `suspended` state, and is
meant for allowing applications to know when they can stop doing
unnecessary work and thus save power.
In the other backends, the `suspended` state is set at the same time as
`minimized` as it's the closest there is to traditional windowing
systems.
The relevant question here is about details, because we have to choose
if we declare alpha-only formats as having their (nonexistant) color
channels premultiplied or not, so that the code paths using them can do
the right thing.
Because we are premultiplied by default, it makes sense to treat alpha
like that, because then the alpha-only code doesn't need to do
workarounds for straight alpha.
Where this is relevant of course is when expanding the alpha channel
into color channels, where we want to end up with white.
So make sure we do color = alpha there instead of color = 1 like we did
before.
We need them for mask-only textures.
For tiffs, we convert the formats to RGBA (the idea that tiff can save
everything needs to be buried I guess) as tiffs can't do alpha-only.
Basically, memcpy() asap if possible.
This happens a lot in Vulkan, where we gdk_memory_conert() image
data from memory textures straight into the VulkanBuffer.
And usually we support the format.
Have a resource path => vkShaderModule hash table instead of doing fancy
custom objects.
A benefit is that shader modules are now shared between all renderers
and pipelines.
Wait for device to be idle because this function is also called in
window resizes.
And if we destroy old swapchain it also destroy the old VkImages,
those images could be in use by a vulkan render.
This fixes a issue reported in Mesa repository when running
GTK with Xe KMD.
Fixes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9044
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
This mapping of stylus evdev input event codes into GDK button numbers
makes gdk/wayland inconsistent with gdk/x11, so depending on the backend
the same button middle-click pastes or right-click pops up menus.
Make the wayland backend consistent with X11, so that a GNOME wayland
session gets these buttons consistently mapped across all kinds of
clients.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5935
Make the display handle the cache, because we only need one.
We store the cache in
$CACHE_DIR/gtk-4.0/vulkan-pipeline-cache/$UUID.$VERSION
so we regenerate caches for each different device (different UUID) and
each different driver version.
We also keep track of the etag of the cache file, so if 2 different
applications update the cache, we can detect that.
Vulkan allows merging caches, so the 2nd app reloads the new cache file
and merges it into its cache before saving.
It's necessary now that we use storage buffers for gradients:
[ VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageBufferUpdateAfterBind-03008 ] Object 0: handle = 0x1e72d70, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x943cc552 | vkCreateDescriptorSetLayout(): pBindings[0] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT for VK_DESCRIPTOR_TYPE_STORAGE_BUFFER since descriptorBindingStorageBufferUpdateAfterBind is not enabled. The Vulkan spec states: If VkPhysicalDeviceDescriptorIndexingFeatures::descriptorBindingStorageBufferUpdateAfterBind is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER must not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageBufferUpdateAfterBind-03008)
Pretty much copy what GL does and just use the default display to create
GPU-related resources without the need for a display.
This also adds gdk_display_create_vulkan_context() but I've
kept it private because the Vulkan API is generally considered in flux,
in particular with our pending attempts to redo how renderers work.
Replace gdk_memory_format_prefers_high_depth with the more generic
gdk_memory_format_get_depth() that returns the depth of the individual
channels.
Also make the GL renderer use that to pick the generic F16 format
instead of immediately going for F32 when uploading textures.
The GDK_SEAT_CAPABILITY_TABLET_PAD stood awkwardly out of the
ALL value. Even though it's not a keyboard, its focus has more
resemblance to it, so it should be part of this group together
with keyboards.
We were creating the pad device on wp_tablet_pad.done, but
at that time we do not know what tablet it is associated with,
thus we cannot get appropriate vid/pid/name properties for it.
To get that, we need to wait for the pad to enter a surface,
at that time we do know what tablet it is associated with, so
we can get better information about the device.
There are pads that may plausibly "change" tablet between
one .enter event and the next (e.g. Wacom Express Key Remote),
but this situation is highly unlikely. The pad devices created
are thus persistent until that situation happens.
Sometimes, GLX can decide to use the previous request serial when faking
XErrors via __glXSendError() (look through the Mesa sources to enjoy).
This can cause the error trap we just installed to not feel responsible
for the error. And that makes GDK decide to immediately abort the
application.
That is not what we or GLX want.
So we use a no-op X Request to bump the request number so that when GLX
does its shenanigans, it uses a serial that our error trap will catch.
Fixes a crash in mutter's CI which apparently manages to drive GLX
without an X server.
In error cases, glXCreateContextAttribsARB() will always return NULL so
it is enough to run the loop until the first non-NULL context is
returned.
And at that point, we can just look at the return value and ignore all
errors.
Instead of having a descriptor set per operation, we just have one
descriptor set and bind all our images into it.
Then the shaders get to use an index into the large texture array
instead.
Getting this to work - because it's a Vulkan extension that needs to be
manually enabled, even though it's officially part of Vulkan 1.2 - is
insane.
Instead of trapping errors for the whole loop trying to create GL
contexts, trap them once per GL context.
Apparently GLX does throw an error when a too high version is requested
and doesn't just return NULL and then that error lingers when we try
lower versions.
Fixes#5857