Bug 1707744 - Avoid far gradient endpoints causing large gradient segments. r=gfx-reviewers,lsalzman

Large segment bounds trip an assertion when casting coordinates to integers. Clipping early also reduces the amount of cached pixels.

Differential Revision: https://phabricator.services.mozilla.com/D113819
This commit is contained in:
Nicolas Silva 2021-05-03 09:12:42 +00:00
parent 720d336a44
commit 06ef812482
4 changed files with 31 additions and 6 deletions

View File

@ -118,8 +118,8 @@ pub fn optimize_linear_gradient(
end: &mut LayoutPoint,
extend_mode: ExtendMode,
stops: &mut [GradientStopKey],
// Callback called for each fast-path segment (rect, clip, start end, stops).
callback: &mut dyn FnMut(&LayoutRect, &LayoutRect, LayoutPoint, LayoutPoint, &[GradientStopKey])
// Callback called for each fast-path segment (rect, start end, stops).
callback: &mut dyn FnMut(&LayoutRect, LayoutPoint, LayoutPoint, &[GradientStopKey])
) -> bool {
let offset = apply_gradient_local_clip(
prim_rect,
@ -264,13 +264,25 @@ pub fn optimize_linear_gradient(
let mut start = point2(0.0, 0.0);
let mut end = point2(segment_length, 0.0);
adjust_rect(&mut segment_rect);
adjust_point(&mut start);
adjust_point(&mut end);
adjust_rect(&mut segment_rect);
let origin_before_clip = segment_rect.origin;
segment_rect = match segment_rect.intersection(&clip_rect) {
Some(rect) => rect,
None => {
continue;
}
};
let offset = segment_rect.origin - origin_before_clip;
// Account for the clipping since start and end are relative to the origin.
start -= offset;
end -= offset;
callback(
&segment_rect,
&clip_rect,
start,
end,
&[

View File

@ -1244,8 +1244,8 @@ impl<'a> SceneBuilder<'a> {
&mut end,
info.gradient.extend_mode,
&mut stops,
&mut |rect, clip, start, end, stops| {
let layout = LayoutPrimitiveInfo { rect: *rect, clip_rect: *clip, flags };
&mut |rect, start, end, stops| {
let layout = LayoutPrimitiveInfo { rect: *rect, clip_rect: *rect, flags };
if let Some(prim_key_kind) = self.create_linear_gradient_prim(
&layout,
start,

View File

@ -0,0 +1,10 @@
# Axis-aligned linear gradient with very far endpoints. It goes through the gradient
# decomposition path which should not choke on overflow or casting failure.
---
root:
items:
- type: gradient
bounds: 50 50 500 500
start: -19958788096 0
end: 19958788096 0
stops: [0.0, red, 1.0, blue]

View File

@ -115,3 +115,6 @@ fuzzy-range(<=1,1) == gradient_cache_hardstop_clip.yaml gradient_cache_hardstop_
fuzzy(2,23000) == linear-large.yaml linear-large-ref.yaml
== conic-large.yaml conic-large-ref.yaml
fuzzy(1,7000) == radial-large.yaml radial-large-ref.png
# crash tests
== linear-far-endpoints.yaml linear-far-endpoints.yaml