Commit Graph

79 Commits

Author SHA1 Message Date
Benjamin Otte
87a1a17868 memoryformat: Rename parameter
It's meant to match the prototype.
2024-09-25 02:50:22 +02:00
Benjamin Otte
376dbe9def memoryformat: Move fast path into the threaded path
We don't want to get slower in the fast path.
2024-09-15 02:31:02 +02:00
Benjamin Otte
bba7979670 memoryformat: Add a fastpath for RGBA8 <=> BGRA8
Cairo is using BGRA8 but we want to use RGBA8 because it's the canonical
GL format.

So getting this fast sounds useful.
2024-09-15 02:31:02 +02:00
Benjamin Otte
01aafc6e65 memoryformat: Don't always convert to rec2100-linear and back
It turns out we lost the check to see if color states are equal when we
multithreaded things in !7657

Whoops.
2024-09-15 02:31:01 +02:00
Matthias Clasen
d3db28b3f4 memory format: Add profiler marks
Add profiler marks to our long-running threaded operations.
To avoid spamming profiles too much, only report runs that take
at least 0.5 ms.
2024-09-06 16:14:24 -04:00
Benjamin Otte
896ea5b753 memoryformat: Add linear/nearest choice for mipmaping
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.
2024-09-06 15:47:35 -04:00
Benjamin Otte
5498b077fd memoryformat: Parallelize gdk_memory_mipmap() 2024-09-06 15:47:34 -04:00
Benjamin Otte
534a9b6ba0 memoryformat: Add fast path for mipmap
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.
2024-09-06 15:47:34 -04:00
Benjamin Otte
cea961f4f4 memoryformat: Take src_format and dest_format
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).
2024-09-06 15:47:34 -04:00
Benjamin Otte
848c6815d3 gpu: Allow uploading of mipmap levels when tiling
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.
2024-09-06 15:47:34 -04:00
Benjamin Otte
46559039f3 memoryformat: Parallelize gdk_memory_convert_color_state() 2024-09-06 15:47:34 -04:00
Benjamin Otte
eb7a42bc13 memoryformat: Parallelize generic path of gdk_memory_convert() 2024-09-06 15:47:34 -04:00
Benjamin Otte
ffe56fe6b3 memoryformat: Parallelize
Refactor code so that it uses g_parallel_task_run().
2024-09-06 15:47:34 -04:00
Benjamin Otte
a95c9ebc51 memoryformat: Split out a function
Allow querying the fast conversion functions outside of
gdk_memory_convert().
2024-09-06 15:47:34 -04:00
Matthias Clasen
fd78bd3eaf memoryformat: Add a debug helper
I need this often enough that I'll just put it here.
2024-08-07 08:22:05 -04:00
Benjamin Otte
a4854dfa9e memoryformat: Use "(p)" as premultiplied indicator in names
This matches what the gpu renderer does when printing
colorstates.

It also avoids it printing "S*RGBA8" for the format and instead prints
"SRGBA8(p)" now.
2024-08-06 22:15:17 +02:00
Matthias Clasen
3d75292c4d Fix indirect color state conversions
convert_func2 is a 'from' conversion function, ie it expects to
be passed the target color state. This was wrong both in
gdk_memory_convert and gdk_memory_convert_color_state.
2024-07-28 23:40:59 -04:00
Matthias Clasen
32b348776e memoryformat: Allow indirect conversions
If we don't have a direct conversion function between two
colorstates, go indirectly via rec2100-linear.
2024-07-24 07:46:05 -06:00
Benjamin Otte
11543a229a texturedownloader: Add color state
... 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.
2024-07-16 21:23:44 +02:00
Matthias Clasen
2879d35f3d gdk: Add a fast-path
Special case u8 RGBA8p, which is the common case.
2024-07-11 14:57:20 +02:00
Matthias Clasen
e1031ac5ad gdk: Add gdk_memory_format_convert_color_state
This allows in-place color state conversions.
2024-07-11 14:57:20 +02:00
Benjamin Otte
1bbf5f7a17 gdk: Add GDK_MEMORY_NONE depth
That's basically the "undefined" value. We need that when drawing
nothing, which so far only happens with empty container nodes.

But empty container nodes can be children of other nodes, and that makes
things propagate. So instead of catching them, force the whole rest of
the code to deal with an undefined depth.

We also can't just set a random depth, because that will cause merging
to fail.
2024-07-11 14:57:20 +02:00
Benjamin Otte
9abc83fdad gdk: Make gdk_memory_depth_merge() use a table
This makes it clearer how depths are merged.

Also use the actual desired merge modes, the previous code had some
weird behaviors.
2024-07-11 14:57:20 +02:00
Benjamin Otte
a7ceb8ce66 gdk: Add GDK_MEMORY_U8_SRGB depth
This is an experiment for now, but it seems that encoding srgb inside
the depth makes sense, as we not just use depth to decide on the
GL fbconfigs/Vulkan formats to pick, depth also encodes how the [0...1]
color values are quantized when stored.

Let's see where this goes.
2024-07-11 14:57:19 +02:00
Benjamin Otte
2f4e19d514 gdk: Allow querying GL SRGB formats
Nobody is using this yet.
2024-07-11 14:57:19 +02:00
Benjamin Otte
8d5224eba7 gdk: Allow querying Vulkan SRGB formats
Nobody is using this yet, this is just infrastructure.
2024-07-11 14:57:19 +02:00
Benjamin Otte
dd33a2f280 rendernode: Make sure depth variable has enough bits
This will be relevant when we add new values to it.
2024-07-03 19:55:15 +02:00
Benjamin Otte
3539128d42 memoryformat: Split out a function
It's used in many places and attaching a name to what it does is useful.
2024-07-03 04:16:56 +02:00
Benjamin Otte
c645acc214 memoryformat: Use the correct type
Our color values are float[4], so make them float[4].
2024-07-01 20:07:22 +02:00
Benjamin Otte
33d87bc22e gdk: Add GDK_N_DEPTHS to the enum
We are indexing arrays by the number of depths, and when adding depths
we don't want to forget to grow those arrays.
2024-07-01 20:07:22 +02:00
Matthias Clasen
0045ac839b Give memory formats a name
This is useful in debugging.

The names I chose are shortened a bit from the enum values. We
use just a single depth, * for premultiplied, and f for float.
2024-06-09 15:59:27 -04:00
Benjamin Otte
d97767014c gl: BGRA formats need a different internal format
In GLES, BGRA is still done by GL_EXT_texture_format_BGRA8888 which is
an extension that is older than GLES 2.0.

And back then, internal formats had to be specified unsized. And when
that was changed with GLES3, nobody updated the extension.
However, on OpenGL, this extension doesn't exist, and internal formats
need to be sized.

So let's use different internal formats depending on GL version.

Fixes #6333
2024-01-16 20:35:20 +01:00
Benjamin Otte
2f974a1f5a gl: Split internal format for GdkMemoryFormat into GL/GLES
This commit just duplicates the struct.

It's separate because it's just a bunch of boilerplate.
2024-01-16 20:35:20 +01:00
Benjamin Otte
4e2c7d5eb0 gl: Require GL/GLES flag when looking up memory formats
This code just adds the argument to the function and fixes all callers.

It's separate because it's just a bunch of boilerplate.
2024-01-16 20:35:20 +01:00
Matthias Clasen
59578c6d18 Fix typos throughout
These were pointed out by codespell.
2024-01-07 20:44:05 -05:00
Benjamin Otte
d2a85abf79 Merge branch 'wip/otte/dmabuf-refactoring' into 'main'
dmabuf refactoring

See merge request GNOME/gtk!6678
2023-12-20 10:25:29 +00:00
Benjamin Otte
cccec91b66 memoryformat: Put dmabuf fourccs into the big format table
I'm concentrating the data about memory formats, and this part was
missing.
2023-12-16 17:01:42 +01:00
Benjamin Otte
ff082a7758 memoryformat: Add Vulkan format information
This is not used yet, but I want to add it, so that it exists.

That way, when we add new formats, people don't forget to add the Vulkan
formats.
2023-12-16 09:20:36 +01:00
Benjamin Otte
f357623170 memoryformat: Fix broken swizzle values
I can't copy/paste.
2023-12-16 09:20:29 +01:00
Matthias Clasen
c48a3152f0 memoryformat: Expand docs
This captures some irc exchanges about the intended use of
the new memory format apis.
2023-12-13 12:44:20 -05:00
Benjamin Otte
4dfc07ef57 memoryformat: Fix variable types
Use the same types that GL uses.
2023-12-12 01:49:41 +01:00
Benjamin Otte
e3c85be53f memoryformat: Add gdk_memory_format_get_fallbacks()
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.
2023-12-12 01:49:40 +01:00
Benjamin Otte
0f5fda2277 memoryformat: Introduce new (private) API
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.
2023-12-12 01:49:40 +01:00
Benjamin Otte
ee56ad792c memoryformat: Fix 2 broken formats
They are straight alpha, and the GL renderer isn't using them yet, so
existing code is not affected.
2023-12-12 01:49:40 +01:00
Benjamin Otte
5688b7b4bb gl: Add a new alternative format
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.
2023-12-12 01:49:40 +01:00
Benjamin Otte
84de90756d memoryformat: Make the big array more readable
Prefix the struct members with their name, similar to how our Vulkan
code looks.
2023-12-11 22:11:28 +01:00
Benjamin Otte
3a1349e8ef gl: Make gdk_memory_format_gl_format() no longer check support
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.
2023-12-11 07:33:26 +01:00
Matthias Clasen
06dda4e12b Merge branch 'memory-format-swizzle-check' into 'main'
gl: Check all swizzle values

See merge request GNOME/gtk!6524
2023-10-26 02:38:35 +00:00
Matthias Clasen
4a749aee6e Fix swizzle values for some memory formats
For opaque formats with 3 channels, we should use the default
GL_ALPHA, but for opaque formats with an ignored 4th channel,
we must use GL_ONE.
2023-10-25 21:39:52 -04:00
Benjamin Otte
e2edf693f5 gdk: Make float32 report its true depth
I have no idea how this is the only value that is wrong.
2023-10-23 21:22:17 +02:00