зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1706678 - Fix cached gradient scaling. r=gfx-reviewers,lsalzman
Large gradients are cached scaled down and stretched back by the image brush. Because the scaling factor is non-uniform the shader has to take it into account. The previous implementation was incorrectly accounting for the scale. Differential Revision: https://phabricator.services.mozilla.com/D113753
This commit is contained in:
Родитель
2f83f1a6f4
Коммит
720d336a44
|
@ -15,6 +15,7 @@ flat varying float v_start_radius;
|
|||
// Rectangle in origin+size format
|
||||
PER_INSTANCE in vec4 aTaskRect;
|
||||
PER_INSTANCE in vec2 aCenter;
|
||||
PER_INSTANCE in vec2 aScale;
|
||||
PER_INSTANCE in float aStartRadius;
|
||||
PER_INSTANCE in float aEndRadius;
|
||||
PER_INSTANCE in float aXYRatio;
|
||||
|
@ -37,7 +38,7 @@ void main(void) {
|
|||
|
||||
// v_pos is in a coordinate space relative to the task rect
|
||||
// (so it is independent of the task origin).
|
||||
v_pos = (aTaskRect.zw * aPosition.xy - aCenter) * radius_scale;
|
||||
v_pos = (aTaskRect.zw * aPosition.xy * aScale - aCenter) * radius_scale;
|
||||
v_pos.y *= aXYRatio;
|
||||
|
||||
v_gradient_repeat = float(aExtendMode == EXTEND_MODE_REPEAT);
|
||||
|
|
|
@ -142,11 +142,11 @@ impl From<ConicGradientKey> for ConicGradientTemplate {
|
|||
let mut task_size: DeviceSize = stretch_size.cast_unit();
|
||||
let mut scale = vec2(1.0, 1.0);
|
||||
if task_size.width > MAX_SIZE {
|
||||
scale.x = MAX_SIZE / task_size.width;
|
||||
scale.x = task_size.width / MAX_SIZE;
|
||||
task_size.width = MAX_SIZE;
|
||||
}
|
||||
if task_size.height > MAX_SIZE {
|
||||
scale.y = MAX_SIZE / task_size.height;
|
||||
scale.y = task_size.height / MAX_SIZE;
|
||||
task_size.height = MAX_SIZE;
|
||||
}
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ fn test_struct_sizes() {
|
|||
assert_eq!(mem::size_of::<LinearGradientKey>(), 88, "LinearGradientKey size changed");
|
||||
|
||||
assert_eq!(mem::size_of::<RadialGradient>(), 72, "RadialGradient size changed");
|
||||
assert_eq!(mem::size_of::<RadialGradientTemplate>(), 136, "RadialGradientTemplate size changed");
|
||||
assert_eq!(mem::size_of::<RadialGradientTemplate>(), 144, "RadialGradientTemplate size changed");
|
||||
assert_eq!(mem::size_of::<RadialGradientKey>(), 96, "RadialGradientKey size changed");
|
||||
|
||||
assert_eq!(mem::size_of::<ConicGradient>(), 72, "ConicGradient size changed");
|
||||
|
|
|
@ -96,6 +96,7 @@ pub struct RadialGradientTemplate {
|
|||
pub params: RadialGradientParams,
|
||||
pub center: DevicePoint,
|
||||
pub task_size: DeviceIntSize,
|
||||
pub scale: DeviceVector2D,
|
||||
pub stretch_size: LayoutSize,
|
||||
pub tile_spacing: LayoutSize,
|
||||
pub brush_segments: Vec<BrushSegment>,
|
||||
|
@ -143,30 +144,24 @@ impl From<RadialGradientKey> for RadialGradientTemplate {
|
|||
// differences, especially with 8 bits per channel.
|
||||
const MAX_SIZE: f32 = 1024.0;
|
||||
let mut task_size: DeviceSize = stretch_size.cast_unit();
|
||||
let mut center = DevicePoint::new(item.center.x, item.center.y);
|
||||
let mut params = item.params;
|
||||
let mut scale = vec2(1.0, 1.0);
|
||||
if task_size.width > MAX_SIZE {
|
||||
let sx = MAX_SIZE / task_size.width;
|
||||
scale.x = task_size.width/ MAX_SIZE;
|
||||
task_size.width = MAX_SIZE;
|
||||
params.ratio_xy *= sx;
|
||||
center.x *= sx;
|
||||
params.start_radius *= sx;
|
||||
params.end_radius *= sx;
|
||||
}
|
||||
if task_size.height > MAX_SIZE {
|
||||
let sy = MAX_SIZE / task_size.height;
|
||||
scale.y = task_size.height /MAX_SIZE;
|
||||
task_size.height = MAX_SIZE;
|
||||
params.ratio_xy /= sy;
|
||||
center.y *= sy;
|
||||
}
|
||||
|
||||
RadialGradientTemplate {
|
||||
common,
|
||||
center,
|
||||
center: DevicePoint::new(item.center.x, item.center.y),
|
||||
extend_mode: item.extend_mode,
|
||||
params,
|
||||
params: item.params,
|
||||
stretch_size,
|
||||
task_size: task_size.ceil().to_i32(),
|
||||
scale,
|
||||
tile_spacing: item.tile_spacing.into(),
|
||||
brush_segments,
|
||||
stops_opacity,
|
||||
|
@ -221,6 +216,7 @@ impl RadialGradientTemplate {
|
|||
let cache_key = RadialGradientCacheKey {
|
||||
size: task_size,
|
||||
center: PointKey { x: self.center.x, y: self.center.y },
|
||||
scale: PointKey { x: self.scale.x, y: self.scale.y },
|
||||
start_radius: FloatKey(self.params.start_radius),
|
||||
end_radius: FloatKey(self.params.end_radius),
|
||||
ratio_xy: FloatKey(self.params.ratio_xy),
|
||||
|
@ -245,6 +241,7 @@ impl RadialGradientTemplate {
|
|||
RenderTaskKind::RadialGradient(RadialGradientTask {
|
||||
extend_mode: self.extend_mode,
|
||||
center: self.center,
|
||||
scale: self.scale,
|
||||
params: self.params.clone(),
|
||||
stops: self.stops_handle,
|
||||
}),
|
||||
|
@ -317,6 +314,7 @@ impl IsVisible for RadialGradient {
|
|||
pub struct RadialGradientTask {
|
||||
pub extend_mode: ExtendMode,
|
||||
pub center: DevicePoint,
|
||||
pub scale: DeviceVector2D,
|
||||
pub params: RadialGradientParams,
|
||||
pub stops: GpuCacheHandle,
|
||||
}
|
||||
|
@ -326,6 +324,7 @@ impl RadialGradientTask {
|
|||
RadialGradientInstance {
|
||||
task_rect: target_rect.to_f32(),
|
||||
center: self.center,
|
||||
scale: self.scale,
|
||||
start_radius: self.params.start_radius,
|
||||
end_radius: self.params.end_radius,
|
||||
ratio_xy: self.params.ratio_xy,
|
||||
|
@ -345,6 +344,7 @@ impl RadialGradientTask {
|
|||
pub struct RadialGradientInstance {
|
||||
pub task_rect: DeviceRect,
|
||||
pub center: DevicePoint,
|
||||
pub scale: DeviceVector2D,
|
||||
pub start_radius: f32,
|
||||
pub end_radius: f32,
|
||||
pub ratio_xy: f32,
|
||||
|
@ -358,6 +358,7 @@ pub struct RadialGradientInstance {
|
|||
pub struct RadialGradientCacheKey {
|
||||
pub size: DeviceIntSize,
|
||||
pub center: PointKey,
|
||||
pub scale: PointKey,
|
||||
pub start_radius: FloatKey,
|
||||
pub end_radius: FloatKey,
|
||||
pub ratio_xy: FloatKey,
|
||||
|
|
|
@ -186,6 +186,11 @@ pub mod desc {
|
|||
count: 2,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aScale",
|
||||
count: 2,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aStartRadius",
|
||||
count: 1,
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
root:
|
||||
items:
|
||||
- type: rect
|
||||
bounds: 50 50 2000 300
|
||||
color: blue
|
||||
|
||||
- type: conic-gradient
|
||||
bounds: 50 50 2000 300
|
||||
center: 150 150
|
||||
angle: 0.0
|
||||
stops: [0.0, red,
|
||||
0.125, blue,
|
||||
0.375, blue,
|
||||
0.5, yellow,
|
||||
1.0, red]
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
root:
|
||||
items:
|
||||
- type: conic-gradient
|
||||
bounds: 50 50 2000 300
|
||||
center: 150 150
|
||||
angle: 0.0
|
||||
stops: [0.0, red,
|
||||
0.125, blue,
|
||||
0.375, blue,
|
||||
0.5, yellow,
|
||||
1.0, red]
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
root:
|
||||
items:
|
||||
- type: rect
|
||||
bounds: 50 50 2000 300
|
||||
color: blue
|
||||
|
||||
- type: gradient
|
||||
bounds: 50 50 400 300
|
||||
start: 0 0
|
||||
end: 100 20
|
||||
stops: [0.0, red, 1.0, blue]
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
root:
|
||||
items:
|
||||
- type: gradient
|
||||
bounds: 50 50 2000 300
|
||||
start: 0 0
|
||||
end: 100 20
|
||||
stops: [0.0, red, 1.0, blue]
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 36 KiB |
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
root:
|
||||
items:
|
||||
- type: radial-gradient
|
||||
bounds: 50 50 2000 300
|
||||
center: 1000 150
|
||||
radius: 900 200
|
||||
stops: [0, red, 1, blue]
|
|
@ -110,3 +110,8 @@ fuzzy-range(<=1,1) == gradient_cache_hardstop_clip.yaml gradient_cache_hardstop_
|
|||
# Exercise the radial gradient optimization code path
|
||||
== radial-optimized.yaml radial-optimized-ref.yaml
|
||||
== radial-tiling-optimized.yaml radial-tiling-optimized-ref.yaml
|
||||
|
||||
# Exercise the cached gradient scaling code path
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче