Commit Graph

303 Commits

Author SHA1 Message Date
Matthias Clasen
690c06109e gsk: Speed up mask nodes with cairo
Switch symbolc icon drawing from color-matrix to mask nodes
make the performance of the iconscroll demo crater (from 60fps
to 10fps).

Apply the same optimization we already have for color-matrix
nodes when drawing mask nodes. This gets us back to 60fps.

Fixes: #6700
2024-05-10 07:24:25 -04:00
Matthias Clasen
0a5a720fe1 Use gdkrgbaprivate.h in more places
This gets inline functions used where it matters.
2024-04-15 22:57:01 -04:00
Matthias Clasen
f445d8b518 gsk: Use hinted extents
This works better for cff fonts, where hinting is not as local as
what the autohinter does for ttf fonts, and it does not seem to
have negative effects.

Fixes: #6577
Fixes: #6568
2024-04-03 10:52:13 +02:00
Matthias Clasen
1e5e977b37 gsk: Minor reshuffling
Hide the temporary unhinted font object behind the private API.
There might be a way to implement this without instantiating a
font, at some point.
2024-03-09 12:43:33 -05:00
Matthias Clasen
d1b52cc292 gsk: Preserve the antialiasing setting of the font
When we get an unhinted font for text node extents, don't change
the antialiasing setting. It doesn't affect the extents we get
here, but if we later need an unhinted font for rendering, the
one we create this way will be the right one, so it will already
exist.
2024-03-03 13:08:29 -05:00
Matthias Clasen
8a48becb7e Cosmetics 2024-03-03 08:56:32 -05:00
Matthias Clasen
ab5f3f59ce gsk: Use unhinted extents for text nodes
We need precise bounds. And while hinting might shift the rendering
around from these bounds by a fraction of a pixel, we account for
this in the places where it matters: when determining diff regions,
when sizing offscreens, and when determining the size of atlas
regions for glyphs.
2024-03-02 18:39:14 -05:00
Matthias Clasen
24de5ffd4e gsk: Stop padding text node bounds
This should not be necessary, provided that the ink extents that
pango provides are accurate.

Update affected tests.
2024-02-16 14:45:20 -05:00
Matthias Clasen
72614fdb67 gsk: Normalize node bounds upon creation
We lost this when a bunch of rect code was inlined in
commit 36314f28e2, and as it turns out, that broke some
applications. So, bring it back.

Fixes: #6435
2024-02-13 20:06:16 -05:00
Matthias Clasen
5b55456b75 Rework diffing one more time
Pass the surface along. We need it to identify the inspector case
in gsk_subsurface_node_diff.
2024-02-11 20:48:59 -05:00
Matthias Clasen
26c25cc6b7 Simplify gsk_subsurface_node_diff
Most of the time, the subsurfaces will be the same. And if they
aren't, can_diff() will return FALSE anyway.
2024-02-11 20:24:28 -05:00
Benjamin Otte
30afac9a6b offload: No need to pass the offload to the diff
We can just check if the subsurfaces contain content - and if they do,
they will be offloading and we can ignore the diff.

This essentially reverts 48740de71a
2024-02-11 20:24:28 -05:00
Benjamin Otte
dac56dd757 offload: Change the way we compute damage regions
Instead of relying on diffing subsurface nodes, we track damage
generated by offloaded contents inside GskOffload.

There are 3 stages a subsurface node can be in:

1. not offloaded
   Drawing is done by the renderer
2. offloaded above
   The renderer draws nothing
3. offloaded below
   The renderer needs to punch a hole.

Whenever the stage changes, we need to repaint.
And that can happen without the subsurface's contents changing, like
when a widget is put above the subsurface and it needs to to go from
offloaded above to below.

So we now recruit GskOffload for tracking these changes, instead of
relying on the subsurface diffing.

But we still need the subsurface diffing code to work for the
non-offloaded case, because then the offloading code is not used.
So we keep using it whenever that happens.

Not that when a subsurface transitions between being offloaded and not
being offloaded, we may diff it twice - once in the offload code and
once in the node diffing - but that shouldn't matter.
2024-02-11 20:24:28 -05:00
Benjamin Otte
e4ca3a285e gsk: Split out a function
I want to use it elsewhere.

I didn't come up with a better name, if anyone knows one, please
rename.
2024-02-11 20:24:28 -05:00
Benjamin Otte
30b5a33444 rendernode: Fix subsurface diff code 2024-02-11 20:24:28 -05:00
Benjamin Otte
e647ebae87 rendernode: Do full diff when starting/stopping offload
When a subsurface goes from not offloaded to offloaded (or vice versa),
we need to add the whole node to the diff region, because we switch from
whatever contents were drawn to a punched hole.
2024-02-11 20:24:28 -05:00
Benjamin Otte
b49b055183 rendernode: Implement diff() for repeat nodes
If the children have an empty diff and the repeat nodes' sizes are
equal, the diff is empty.
2024-02-04 21:57:13 +01:00
Benjamin Otte
b7f7487b53 cairo: Fix wrong offset when tiling repeat nodes 2024-01-23 06:17:14 +01:00
Benjamin Otte
00be97e741 gsk: Respect offscreen_for_opacity of first child
The container node constructor forgot to initialize that value from the
first child.

Testcase included.

Fixes #6350
2024-01-22 18:22:50 +01:00
Matthias Clasen
1c85141612 gsk: Keep a fontmap reference in text nodes
A PangoFont keeps a weak reference to its fontmap. In addition,
keep a strong reference in GskTextNode, so we can be sure that
custom font maps won't go away before the node is finalized.
2024-01-15 18:25:15 -05:00
Matthias Clasen
bda6530fea docs: Fix: gsk->gtk links
gi-docgen can only generate links for dependencies, so we have
to manually expand to a relative url here.
2024-01-05 14:57:16 -05:00
Matthias Clasen
c56360f20b Merge branch 'matthiasc/for-main' into 'main'
gsk: Mark some subsurface node apis as skip

See merge request GNOME/gtk!6702
2024-01-03 14:09:38 +00:00
Matthias Clasen
726d5b25e8 Merge branch 'bilelmoussaoui/add-missing-annotations' into 'main'
gi: Add missing Since annotations

See merge request GNOME/gtk!6701
2024-01-03 13:35:44 +00:00
Matthias Clasen
681aac7317 gsk: Mark some subsurface node apis as skip
These are not usable outside of GTK, so lets not burden bindings
with them.

I'll keep the get_child() function exposed, since it is needed to
iterate over node trees containing subsurface nodes.
2024-01-03 07:53:27 -05:00
Bilal Elmoussaoui
2cd550cdbc gi: Add missing Since annotations 2024-01-03 08:49:39 +01:00
Benjamin Otte
cdf5d08294 rendernode: Fix a memleak 2024-01-03 04:58:08 +01:00
Benjamin Otte
7742434dde rendernode: Allow drawing oversized textures
Create surfaces for tiles of the image and then combine those tiles.

Use an offscreen and OPERATOR_ADD to avoid seams.
2024-01-03 04:11:35 +01:00
Benjamin Otte
09882701c2 rendernode: Fix various places where clip was double applied
This is mostly untested and a result of reading the code.

The main effect here happens when a node was drawn that didn't start on
an integer boundary, which is very rare.
However, with specially crafted tests and when using fractional scaling,
this can happen.

This happened most often when clipping by the node bounds to restrict a
push_group() call. Enlarge that rectangle to fall on a pixel boundary.
2024-01-03 04:11:35 +01:00
Benjamin Otte
a19bc6620a rendernode: Apply the same radius for begin and end
Somebody fixed the end() call but not the begin() call when the too
large blur radius was fixed.
2024-01-03 04:11:35 +01:00
Benjamin Otte
28b552ad8c rendernode: Remove unnecessary save/restore 2023-12-28 07:35:47 +01:00
Benjamin Otte
0c3c8a6a85 stroke: Turn stroke copy intialization into a macro
That way I can use it in static initializers.
2023-12-28 07:35:46 +01:00
Benjamin Otte
914e9bc316 Merge branch 'wip/otte/lots-of-tests' into 'main'
Lots of rendering tests and fixes

See merge request GNOME/gtk!6692
2023-12-26 15:22:35 +00:00
Benjamin Otte
1385ffd2c2 gsk: Repurpose GSK_DEBUG=cairo
Use it to overlay an error pattern over all Cairo drawing done by
renderers.

This has 2 purposes:
1. It allows detecting fallbacks in GPU renderers.
2. Application code can use it to detect where it is using Cairo
   drawing.

As such, it is meant to trigger both with cairo nodes as well as when
renderers fallback for regular nodes.

The old use of the debug flag - which were 2 not very useful print
statements - was removed.
2023-12-26 05:31:05 +01:00
Benjamin Otte
b01ed4ce39 rendernode: Set better size for mask nodes
Mask nodes are transparent outside of the intersection of source and
mask, unless the mask ode is inverted alpha.

Set the bounds accordingly.

Tests have been updated accordingly.
2023-12-26 05:03:24 +01:00
Benjamin Otte
6ab6109149 rendernode: Redo repeat handling
The previous approach could lead to offscreens that were too large and
cause errors.
2023-12-25 19:12:57 +01:00
Benjamin Otte
c341da32aa gsk: Set correct blur radius for cairo shadows 2023-12-11 07:33:26 +01:00
Benjamin Otte
d39ec8c09e gsk: Quality of life improvements for Cairo rendering
1. Check for an empty clip region before push/pop_group() calls

2. Remove save/restore() pairs as the vfunc invocation does so already.
2023-12-11 07:33:26 +01:00
Benjamin Otte
e3299e38df cairo: Handle clipped blur content
This is the result of experimenting with corner cases when blurring.

The result is a test that tests when the child of a blur node is
clipped out but the blurred child is not, the blurred parts are still
visible.

This immediately broke the cairo renderer, so the fix is included.
2023-12-11 07:33:24 +01:00
Matthias Clasen
36314f28e2 gsk: Some more rect inlining 2023-11-24 10:35:57 -05:00
Matthias Clasen
c57245b73c diff: Take above-ness into account
We need to include the full area if a subsurface
above-ness changes, since we only punch holes if
it is above.

Fixes: #6214
2023-11-18 08:19:43 -05:00
Matthias Clasen
48740de71a gsk: Add a subsurface mode to node diffing
Add an extra argument to pass offload info to the diffing code.
This is then used for diffing subsurface nodes differently,
depending on their offloading status.
2023-11-13 22:17:35 +01:00
Matthias Clasen
d0a675ab01 gsk: Add subsurface nodes
Also show them in the inspector recorder, with some information.
2023-11-13 22:17:35 +01:00
Matthias Clasen
b766f92026 gsk: Use some more inline helpers 2023-11-13 22:17:35 +01:00
Benjamin Otte
85e1088171 gsk: Fix texture-scale node Cairo drawing
The code was interpreting x/y coordinates wrong sometimes and causing
things to not be drawn at the correct offset.

Testcase included.
2023-10-31 00:36:27 +01:00
Benjamin Otte
c1ed034367 rendernode: Use an exisiting function instead of reimplementing it 2023-10-31 00:36:27 +01:00
Benjamin Otte
95865cb1bf gsk: Fix clipping error when drawing shadows
When shadows were offset - in particular when offset so the original
source was out of bounds of the result - the drawing code would create a
pattern for it that didn't include enough of it to compose a shadow.

Fix that by not creating those patterns anymore, but instead drawing the
source (potentially multiple times) at the required offsets.

While that does more drawing, it simplifies the shadow node draw code,
and that's the primary goal of the Cairo rendering.

Test included.
2023-09-18 07:53:03 +02:00
Benjamin Otte
f8627755b5 rendernode: Shadow nodes need offscreen for opacity
Otherwise the shadow will not be properly computed as opaque regions
become translucent after applying opacity.

Testcase included.
2023-09-15 03:46:27 +02:00
Benjamin Otte
a05a021fd1 rendernode: Fix Cairo rendering of repeating gradients
Cairo and the GL renderer have a different idea of how to handle
transitioning of colors outside the defined range.

Consider these stops:
  black 50%, white 50%

What color is at 0%?

Cairo would transition between the last and first stop, ie it'd do a
white-to-black transition and end up at rgb(0.5,0.5,0.5) at 0%.
GL would behave as it would for non-repeating gradients and use black
for the range [0%..50%] and white for [50%..100%].
The web would rescale the range so the first stop would be at 0% and
the last stop would be at 100%, so this gradient would be illegal.

Considering that it's possible for code to transition between the
different behaviors by adding explicit stops at 0%/100%, I could choose
any method.
So I chose the simplest one, which is what the GL renderer does and
which treats repeating and non-repeating gradients the same.

Tests attached.
2023-09-07 16:19:20 +02:00
Sergey Bugaev
246a7cfeab rendernode, snapshot: Slightly expand color matrix docs
Based on reverse engineering the color node and contrary to my
expectations, the matrix/offset is expressed in, and applied to,
unpremultiplied colors. The colors are being explicitly
unpremultiplied, transformed according to the matrix/offset, and
premultiplied back (see color_matrix.glsl). The matrix is getting
transposed.

Also, copy the same blurb to the corresponding GtkSnapshot function.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-08-16 13:55:04 +03:00
Matthias Clasen
47ddc742fc path: Some documentation improvements
Among other things, add a quick summary of
SVG path syntax, and add a few illustrations.
2023-08-11 12:09:12 -04:00