Copy what gcc's libstdc++ does for vectors to avoid overflows:
1. Define a max size macro and assert against it
Note that we don't assert but actually check, because this needs
to abort even if assertions are disabled.
2. Don't do fancy math to compute new capacity.
Just size *= 2 instead and be careful about overflow.
We'll need this to support variables in @keyframes, since styles will
need to combine their own variables and the ones from the keyframes.
See the next commit, this one is split out to avoid a huge diff.
We want to store some metadata in our symbolic pngs, so make it
possible to get options when loading a png, along with the texture.
Update all callers.
Due to rounding errors, it is possible after intersecting a lot of
rectangles to end up with a tiny size for an offscreen. And because we
allow an epsilon before ceil()ing to an integer (see commit afc7b46264
for details) it is now possible that we end up with a size of 0.
Avoid that by always enforcing a minimum size of 1px.
Test included
The test uses a different codepath to arrive at the same problem - it
specifies the small size instead of triggering it via rounding errors
and clipping like the original bug (and most likely the more common case
to encounter this problem.
Fixes#6656
Rename things so they make more sense. The dest/source naming got
a bit unclear when we added background into the mix. Now we're going
for:
source_rect - the texture region to display
texture_rect - dimensions of the subsurface showing the texture
background_rect - dimensions of the background subsurface
bounds - union of texture_rect and background_rect
Also use this opportunity to add some api docs.
Make it possible for subsurfaces to have a black background on a
secondary subsurface below the actual subsurface. Using a single-pixel
buffer for that background increases the changes that the compositor
will use direct scanout for the actual subsurface.
This changes the private subsurface API. All callers have been
updated to pass an empty background rect.
The goal is to generate an offscreen at 1x scale.
When not ceil()ing the numbers the offscreen code would do it *and*
adjust the scale accordingly, so we'd end up with something like a
1.01x scale.
And that would cause the code to reenter this codepath with the goal to
generate an offscreen at 1x scale.
And indeed, this would lead to infinite recursion.
Tests included.
Fixes#6553
Allow to specify a D₂ transform when attaching a texture to a
subsurface, to handle flipped and rotated content. The Wayland
implementation handles these transforms by setting a buffer
transform on the subsurface.
All callers have been updated to pass GDK_TEXTURE_TRANSFORM_NORMAL.
In a very particular situation, it could happen that our renderpass
reordering did not work out.
Consider this nesting of renderpasses (indentation indicates subpasses):
pass A
subpass of A
pass B
subpass of B
Out reordering code would reorder this as:
subpass of B
subpass of A
pass A
pass B
Which doesn't sound too bad, the subpasses happen before the passes
after all.
However, a subpass might be a pass that converts the image for a texture
stored in the texture cache and then updates the cached image.
If "subpass of A" is such a pass *and* if "subpass of B" then renders
with exactly this texture, then "subpass of B" will use the result of
"subpass of A" as a source.
The fix is to ensure that subpasses stay ordered, too.
The new order moves subpasses right before their parent pass, so the
order of the example now looks like:
subpass of A
pass A
subpass of B
pass B
The place where this would happen most common was when drawing thumbnail
images in Nautilus, the GTK filechooser or Fractal.
Those images are usually PNG files, which are straight alpha. They are then
drawn with a drop shadow, which requires an offscreen for drawing as
well as those images as premultipled sources, so lots of subpasses happen.
If there is then a redraw with a somewhat tricky subregion, then the
slicing of the region code could end up generating 2 passes that each draw
half of the thumbnail image - the first pass drawing the top half and the
second pass drawing the bottom half.
And due to the bug the bottom half would then be drawn from the
offscreen before the actual contents of the offscreen would be drawn,
leading to a corrupt bottom part of the image.
Test included.
Fixes: #6318