We wanted premultiplied images in all cases anyway, and moving that
requirement means we can also move the caching code for re-caching
textures into the texture specific code.
This uses offscreens for every call to get_node_as_image().
This is useful both for benchmarking benefits of those implementations
as well as checking that the node-specific paths produce identical
results.
gsk_gpu_node_processor_ensure_image() was a weird amalgamation of stuff
withe weird required and disallowed flags.
Refactor it to make the two operations we actually do there more
explicit: Removing straight alpha and generating mipmaps.
This untangling is also desirable in the future when we also want to
handle colorstates here.
Always return premultiplied images.
2 fallback cases for clip and transform nodes did not require that. If
those cases turn out to be important, they can call
gsk_gpu_get_node_as_image() directly as that's the more flexible option.
Pass through to the child instead of offscreening.
I mainly implemented it for the assertion, because this might be a
sneaky way to introduce bugs without exhaustive checking that we don't
offload stuff that is offscreened.
No actual bugs that I'm aware of, so no tests.
Strictly defensive coding.
When getting a texture as image, we were always returning the texture
unconditionally.
However, we want to mipmap textures when the scale factor is too large,
and this code path did not do that.
The same codepath on the GL renderer doesn't do that either, so the test
is disabled for it.
The switch statement was ugly.
Plus, the code should be close to the add_node() vfunc implementation,
so they can be modified together.
See future commits for an example where this matters.
Make the whole window area draggable, like usually the titlebar.
This is especially useful with --undecorated.
In that case we need to make the window non-resizable though, becuase
otherwise it can be accidentally maximized and whatnot.
It didn't bring any noticable benefits and it isn't compatible with the
way we intend to do colorstate support.
And nobody seems to want to spend time on it, so let's get rid of it.
We can bring it back later if someone wants to work on it.
* The variables are const. Keep them const when casting
* Print float16 values
* Print integer values as hex. This is better for detecting
byteswapping, off by one, and such. Besides, we tend to use values
that have the same 2 hex digits, so detecting corruption is also easy.
The new renderers don't support them due to the required complexity of
integrating them with Vulkan and the assumptions those nodes make about
the renderer (the GL renderer exports its internal APIs into the
GLShader).
There haven't been any complaints that I'm aware of since 4.14 was
released where the default renderer does not support the nodes, so usage
in public seems to be close to nonexistant.
The 2 uses I know of were workarounds about missing features in GTK that
have stopped since GTK now supports them:
1. GStreamer used in to do premultiplication when the old GL renderer
did not do so in hardware but on the CPU.
2. Adwaita used it for masking before the mask node wa added in 4.10.
I was watching the log in my terminal and nothing happened.
And I wasn't sure if that was because nothing was printed or because the
same thing was printed every few seconds.
Fix that by printing a timestamp, so that in a few seconds something
else will be printed.
Previously we tracked the dead pixels, but that meant we didn't know the
alive pixels (because there's also unused pixels never accounted for).
And we would free the current atlas randomly due to that.
Now we track if any pixels are alive, and if so, we never gc the current
atlas.
After 60s, we gc the atlas, too. This ensures that after that time, we
free all cache resources, so if an application gets moved to the
background, it will no longer use GPU resources. (Well, at least the
cache won't.)
Only if a non-stale item is in the cache do we consider the cache not
empty.
Once the cache is empty, the device frees it and stops running the
periodic GC.
This is for 3 reasons:
1. Separation of concerns
The device is meant to manage the Vulkan/GL device and check stuff
like image sizes.
Caching is not part of that.
2. Refcounting
Images etc want to reference the device, but the cache wants to
reference images. If the cache is the device, that's a refcycle.
3. Flexibility
It's now easier to implement >1 cache, say one per depth or one per
color state.
If we unparent the widget, we should sever a11y relations too.
Otherwise, an a11y implementation might follow them and be surprised
to find a parentless widget (and not in a good way).
Updated tests to not check the relation on an unexpanded expander.
The unary (closure) annotation is for function pointer types; function
arguments that represent the user data to be passed to the callback are
annotated on the callback argument itself, with (closure arg-name).