Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite push_line interface, and make patterned lines match gecko closer #1923

Merged
merged 4 commits into from Oct 25, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -22,13 +22,14 @@ varying vec2 vLocalPos;

struct Line {
vec4 color;
float wavyLineThickness;
float style;
float orientation;
};

Line fetch_line(int address) {
vec4 data[2] = fetch_from_resource_cache_2(address);
return Line(data[0], data[1].x, data[1].y);
return Line(data[0], data[1].x, data[1].y, data[1].z);
}

void main(void) {
@@ -58,41 +59,37 @@ void main(void) {
break;
}
case LINE_STYLE_DASHED: {
// y = dash on + off length
// z = dash length
// w = center line of edge cross-axis (for dots only)
float desired_dash_length = size.y * 3.0;
// Consider half total length since there is an equal on/off for each dash.
float dash_count = 1.0 + ceil(size.x / desired_dash_length);
float dash_length = size.x / dash_count;
vParams = vec4(2.0 * dash_length,
dash_length,
float dash_length = size.y * 3.0;
vParams = vec4(2.0 * dash_length, // period
dash_length, // dash length
0.0,
0.0);
break;
}
case LINE_STYLE_DOTTED: {
float diameter = size.y;
float radius = 0.5 * diameter;
float dot_count = ceil(0.5 * size.x / diameter);
float empty_space = size.x - dot_count * diameter;
float distance_between_centers = diameter + empty_space / dot_count;
float period = diameter * 2.0;
float center_line = pos.y + 0.5 * size.y;
vParams = vec4(distance_between_centers,
radius,
float max_x = floor(size.x / period) * period;
vParams = vec4(period,
diameter / 2.0, // radius
center_line,
0.0);
max_x);
break;
}
case LINE_STYLE_WAVY: {
// Choose some arbitrary values to scale thickness,
// wave period etc.
// TODO(gw): Tune these to get closer to what Gecko uses.
float thickness = 0.15 * size.y;
vParams = vec4(thickness,
size.y * 0.5,
size.y * 0.75,
size.y * 0.5);
// This logic copied from gecko to get the same results
float line_thickness = max(line.wavyLineThickness, 1.0);
// Difference in height between peaks and troughs
// (and since slopes are 45 degrees, the length of each slope)
float slope_length = size.y - line_thickness;
// Length of flat runs
float flat_length = max((line_thickness - 1.0) * 2.0, 1.0);

vParams = vec4(line_thickness / 2.0,
slope_length,
flat_length,
size.y);
break;
}
}
@@ -142,6 +139,9 @@ void main(void) {
#endif

#ifdef WR_FRAGMENT_SHADER

#define MAGIC_WAVY_LINE_AA_SNAP 0.7

float det(vec2 a, vec2 b) {
return a.x * b.y - b.x * a.y;
}
@@ -215,40 +215,51 @@ void main(void) {
vec2 dot_relative_pos = vec2(x, pos.y) - vParams.yz;
float dot_distance = length(dot_relative_pos) - vParams.y;
alpha = min(alpha, distance_aa(aa_range, dot_distance));
// Clip off partial dots
alpha *= step(pos.x - vLocalOrigin.x, vParams.w);
break;
}
case LINE_STYLE_WAVY: {
vec2 normalized_local_pos = pos - vLocalOrigin.xy;

float y0 = vParams.y;
float dy = vParams.z;
float dx = vParams.w;

// Flip the position of the bezier center points each
// wave period.
dy *= step(mod(normalized_local_pos.x, 4.0 * dx), 2.0 * dx) * 2.0 - 1.0;

// Convert pos to a local position within one wave period.
normalized_local_pos.x = dx + mod(normalized_local_pos.x, 2.0 * dx);

// Evaluate SDF to the first bezier.
vec2 b0_0 = vec2(0.0 * dx, y0);
vec2 b1_0 = vec2(1.0 * dx, y0 - dy);
vec2 b2_0 = vec2(2.0 * dx, y0);
float d1 = approx_distance(normalized_local_pos, b0_0, b1_0, b2_0);

// Evaluate SDF to the second bezier.
vec2 b0_1 = vec2(2.0 * dx, y0);
vec2 b1_1 = vec2(3.0 * dx, y0 + dy);
vec2 b2_1 = vec2(4.0 * dx, y0);
float d2 = approx_distance(normalized_local_pos, b0_1, b1_1, b2_1);

// SDF union - this is needed to avoid artifacts where the
// bezier curves join.
float d = min(d1, d2);
float half_line_thickness = vParams.x;
float slope_length = vParams.y;
float flat_length = vParams.z;
float vertical_bounds = vParams.w;
// Our pattern is just two slopes and two flats
float half_period = slope_length + flat_length;

float mid_height = vertical_bounds / 2.0;
float peak_offset = mid_height - half_line_thickness;
// Flip the wave every half period
float flip = -2.0 * (step(mod(normalized_local_pos.x, 2.0 * half_period), half_period) - 0.5);
// float flip = -1.0;
peak_offset *= flip;
float peak_height = mid_height + peak_offset;

// Convert pos to a local position within one half period
normalized_local_pos.x = mod(normalized_local_pos.x, half_period);

// Compute signed distance to the 3 lines that make up an arc
float dist1 = distance_to_line(vec2(0.0, peak_height),
vec2(1.0, -flip),
normalized_local_pos);
float dist2 = distance_to_line(vec2(0.0, peak_height),
vec2(0, -flip),
normalized_local_pos);
float dist3 = distance_to_line(vec2(flat_length, peak_height),
vec2(-1.0, -flip),
normalized_local_pos);
float dist = abs(max(max(dist1, dist2), dist3));

// Apply AA based on the thickness of the wave
alpha = distance_aa(aa_range, dist - half_line_thickness);

// Disable AA for thin lines
if (half_line_thickness <= 1.0) {
alpha = 1.0 - step(alpha, MAGIC_WAVY_LINE_AA_SNAP);
}

// Apply AA based on the thickness of the wave.
alpha = distance_aa(aa_range, d - vParams.x);
break;
}
}
@@ -518,21 +518,11 @@ impl FrameContext {
}
}
SpecificDisplayItem::Line(ref info) => {
let prim_info = LayerPrimitiveInfo {
rect: LayerRect::zero(),
local_clip: *item.local_clip(),
is_backface_visible: prim_info.is_backface_visible,
tag: prim_info.tag,
};

context.builder.add_line(
clip_and_scroll,
&prim_info,
info.baseline,
info.start,
info.end,
info.wavy_line_thickness,
info.orientation,
info.width,
&info.color,
info.style,
);
@@ -651,26 +651,13 @@ impl FrameBuilder {
&mut self,
clip_and_scroll: ClipAndScrollInfo,
info: &LayerPrimitiveInfo,
baseline: f32,
start: f32,
end: f32,
wavy_line_thickness: f32,
orientation: LineOrientation,
width: f32,
color: &ColorF,
style: LineStyle,
) {
let new_rect = match orientation {
LineOrientation::Horizontal => LayerRect::new(
LayerPoint::new(start, baseline),
LayerSize::new(end - start, width),
),
LineOrientation::Vertical => LayerRect::new(
LayerPoint::new(baseline, start),
LayerSize::new(width, end - start),
),
};

let line = LinePrimitive {
wavy_line_thickness,
color: *color,
style: style,
orientation: orientation,
@@ -690,7 +677,7 @@ impl FrameBuilder {
let mut line = line.clone();
line.color = shadow.color;
let mut info = info.clone();
info.rect = new_rect.translate(&shadow.offset);
info.rect = info.rect.translate(&shadow.offset);
let prim_index = self.create_primitive(
clip_and_scroll,
&info,
@@ -700,8 +687,6 @@ impl FrameBuilder {
self.shadow_prim_stack[idx].1.push((prim_index, clip_and_scroll));
}

let mut info = info.clone();
info.rect = new_rect;
let prim_index = self.create_primitive(
clip_and_scroll,
&info,
@@ -714,7 +699,7 @@ impl FrameBuilder {
self.add_primitive_to_hit_testing_list(&info, clip_and_scroll);
self.add_primitive_to_draw_list(prim_index, clip_and_scroll);
} else {
self.pending_shadow_contents.push((prim_index, clip_and_scroll, info));
self.pending_shadow_contents.push((prim_index, clip_and_scroll, *info));
}
}

@@ -727,7 +712,7 @@ impl FrameBuilder {

// Only run real blurs here (fast path zero blurs are handled above).
if blur_radius > 0.0 {
let shadow_rect = new_rect.inflate(
let shadow_rect = info.rect.inflate(
blur_radius,
blur_radius,
);
@@ -197,6 +197,7 @@ impl ToGpuBlocks for BrushPrimitive {
#[repr(C)]
pub struct LinePrimitive {
pub color: ColorF,
pub wavy_line_thickness: f32,
pub style: LineStyle,
pub orientation: LineOrientation,
}
@@ -205,10 +206,10 @@ impl ToGpuBlocks for LinePrimitive {
fn write_gpu_blocks(&self, mut request: GpuDataRequest) {
request.push(self.color);
request.push([
self.wavy_line_thickness,
pack_as_float(self.style as u32),
pack_as_float(self.orientation as u32),
0.0,
0.0,
]);
}
}
@@ -148,11 +148,8 @@ pub struct RectangleDisplayItem {

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct LineDisplayItem {
pub baseline: f32, // LayerPixel
pub start: f32,
pub end: f32,
pub orientation: LineOrientation, // toggles whether above values are interpreted as x/y values
pub width: f32,
pub wavy_line_thickness: f32,
pub color: ColorF,
pub style: LineStyle,
}
@@ -773,21 +773,15 @@ impl DisplayListBuilder {
pub fn push_line(
&mut self,
info: &LayoutPrimitiveInfo,
baseline: f32,
start: f32,
end: f32,
wavy_line_thickness: f32,
orientation: LineOrientation,
width: f32,
color: ColorF,
color: &ColorF,
style: LineStyle,
) {
let item = SpecificDisplayItem::Line(LineDisplayItem {
baseline,
start,
end,
wavy_line_thickness,
orientation,
width,
color,
color: *color,
style,
});

Binary file not shown.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.