Bug 1677872 - reduce division usage in brush shaders. r=gw

Differential Revision: https://phabricator.services.mozilla.com/D97379
This commit is contained in:
Lee Salzman 2020-11-18 04:35:22 +00:00
Родитель e0d3bfd380
Коммит bca1de14ee
12 изменённых файлов: 94 добавлений и 50 удалений

Просмотреть файл

@ -3452,6 +3452,13 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
Type::new(Float),
vec![Type::new(Float)],
);
declare_function(
state,
"fract",
None,
Type::new(Vec2),
vec![Type::new(Vec2)],
);
declare_function(state, "mod", None, Type::new(Vec2), vec![Type::new(Vec2)]);
declare_function(state, "mod", None, Type::new(Float), vec![Type::new(Float)]);

Просмотреть файл

@ -361,6 +361,12 @@ struct vec2_scalar {
return *this;
}
vec2_scalar operator/=(vec2_scalar a) {
x /= a.x;
y /= a.y;
return *this;
}
vec2_scalar operator+=(vec2_scalar a) {
x += a.x;
y += a.y;
@ -641,12 +647,14 @@ template <typename T> SI auto round_pixel(T v) { return roundfast(v, 255.0f); }
float round(float a) { return roundf(a); }
float fract(float a) { return a - floor(a); }
Float round(Float v) { return floor(v + 0.5f); }
float fract(float a) { return a - floor(a); }
Float fract(Float v) { return v - floor(v); }
vec2 fract(vec2 v) { return vec2(fract(v.x), fract(v.y)); }
// X derivatives can be approximated by dFdx(x) = x[1] - x[0].
// Y derivatives are not easily available since we operate in terms of X spans
// only. To work around, assume dFdy(p.x) = dFdx(p.y), which only holds for

Просмотреть файл

@ -10,7 +10,7 @@ flat varying HIGHP_FS_ADDRESS int v_gradient_address;
flat varying vec2 v_center;
flat varying float v_start_offset;
flat varying float v_end_offset;
flat varying float v_offset_scale;
flat varying float v_angle;
// Size of the gradient pattern's rectangle, used to compute horizontal and vertical
@ -73,13 +73,22 @@ void brush_vs(
}
v_center = gradient.center_point;
v_angle = gradient.angle;
v_angle = PI / 2.0 - gradient.angle;
v_start_offset = gradient.start_end_offset.x;
v_end_offset = gradient.start_end_offset.y;
if (gradient.start_end_offset.x != gradient.start_end_offset.y) {
// Store 1/scale where scale = end_offset - start_offset
v_offset_scale = 1.0 / (gradient.start_end_offset.y - gradient.start_end_offset.x);
} else {
// If scale = 0, we can't get its reciprocal. Instead, just use a zero scale.
v_offset_scale = 0.0;
}
vec2 tile_repeat = local_rect.size / gradient.stretch_size;
v_repeated_size = gradient.stretch_size;
// Normalize UV to 0..1 scale.
v_pos /= v_repeated_size;
v_gradient_address = prim_user_data.x;
// Whether to repeat the gradient along the line instead of clamping.
@ -100,25 +109,27 @@ Fragment brush_fs() {
vec2 local_pos = max(v_pos, vec2(0.0));
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(local_pos, v_repeated_size);
vec2 pos = fract(local_pos);
vec2 prim_size = v_repeated_size * v_tile_repeat;
// Handle bottom and right inflated edges (see brush_image).
if (local_pos.x >= prim_size.x) {
pos.x = v_repeated_size.x;
if (local_pos.x >= v_tile_repeat.x) {
pos.x = 1.0;
}
if (local_pos.y >= prim_size.y) {
pos.y = v_repeated_size.y;
if (local_pos.y >= v_tile_repeat.y) {
pos.y = 1.0;
}
#else
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(v_pos, v_repeated_size);
vec2 pos = fract(v_pos);
#endif
// Rescale UV to actual repetition size. This can't be done in the vertex
// shader due to the use of atan() below.
pos *= v_repeated_size;
vec2 current_dir = pos - v_center;
float current_angle = atan(current_dir.y, current_dir.x) + (PI / 2.0 - v_angle);
float offset = mod(current_angle / (2.0 * PI), 1.0) - v_start_offset;
offset = offset / (v_end_offset - v_start_offset);
float current_angle = atan(current_dir.y, current_dir.x) + v_angle;
float offset = (fract(current_angle / (2.0 * PI)) - v_start_offset) * v_offset_scale;
vec4 color = sample_gradient(v_gradient_address,
offset,

Просмотреть файл

@ -221,6 +221,13 @@ void brush_vs(
v_uv_bounds = vec4(min_uv, max_uv) / texture_size.xyxy;
#endif
#ifdef WR_FEATURE_REPETITION
// Normalize UV to 0..1 scale only if using repetition. Otherwise, leave
// UVs unnormalized since we won't compute a modulus without repetition
// enabled.
v_uv /= (v_uv_bounds.zw - v_uv_bounds.xy);
#endif
#ifdef WR_FEATURE_ALPHA_PASS
v_tile_repeat = repeat.xy;
@ -279,19 +286,19 @@ vec2 compute_repeated_uvs(float perspective_divisor) {
vec2 local_uv = max(v_uv * perspective_divisor, vec2(0.0));
// Handle horizontal and vertical repetitions.
vec2 repeated_uv = mod(local_uv, uv_size) + v_uv_bounds.xy;
vec2 repeated_uv = fract(local_uv) * uv_size + v_uv_bounds.xy;
// This takes care of the bottom and right inflated parts.
// We do it after the modulo because the latter wraps around the values exactly on
// the right and bottom edges, which we do not want.
if (local_uv.x >= v_tile_repeat.x * uv_size.x) {
if (local_uv.x >= v_tile_repeat.x) {
repeated_uv.x = v_uv_bounds.z;
}
if (local_uv.y >= v_tile_repeat.y * uv_size.y) {
if (local_uv.y >= v_tile_repeat.y) {
repeated_uv.y = v_uv_bounds.w;
}
#else
vec2 repeated_uv = mod(v_uv * perspective_divisor, uv_size) + v_uv_bounds.xy;
vec2 repeated_uv = fract(v_uv * perspective_divisor) * uv_size + v_uv_bounds.xy;
#endif
return repeated_uv;

Просмотреть файл

@ -10,10 +10,6 @@ flat varying HIGHP_FS_ADDRESS int v_gradient_address;
flat varying vec2 v_start_point;
flat varying vec2 v_scale_dir;
// Size of the gradient pattern's rectangle, used to compute horizontal and vertical
// repetitions. Not to be confused with another kind of repetition of the pattern
// which happens along the gradient stops.
flat varying vec2 v_repeated_size;
// Repetition along the gradient stops.
flat varying float v_gradient_repeat;
@ -71,7 +67,16 @@ void brush_vs(
v_scale_dir = dir / dot(dir, dir);
vec2 tile_repeat = local_rect.size / gradient.stretch_size;
v_repeated_size = gradient.stretch_size;
// Size of the gradient pattern's rectangle, used to compute horizontal and vertical
// repetitions. Not to be confused with another kind of repetition of the pattern
// which happens along the gradient stops.
vec2 repeated_size = gradient.stretch_size;
// Normalize UV and offsets to 0..1 scale.
v_pos /= repeated_size;
v_start_point /= repeated_size;
v_scale_dir *= repeated_size;
v_gradient_address = prim_user_data.x;
@ -93,19 +98,18 @@ Fragment brush_fs() {
vec2 local_pos = max(v_pos, vec2(0.0));
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(local_pos, v_repeated_size);
vec2 pos = fract(local_pos);
vec2 prim_size = v_repeated_size * v_tile_repeat;
// Handle bottom and right inflated edges (see brush_image).
if (local_pos.x >= prim_size.x) {
pos.x = v_repeated_size.x;
if (local_pos.x >= v_tile_repeat.x) {
pos.x = 1.0;
}
if (local_pos.y >= prim_size.y) {
pos.y = v_repeated_size.y;
if (local_pos.y >= v_tile_repeat.y) {
pos.y = 1.0;
}
#else
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(v_pos, v_repeated_size);
vec2 pos = fract(v_pos);
#endif
float offset = dot(pos - v_start_point, v_scale_dir);

Просмотреть файл

@ -66,7 +66,7 @@ void brush_vs(
v_center = gradient.center_start_end_radius.xy;
v_start_radius = gradient.center_start_end_radius.z;
if (gradient.center_start_end_radius.z != gradient.center_start_end_radius.w) {
// Store 1/rd where rd = end_radius - start_start
// Store 1/rd where rd = end_radius - start_radius
v_radius_scale = 1.0 / (gradient.center_start_end_radius.w - gradient.center_start_end_radius.z);
} else {
// If rd = 0, we can't get its reciprocal. Instead, just use a zero scale.
@ -81,6 +81,9 @@ void brush_vs(
v_repeated_size = gradient.stretch_size;
v_repeated_size.y *= gradient.ratio_xy;
// Normalize UV to 0..1 scale.
v_pos /= v_repeated_size;
v_gradient_address = prim_user_data.x;
// Whether to repeat the gradient instead of clamping.
@ -101,21 +104,24 @@ Fragment brush_fs() {
vec2 local_pos = max(v_pos, vec2(0.0));
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(local_pos, v_repeated_size);
vec2 pos = fract(local_pos);
vec2 prim_size = v_repeated_size * v_tile_repeat;
// Handle bottom and right inflated edges (see brush_image).
if (local_pos.x >= prim_size.x) {
pos.x = v_repeated_size.x;
if (local_pos.x >= v_tile_repeat.x) {
pos.x = 1.0;
}
if (local_pos.y >= prim_size.y) {
pos.y = v_repeated_size.y;
if (local_pos.y >= v_tile_repeat.y) {
pos.y = 1.0;
}
#else
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(v_pos, v_repeated_size);
vec2 pos = fract(v_pos);
#endif
// Rescale UV to actual repetition size. This can't be done in the vertex
// shader due to the use of length() below.
pos *= v_repeated_size;
// Solve for t in length(pd) = v_start_radius + t * rd
vec2 pd = pos - v_center;
float offset = (length(pd) - v_start_radius) * v_radius_scale;

Просмотреть файл

@ -60,7 +60,7 @@ platform(linux,mac) == svg-filter-drop-shadow.yaml svg-filter-drop-shadow.png
platform(linux,mac) == fuzzy(5,35250) svg-filter-drop-shadow-rotate.yaml svg-filter-drop-shadow-rotate-ref.yaml
platform(linux,mac) fuzzy(3,3184) == svg-filter-blur-transforms.yaml svg-filter-blur-transforms.png
platform(linux,mac) == svg-filter-drop-shadow-on-viewport-edge.yaml svg-filter-drop-shadow-on-viewport-edge.png
platform(linux,mac) == svg-filter-drop-shadow-perspective.yaml svg-filter-drop-shadow-perspective.png
fuzzy(1,1) platform(linux,mac) == svg-filter-drop-shadow-perspective.yaml svg-filter-drop-shadow-perspective.png
== backdrop-filter-basic.yaml backdrop-filter-basic-ref.yaml
platform(linux,mac) == backdrop-filter-perspective.yaml backdrop-filter-perspective.png
platform(linux,max) == svg-filter-offset.yaml svg-filter-offset-ref.yaml

Просмотреть файл

@ -1,5 +1,5 @@
platform(linux,mac) == premultiplied-aligned.yaml premultiplied-aligned.png
platform(linux,mac) == premultiplied-angle.yaml premultiplied-angle.png
fuzzy(1,500) platform(linux,mac) == premultiplied-angle.yaml premultiplied-angle.png
platform(linux,mac) == premultiplied-radial.yaml premultiplied-radial.png
platform(linux,mac) == premultiplied-conic.yaml premultiplied-conic.png
@ -67,7 +67,7 @@ fuzzy(1,17) == tiling-radial-4.yaml tiling-radial-4-ref.yaml
fuzzy(1,17) == tiling-conic-1.yaml tiling-conic-1-ref.yaml
fuzzy(1,1) == tiling-conic-2.yaml tiling-conic-2-ref.yaml
fuzzy(1,3) == tiling-conic-3.yaml tiling-conic-3-ref.yaml
fuzzy(1,7) == tiling-conic-3.yaml tiling-conic-3-ref.yaml
== radial-zero-size-1.yaml radial-zero-size-ref.yaml
== radial-zero-size-2.yaml radial-zero-size-ref.yaml
@ -81,7 +81,7 @@ platform(linux,mac) fuzzy-range(<=1,*1404) == repeat-border-radius.yaml repeat-b
== conic.yaml conic-ref.yaml
fuzzy(1,57) == conic-simple.yaml conic-simple.png
fuzzy(255,166) == conic-angle.yaml conic-angle.png
fuzzy(255,302) == conic-angle.yaml conic-angle.png
== conic-center.yaml conic-center.png
fuzzy(1,2) == conic-angle-wraparound.yaml conic-angle.yaml
fuzzy(1,1) == conic-angle-wraparound-negative.yaml conic-angle.yaml

Просмотреть файл

@ -14,7 +14,7 @@ platform(linux,mac) == coord-system.yaml coord-system.png
platform(linux,mac) fuzzy(1,5) zoom(4) == border-zoom.yaml border-zoom.png
platform(linux) fuzzy(1,520) == perspective-origin.yaml perspective-origin.png
platform(linux,mac) color_targets(3) alpha_targets(0) fuzzy(1,180) == screen-space-blit.yaml screen-space-blit.png
platform(linux,mac) fuzzy(1,331) color_targets(2) alpha_targets(0) == screen-space-blit-trivial.yaml screen-space-blit-trivial.png
platform(linux,mac) fuzzy(1,346) color_targets(2) alpha_targets(0) == screen-space-blit-trivial.yaml screen-space-blit-trivial.png
platform(linux) fuzzy(11,4592) == screen-space-blur.yaml screen-space-blur.png
platform(linux,mac) == nested-rotate-x.yaml nested-rotate-x.png
platform(linux,mac) != nested-rotate-x.yaml nested-rotate-x-flat.yaml

Просмотреть файл

@ -42,20 +42,20 @@ fuzzy-if(asyncPan&&!layersGPUAccelerated,0-140,0-514) fuzzy-if(winWidget,0-144,0
== border-image-style-none-auto.html border-image-style-none-auto-ref.html
# border images with gradients
fuzzy-if(webrender&&!geckoview,1-3,784-1804) == border-image-linear-gradient.html border-image-linear-gradient-ref.html
fuzzy-if(webrender&&!geckoview,1-3,554-1804) == border-image-linear-gradient.html border-image-linear-gradient-ref.html
fuzzy(0-1,0-98) fuzzy-if(skiaContent,0-1,0-350) fuzzy-if(webrender&&!geckoview,1-3,1086-37537) == border-image-linear-gradient-slice-1.html border-image-linear-gradient-slice-1-ref.html
fuzzy(0-1,0-515) fuzzy-if(OSX,0-1,0-10595) fuzzy-if(webrender&&!geckoview,1-3,272-25136) == border-image-linear-gradient-slice-2.html border-image-linear-gradient-slice-2-ref.html
fuzzy-if(skiaContent,0-1,0-2500) fuzzy-if(webrender&&!geckoview,1-3,2500-86037) == border-image-linear-gradient-slice-fill-1.html border-image-linear-gradient-slice-fill-1-ref.html
fuzzy(0-1,0-649) fuzzy-if(OSX,0-1,0-25771) fuzzy-if(skiaContent&&!Android,0-1,0-546) fuzzy-if(Android,0-1,0-6093) fuzzy-if(webrender&&!geckoview,1-3,480-57480) == border-image-linear-gradient-slice-fill-2.html border-image-linear-gradient-slice-fill-2-ref.html
fuzzy(0-1,0-134) fuzzy-if(OSX,0-5,0-1676) fuzzy-if(webrender&&!geckoview,1-1,0-4537) == border-image-linear-gradient-width.html border-image-linear-gradient-width-ref.html
fuzzy(0-2,0-60590) fuzzy-if(Android,0-4,0-18022) fuzzy-if(OSX,0-1,0-15000) fuzzy-if(webrender&&!geckoview,1-2,14300-60581) == border-image-linear-gradient-slice-width.html border-image-linear-gradient-slice-width-ref.html
fuzzy(0-2,0-26758) fuzzy-if(OSX,0-1,0-6000) fuzzy-if(webrender&&!geckoview,1-3,3964-26758) == border-image-linear-gradient-outset.html border-image-linear-gradient-outset-ref.html
fuzzy(0-2,0-26758) fuzzy-if(OSX,0-1,0-6000) fuzzy-if(webrender&&!geckoview,1-3,3803-26758) == border-image-linear-gradient-outset.html border-image-linear-gradient-outset-ref.html
fuzzy(0-1,0-12) fuzzy-if(skiaContent,0-1,0-400) fuzzy-if(webrender&&!geckoview,1-3,1397-26872) == border-image-linear-gradient-repeat-repeat-1.html border-image-linear-gradient-repeat-repeat-1-ref.html
fuzzy(0-1,0-13) fuzzy-if(skiaContent,0-1,0-300) fuzzy-if(webrender&&!geckoview,1-3,1400-27131) == border-image-linear-gradient-repeat-round-1.html border-image-linear-gradient-repeat-round-1-ref.html
fuzzy-if(Android,0-1,0-1894) fuzzy-if(webrender&&!geckoview,1-2,3163-67805) == border-image-linear-gradient-repeat-repeat-2.html border-image-linear-gradient-repeat-repeat-2-ref.html
fuzzy(0-1,0-2000) fuzzy-if(webrender&&!geckoview,1-2,3249-9500) == border-image-linear-gradient-repeat-round-2.html border-image-linear-gradient-repeat-round-2-ref.html
fuzzy(0-1,0-8533) fuzzy-if(webrender&&!geckoview,1-3,3188-9500) == border-image-linear-gradient-repeat-repeat-3.html border-image-linear-gradient-repeat-repeat-3-ref.html
fuzzy(0-3,0-107563) fuzzy-if(webrender&&!geckoview,1-3,43500-107563) == border-image-linear-gradient-repeat-round-3.html border-image-linear-gradient-repeat-round-3-ref.html
fuzzy(0-1,0-8533) fuzzy-if(webrender&&!geckoview,1-3,2967-9500) == border-image-linear-gradient-repeat-repeat-3.html border-image-linear-gradient-repeat-repeat-3-ref.html
fuzzy(0-3,0-107563) fuzzy-if(webrender&&!geckoview,1-3,42909-107563) == border-image-linear-gradient-repeat-round-3.html border-image-linear-gradient-repeat-round-3-ref.html
fuzzy-if(webrender,0-1,0-2096) == border-image-radial-gradient.html border-image-radial-gradient-ref.html
fuzzy(0-1,0-42) fuzzy-if(skiaContent,0-2,0-20) fuzzy-if(webrender,0-1,0-37818) == border-image-radial-gradient-slice-1.html border-image-radial-gradient-slice-1-ref.html
@ -66,7 +66,7 @@ fuzzy-if(skiaContent,0-1,0-2) fuzzy-if(webrender,0-2,0-4894) == border-image-rad
fuzzy(0-1,0-9000) fuzzy-if(webrender,0-3,0-66698) == border-image-radial-gradient-slice-width.html border-image-radial-gradient-slice-width-ref.html
# OS X failures tracked in bug 957025
fuzzy-if(webrender&&!geckoview,1-4,940-2000) == border-image-repeating-linear-gradient.html border-image-repeating-linear-gradient-ref.html
fuzzy-if(webrender&&!geckoview,1-4,938-2000) == border-image-repeating-linear-gradient.html border-image-repeating-linear-gradient-ref.html
fuzzy(0-1,0-6690) fails-if(OSX) fuzzy-if(skiaContent,0-1,0-6093) fuzzy-if(webrender,0-3,0-95449) == border-image-repeating-linear-gradient-slice-fill-2.html border-image-repeating-linear-gradient-slice-fill-2-ref.html
fuzzy(0-1,0-19200) fails-if(OSX) fuzzy-if(skiaContent,0-3,0-20000) fuzzy-if(webrender&&!geckoview,1-4,4150-14000) == border-image-repeating-linear-gradient-repeat-round-2.html border-image-repeating-linear-gradient-repeat-round-2-ref.html

Просмотреть файл

@ -137,7 +137,7 @@ pref(svg.transform-box.enabled,true) == transform-box-svg-3a.svg pass.svg
== transform-origin-svg-2b.svg transform-origin-svg-2-ref.svg
# Bug 1122526
== animate-layer-scale-inherit-1.html animate-layer-scale-inherit-1-ref.html
== animate-layer-scale-inherit-2.html animate-layer-scale-inherit-2-ref.html
fuzzy-if(webrender&&swgl,0-1,0-2) == animate-layer-scale-inherit-2.html animate-layer-scale-inherit-2-ref.html
== animate-layer-scale-inherit-3.html animate-layer-scale-inherit-1-ref.html
# Bug 1301500
== dynamic-add-without-change-cb-1.html dynamic-add-without-change-cb-1-ref.html

Просмотреть файл

@ -2,3 +2,4 @@
expected:
if webrender and (os == "win"): FAIL
if webrender and (os == "mac"): FAIL # bug 1646043
if webrender and (os == "linux"): FAIL # bug 1677872