diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 715aa9eb11f..d5083dc0c06 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -2593,7 +2593,7 @@ dependencies = [ [[package]] name = "webrender" version = "0.5.1" -source = "git+https://github.com/servo/webrender#5e4c18b22c6b441319959bd0e66b269a50d866be" +source = "git+https://github.com/servo/webrender#4171ab07f36d9dff12cc4fc31b23c037851cd747" 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)", @@ -2618,7 +2618,7 @@ dependencies = [ [[package]] name = "webrender_traits" version = "0.5.1" -source = "git+https://github.com/servo/webrender#5e4c18b22c6b441319959bd0e66b269a50d866be" +source = "git+https://github.com/servo/webrender#4171ab07f36d9dff12cc4fc31b23c037851cd747" 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)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 5073c6f0782..c76afd37c50 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -2453,7 +2453,7 @@ dependencies = [ [[package]] name = "webrender" version = "0.5.1" -source = "git+https://github.com/servo/webrender#5e4c18b22c6b441319959bd0e66b269a50d866be" +source = "git+https://github.com/servo/webrender#4171ab07f36d9dff12cc4fc31b23c037851cd747" 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)", @@ -2478,7 +2478,7 @@ dependencies = [ [[package]] name = "webrender_traits" version = "0.5.1" -source = "git+https://github.com/servo/webrender#5e4c18b22c6b441319959bd0e66b269a50d866be" +source = "git+https://github.com/servo/webrender#4171ab07f36d9dff12cc4fc31b23c037851cd747" 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)", diff --git a/resources/shaders/ps_border.fs.glsl b/resources/shaders/ps_border.fs.glsl index 80ebc55bc33..ef5b7ac16b2 100644 --- a/resources/shaders/ps_border.fs.glsl +++ b/resources/shaders/ps_border.fs.glsl @@ -4,6 +4,21 @@ * 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/. */ +void discard_pixels_in_rounded_borders(vec2 local_pos) { + float distanceFromRef = distance(vRefPoint, local_pos); + if (vRadii.x > 0.0 && (distanceFromRef > vRadii.x || distanceFromRef < vRadii.z)) { + discard; + } +} + +vec4 get_fragment_color(float distanceFromMixLine, float pixelsPerFragment) { + // Here we are mixing between the two border colors. We need to convert + // distanceFromMixLine it to pixel space to properly anti-alias and then push + // it between the limits accepted by `mix`. + float colorMix = min(max(distanceFromMixLine / pixelsPerFragment, -0.5), 0.5) + 0.5; + return mix(vHorizontalColor, vVerticalColor, colorMix); +} + #ifdef WR_FEATURE_TRANSFORM #else @@ -73,11 +88,10 @@ vec4 draw_double_edge(float pos, float len) { // And 0.0 for the blank part. float should_fill = in_first_part + in_third_part; - float color_weight = step(0.0, vF); - vec4 color = mix(vHorizontalColor, vVerticalColor, color_weight); - + // 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, color, should_fill); + return mix(white, get_fragment_color(vDistanceFromMixLine, pixels_per_fragment), should_fill); } vec4 draw_double_edge_vertical() { @@ -104,7 +118,8 @@ vec4 draw_double_edge_corner() { return draw_double_edge_with_radius(); } - bool is_vertical = (vBorderPart == PST_TOP_LEFT) ? vF < 0 : vF >= 0; + bool is_vertical = (vBorderPart == PST_TOP_LEFT) ? vDistanceFromMixLine < 0 : + vDistanceFromMixLine >= 0; if (is_vertical) { return draw_double_edge_vertical(); } else { @@ -225,23 +240,14 @@ void draw_double_border(void) { } } } + #endif -void discard_pixels_in_rounded_borders(vec2 local_pos) { - float distanceFromRef = distance(vRefPoint, local_pos); - if (vRadii.x > 0.0 && (distanceFromRef > vRadii.x || distanceFromRef < vRadii.z)) { - discard; - } -} - -void draw_antialiased_solid_border_corner(vec2 local_pos) { +void draw_antialiased_solid_border_corner(vec2 local_pos, float pixelsPerFragment) { if (vRadii.x <= 0.0) { return; } - // This is the conversion factor for transformations and device pixel scaling. - float pixelsPerFragment = length(fwidth(local_pos.xy)); - float distanceFromRef = distance(vRefPoint, local_pos); // We want to start anti-aliasing one pixel in from the border. @@ -262,6 +268,25 @@ void draw_antialiased_solid_border_corner(vec2 local_pos) { } } +void draw_solid_border(float distanceFromMixLine, vec2 localPos) { + switch (vBorderPart) { + case PST_TOP_LEFT: + case PST_TOP_RIGHT: + case PST_BOTTOM_LEFT: + case PST_BOTTOM_RIGHT: { + // 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); + break; + } + default: + oFragColor = vHorizontalColor; + discard_pixels_in_rounded_borders(localPos); + } +} + + // TODO: Investigate performance of this shader and see // if it's worthwhile splitting it / removing branches etc. void main(void) { @@ -274,9 +299,12 @@ void main(void) { #ifdef WR_FEATURE_TRANSFORM // TODO(gw): Support other border styles for transformed elements. - discard_pixels_in_rounded_borders(local_pos); - float f = (local_pos.x - vSizeInfo.x) * vSizeInfo.w - (local_pos.y - vSizeInfo.y) * vSizeInfo.z; - oFragColor = vec4(1, 1, 1, alpha) * mix(vHorizontalColor, vVerticalColor, step(0.0, f)); + 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); + #else switch (vBorderStyle) { case BORDER_STYLE_DASHED: @@ -289,25 +317,9 @@ void main(void) { break; case BORDER_STYLE_OUTSET: case BORDER_STYLE_INSET: - discard_pixels_in_rounded_borders(local_pos); - oFragColor = mix(vVerticalColor, vHorizontalColor, step(0.0, vF)); - break; case BORDER_STYLE_SOLID: - oFragColor = mix(vHorizontalColor, vVerticalColor, step(0.0, vF)); - switch (vBorderPart) { - case PST_TOP_LEFT: - case PST_TOP_RIGHT: - case PST_BOTTOM_LEFT: - case PST_BOTTOM_RIGHT: - draw_antialiased_solid_border_corner(local_pos); - break; - default: - discard_pixels_in_rounded_borders(local_pos); - } - break; case BORDER_STYLE_NONE: - discard_pixels_in_rounded_borders(local_pos); - oFragColor = mix(vHorizontalColor, vVerticalColor, step(0.0, vF)); + draw_solid_border(vDistanceFromMixLine, local_pos); break; case BORDER_STYLE_DOUBLE: discard_pixels_in_rounded_borders(local_pos); diff --git a/resources/shaders/ps_border.glsl b/resources/shaders/ps_border.glsl index da982249046..badbcdc342e 100644 --- a/resources/shaders/ps_border.glsl +++ b/resources/shaders/ps_border.glsl @@ -19,12 +19,14 @@ flat varying uint vBorderPart; // Which part of the border we're drawing. // These are in device space #ifdef WR_FEATURE_TRANSFORM varying vec3 vLocalPos; // The clamped position in local space. -flat varying vec4 vSizeInfo; +flat varying vec4 vPieceRect; +flat varying float vPieceRectHypotenuseLength; #else varying vec2 vLocalPos; // The clamped position in local space. // These two are interpolated -varying float vF; // This is a weighting as we get closer to the bottom right corner? +varying float vDistanceFromMixLine; // This is the distance from the line where two colors + // meet in border corners. varying vec2 vDevicePos; // The clamped position in device space. flat varying vec4 vBorders; // the rect of the border in (x, y, width, height) form #endif diff --git a/resources/shaders/ps_border.vs.glsl b/resources/shaders/ps_border.vs.glsl index 5cf7b72054d..d78efc99145 100644 --- a/resources/shaders/ps_border.vs.glsl +++ b/resources/shaders/ps_border.vs.glsl @@ -109,11 +109,17 @@ void main(void) { // x1 - x0 is the width of the corner / line. float width = x1 - x0; float height = y1 - y0; + + // The fragment shader needs to calculate the distance from the bisecting line + // to properly mix border colors. For transformed borders, we calculate this distance + // in the fragment shader itself. For non-transformed borders, we can use the + // interpolator. #ifdef WR_FEATURE_TRANSFORM - vSizeInfo = vec4(x0, y0, width, height); + vPieceRect = vec4(x0, y0, width, height); + vPieceRectHypotenuseLength = sqrt(pow(width, 2) + pow(height, 2)); #else - // This is just a weighting of the pixel colors it seems? - vF = (vi.local_clamped_pos.x - x0) * height - (vi.local_clamped_pos.y - y0) * width; + vDistanceFromMixLine = (vi.local_clamped_pos.x - x0) * height - + (vi.local_clamped_pos.y - y0) * width; // These are in device space vDevicePos = vi.global_clamped_pos; diff --git a/resources/shaders/ps_text_run.fs.glsl b/resources/shaders/ps_text_run.fs.glsl new file mode 100644 index 00000000000..175102f790e --- /dev/null +++ b/resources/shaders/ps_text_run.fs.glsl @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +void main(void) { + float a = texture(sDiffuse, vUv).a; + oFragColor = vec4(vColor.rgb, vColor.a * a); +} diff --git a/resources/shaders/ps_text_run.glsl b/resources/shaders/ps_text_run.glsl new file mode 100644 index 00000000000..d58ff7d14bb --- /dev/null +++ b/resources/shaders/ps_text_run.glsl @@ -0,0 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +flat varying vec4 vColor; +varying vec2 vUv; + +#ifdef WR_FEATURE_TRANSFORM +varying vec3 vLocalPos; +flat varying vec4 vLocalRect; +#endif diff --git a/resources/shaders/ps_text_run.vs.glsl b/resources/shaders/ps_text_run.vs.glsl new file mode 100644 index 00000000000..894a2bb9cc6 --- /dev/null +++ b/resources/shaders/ps_text_run.vs.glsl @@ -0,0 +1,43 @@ +#line 1 +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +struct TextRunGlyph { + vec4 local_rect; + ivec4 uv_rect; +}; + +struct TextRun { + PrimitiveInfo info; + TextRunGlyph glyphs[WR_GLYPHS_PER_TEXT_RUN]; + vec4 color; +}; + +layout(std140) uniform Items { + TextRun text_runs[WR_MAX_PRIM_ITEMS]; +}; + +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; + +#ifdef WR_FEATURE_TRANSFORM + TransformVertexInfo vi = write_transform_vertex(text_run.info); + vLocalRect = vi.clipped_local_rect; + vLocalPos = vi.local_pos; + vec2 f = (vi.local_pos.xy - text_run.info.local_rect.xy) / text_run.info.local_rect.zw; +#else + VertexInfo vi = write_vertex(text_run.info); + vec2 f = (vi.local_clamped_pos - vi.local_rect.p0) / (vi.local_rect.p1 - vi.local_rect.p0); +#endif + + vec2 texture_size = textureSize(sDiffuse, 0); + vec2 st0 = uv_rect.xy / texture_size; + vec2 st1 = uv_rect.zw / texture_size; + + vColor = text_run.color; + vUv = mix(st0, st1, f); +}