Commit 1580490670 included a reordering of
acquiring the frame before making the context current.
Sometimes (like at startup) new frames need to be created.
Setting up a new frame assumed the GL context was current.
Change it so that we delay the one GL setup we do in frames until later.
Building GTK with GCC 8 results in the following warning:
gtk/gtkurilauncher.c: In function ‘gtk_uri_launcher_launch’:
gtk/gtkurilauncher.c:315:3: warning: this ‘else’ clause does not guard... [-Wmisleading-indentation]
else
^~~~
gtk/gtkurilauncher.c:317:1: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘else’
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
^~~
In the compiled code, gtk_show_uri_full () is invoked whether the portal
branch is taken or not, leading to use-after-free of the task.
It looks like GCC in versions older than 12 treats the _Pragma(s) that
G_GNUC_BEGIN_IGNORE_DEPRECATIONS expands to as C-level statements, and
therefore the pragma takes up the 'else' statement slot.
See https://godbolt.org/z/e5zqbaqxo for a simple reproducer.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
* We cannot map with offset, because offsets need to be page-size
aligned. And our code doesn't expect an offset anyway.
* The error return value from mmap() is MAP_FAILED aka -1, not NULL aka
0.
Vulkan requires us waiting on the image acquired from
vkAcquireNextImageKHR() before we start rendering to it, as that
function is allowed to return images that are still in use by the
compositor.
Because of that requirement, vkAcquireNextImageKHR() requires a
semaphore or fence to be passed that it can signal once it's done.
We now use a side channel to begin_frame() - calling
set_draw_semaphore() - to pass that semaphore so that the
vkAcquireNextImageKHR() call inside begin_frame() can use it, and then
we can wait on it later when we submit.
And yes, this is insanely convoluted, the Vulkan developers should
totally have thought about GTK's internal designs before coming up
with that idea.
These are just factoring out gdk_draw_context_begin/end_frame() so I can
add one tiny thing there later.
And I did both even though I only need one, because it felt wrong to
just do one.
Make the function look like that:
1. handle special case
2. maybe GC
3. draw
4. queue next gc
5. cleanup
This seems like the sanest approach to avoid gc() collecting things
necessary for drawing in the future.
And I need to refactor stuff, so having it out of the way is a good
idea.
When loading or saving png files, encode the CICP flags of the color
state into the PNG.
When loading, decode the CICP flags if available and detect the
colorstate they use.
If we do not support the cicp tags, we do not load the image.
So far, we ignore the ICC profiles.
Includes regeneration of nodeparse test *reference* output to include
the new tags we write to PNGs.
The original tests do not include those tags, so we implicitly test that
we read untagged files correctly.
We only download the data when we actually need it for writing into the
PNG stream.
This allows modifying the download parameters (in particular color state
in the next commit) while writing out their settings, so the code for
selecting the right colorstate liives in only one place.
We have to be careful though, because the download now happens after the
setjmp(), so we need to make sure the error path handles both cases
without leaking: Where the download has happened and where it hasn't.
Same thing as dmabuf and GL texture builders. Preparation for adding
color state support to texture constructors.
As a bonus, we can now do update regions with memory textures.
... and plumb the color state through the downloading machinery, where
no matter what path it takes it ends up in
gdk_memory_convert_color_state() or gdk_memory_convert().
The 2nd of those has been expanded to optionally do colorstate
conversion when the 2 colorstates are different.
When a cache item is invalid, don't move it into the hash table.
Instead, just delete it.
Something like this could happen:
1. A texture is cached
In the case of #6867 this would be a webpage in epiphany.
2. The texture cache item is garbage-collected
For example, epiphany might switch to a new tab, and the previous page's
texture will remain. After 15s or so, we collect our item for that
texture.
3. The texture is cached again, but in the target colorspace
We now decide we need the texture again, but not in any colorspace, we
need it in the target colorspace. This might be because we run an
effect on it (like a crossfade) or because we want mipmaps (like in the
overview map, where its zoomed out).
4. The old invalid item is transitioned into the hash table
We now have an invalid item in the hash table. This is extra bad,
because it had only one reference (from the texture), but we treat it
like it has 2 (from us in the hash table and from the texture).
So depending on if the texture is freed before we reuse it, we get
different results: If it was free, we get invalid memory accesses, if it
was not freed, we treat it like a valid cache item and think the image
inside is still valid.
Fixes#6867
This happens when buffer creation fails in `get_dmabuf_wl_buffer()` and
we manually call `listener->release (data, NULL)`.
Fixes: 2478dd8322 ("subsurface: Split a function")
gsk_gpu_device_gc() may release the last ref on the GskGpuDevice,
leading to memory corruption when setting priv->cache_gc_source = 0.
Includes a bit of refactoring, so the ref/unref wraps nicely around the
actual code.
Fixes crashes seen after using the inspector and closing the window,
thereby closing all windows of a display and releasing all references to
the device.
Fixes#6861