Use the gdk_win32_surface_parent_class that is given to us by
G_DEFINE_TYPE() instead of using a global variable to store up the
parent class of GdkWin32Surface.
... and print if a format is advertised.
We now use the same style of message and use the term "advertise" for
formats that will be available via GdkDisplay::dmabuf-formats and
"supports" for formats the backend pretends it can handle but don't
want to advertise them.
Instead of only printing the advertised dmabuf formats, print all
supported ones. This is now useful information because we will try to
use them when downloading.
Fixes me looking like I don't know what I'm talking about on IRC when
claiming that llvmpipe can't do dmabufs, because it only supports linear
ones and we didn't print those.
We want to make the distinction between GdkSurface's and native Windows
HWNDs clear, and we don't want to confuse between GdkSurface's and
Vulkan surfaces.
In order to help us in our refactoring, make the distinction between Gdk
surfaces and native Win32 HWND clearer in terms of the variables that we
used, and in the comments in the code.
Also, group forward function prototype declarations in one place, and
drop some unneeded items in gdkprivate-win32.h to fold them into
gdksurface-win32.c, as they are only used there.
We don't need our own mechanism for device selection; mesa has a
Vulkan layer that works perfectly fine for this purpose; just set
MESA_VK_DEVICE_SELECT.
Treat external as the normal case, and only try importing dmabufs
as non-external images if their format is on the internal formats
list.
Also add internal linear formats to the internal formats list.
This fixes an issue where AR24:0 dmabufs were imported as external
textures, causing some of the compare tests to fail.
Make this function return whether it was successful, and only emit
a debug message if we succeeded. In particular, make it return FALSE
if the dmabuf format is not linear.
I've seen valgrind complain about external_only being uninitialized
after the call, when using llvmpipe. Better be safe than sorry, and
initialize these arrays.
When picking a cursor image size for a given size, look for sizes
that do better when scaled by the viewporter:
- exact size
- twice the size
- closest larger size
- closest size
This was a thinko in 403da9a2d5. We have the cursor
image in device pixels, but we still need to apply the viewporter
to inform the compositor about the desired pointer size in
application pixels.
Stop using a viewporter to scale cursors. Instead, just pass
the surface scale to the cursor loading code, and take the
buffer dimensions and hotspot that it returns, unchanged.
This avoids problems with cursor themes like Breeze, where
buffer dimensions are different from the nominal cursor size.
Make the cursor loading code take a floating point scale,
and return the closest sized cursor that it can find.
It works, now and is faster than the old GL downloader.
Playing the Barbie trailer @ 4k with hardware decoding but the Cairo
renderer on a 4k screen:
downloader windowed fullscreen
GL 12fps 19fps
NGL 16fps 29fps
Vulkan 16fps 29fps
no dmabufs 12fps 19fps
We want to share the texture download function with the renderers, so
they can download textures without needing to wrap them in a
GdkGLTexture.
Move it into gdkglcontext.c for that purpose.
Sometimes, jokers send us 'mimetypes' like DELETE or
org.webkitgtk.WebKit.custom-pasteboard-data, and gdk_intern_mime_type
will return NULL for such things. Handle that by just closing the fd.
Better than running into an assertion further down.
This is unnecessary.
Worse, it is reentrant and can cause all sorts of avoc when processing
events halfway through initializing the Vulkan context.
It was introduced in commit e11a6a0e68 but back then GTK was barely
branched for GTK4 and Vulkan drivers were very new, and it looks like an
unnecessary workaround.
Testing did not seem to indicate any issues with just removing it, so
here it goes.
Related: #7022
This is unnecessary.
Worse, it is reentrant and causes all sorts of avoc when processing
events halfway through initializing the context.
It only exists because in commit c4244ea1 the win32 Vulkan code was
copy/pasted from another backend.
Related: #7022
It is not necessary.
Worse, it is reentrant and causes all sorts of avoc when processing
events halfway through initializing the context.
It only exists because in commit 3887548 the Wayland Vulkan code
was copy/pasted from X11.
Fixes#7022Fixes#7025
For VK_DEBUG_REPORT_WARNING_BIT_EXT we should always have used
g_warning().
For VK_DEBUG_REPORT_ERROR_BIT_EXT g_critical() is technically the right
choice, but Mesa has been using this flag for normal warnings, so until
that gets fixed, we don't want to throw criticals.
Related: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31292Fixes: !7020
Only initialize the Vulkan or EGL parts where possible.
When dmabufs or dmabuf formats are actually used, we still
initialize fully by creating both a Vulkan and EGL downloader.
This shortens the time to first commit from 149ms to 108ms.
Just use two individual fields, so we can track if we've already
created each one. This also matches the individual fields we have
for the dmabuf formats.
And change preference order of downloaders
Previously, our order was mmap > vulkan > egl.
But depending on the hw (discrete vs integrated gpu), mmap
can be catastrophically slower (on the order of 20ms vs 1.5s).
So, change the order to egl > vulkan > mmap.
Note that this currently has less effect than we'd like to,
since we don't let the downloaders claim linear formats.
This one got added in 66ba1f76ba but didn’t end
the sentence with a dot, and didn’t have its enum name between parentheses so
that people can debug more easily which error code got generated.
`thread_current_context` might be holding the last reference to
`previous`, in which case `gdk_gl_context_make_current` on the new
context will free `previous`, leaving it a dangling pointer.
Avoid this by making sure to hold a reference.
Fixes: 41cd0c6f "gl: Fix initial EGL context creation on X11"
Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/6995
Signed-off-by: Simon McVittie <smcv@debian.org>
Set the alpha channel to "undefined" in this case.
Gimp doesn't seem to like this when opening the image and insists to
doing something with it, that's a bit of a bummer.
But it allows GTK to load RGBx textures.
It seems Mesa doesn't support that yet, but having it doesn't hurt.
And it allows drivers to allocate less memory for the swapchains,
because we don't need all the 4 images we request in minImageCount.
But drivers tend to take that minimum image count as gospel, so we need
to use a higher number to not cause lag in corner cases.
Removed via regex and grep.
The following were intentionally not removed:
- GtkImage:file: (attributes org.gtk.Property.set=gtk_image_set_from_file)
- GtkImage:resource: (attributes org.gtk.Property.set=gtk_image_set_from_resource)
As they have no getter and (setter PROP) without a (getter PROP) crash
gobject-introspection. This is fixed by
ad3118eb51.
The annotations should only be set when the name of the setter or getter
for a property "GtkClassName:prop-name" is not gtk_class_name_g(s)et_property_name.
linear will average all the pixels for the lod, nearest will just pick
one (using the same method as OpenGL/Vulkan, picking bottom right
center).
This doesn't really make linear/nearest filtering work as it should
(because it's still a form of mipmaps), but it has 2 advantages:
1. it gets closer to the desired effect
2. it is a lot faster
Because only 1 pixel is chosen from the original image, instead of
averaging all pixels, a lot less memory needs to be accessed, and
because memory access is the bottleneck for large images, the speedup is
almost linear with the number of pixels not accessed.
And that means that even for lot level 3, aka 1/8th scale, only 1/64 of
the pixels need to be accessed, and everything is 50x faster.
Switching gtk4-demo --run=image_scaling to linear/nearest makes all the
lag go away for me, even with a 64k x 64k image.
We have fast conversion functions, use those directly instead of calling
into gdk_memory_convert().
This is useful because as mentioned before, the main optimization here
is RGB8 => RGBA8 and we have a fastpath for that.
Why do we need this? Because RGB images are provided in RGB format but
GPUs can't handle RGB, only RGBA, so we need to convert.
And we need to do that without allocating too much memory, because
allocating memory is slow. Which means in aprticular we need to do the
conversion after mipmapping, not before (like we were doing).
This allows uploading less memory but requires computing lod levels on
the CPU which is slow because it reads through all of the memory and so
far entirely not optimized.
However, it uses significantly less VRAM.
This is done by adding a gdk_memory_mipmap() function that does this
task.
The texture upload op now accepts a lod level and if that is >0 it uses
gdk_memory_mipmap() on the source texture.
This is just the API. Users will come later.
I considered putting it into gdkmemoryformat.c because it's likely gonna
be the only user and this one function is so little code, but it didn't
fit at all.
So now it's a new file.
Depth of a rendernode should be determined by the textures used and the
compositing colorstate requirements.
Colors influence the colorstate choice, so they indirectly influence the
depth, but they should not influence the depth directly.
Otherwise a single color in a border being rec2100-pq would make us
switch to 16bit float.
Also remove gdk_color_get_depth(), because it was only used here and
because again: Colors should not influence depth decisions.
When prepare_gl fails in the right way (or the wrong way?), we
end up creating the leader window twice, and as a side effect,
creating two instances of the "Virtual core pointer" device, which
is bad news for grabs.
Fixes: #6840
Call wl_surface_offset in end_frame to apply the offset for drag
surfaces. This matches what the GL draw context already does, and
it fixes drag surfaces jumping at the beginning of the drag.
Fixes: #6972
We switched to using the Unicode (UTF-16) versions of the Windows API by
default, so we also obtain the display name in UTF-16 form as well.
This updates the implementation in the Windows backend so that we
properly acquire the names that we need in UTF-16, and then convert the
results to UTF-8, which is what we use in GTK/GLib.
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: !7662Fixes: #6964 on X11
This essentially reverts the changes from
c230546a2c but implies new semantics.
Namely, surface-attached contexts can now be bound to EGL_NO_SURFACE if
the windowing system isn't ready yet.
It is the task of the windowing system to make sure the context is
properly rebound when the contents become available.
We ensure this by checking in begin_frame() if we created the EGL window
and if we did, we make_current(). This works because creating the EGL
window creates the EGL surface and that does a clear_current(), so this
is always going to have the desired effect of re-making the current
context.
It is very convoluted though.
Fixes: #6964
Related: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11784
We do this because:
a) The parent class (GdkGLContext) already stores the paint regions of
previous frames, no need to do the same.
b) The painted region passed to end_frame () includes the backbuffer's
damage region, so it's not really what we want.
This also fixes a leak of cairo_region_t that I introduced by mistake
in !7418
We need to ensure that an EGL surface exists before we call
eglMakeCurrent() with it. Otherwise we might end up binding to
EGL_NO_SURFACE and then never revising that decision.
Which leads to not rendering to the backbuffer, but into the void.
Fixes X11 rendering being black
Fixes#6930
The current resizing implementation in the GDK-Win32 backend is not
telling GDK early enough for Vulkan that a resize in the surface (i.e.
HWND) is done, so that GDK can re-create swapchain in time, which is
apparent on nVidia drivers (and AMD drivers that utilize the mailbox
presentation mode on Windows) when the HWND is being enlarged
interactively.
To work around this, bar a refactor in the Windows resizing/presentation
code, is to call _gdk_surface_update_size() when we really did resize
the HWND when we handle queued resizes via SetWindowsPos().
The existing call in gdksurface-win32.c in
_gdk_win32_surface_compute_size() remains required, otherwise the
surface won't display initially.
Thanks to Benjamin Otte for pointing this possibility out.
We don't need to hardcode all the interface names as string literals,
since they come as part of the wl_interface structs in the protocol
bindings we use.