mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1565039. In PicturePrimitive::take_context do calculation in float in case the unclipped rect is too big for int. r=gw
The final clipped result should hopefully not overflow. Differential Revision: https://phabricator.services.mozilla.com/D37813 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
71cf2ae4e8
commit
e4f60aaea0
@ -2316,7 +2316,7 @@ impl PicturePrimitive {
|
||||
blur_std_deviation * scale_factors.1
|
||||
);
|
||||
let inflation_factor = frame_state.surfaces[raster_config.surface_index.0].inflation_factor;
|
||||
let inflation_factor = (inflation_factor * device_pixel_scale.0).ceil() as i32;
|
||||
let inflation_factor = (inflation_factor * device_pixel_scale.0).ceil();
|
||||
|
||||
// The clipped field is the part of the picture that is visible
|
||||
// on screen. The unclipped field is the screen-space rect of
|
||||
@ -2326,10 +2326,20 @@ impl PicturePrimitive {
|
||||
// blur results, inflate that clipped area by the blur range, and
|
||||
// then intersect with the total screen rect, to minimize the
|
||||
// allocation size.
|
||||
let mut device_rect = clipped
|
||||
// We cast clipped to f32 instead of casting unclipped to i32
|
||||
// because unclipped can overflow an i32.
|
||||
let device_rect = clipped.to_f32()
|
||||
.inflate(inflation_factor, inflation_factor)
|
||||
.intersection(&unclipped.to_i32())
|
||||
.intersection(&unclipped)
|
||||
.unwrap();
|
||||
|
||||
let mut device_rect = match device_rect.try_cast::<i32>() {
|
||||
Some(rect) => rect,
|
||||
None => {
|
||||
return None
|
||||
}
|
||||
};
|
||||
|
||||
// Adjust the size to avoid introducing sampling errors during the down-scaling passes.
|
||||
// what would be even better is to rasterize the picture at the down-scaled size
|
||||
// directly.
|
||||
@ -2379,10 +2389,21 @@ impl PicturePrimitive {
|
||||
}
|
||||
|
||||
max_std_deviation = max_std_deviation.round();
|
||||
let max_blur_range = (max_std_deviation * BLUR_SAMPLE_SCALE).ceil() as i32;
|
||||
let mut device_rect = clipped.inflate(max_blur_range, max_blur_range)
|
||||
.intersection(&unclipped.to_i32())
|
||||
let max_blur_range = (max_std_deviation * BLUR_SAMPLE_SCALE).ceil();
|
||||
// We cast clipped to f32 instead of casting unclipped to i32
|
||||
// because unclipped can overflow an i32.
|
||||
let device_rect = clipped.to_f32()
|
||||
.inflate(max_blur_range, max_blur_range)
|
||||
.intersection(&unclipped)
|
||||
.unwrap();
|
||||
|
||||
let mut device_rect = match device_rect.try_cast::<i32>() {
|
||||
Some(rect) => rect,
|
||||
None => {
|
||||
return None
|
||||
}
|
||||
};
|
||||
|
||||
device_rect.size = RenderTask::adjusted_blur_source_size(
|
||||
device_rect.size,
|
||||
DeviceSize::new(max_std_deviation, max_std_deviation),
|
||||
|
@ -0,0 +1,17 @@
|
||||
# Don't crash on large blur radius with large transform!
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 1000, 1000]
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 1000, 1000]
|
||||
transform: scale-y(999999.25)
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 1000, 1000]
|
||||
filters: drop-shadow([999999, 999999], 999999, [255, 0, 0, 1])
|
||||
items:
|
||||
- image: checkerboard(2, 16, 16)
|
||||
bounds: [0, 0, 1000, 1000]
|
@ -42,6 +42,7 @@ skip_on(android) == filter-mix-blend-mode.yaml filter-mix-blend-mode-ref.yaml #
|
||||
!= srgb-to-linear-2.yaml srgb-to-linear-ref.yaml
|
||||
!= filter-blur-huge.yaml blank.yaml
|
||||
!= filter-drop-shadow-huge.yaml blank.yaml
|
||||
!= filter-drop-shadow-transform-huge.yaml blank.yaml
|
||||
== filter-blur-scaled.yaml filter-blur-scaled-ref.yaml
|
||||
skip_on(android) == filter-blur-scaled-xonly.yaml filter-blur-scaled-xonly.png # fails on Android emulator and Pixel2
|
||||
skip_on(android,emulator) == svg-filter-component-transfer.yaml filter-component-transfer-ref.yaml # fails on Android emulator
|
||||
|
Loading…
Reference in New Issue
Block a user