Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions webrender/res/cs_clip_border.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,7 @@ void main(void) {
clip_relative_pos);

// Get AA widths based on zoom / scale etc.
vec2 fw = fwidth(local_pos);
float afwidth = length(fw);
float aa_range = compute_aa_range(local_pos);

// SDF subtract edges for dash clip
float dash_distance = max(d0, -d1);
Expand All @@ -167,8 +166,8 @@ void main(void) {
// Select between dot/dash clip based on mode.
float d = mix(dash_distance, dot_distance, vAlphaMask.x);

// Apply AA over half a device pixel for the clip.
d = 1.0 - smoothstep(0.0, 0.5 * afwidth, d);
// Apply AA.
d = distance_aa(aa_range, d);

// Completely mask out clip if zero'ing out the rect.
d = d * vAlphaMask.y;
Expand Down
33 changes: 15 additions & 18 deletions webrender/res/cs_clip_rectangle.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -101,50 +101,47 @@ void main(void) {
float clip_against_ellipse_if_needed(vec2 pos,
float current_distance,
vec4 ellipse_center_radius,
vec2 sign_modifier,
float afwidth) {
vec2 sign_modifier) {
float ellipse_distance = distance_to_ellipse(pos - ellipse_center_radius.xy,
ellipse_center_radius.zw);

return mix(current_distance,
ellipse_distance + afwidth,
ellipse_distance,
all(lessThan(sign_modifier * pos, sign_modifier * ellipse_center_radius.xy)));
}

float rounded_rect(vec2 pos) {
float current_distance = 0.0;

// Apply AA
float afwidth = 0.5 * length(fwidth(pos));
// Start with a negative value (means "inside") for all fragments that are not
// in a corner. If the fragment is in a corner, one of the clip_against_ellipse_if_needed
// calls below will update it.
float current_distance = -1.0;

// Clip against each ellipse.
current_distance = clip_against_ellipse_if_needed(pos,
current_distance,
vClipCenter_Radius_TL,
vec2(1.0),
afwidth);
vec2(1.0));

current_distance = clip_against_ellipse_if_needed(pos,
current_distance,
vClipCenter_Radius_TR,
vec2(-1.0, 1.0),
afwidth);
vec2(-1.0, 1.0));

current_distance = clip_against_ellipse_if_needed(pos,
current_distance,
vClipCenter_Radius_BR,
vec2(-1.0),
afwidth);
vec2(-1.0));

current_distance = clip_against_ellipse_if_needed(pos,
current_distance,
vClipCenter_Radius_BL,
vec2(1.0, -1.0),
afwidth);
vec2(1.0, -1.0));

return smoothstep(0.0, afwidth, 1.0 - current_distance);
}
// Apply AA
// See comment in ps_border_corner about the choice of constants.
float aa_range = compute_aa_range(pos);

return distance_aa(aa_range, current_distance);
}

void main(void) {
float alpha = 1.f;
Expand Down
33 changes: 31 additions & 2 deletions webrender/res/prim_shared.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,35 @@ void write_clip(vec2 global_pos, ClipArea area) {

#ifdef WR_FRAGMENT_SHADER

/// Find the appropriate half range to apply the AA smoothstep over.
/// This range represents a coefficient to go from one CSS pixel to half a device pixel.
float compute_aa_range(vec2 position) {
// The constant factor is chosen to compensate for the fact that length(fw) is equal
// to sqrt(2) times the device pixel ratio in the typical case. 0.5/sqrt(2) = 0.35355.
//
// This coefficient is chosen to ensure that any sample 0.5 pixels or more inside of
// the shape has no anti-aliasing applied to it (since pixels are sampled at their center,
// such a pixel (axis aligned) is fully inside the border). We need this so that antialiased
// curves properly connect with non-antialiased vertical or horizontal lines, among other things.
//
// Using larger aa steps is quite common when rendering shapes with distance fields.
// It gives a smoother (although blurrier look) by extending the range that is smoothed
// to produce the anti aliasing. In our case, however, extending the range inside of
// the shape causes noticeable artifacts at the junction between an antialiased corner
// and a straight edge.
// We may want to adjust this constant in specific scenarios (for example keep the principled
// value for straight edges where we want pixel-perfect equivalence with non antialiased lines
// when axis aligned, while selecting a larger and smoother aa range on curves).
return 0.35355 * length(fwidth(position));
}

/// Return the blending coefficient to for distance antialiasing.
///
/// 0.0 means inside the shape, 1.0 means outside.
float distance_aa(float aa_range, float signed_distance) {
return 1.0 - smoothstep(-aa_range, aa_range, signed_distance);
}

#ifdef WR_FEATURE_TRANSFORM
float signed_distance_rect(vec2 pos, vec2 p0, vec2 p1) {
vec2 d = max(p0 - pos, pos - p1);
Expand All @@ -733,10 +762,10 @@ vec2 init_transform_fs(vec3 local_pos, out float fragment_alpha) {
float d = signed_distance_rect(pos, vLocalBounds.xy, vLocalBounds.zw);

// Find the appropriate distance to apply the AA smoothstep over.
float afwidth = 0.5 * length(fwidth(pos.xy));
float aa_range = compute_aa_range(pos.xy);

// Only apply AA to fragments outside the signed distance field.
fragment_alpha = 1.0 - smoothstep(0.0, afwidth, d);
fragment_alpha = distance_aa(aa_range, d);

return pos;
}
Expand Down
27 changes: 10 additions & 17 deletions webrender/res/ps_border_corner.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,7 @@ void main(void) {

alpha = min(alpha, do_clip());

// Find the appropriate distance to apply the AA smoothstep over.
// Using 0.7 instead of 0.5 for the step compensates for the fact that smoothstep
// is smooth at its endpoints and has a steeper maximum slope than a linear ramp.
vec2 fw = fwidth(local_pos);
float aa_step = 0.7 * length(fw);
float aa_range = compute_aa_range(local_pos);

float distance_for_color;
float color_mix_factor;
Expand All @@ -349,29 +345,26 @@ void main(void) {
// To correct this exactly we would need to offset p by half a pixel in the
// direction of the center of the ellipse (a different offset for each corner).

// A half device pixel in css pixels (using the average of width and height in case
// there is any kind of transform applied).
float half_px = 0.25 * (fw.x + fw.y);
// Get signed distance from the inner/outer clips.
float d0 = distance_to_ellipse(p, vRadii0.xy) + half_px;
float d1 = distance_to_ellipse(p, vRadii0.zw) + half_px;
float d2 = distance_to_ellipse(p, vRadii1.xy) + half_px;
float d3 = distance_to_ellipse(p, vRadii1.zw) + half_px;
float d0 = distance_to_ellipse(p, vRadii0.xy);
float d1 = distance_to_ellipse(p, vRadii0.zw);
float d2 = distance_to_ellipse(p, vRadii1.xy);
float d3 = distance_to_ellipse(p, vRadii1.zw);

// SDF subtract main radii
float d_main = max(d0, aa_step - d1);
float d_main = max(d0, -d1);

// SDF subtract inner radii (double style borders)
float d_inner = max(d2 - aa_step, -d3);
float d_inner = max(d2, -d3);

// Select how to combine the SDF based on border style.
float d = mix(max(d_main, -d_inner), d_main, vSDFSelect);

// Only apply AA to fragments outside the signed distance field.
alpha = min(alpha, 1.0 - smoothstep(0.0, aa_step, d));
alpha = min(alpha, distance_aa(aa_range, d));

// Get the groove/ridge mix factor.
color_mix_factor = smoothstep(-aa_step, aa_step, -d2);
color_mix_factor = distance_aa(aa_range, d2);
} else {
// Handle the case where the fragment is outside the clip
// region in a corner. This occurs when border width is
Expand Down Expand Up @@ -403,7 +396,7 @@ void main(void) {
// Select color based on side of line. Get distance from the
// reference line, and then apply AA along the edge.
float ld = distance_to_line(vColorEdgeLine.xy, vColorEdgeLine.zw, local_pos);
float m = smoothstep(-aa_step, aa_step, ld);
float m = distance_aa(aa_range, -ld);
vec4 color = mix(color0, color1, m);

oFragColor = color * vec4(1.0, 1.0, 1.0, alpha);
Expand Down
7 changes: 2 additions & 5 deletions webrender/res/ps_border_edge.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,7 @@ void main(void) {
alpha = min(alpha, do_clip());

// Find the appropriate distance to apply the step over.
vec2 fw = fwidth(local_pos);
float afwidth = length(fw);
float aa_range = compute_aa_range(local_pos);

// Applies the math necessary to draw a style: double
// border. In the case of a solid border, the vertex
Expand Down Expand Up @@ -291,9 +290,7 @@ void main(void) {
// Get the dot alpha
vec2 dot_relative_pos = vec2(x, pos.x) - vClipParams.zw;
float dot_distance = length(dot_relative_pos) - vClipParams.z;
float dot_alpha = 1.0 - smoothstep(-0.5 * afwidth,
0.5 * afwidth,
dot_distance);
float dot_alpha = distance_aa(aa_range, dot_distance);

// Select between dot/dash alpha based on clip mode.
alpha = min(alpha, mix(dash_alpha, dot_alpha, vClipSelect));
Expand Down
11 changes: 3 additions & 8 deletions webrender/res/ps_line.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,7 @@ void main(void) {
#endif

// Find the appropriate distance to apply the step over.
vec2 fw = fwidth(local_pos);
float afwidth = length(fw);
float aa_range = compute_aa_range(local_pos);

// Select the x/y coord, depending on which axis this edge is.
vec2 pos = mix(local_pos.xy, local_pos.yx, vAxisSelect);
Expand All @@ -215,9 +214,7 @@ void main(void) {
// Get the dot alpha
vec2 dot_relative_pos = vec2(x, pos.y) - vParams.yz;
float dot_distance = length(dot_relative_pos) - vParams.y;
alpha = min(alpha, 1.0 - smoothstep(-0.5 * afwidth,
0.5 * afwidth,
dot_distance));
alpha = min(alpha, distance_aa(aa_range, dot_distance));
break;
}
case LINE_STYLE_WAVY: {
Expand Down Expand Up @@ -251,9 +248,7 @@ void main(void) {
float d = min(d1, d2);

// Apply AA based on the thickness of the wave.
alpha = 1.0 - smoothstep(vParams.x - 0.5 * afwidth,
vParams.x + 0.5 * afwidth,
d);
alpha = distance_aa(aa_range, d - vParams.x);
break;
}
}
Expand Down
Binary file modified wrench/reftests/aa/rounded-rects-ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/border/border-radii.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/border/border-suite-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/border/border-suite-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/border/border-suite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/border/degenerate-curve.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/boxshadow/boxshadow-spread-only-ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/boxshadow/inset-large-offset-ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/boxshadow/inset-no-blur-radius-ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/gradient/linear-aligned-border-radius.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/gradient/repeat-border-radius.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/mask/rounded-corners.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/text/border-radius-alpha.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/text/border-radius-subpx.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/text/decorations-suite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/transforms/image-rotated-clip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/transforms/local-clip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/transforms/rotated-clip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified wrench/reftests/transforms/rotated-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.