servo: Merge #13198 - Update WR/shaders (more AA, VTF mac fix, reftest fixes) (from glennw:wr-update-vtf); r=ConnorGBrewster

Source-Repo: https://github.com/servo/servo
Source-Revision: 0daf71d58b7081aaa2900e5b8c76f5ac0b8b19e4
This commit is contained in:
Glenn Watson 2016-09-08 14:53:06 -05:00
Родитель fc0990e5cc
Коммит 187b8b6183
7 изменённых файлов: 122 добавлений и 147 удалений

4
servo/components/servo/Cargo.lock сгенерированный
Просмотреть файл

@ -2594,7 +2594,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.5.1"
source = "git+https://github.com/servo/webrender#b2cca277407b59c4c3b8122f36b64bd81f83a4dc"
source = "git+https://github.com/servo/webrender#c9ceb97e9f6b919518f3c70cdae85d3213c8290c"
dependencies = [
"app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2619,7 +2619,7 @@ dependencies = [
[[package]]
name = "webrender_traits"
version = "0.5.1"
source = "git+https://github.com/servo/webrender#b2cca277407b59c4c3b8122f36b64bd81f83a4dc"
source = "git+https://github.com/servo/webrender#c9ceb97e9f6b919518f3c70cdae85d3213c8290c"
dependencies = [
"app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",

4
servo/ports/cef/Cargo.lock сгенерированный
Просмотреть файл

@ -2454,7 +2454,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.5.1"
source = "git+https://github.com/servo/webrender#b2cca277407b59c4c3b8122f36b64bd81f83a4dc"
source = "git+https://github.com/servo/webrender#c9ceb97e9f6b919518f3c70cdae85d3213c8290c"
dependencies = [
"app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2479,7 +2479,7 @@ dependencies = [
[[package]]
name = "webrender_traits"
version = "0.5.1"
source = "git+https://github.com/servo/webrender#b2cca277407b59c4c3b8122f36b64bd81f83a4dc"
source = "git+https://github.com/servo/webrender#c9ceb97e9f6b919518f3c70cdae85d3213c8290c"
dependencies = [
"app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",

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

@ -30,6 +30,8 @@
#define MAX_STOPS_PER_ANGLE_GRADIENT 8
#ifdef WR_VERTEX_SHADER
uniform sampler2D sLayers;
struct Layer {
mat4 transform;
mat4 inv_transform;
@ -45,31 +47,32 @@ layout(std140) uniform Tiles {
vec4 tiles[WR_MAX_UBO_VECTORS];
};
layout(std140) uniform Layers {
vec4 layers[WR_MAX_UBO_VECTORS];
};
Layer fetch_layer(int index) {
Layer layer;
int offset = index * 13;
// Create a UV base coord for each 8 texels.
// This is required because trying to use an offset
// of more than 8 texels doesn't work on some versions
// of OSX.
ivec2 uv0 = ivec2(0, index);
ivec2 uv1 = ivec2(8, index);
layer.transform[0] = layers[offset + 0];
layer.transform[1] = layers[offset + 1];
layer.transform[2] = layers[offset + 2];
layer.transform[3] = layers[offset + 3];
layer.transform[0] = texelFetchOffset(sLayers, uv0, 0, ivec2(0, 0));
layer.transform[1] = texelFetchOffset(sLayers, uv0, 0, ivec2(1, 0));
layer.transform[2] = texelFetchOffset(sLayers, uv0, 0, ivec2(2, 0));
layer.transform[3] = texelFetchOffset(sLayers, uv0, 0, ivec2(3, 0));
layer.inv_transform[0] = layers[offset + 4];
layer.inv_transform[1] = layers[offset + 5];
layer.inv_transform[2] = layers[offset + 6];
layer.inv_transform[3] = layers[offset + 7];
layer.inv_transform[0] = texelFetchOffset(sLayers, uv0, 0, ivec2(4, 0));
layer.inv_transform[1] = texelFetchOffset(sLayers, uv0, 0, ivec2(5, 0));
layer.inv_transform[2] = texelFetchOffset(sLayers, uv0, 0, ivec2(6, 0));
layer.inv_transform[3] = texelFetchOffset(sLayers, uv0, 0, ivec2(7, 0));
layer.local_clip_rect = layers[offset + 8];
layer.local_clip_rect = texelFetchOffset(sLayers, uv1, 0, ivec2(0, 0));
layer.screen_vertices[0] = layers[offset + 9];
layer.screen_vertices[1] = layers[offset + 10];
layer.screen_vertices[2] = layers[offset + 11];
layer.screen_vertices[3] = layers[offset + 12];
layer.screen_vertices[0] = texelFetchOffset(sLayers, uv1, 0, ivec2(1, 0));
layer.screen_vertices[1] = texelFetchOffset(sLayers, uv1, 0, ivec2(2, 0));
layer.screen_vertices[2] = texelFetchOffset(sLayers, uv1, 0, ivec2(2, 0));
layer.screen_vertices[3] = texelFetchOffset(sLayers, uv1, 0, ivec2(3, 0));
return layer;
}
@ -534,7 +537,7 @@ Composite fetch_composite(int index) {
#endif
#ifdef WR_FRAGMENT_SHADER
void do_clip(vec2 pos, vec4 clip_rect, vec4 radius) {
float do_clip(vec2 pos, vec4 clip_rect, vec4 radius) {
vec2 ref_tl = clip_rect.xy + vec2( radius.x, radius.x);
vec2 ref_tr = clip_rect.zy + vec2(-radius.y, radius.y);
vec2 ref_br = clip_rect.zw + vec2(-radius.z, -radius.z);
@ -545,15 +548,26 @@ void do_clip(vec2 pos, vec4 clip_rect, vec4 radius) {
float d_br = distance(pos, ref_br);
float d_bl = distance(pos, ref_bl);
bool out0 = pos.x < ref_tl.x && pos.y < ref_tl.y && d_tl > radius.x;
bool out1 = pos.x > ref_tr.x && pos.y < ref_tr.y && d_tr > radius.y;
bool out2 = pos.x > ref_br.x && pos.y > ref_br.y && d_br > radius.z;
bool out3 = pos.x < ref_bl.x && pos.y > ref_bl.y && d_bl > radius.w;
float pixels_per_fragment = length(fwidth(pos.xy));
float nudge = 0.5 * pixels_per_fragment;
// TODO(gw): Alpha anti-aliasing based on edge distance!
if (out0 || out1 || out2 || out3) {
discard;
}
bool out0 = pos.x < ref_tl.x && pos.y < ref_tl.y && d_tl > radius.x - nudge;
bool out1 = pos.x > ref_tr.x && pos.y < ref_tr.y && d_tr > radius.y - nudge;
bool out2 = pos.x > ref_br.x && pos.y > ref_br.y && d_br > radius.z - nudge;
bool out3 = pos.x < ref_bl.x && pos.y > ref_bl.y && d_bl > radius.w - nudge;
float distance_from_border = (float(out0) * (d_tl - radius.x + nudge)) +
(float(out1) * (d_tr - radius.y + nudge)) +
(float(out2) * (d_br - radius.z + nudge)) +
(float(out3) * (d_bl - radius.w + nudge));
// Move the distance back into pixels.
distance_from_border /= pixels_per_fragment;
// Apply a more gradual fade out to transparent.
//distance_from_border -= 0.5;
return smoothstep(1.0, 0, distance_from_border);
}
float squared_distance_from_rect(vec2 p, vec2 origin, vec2 size) {

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

@ -52,36 +52,43 @@ float alpha_for_solid_border_corner(vec2 local_pos,
return alpha_for_solid_border(distance_from_ref, inner_radius, outer_radius, pixels_per_fragment);
}
#ifdef WR_FEATURE_TRANSFORM
#else
vec4 draw_dotted_edge(vec2 position, vec2 edge_size, float pixels_per_fragment) {
float two_pixels = 2 * pixels_per_fragment;
vec4 draw_dotted_edge(vec2 local_pos, vec4 piece_rect, float pixels_per_fragment) {
// We don't use pixels_per_fragment here, since it can change along the edge
// of a transformed border edge. We want this calculation to be consistent
// across the entire edge so that the positioning of the dots stays the same.
float two_pixels = 2 * length(fwidth(vLocalPos.xy));
// Circle diameter is stroke width, minus a couple pixels to account for anti-aliasing.
float circle_diameter = max(edge_size.x - two_pixels, min(edge_size.x, two_pixels));
float circle_diameter = max(piece_rect.z - two_pixels, min(piece_rect.z, two_pixels));
//// Divide the edge into segments which are the size of the circle diameter.
float segments_in_edge = floor(edge_size.y / circle_diameter);
// We want to spread the circles across the edge, but keep one circle diameter at the end
// reserved for two half-circles which connect to the corners.
float edge_available = piece_rect.w - (circle_diameter * 2);
float number_of_circles = floor(edge_available / (circle_diameter * 2));
// Every other segment has a circle.
float number_of_circles = floor(segments_in_edge / 2);
if (number_of_circles <= 0)
return vec4(0, 0, 0, 0);
// Here we are initializing the distance from the y coordinate of the center of the circle to
// the closest end half-circle.
vec2 relative_pos = local_pos - piece_rect.xy;
float y_distance = min(relative_pos.y, piece_rect.w - relative_pos.y);
// Spread the circles throughout the edge, to distribute the extra space evenly. We want
// to ensure that we have at last two pixels of space for each circle so that they aren't
// touching.
float space_for_each_circle = ceil(max(edge_size.y / number_of_circles, two_pixels));
if (number_of_circles > 0) {
// Spread the circles throughout the edge, to distribute the extra space evenly. We want
// to ensure that we have at last two pixels of space for each circle so that they aren't
// touching.
float space_for_each_circle = ceil(max(edge_available / number_of_circles, two_pixels));
// Find the circle index. We adjust the y position here because the first circle is a
// half circle at the edge of this border side.
float circle_index = floor((position.y + (space_for_each_circle / 2)) / space_for_each_circle);
float first_half_circle_space = circle_diameter;
// Find the center of the circle that is closest to our position. We will then calculate
// the distance from the edge of the circle.
vec2 circle_center = vec2(edge_size.x / 2, circle_index * space_for_each_circle);
float distance_from_circle_edge = length(circle_center - position) - (circle_diameter / 2);
float circle_index = (relative_pos.y - first_half_circle_space) / space_for_each_circle;
circle_index = floor(clamp(circle_index, 0, number_of_circles - 1));
float circle_y_pos =
circle_index * space_for_each_circle + (space_for_each_circle / 2) + circle_diameter;
y_distance = min(abs(circle_y_pos - relative_pos.y), y_distance);
}
float distance_from_circle_center = length(vec2(relative_pos.x - (piece_rect.z / 2), y_distance));
float distance_from_circle_edge = distance_from_circle_center - (circle_diameter / 2);
// Don't anti-alias if the circle diameter is small to avoid a blur of color.
if (circle_diameter < two_pixels && distance_from_circle_edge > 0)
@ -94,7 +101,24 @@ vec4 draw_dotted_edge(vec2 position, vec2 edge_size, float pixels_per_fragment)
return vHorizontalColor * vec4(1, 1, 1, alpha);
}
void draw_dotted_border(vec2 local_pos, float distance_from_mix_line) {
vec4 draw_dashed_edge(float position, float border_width, float pixels_per_fragment) {
// TODO: Investigate exactly what FF does.
float size = border_width * 3;
float segment = floor(position / size);
float alpha = alpha_for_solid_border(position,
segment * size,
(segment + 1) * size,
pixels_per_fragment);
if (mod(segment + 2, 2) == 0) {
return vHorizontalColor * vec4(1, 1, 1, 1 - alpha);
} else {
return vHorizontalColor * vec4(1, 1, 1, alpha);
}
}
void draw_dashed_or_dotted_border(vec2 local_pos, float distance_from_mix_line) {
// This is the conversion factor for transformations and device pixel scaling.
float pixels_per_fragment = length(fwidth(local_pos.xy));
@ -117,76 +141,30 @@ void draw_dotted_border(vec2 local_pos, float distance_from_mix_line) {
}
case PST_BOTTOM:
case PST_TOP: {
vec2 piece_relative_position = vLocalPos - vPieceRect.xy;
oFragColor = draw_dotted_edge(piece_relative_position.yx, vPieceRect.wz, pixels_per_fragment);
break;
}
case PST_LEFT:
case PST_RIGHT:
{
vec2 piece_relative_position = vLocalPos - vPieceRect.xy;
oFragColor = draw_dotted_edge(piece_relative_position.xy, vPieceRect.zw, pixels_per_fragment);
break;
}
}
}
#endif
vec4 draw_dashed_edge(float position, float border_width, float pixels_per_fragment) {
// TODO: Investigate exactly what FF does.
float size = border_width * 3;
float segment = floor(position / size);
float alpha = alpha_for_solid_border(position,
segment * size,
(segment + 1) * size,
pixels_per_fragment);
if (mod(segment + 2, 2) == 0) {
return vHorizontalColor * vec4(1, 1, 1, 1 - alpha);
} else {
return vHorizontalColor * vec4(1, 1, 1, alpha);
}
}
void draw_dashed_border(vec2 local_pos, float distance_from_mix_line) {
// This is the conversion factor for transformations and device pixel scaling.
float pixels_per_fragment = length(fwidth(local_pos.xy));
switch (vBorderPart) {
// These are the layer tile part PrimitivePart as uploaded by the tiling.rs
case PST_TOP_LEFT:
case PST_TOP_RIGHT:
case PST_BOTTOM_LEFT:
case PST_BOTTOM_RIGHT:
{
oFragColor = get_fragment_color(distance_from_mix_line, pixels_per_fragment);
if (vRadii.x > 0.0) {
oFragColor *= vec4(1, 1, 1, alpha_for_solid_border_corner(local_pos,
vRadii.z,
vRadii.x,
pixels_per_fragment));
if (vBorderStyle == BORDER_STYLE_DASHED) {
oFragColor = draw_dashed_edge(vLocalPos.x - vPieceRect.x,
vPieceRect.w,
pixels_per_fragment);
} else {
oFragColor = draw_dotted_edge(local_pos.yx, vPieceRect.yxwz, pixels_per_fragment);
}
break;
}
case PST_BOTTOM:
case PST_TOP:
{
oFragColor = draw_dashed_edge(vLocalPos.x - vPieceRect.x, vPieceRect.w, pixels_per_fragment);
break;
}
case PST_LEFT:
case PST_RIGHT:
{
oFragColor = draw_dashed_edge(vLocalPos.y - vPieceRect.y, vPieceRect.z, pixels_per_fragment);
if (vBorderStyle == BORDER_STYLE_DASHED) {
oFragColor = draw_dashed_edge(vLocalPos.y - vPieceRect.y,
vPieceRect.z,
pixels_per_fragment);
} else {
oFragColor = draw_dotted_edge(local_pos.xy, vPieceRect.xyzw, pixels_per_fragment);
}
break;
}
}
}
vec4 draw_double_edge(float pos,
float len,
float distance_from_mix_line,
@ -328,46 +306,30 @@ void main(void) {
float distance_from_mix_line = (local_pos.x - vPieceRect.x) * vPieceRect.w -
(local_pos.y - vPieceRect.y) * vPieceRect.z;
distance_from_mix_line /= vPieceRectHypotenuseLength;
#else
float distance_from_mix_line = vDistanceFromMixLine;
#endif
switch (vBorderStyle) {
case BORDER_STYLE_DASHED:
draw_dashed_border(local_pos, distance_from_mix_line);
break;
case BORDER_STYLE_DOTTED:
draw_dashed_or_dotted_border(local_pos, distance_from_mix_line);
break;
case BORDER_STYLE_DOUBLE:
draw_double_border(distance_from_mix_line, local_pos);
break;
case BORDER_STYLE_OUTSET:
case BORDER_STYLE_INSET:
case BORDER_STYLE_SOLID:
case BORDER_STYLE_NONE:
draw_solid_border(distance_from_mix_line, local_pos);
break;
case BORDER_STYLE_DOUBLE:
draw_double_border(distance_from_mix_line, local_pos);
break;
default:
discard;
}
#ifdef WR_FEATURE_TRANSFORM
oFragColor *= vec4(1, 1, 1, alpha);
#else
switch (vBorderStyle) {
case BORDER_STYLE_DASHED:
draw_dashed_border(local_pos, vDistanceFromMixLine);
break;
case BORDER_STYLE_DOTTED:
draw_dotted_border(local_pos, vDistanceFromMixLine);
break;
case BORDER_STYLE_OUTSET:
case BORDER_STYLE_INSET:
case BORDER_STYLE_SOLID:
case BORDER_STYLE_NONE:
draw_solid_border(vDistanceFromMixLine, local_pos);
break;
case BORDER_STYLE_DOUBLE:
draw_double_border(vDistanceFromMixLine, local_pos);
break;
default:
discard;
}
#endif
}

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

@ -7,12 +7,12 @@ void main(void) {
float alpha = 0;
vec2 local_pos = init_transform_fs(vLocalPos, vLocalRect, alpha);
#else
float alpha = 1;
vec2 local_pos = vPos;
#endif
do_clip(local_pos, vClipRect, vClipRadius);
oFragColor = mix(vColor0, vColor1, vF);
alpha = min(alpha, do_clip(local_pos, vClipRect, vClipRadius));
oFragColor = mix(vColor0, vColor1, vF) * vec4(1, 1, 1, alpha);
#ifdef WR_FEATURE_TRANSFORM
oFragColor.a *= alpha;

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

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
void main(void) {
do_clip(vPos, vClipRect, vClipRadius);
float alpha = do_clip(vPos, vClipRect, vClipRadius);
vec2 st = vTextureOffset + vTextureSize * fract(vUv);
oFragColor = texture(sDiffuse, st);
oFragColor = texture(sDiffuse, st) * vec4(1, 1, 1, alpha);
}

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

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
void main(void) {
do_clip(vPos, vClipRect, vClipRadius);
oFragColor = vColor;
float alpha = do_clip(vPos, vClipRect, vClipRadius);
oFragColor = vColor * vec4(1, 1, 1, alpha);
}