From 25f60a29db8436febc85f14b7c2dc6d3956dc045 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 31 Aug 2016 19:43:32 +1000 Subject: [PATCH] Webrender update (border anti-aliasing, primitive caching). --- components/servo/Cargo.lock | 4 +- ports/cef/Cargo.lock | 4 +- resources/shaders/prim_shared.glsl | 3 + resources/shaders/ps_border.fs.glsl | 78 +++++++++---------------- resources/shaders/ps_border.glsl | 3 +- resources/shaders/ps_border.vs.glsl | 3 +- resources/shaders/ps_image.vs.glsl | 26 +++++++-- resources/shaders/ps_image_clip.vs.glsl | 25 ++++++-- 8 files changed, 80 insertions(+), 66 deletions(-) diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 3acb51618b1f..869984406ee5 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -2591,7 +2591,7 @@ dependencies = [ [[package]] name = "webrender" version = "0.5.1" -source = "git+https://github.com/servo/webrender#8cff5fd308b0d8db21c4008286685854107d25b7" +source = "git+https://github.com/servo/webrender#b3611d501b13281299a073540058547feeb7e4e3" 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#8cff5fd308b0d8db21c4008286685854107d25b7" +source = "git+https://github.com/servo/webrender#b3611d501b13281299a073540058547feeb7e4e3" 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 6546afb20f2f..84b18a5eec4f 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -2451,7 +2451,7 @@ dependencies = [ [[package]] name = "webrender" version = "0.5.1" -source = "git+https://github.com/servo/webrender#8cff5fd308b0d8db21c4008286685854107d25b7" +source = "git+https://github.com/servo/webrender#b3611d501b13281299a073540058547feeb7e4e3" 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#8cff5fd308b0d8db21c4008286685854107d25b7" +source = "git+https://github.com/servo/webrender#b3611d501b13281299a073540058547feeb7e4e3" 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/prim_shared.glsl b/resources/shaders/prim_shared.glsl index 3e80048ce524..f0f6619e1cc6 100644 --- a/resources/shaders/prim_shared.glsl +++ b/resources/shaders/prim_shared.glsl @@ -12,6 +12,9 @@ #define PST_BOTTOM uint(6) #define PST_RIGHT uint(7) +#define UV_NORMALIZED uint(0) +#define UV_PIXEL uint(1) + // Border styles as defined in webrender_traits/types.rs #define BORDER_STYLE_NONE uint(0) #define BORDER_STYLE_SOLID uint(1) diff --git a/resources/shaders/ps_border.fs.glsl b/resources/shaders/ps_border.fs.glsl index 33a1fb823e61..545415e30503 100644 --- a/resources/shaders/ps_border.fs.glsl +++ b/resources/shaders/ps_border.fs.glsl @@ -109,46 +109,6 @@ vec4 draw_dotted_edge() { return mix(white, circleColor, circleColor.a); } -// 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. -// This calculates how much to nudge and which axis to nudge on. -vec2 get_dashed_nudge_factor(vec2 dash_size, bool is_corner) { - if (is_corner) { - return vec2(0.0, 0.0); - } - - bool xAxisFudge = vBorders.z > vBorders.w; - if (xAxisFudge) { - return vec2(dash_size.x / 2.0, 0); - } - - return vec2(0.0, dash_size.y / 2.0); -} - -vec4 draw_dashed_edge(bool is_corner) { - // Everything here should be in device pixels. - // We want the dot to be roughly the size of the whole border spacing - // 5.5 here isn't a magic number, it's just what mostly looks like FF/Chrome - // TODO: Investigate exactly what FF does. - float dash_interval = min(vBorders.w, vBorders.z) * 5.5; - vec2 edge_size = vec2(vBorders.z, vBorders.w); - vec2 dash_size = vec2(dash_interval / 2.0, dash_interval / 2.0); - vec2 position = vDevicePos - vBorders.xy; - - vec2 dash_count = floor(edge_size/ dash_interval); - vec2 dist_between_dashes = edge_size / dash_count; - - vec2 target_rect_index = floor(position / dist_between_dashes); - vec2 target_rect_loc = target_rect_index * dist_between_dashes; - target_rect_loc += get_dashed_nudge_factor(dash_size, is_corner); - vec4 target_rect = vec4(target_rect_loc, dash_size); - - vec4 white = vec4(1.0, 1.0, 1.0, 1.0); - vec4 target_colored_rect = drawRect(position, target_rect, vVerticalColor.xyz); - return mix(white, target_colored_rect, target_colored_rect.a); -} - void draw_dotted_border(void) { switch (vBorderPart) { // These are the layer tile part PrimitivePart as uploaded by the tiling.rs @@ -172,7 +132,19 @@ void draw_dotted_border(void) { } } -void draw_dashed_border(void) { +#endif + +vec4 draw_dashed_edge(float position, float border_width) { + // TODO: Investigate exactly what FF does. + float size = border_width * 3; + float segment = floor(position / size) + 2; + return mix(vec4(0, 0, 0, 0), vHorizontalColor, mod(segment, 2)); +} + +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: @@ -180,24 +152,31 @@ void draw_dashed_border(void) { case PST_BOTTOM_LEFT: case PST_BOTTOM_RIGHT: { - // TODO: Fix for corners with a border-radius - bool is_corner = true; - oFragColor = draw_dashed_edge(is_corner); + 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)); + } + break; } case PST_BOTTOM: case PST_TOP: + { + oFragColor = draw_dashed_edge(vLocalPos.x - vPieceRect.x, vPieceRect.w); + break; + } case PST_LEFT: case PST_RIGHT: { - bool is_corner = false; - oFragColor = draw_dashed_edge(is_corner); + oFragColor = draw_dashed_edge(vLocalPos.y - vPieceRect.y, vPieceRect.z); break; } } } -#endif vec4 draw_double_edge(float pos, float len, @@ -343,6 +322,8 @@ void main(void) { switch (vBorderStyle) { case BORDER_STYLE_DASHED: + draw_dashed_border(local_pos, distance_from_mix_line); + break; case BORDER_STYLE_DOTTED: case BORDER_STYLE_OUTSET: case BORDER_STYLE_INSET: @@ -362,8 +343,7 @@ void main(void) { #else switch (vBorderStyle) { case BORDER_STYLE_DASHED: - discard_pixels_in_rounded_borders(local_pos); - draw_dashed_border(); + draw_dashed_border(local_pos, vDistanceFromMixLine); break; case BORDER_STYLE_DOTTED: discard_pixels_in_rounded_borders(local_pos); diff --git a/resources/shaders/ps_border.glsl b/resources/shaders/ps_border.glsl index badbcdc342e9..d46b72eed497 100644 --- a/resources/shaders/ps_border.glsl +++ b/resources/shaders/ps_border.glsl @@ -16,10 +16,11 @@ flat varying vec2 vRefPoint; flat varying uint vBorderStyle; flat varying uint vBorderPart; // Which part of the border we're drawing. +flat varying vec4 vPieceRect; + // These are in device space #ifdef WR_FEATURE_TRANSFORM varying vec3 vLocalPos; // The clamped position in local space. -flat varying vec4 vPieceRect; flat varying float vPieceRectHypotenuseLength; #else varying vec2 vLocalPos; // The clamped position in local space. diff --git a/resources/shaders/ps_border.vs.glsl b/resources/shaders/ps_border.vs.glsl index d44e5928ae26..6ad3cdb64735 100644 --- a/resources/shaders/ps_border.vs.glsl +++ b/resources/shaders/ps_border.vs.glsl @@ -111,12 +111,13 @@ void main(void) { float width = x1 - x0; float height = y1 - y0; + vPieceRect = vec4(x0, y0, width, height); + // 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 - vPieceRect = vec4(x0, y0, width, height); vPieceRectHypotenuseLength = sqrt(pow(width, 2) + pow(height, 2)); #else vDistanceFromMixLine = (vi.local_clamped_pos.x - x0) * height - diff --git a/resources/shaders/ps_image.vs.glsl b/resources/shaders/ps_image.vs.glsl index a3ce386092e1..16d46a13b668 100644 --- a/resources/shaders/ps_image.vs.glsl +++ b/resources/shaders/ps_image.vs.glsl @@ -5,8 +5,8 @@ struct Image { PrimitiveInfo info; - vec4 st_rect; // Location of the image texture in the texture atlas. - vec4 stretch_size; // Size of the actual image. + vec4 st_rect; // Location of the image texture in the texture atlas. + vec4 stretch_size_uvkind; // Size of the actual image. }; layout(std140) uniform Items { @@ -20,13 +20,27 @@ void main(void) { TransformVertexInfo vi = write_transform_vertex(image.info); vLocalRect = vi.clipped_local_rect; vLocalPos = vi.local_pos; - vStretchSize = image.stretch_size.xy; + vStretchSize = image.stretch_size_uvkind.xy; #else VertexInfo vi = write_vertex(image.info); - vUv = (vi.local_clamped_pos - vi.local_rect.p0) / image.stretch_size.xy; + vUv = (vi.local_clamped_pos - vi.local_rect.p0) / image.stretch_size_uvkind.xy; #endif // vUv will contain how many times this image has wrapped around the image size. - vTextureSize = image.st_rect.zw - image.st_rect.xy; - vTextureOffset = image.st_rect.xy; + vec2 st0 = image.st_rect.xy; + vec2 st1 = image.st_rect.zw; + + switch (uint(image.stretch_size_uvkind.z)) { + case UV_NORMALIZED: + break; + case UV_PIXEL: { + vec2 texture_size = textureSize(sDiffuse, 0); + st0 /= texture_size; + st1 /= texture_size; + } + break; + } + + vTextureSize = st1 - st0; + vTextureOffset = st0; } diff --git a/resources/shaders/ps_image_clip.vs.glsl b/resources/shaders/ps_image_clip.vs.glsl index 89c6198f9909..dea9dc2cf5d1 100644 --- a/resources/shaders/ps_image_clip.vs.glsl +++ b/resources/shaders/ps_image_clip.vs.glsl @@ -5,8 +5,8 @@ struct Image { PrimitiveInfo info; - vec4 st_rect; // Location of the image texture in the texture atlas. - vec4 stretch_size; // Size of the actual image. + vec4 st_rect; // Location of the image texture in the texture atlas. + vec4 stretch_size_uvkind; // Size of the actual image. Clip clip; }; @@ -26,7 +26,22 @@ void main(void) { vPos = vi.local_clamped_pos; // vUv will contain how many times this image has wrapped around the image size. - vUv = (vi.local_clamped_pos - image.info.local_rect.xy) / image.stretch_size.xy; - vTextureSize = image.st_rect.zw - image.st_rect.xy; - vTextureOffset = image.st_rect.xy; + vUv = (vi.local_clamped_pos - image.info.local_rect.xy) / image.stretch_size_uvkind.xy; + + vec2 st0 = image.st_rect.xy; + vec2 st1 = image.st_rect.zw; + + switch (uint(image.stretch_size_uvkind.z)) { + case UV_NORMALIZED: + break; + case UV_PIXEL: { + vec2 texture_size = textureSize(sDiffuse, 0); + st0 /= texture_size; + st1 /= texture_size; + } + break; + } + + vTextureSize = st1 - st0; + vTextureOffset = st0; }