Update webrender + shaders (border AA improvements, float packing work).

This commit is contained in:
Glenn Watson 2016-08-30 10:22:32 +10:00
parent a338beaa70
commit e75386f0dc
11 changed files with 180 additions and 128 deletions

View file

@ -2591,7 +2591,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.5.1"
source = "git+https://github.com/servo/webrender#4171ab07f36d9dff12cc4fc31b23c037851cd747"
source = "git+https://github.com/servo/webrender#6d6ef896a6515e9d850643a9cbedd1e20bce3419"
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)",
@ -2616,7 +2616,7 @@ dependencies = [
[[package]]
name = "webrender_traits"
version = "0.5.1"
source = "git+https://github.com/servo/webrender#4171ab07f36d9dff12cc4fc31b23c037851cd747"
source = "git+https://github.com/servo/webrender#6d6ef896a6515e9d850643a9cbedd1e20bce3419"
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
ports/cef/Cargo.lock generated
View file

@ -2451,7 +2451,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.5.1"
source = "git+https://github.com/servo/webrender#4171ab07f36d9dff12cc4fc31b23c037851cd747"
source = "git+https://github.com/servo/webrender#6d6ef896a6515e9d850643a9cbedd1e20bce3419"
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)",
@ -2476,7 +2476,7 @@ dependencies = [
[[package]]
name = "webrender_traits"
version = "0.5.1"
source = "git+https://github.com/servo/webrender#4171ab07f36d9dff12cc4fc31b23c037851cd747"
source = "git+https://github.com/servo/webrender#6d6ef896a6515e9d850643a9cbedd1e20bce3419"
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)",

View file

@ -3,15 +3,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#define PST_INVALID uint(0)
#define PST_TOP_LEFT uint(1)
#define PST_TOP_RIGHT uint(2)
#define PST_BOTTOM_LEFT uint(3)
#define PST_BOTTOM_RIGHT uint(4)
#define PST_TOP uint(5)
#define PST_LEFT uint(6)
#define PST_BOTTOM uint(7)
#define PST_RIGHT uint(8)
#define PST_TOP_LEFT uint(0)
#define PST_TOP_RIGHT uint(1)
#define PST_BOTTOM_LEFT uint(2)
#define PST_BOTTOM_RIGHT uint(3)
#define PST_TOP uint(4)
#define PST_LEFT uint(5)
#define PST_BOTTOM uint(6)
#define PST_RIGHT uint(7)
// Border styles as defined in webrender_traits/types.rs
#define BORDER_STYLE_NONE uint(0)
@ -38,8 +37,8 @@ layout(std140) uniform Layers {
};
struct Tile {
uvec4 actual_rect;
uvec4 target_rect;
vec4 actual_rect;
vec4 target_rect;
};
layout(std140) uniform Tiles {
@ -47,7 +46,7 @@ layout(std140) uniform Tiles {
};
struct PrimitiveInfo {
uvec4 layer_tile_part;
uvec4 layer_tile;
vec4 local_clip_rect;
vec4 local_rect;
};
@ -111,8 +110,8 @@ struct VertexInfo {
};
VertexInfo write_vertex(PrimitiveInfo info) {
Layer layer = layers[info.layer_tile_part.x];
Tile tile = tiles[info.layer_tile_part.y];
Layer layer = layers[info.layer_tile.x];
Tile tile = tiles[info.layer_tile.y];
vec2 p0 = floor(0.5 + info.local_rect.xy * uDevicePixelRatio) / uDevicePixelRatio;
vec2 p1 = floor(0.5 + (info.local_rect.xy + info.local_rect.zw) * uDevicePixelRatio) / uDevicePixelRatio;
@ -153,8 +152,8 @@ struct TransformVertexInfo {
};
TransformVertexInfo write_transform_vertex(PrimitiveInfo info) {
Layer layer = layers[info.layer_tile_part.x];
Tile tile = tiles[info.layer_tile_part.y];
Layer layer = layers[info.layer_tile.x];
Tile tile = tiles[info.layer_tile.y];
vec2 lp0 = info.local_rect.xy;
vec2 lp1 = info.local_rect.xy + info.local_rect.zw;
@ -198,7 +197,7 @@ TransformVertexInfo write_transform_vertex(PrimitiveInfo info) {
max_pos_clamped,
aPosition.xy);
vec3 layer_pos = get_layer_pos(clamped_pos / uDevicePixelRatio, info.layer_tile_part.x);
vec3 layer_pos = get_layer_pos(clamped_pos / uDevicePixelRatio, info.layer_tile.x);
vec2 final_pos = clamped_pos + vec2(tile.target_rect.xy) - vec2(tile.actual_rect.xy);

View file

@ -6,7 +6,7 @@
struct AngleGradient {
PrimitiveInfo info;
vec4 start_end_point;
uvec4 stop_count;
vec4 stop_count;
vec4 colors[MAX_STOPS_PER_ANGLE_GRADIENT];
vec4 offsets[MAX_STOPS_PER_ANGLE_GRADIENT/4];
};

View file

@ -4,8 +4,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
struct Blend {
uvec4 target_rect;
uvec4 src_rect;
vec4 target_rect;
vec4 src_rect;
vec4 opacity;
};

View file

@ -19,6 +19,39 @@ vec4 get_fragment_color(float distanceFromMixLine, float pixelsPerFragment) {
return mix(vHorizontalColor, vVerticalColor, colorMix);
}
float alpha_for_solid_border(float distance_from_ref,
float inner_radius,
float outer_radius,
float pixels_per_fragment) {
// We want to start anti-aliasing one pixel in from the border.
float nudge = 1 * pixels_per_fragment;
inner_radius += nudge;
outer_radius -= nudge;
if ((distance_from_ref < outer_radius && distance_from_ref > inner_radius)) {
return 1.0;
}
float distance_from_border = max(distance_from_ref - outer_radius,
inner_radius - distance_from_ref);
// 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 alpha_for_solid_border_corner(vec2 local_pos,
float inner_radius,
float outer_radius,
float pixels_per_fragment) {
float distance_from_ref = distance(vRefPoint, local_pos);
return alpha_for_solid_border(distance_from_ref, inner_radius, outer_radius, pixels_per_fragment);
}
#ifdef WR_FEATURE_TRANSFORM
#else
@ -76,57 +109,6 @@ vec4 draw_dotted_edge() {
return mix(white, circleColor, circleColor.a);
}
vec4 draw_double_edge(float pos, float len) {
// Devided border to 3 parts, draw color on first and third part,
// leave second part blank.
float one_third_len = len / 3.0;
float in_first_part = step(pos, one_third_len);
float in_third_part = step(len - one_third_len, pos);
// The result of this should be 1.0 if we're in the 1st or 3rd part.
// And 0.0 for the blank part.
float should_fill = in_first_part + in_third_part;
// This is the conversion factor for transformations and device pixel scaling.
float pixels_per_fragment = length(fwidth(vLocalPos.xy));
vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
return mix(white, get_fragment_color(vDistanceFromMixLine, pixels_per_fragment), should_fill);
}
vec4 draw_double_edge_vertical() {
// Get our position within this specific segment
float position = vLocalPos.x - vLocalRect.x;
return draw_double_edge(position, vLocalRect.z);
}
vec4 draw_double_edge_horizontal() {
// Get our position within this specific segment
float position = vLocalPos.y - vLocalRect.y;
return draw_double_edge(position, vLocalRect.w);
}
vec4 draw_double_edge_with_radius() {
// Get our position within this specific segment
float position = distance(vRefPoint, vLocalPos) - vRadii.z;
float len = vRadii.x - vRadii.z;
return draw_double_edge(position, len);
}
vec4 draw_double_edge_corner() {
if (vRadii.x > 0) {
return draw_double_edge_with_radius();
}
bool is_vertical = (vBorderPart == PST_TOP_LEFT) ? vDistanceFromMixLine < 0 :
vDistanceFromMixLine >= 0;
if (is_vertical) {
return draw_double_edge_vertical();
} else {
return draw_double_edge_horizontal();
}
}
// Our current edge calculation is based only on
// the size of the border-size, but we need to draw
// the dashes in the center of the segment we're drawing.
@ -215,7 +197,82 @@ void draw_dashed_border(void) {
}
}
void draw_double_border(void) {
#endif
vec4 draw_double_edge(float pos,
float len,
float distance_from_mix_line,
float pixels_per_fragment) {
float total_border_width = len;
float one_third_width = total_border_width / 3.0;
// Contribution of the outer border segment.
float alpha = alpha_for_solid_border(pos,
total_border_width - one_third_width,
total_border_width,
pixels_per_fragment);
// Contribution of the inner border segment.
alpha += alpha_for_solid_border(pos, 0, one_third_width, pixels_per_fragment);
return get_fragment_color(distance_from_mix_line, pixels_per_fragment) * vec4(1, 1, 1, alpha);
}
vec4 draw_double_edge_vertical(vec2 local_pos,
float distance_from_mix_line,
float pixels_per_fragment) {
// Get our position within this specific segment
float position = local_pos.x - vLocalRect.x;
return draw_double_edge(position, vLocalRect.z, distance_from_mix_line, pixels_per_fragment);
}
vec4 draw_double_edge_horizontal(vec2 local_pos,
float distance_from_mix_line,
float pixels_per_fragment) {
// Get our position within this specific segment
float position = local_pos.y - vLocalRect.y;
return draw_double_edge(position, vLocalRect.w, distance_from_mix_line, pixels_per_fragment);
}
vec4 draw_double_edge_corner_with_radius(vec2 local_pos,
float distance_from_mix_line,
float pixels_per_fragment) {
float total_border_width = vRadii.x - vRadii.z;
float one_third_width = total_border_width / 3.0;
// Contribution of the outer border segment.
float alpha = alpha_for_solid_border_corner(local_pos,
vRadii.x - one_third_width,
vRadii.x,
pixels_per_fragment);
// Contribution of the inner border segment.
alpha += alpha_for_solid_border_corner(local_pos,
vRadii.z,
vRadii.z + one_third_width,
pixels_per_fragment);
return get_fragment_color(distance_from_mix_line, pixels_per_fragment) * vec4(1, 1, 1, alpha);
}
vec4 draw_double_edge_corner(vec2 local_pos,
float distance_from_mix_line,
float pixels_per_fragment) {
if (vRadii.x > 0) {
return draw_double_edge_corner_with_radius(local_pos,
distance_from_mix_line,
pixels_per_fragment);
}
bool is_vertical = (vBorderPart == PST_TOP_LEFT) ? distance_from_mix_line < 0 :
distance_from_mix_line >= 0;
if (is_vertical) {
return draw_double_edge_vertical(local_pos, distance_from_mix_line, pixels_per_fragment);
} else {
return draw_double_edge_horizontal(local_pos, distance_from_mix_line, pixels_per_fragment);
}
}
void draw_double_border(float distance_from_mix_line, vec2 local_pos) {
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:
@ -223,51 +280,28 @@ void draw_double_border(void) {
case PST_BOTTOM_LEFT:
case PST_BOTTOM_RIGHT:
{
oFragColor = draw_double_edge_corner();
oFragColor = draw_double_edge_corner(local_pos, distance_from_mix_line, pixels_per_fragment);
break;
}
case PST_BOTTOM:
case PST_TOP:
{
oFragColor = draw_double_edge_horizontal();
oFragColor = draw_double_edge_horizontal(local_pos,
distance_from_mix_line,
pixels_per_fragment);
break;
}
case PST_LEFT:
case PST_RIGHT:
{
oFragColor = draw_double_edge_vertical();
oFragColor = draw_double_edge_vertical(local_pos,
distance_from_mix_line,
pixels_per_fragment);
break;
}
}
}
#endif
void draw_antialiased_solid_border_corner(vec2 local_pos, float pixelsPerFragment) {
if (vRadii.x <= 0.0) {
return;
}
float distanceFromRef = distance(vRefPoint, local_pos);
// We want to start anti-aliasing one pixel in from the border.
float nudge = 1 * pixelsPerFragment;
float innerRadius = vRadii.z + nudge;
float outerRadius = vRadii.x - nudge;
if (vRadii.x > 0.0 && (distanceFromRef > outerRadius || distanceFromRef < innerRadius)) {
float distanceFromBorder = max(distanceFromRef - outerRadius,
innerRadius - distanceFromRef);
// Move the distance back into pixels.
distanceFromBorder /= pixelsPerFragment;
// Apply a more gradual fade out to transparent.
distanceFromBorder -= 0.5;
oFragColor = oFragColor * vec4(1, 1, 1, smoothstep(1.0, 0, distanceFromBorder));
}
}
void draw_solid_border(float distanceFromMixLine, vec2 localPos) {
switch (vBorderPart) {
case PST_TOP_LEFT:
@ -277,7 +311,12 @@ void draw_solid_border(float distanceFromMixLine, vec2 localPos) {
// This is the conversion factor for transformations and device pixel scaling.
float pixelsPerFragment = length(fwidth(localPos.xy));
oFragColor = get_fragment_color(distanceFromMixLine, pixelsPerFragment);
draw_antialiased_solid_border_corner(localPos, pixelsPerFragment);
if (vRadii.x > 0.0) {
float alpha = alpha_for_solid_border_corner(localPos, vRadii.z, vRadii.x, pixelsPerFragment);
oFragColor *= vec4(1, 1, 1, alpha);
}
break;
}
default:
@ -286,7 +325,6 @@ void draw_solid_border(float distanceFromMixLine, vec2 localPos) {
}
}
// TODO: Investigate performance of this shader and see
// if it's worthwhile splitting it / removing branches etc.
void main(void) {
@ -302,9 +340,25 @@ 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;
draw_solid_border(distance_from_mix_line, local_pos);
oFragColor *= vec4(1, 1, 1, alpha);
switch (vBorderStyle) {
case BORDER_STYLE_DASHED:
case BORDER_STYLE_DOTTED:
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;
}
oFragColor *= vec4(1, 1, 1, alpha);
#else
switch (vBorderStyle) {
case BORDER_STYLE_DASHED:
@ -322,8 +376,7 @@ void main(void) {
draw_solid_border(vDistanceFromMixLine, local_pos);
break;
case BORDER_STYLE_DOUBLE:
discard_pixels_in_rounded_borders(local_pos);
draw_double_border();
draw_double_border(vDistanceFromMixLine, local_pos);
break;
default:
discard;

View file

@ -8,14 +8,15 @@ struct Border {
vec4 verticalColor;
vec4 horizontalColor;
vec4 radii;
uvec4 border_style_trbl;
vec4 border_style_trbl;
vec4 part;
};
layout(std140) uniform Items {
Border borders[WR_MAX_PRIM_ITEMS];
};
uint get_border_style(Border a_border, uint a_edge) {
float get_border_style(Border a_border, uint a_edge) {
switch (a_edge) {
case PST_TOP:
case PST_TOP_LEFT:
@ -56,7 +57,7 @@ void main(void) {
vRadii = border.radii;
float x0, y0, x1, y1;
vBorderPart = border.info.layer_tile_part.z;
vBorderPart = uint(border.part.x);
switch (vBorderPart) {
// These are the layer tile part PrimitivePart as uploaded by the tiling.rs
case PST_TOP_LEFT:
@ -103,7 +104,7 @@ void main(void) {
break;
}
vBorderStyle = get_border_style(border, vBorderPart);
vBorderStyle = uint(get_border_style(border, vBorderPart));
// y1 - y0 is the height of the corner / line
// x1 - x0 is the width of the corner / line.

View file

@ -4,11 +4,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
struct Composite {
uvec4 src0;
uvec4 src1;
uvec4 target_rect;
ivec4 info;
vec4 amount;
vec4 src0;
vec4 src1;
vec4 target_rect;
vec4 info_amount;
};
layout(std140) uniform Items {
@ -30,8 +29,8 @@ void main(void) {
st1 = vec2(composite.src1.xy + composite.src1.zw) / 2048.0;
vUv1 = mix(st0, st1, aPosition.xy);
vInfo = composite.info.xy;
vAmount = composite.amount.x;
vInfo = ivec2(composite.info_amount.xy);
vAmount = composite.info_amount.z;
gl_Position = uTransform * vec4(local_pos, 0, 1);
}

View file

@ -10,7 +10,7 @@ struct Gradient {
PrimitiveInfo info;
vec4 color0;
vec4 color1;
uvec4 dir;
vec4 dir;
Clip clip;
};
@ -32,7 +32,7 @@ void main(void) {
vPos = vi.local_clamped_pos;
#endif
switch (gradient.dir.x) {
switch (uint(gradient.dir.x)) {
case DIR_HORIZONTAL:
vF = f.x;
break;

View file

@ -6,7 +6,7 @@
struct Glyph {
PrimitiveInfo info;
vec4 color;
ivec4 uv_rect;
vec4 uv_rect;
};
layout(std140) uniform Items {

View file

@ -5,7 +5,7 @@
struct TextRunGlyph {
vec4 local_rect;
ivec4 uv_rect;
vec4 uv_rect;
};
struct TextRun {
@ -22,7 +22,7 @@ void main(void) {
TextRun text_run = text_runs[gl_InstanceID / WR_GLYPHS_PER_TEXT_RUN];
TextRunGlyph glyph = text_run.glyphs[gl_InstanceID % WR_GLYPHS_PER_TEXT_RUN];
text_run.info.local_rect = glyph.local_rect;
ivec4 uv_rect = glyph.uv_rect;
vec4 uv_rect = glyph.uv_rect;
#ifdef WR_FEATURE_TRANSFORM
TransformVertexInfo vi = write_transform_vertex(text_run.info);