Commit Graph

3049 Commits

Author SHA1 Message Date
Benjamin Otte
340c98c6cd gpu: Split a function
Split drawing the tiles from setting up the offscreen for drawing the
tiles.
2024-07-12 17:31:36 +02:00
Benjamin Otte
39f5c5bf49 gpu: Implement tiling for texture nodes
Use the new cache feature to split oversized textures into tiles the
size given by the new device API.

Then number those tiles from left to right and top to bottom and use
that number as the tile id.
2024-07-12 17:31:36 +02:00
Benjamin Otte
392f6855ca gpu: Add gsk_gpu_device_get_tile_size()
This allows managing tiling of images. And I'd like this value to live
somewhere prominent instead of as a hardcoded number in the
nodeprocessor.
2024-07-12 17:31:36 +02:00
Benjamin Otte
1cae48ab93 gpu: Add a tile cache
Nobody is using it yet, but it's the API.

It's very simple and just allows adding tiles by an index. What that
index means is up to the caller.
2024-07-12 17:31:36 +02:00
Benjamin Otte
d0f8ef09a0 gpu: Do a GC run after every tile of large images
When we draw large images, we absolutely do not want to keep memory that
we do not need. So do a GC run after every tile. That otentially slows
down things, but it also improves the chances of not running out of
memory.

Here's the node for the image I managed to create after I applied this
patch:

repeat {
  bounds: 0 0 50000 50000;
  child: text {
    font: "Noto Color Emoji 10000px";
    glyphs: 661 0 0 0 color;
    offset: 0 10000;
    hint-style: none;
  }
}
2024-07-12 16:57:23 +02:00
Benjamin Otte
0516dca116 vulkan: Don't try to use nonexisting formats
Handle the error that new rgba format exists.
2024-07-12 16:56:23 +02:00
Benjamin Otte
ebc6a043c9 gpu: Cleanups 2024-07-12 16:56:23 +02:00
Benjamin Otte
8e2ae79875 gpu: Change function to (transfer full)
Functions should behave as I expect, and I just spent an hour debugging
a refcount issue because I assumed our image creation functions return
refrences. Which is a very sane assumption.
2024-07-12 16:55:59 +02:00
Benjamin Otte
27ac764653 gpu: Don't multiply by 1/x, divide by x
This is less error-prone with floating point math, even though it is
somewhat slower.
2024-07-12 16:55:59 +02:00
Benjamin Otte
e40ad5faa5 gpu: Cache textures when doing copies
The texture and texture-scale node code is creating image copies
for mipmaps and to adapt to the compositing colorstate.

Those texture should be cached.
2024-07-11 14:57:20 +02:00
Benjamin Otte
dd393a4a0e gpu: Split out texture lookup function
It's unused in 3 function and has become somewhat unwieldy.
2024-07-11 14:57:20 +02:00
Benjamin Otte
881954dfca gpu: Rework texture caching
We want to cache textures in the compositing color state, not in their
original color state. However, the compositing color state may change
(think multimonitor setups).

So we additionally keep a cache per colorstate.

That means texture lookup is now a 3-step process:

1. Look up in the compositing colorstate's cache

2. Look up in the general cache

3. Upload
2024-07-11 14:57:20 +02:00
Benjamin Otte
cf12503fec gpu: Don't replace cache items
Instead, keep them. This is not useful yet, but will become so in the
next commits.
2024-07-11 14:57:20 +02:00
Benjamin Otte
ad757cccb6 Don't use GL_SRGB for premultiplied textures
GL_SRGB is doing postmultiplied alpha, so if the texture is
premultiplied, we can't use this optimization.

The optimization still works for unpremultiplied and opaque images,
because those don't do that step.
2024-07-11 14:57:20 +02:00
Benjamin Otte
b801eae00f gpu: All ops obey the ccs now
Remove the macro used for the not-yet converted ops.
2024-07-11 14:57:20 +02:00
Benjamin Otte
2fe9ff7918 gpu: Make mask op obey ccs
No colorstate conversions allowed here, though technically we could use
the alternate color state for the source most of the time, as the mask's
colorstate is only relevant for luminance.
2024-07-11 14:57:20 +02:00
Benjamin Otte
c407582096 gpu: Make blur op obey ccs
Blend ops don't do colorspace conversion, so this commit just hardcodes
that and rewrites the shader to use recent APIs.
2024-07-11 14:57:20 +02:00
Benjamin Otte
0fc3dbaa9b gpu: Make texture op obey ccs
Well, texture ops actually don't do any colorspace stuff, but let's
explicitly hardcode that.
2024-07-11 14:57:20 +02:00
Benjamin Otte
77ed264714 gpu: Introduce gsk_gpu_color_states_create_equal()
This is a function that's meant to be used whenever both color states
of the shader are equal. In that case no colorspace conversion code
needs to be created and shaders can be shared.
2024-07-11 14:57:20 +02:00
Benjamin Otte
a14efce914 gpu: Make blur op obey ccs 2024-07-11 14:57:20 +02:00
Benjamin Otte
08f90a188c gl: Force U8 textures for U8_SRGB depths
The GL renderer is using FLOAT32 instead of GL_SRGB, which is screwing
up the node-editor by making it turn on high bit depth unconditionally.

So until someone fixes the GL renderer properly, do this quickfix.
2024-07-11 14:57:20 +02:00
Benjamin Otte
df46eeafdb gpu: Make colormatrix op obey ccs
The colormatrix needs to be applied to unpremultiplied values, so we use
the alternative colorstate for that.
2024-07-11 14:57:20 +02:00
Benjamin Otte
0029286a1e gpu: Remove unused function
The colormatrix shader is no longer used for opacity.
2024-07-11 14:57:20 +02:00
Benjamin Otte
0e46d4eb98 gpu: Pass sampler to the image op
That way, we can use it in one other place where we want to use mipmaps.

I don't really like it because it adds yet another argument,
but then the one new caller was selecting suboptimal shaders, and that's
worse.
2024-07-11 14:57:20 +02:00
Benjamin Otte
f80e3fff92 gpu: Don't use the colormatrix shader for opacity
The colormatrix shade does a whole matrix multiplication, which is
absolutely not necessary.

The convert shader has builtin opacity handling and when the colorstates
match will do no conversion.
2024-07-11 14:57:20 +02:00
Benjamin Otte
504c6ba792 gpu: Don't use color matrix for opacity
We can use the regular image op which will select the fastest shader.
2024-07-11 14:57:20 +02:00
Benjamin Otte
c0aba9aee1 gpu: Make crossfade op obey ccs
I didn't have an idea what to use the alternate color state for, so I
don't use it.
2024-07-11 14:57:20 +02:00
Benjamin Otte
b97cf2b9d9 gpu: Track image colorstate
So far we only track the image colorstate and convert if necessary.

There is no caching of the converted images happening.
2024-07-11 14:57:20 +02:00
Benjamin Otte
f81e7b2112 gpu: Make conic gradient op obey ccs
Straight copy of the linear gradient changes.
2024-07-11 14:57:20 +02:00
Benjamin Otte
b59e4a929e gpu: Make radial gradient op obey ccs
Straight copy of the linear gradient changes.
2024-07-11 14:57:20 +02:00
Benjamin Otte
099d72f037 gpu: Make box shadow op obey ccs 2024-07-11 14:57:20 +02:00
Benjamin Otte
73acb41931 gpu: Make colorize op obey ccs 2024-07-11 14:57:20 +02:00
Benjamin Otte
ebb7fdb099 gpu: Make linear gradient op obey ccs
The alternative color state is used as the interpolation color state.
Colors are transformed into that space on the CPU.

For now we set the interpolation color state to SRGB, because ultimately
we want to let callers specify it, so having something that's easy to
map to that behavior is desirable.
Otherwise we might have chosen to interpolate in the compositing
colorstate.

It also means that we need to premultiply colors on the CPU now because
of the limitations of the shader colorstates APIs.
2024-07-11 14:57:20 +02:00
Benjamin Otte
ec3cb0ad9a gpu: Make border op obey ccs 2024-07-11 14:57:20 +02:00
Benjamin Otte
7ffef6792f gpu: Make rounded-color op obey ccs
This is the same as the color op.
2024-07-11 14:57:20 +02:00
Benjamin Otte
383148dc31 gpu: Make color op obey ccs
This makes use of the GskGpuColorStates by setting the ccs as output
colorstate and the color's colorstate as alternative color state.

The shader adaption is very straightforward because of that.
2024-07-11 14:57:20 +02:00
Benjamin Otte
a31601ccfc gpu: Make clear op obey ccs
This is the first op to obey the compositing color state. This means
from now on until all ops obey the ccs rendering is broken when ccs is
not set to linear.

I'll keep individual ops in seperate commits for easier review, because
they all need different adaptations.
2024-07-11 14:57:20 +02:00
Benjamin Otte
a587492cad gpu: Handle target not being composite colorstate
Render to an offscreen and add a final conversion if the target
colorstate is not a rendering colorstate.

This now allows the GPU renderer to render to any colorstate.
2024-07-11 14:57:20 +02:00
Benjamin Otte
f65d4914e4 gpu: Port convert op to GskGpuColorStates
Make it handle straight alpha, too, by checking if the alt colorspace is
premultiplied - which is the colorspace of the source.
2024-07-11 14:57:20 +02:00
Benjamin Otte
88dc49a5b6 gpu: Print the color states of shader ops
Makes the verbose output (a lot) more verbose, but it makes the
colorstates used in the shaders very visible.

And it will be relevant once people start using different colorstates
everywhere (like oklab for gradients/colors and so on).
2024-07-11 14:57:20 +02:00
Benjamin Otte
91d970e9c5 gpu: Add shaders for the new specialization constant
This adds the following functions:

output_color_from_alt()
alt_color_from_output()
  Converts between the two colors

output_color_alpha()
alt_color_alpha()
  Multiplies a color with an alpha value
2024-07-11 14:57:20 +02:00
Benjamin Otte
6c5ae48a05 gpu: Pass color states as specialization constant
This adds a GdkColorStates that encodes 2 of the default GdkColorStates
and wether their values are premultiplied or not.

Neither do the shaders do anything with this information yet, nor do the
shaders do anything with it yet, this is just the plumbing.
2024-07-11 14:57:20 +02:00
Benjamin Otte
d85ec2cbb4 gpu: create SRGB images
If desired, try creating GL_SRGB images. Pass a try_srgb boolean down to
the image creation functions and have them attempt to create images like
that.

When it is not possible to create srgb images in the given format, just
fall back to regular images. The calling code is meant to check the
GSK_GPU_IMAGE_SRGB flags to determine the actual format of the resulting
image.
2024-07-11 14:57:20 +02:00
Benjamin Otte
05b79bc378 gpu: Handle SRGB in render_texture()
When GDK_MEMORY_U8_SRGB is desired by the node, and a SRGB image is
created, pick SRGB_LINEAR as the colorspace to pass to frame_render().
2024-07-11 14:57:20 +02:00
Matthias Clasen
3ba63315d5 gpu: Pass compositing color states
Make the node processor and the pattern writer track the current
compositing color state. Color state nodes change it. We pass
the surface color state down via the frame apis.

The name of the variable is "ccs" for "compositing color space". It's an
unused variable name and it's common enough to deserve a short and sweet
name.
2024-07-11 14:57:20 +02:00
Benjamin Otte
eccdb594eb gpu: Remove straightalpha shader
As the new convert shader can do everything this shader could, use it
instead.
2024-07-11 14:57:20 +02:00
Matthias Clasen
a78796f22c gpu: Add a color convert shader
This shader converts between two color states, by using the
same functions that we use on the cpu. The conversion to perform
is passed as part of the variation.

As premultiplication is part of color states on the shader, we also
encode the premultiplication in the shader.
And because opacity is a useful optimization, we also allow setting
opacity.

For now, the only possible color states are srgb and srgb-linear.
2024-07-11 14:57:20 +02:00
Benjamin Otte
4fa6f791f4 cairo: Use the draw context's color state
This just passes through the sRGB set by the GDK backends instead of
hardcoding sRGB, so no functional changes.
2024-07-11 14:57:20 +02:00
Benjamin Otte
6287eaa745 cairo: Add colorstate to GskRenderNode::draw and use it
This adds the following:
- ccs argument to GskRenderNode::draw
  This is the compositing color state to use when drawing.

- make implementations use the CCS argument
  FIXME: Some implementations are missing

- gsk_render_node_draw_with_color_state()
  Draws a node with any color state, by switching to its compositing
  color state, drawing in that color state and then converting to the
  desired color state.
  This does draw the result OVER the previous contents in the passed in
  color state, so this function should be called with the target being
  empty.

- gsk_render_node_draw_ccs()
  This needs to be passed a css and then draws with that ccs.
  The main use for this is chaining up in rendernode draw()
  implementations.

- split out shared Cairo functions into gdkcairoprivate.h
  gskrendernode.c and gskrendernodeimpl.c need the same functions.
  Plus, there's various code in GDK that wants to use it, so put it in
  gdk/ not in gsk/

gsk_render_node_draw() now calls gsk_render_node_draw_with_color_state()
with GDK_COLOR_STATE_SRGB.
2024-07-11 14:57:20 +02:00
Benjamin Otte
ab7d969700 gdk: Add color state arg to gdk_texture_download_surface()
All callers set it to SRGB at the moment.
2024-07-11 14:57:20 +02:00