| author | Oana Pop Rus <opoprus@mozilla.com> |
| Mon, 03 Feb 2020 22:00:29 +0200 | |
| changeset 512404 | 801277ae423f6f5183d62c45cda342ea28ee6040 |
| parent 512403 | 76ba712aa17975a92753b75c0d2ac3928aede74b |
| child 512405 | 0a3bf632a719c224b8cb03063bc763c53143da10 |
| push id | 37087 |
| push user | nbeleuzu@mozilla.com |
| push date | Tue, 04 Feb 2020 04:04:16 +0000 |
| treeherder | mozilla-central@c32017c40f19 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| bugs | 1571974, 1518179 |
| milestone | 74.0a1 |
| backs out | dfb21632ea198c1acdc6a34ee08113d516f666d5 3549dd471446c291864822736f4587c81741cd56 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/wr/webrender/res/cs_line_decoration.glsl +++ b/gfx/wr/webrender/res/cs_line_decoration.glsl @@ -4,47 +4,51 @@ #include shared #define LINE_STYLE_SOLID 0 #define LINE_STYLE_DOTTED 1 #define LINE_STYLE_DASHED 2 #define LINE_STYLE_WAVY 3 -// Fragment position in the coordinate system used for positioning decorations. -// To keep the code independent of whether the line is horizontal or vertical, -// vLocalPos.x is always parallel, and .y always perpendicular, to the line -// being decorated. +// Local space position varying vec2 vLocalPos; +flat varying float vAxisSelect; flat varying int vStyle; flat varying vec4 vParams; #ifdef WR_VERTEX_SHADER -// The size of the mask tile we're rendering, in pixels. -in vec4 aTaskRect; - -// The size of the mask tile. aLocalSize.x is always horizontal and .y vertical, -// regardless of the line's orientation. The size is chosen by -// prim_store::get_line_decoration_sizes. -in vec2 aLocalSize; +#define LINE_ORIENTATION_VERTICAL 0 +#define LINE_ORIENTATION_HORIZONTAL 1 -// A LINE_STYLE_* value, indicating what sort of line to draw. +in vec4 aTaskRect; +in vec2 aLocalSize; in int aStyle; - -// 0.0 for a horizontal line, 1.0 for a vertical line. -in float aAxisSelect; - -// The thickness of the wavy line itself, not the amplitude of the waves (i.e., -// the thickness of the final decorated line). +in int aOrientation; in float aWavyLineThickness; void main(void) { - vec2 size = mix(aLocalSize, aLocalSize.yx, aAxisSelect); + vec2 size; + + switch (aOrientation) { + case LINE_ORIENTATION_HORIZONTAL: + vAxisSelect = 0.0; + size = aLocalSize; + break; + case LINE_ORIENTATION_VERTICAL: + vAxisSelect = 1.0; + size = aLocalSize.yx; + break; + default: + vAxisSelect = 0.0; + size = vec2(0.0); + } + vStyle = aStyle; switch (vStyle) { case LINE_STYLE_SOLID: { break; } case LINE_STYLE_DASHED: { vParams = vec4(size.x, // period @@ -77,32 +81,35 @@ void main(void) { flat_length, size.y); break; } default: vParams = vec4(0.0); } - vLocalPos = mix(aPosition.xy, aPosition.yx, aAxisSelect) * size; + vLocalPos = aPosition.xy * aLocalSize; gl_Position = uTransform * vec4(aTaskRect.xy + aTaskRect.zw * aPosition.xy, 0.0, 1.0); } #endif #ifdef WR_FRAGMENT_SHADER #define MAGIC_WAVY_LINE_AA_SNAP 0.5 void main(void) { // Find the appropriate distance to apply the step over. - vec2 pos = vLocalPos; - float aa_range = compute_aa_range(pos); + vec2 local_pos = vLocalPos; + float aa_range = compute_aa_range(local_pos); float alpha = 1.0; + // Select the x/y coord, depending on which axis this edge is. + vec2 pos = mix(local_pos.xy, local_pos.yx, vAxisSelect); + switch (vStyle) { case LINE_STYLE_SOLID: { break; } case LINE_STYLE_DASHED: { // Calculate dash alpha (on/off) based on dash length alpha = step(floor(pos.x + 0.5), vParams.y); break;
--- a/gfx/wr/webrender/src/prim_store/mod.rs +++ b/gfx/wr/webrender/src/prim_store/mod.rs @@ -4124,82 +4124,59 @@ pub fn get_raster_rects( // Ensure that we won't try to allocate a zero-sized clip render task. if clipped.is_empty() { return None; } Some((clipped.to_i32(), unclipped)) } -/// Choose the decoration mask tile size for a given line. -/// -/// Given a line with overall size `rect_size` and the given `orientation`, -/// return the dimensions of a single mask tile for the decoration pattern -/// described by `style` and `wavy_line_thickness`. -/// -/// If `style` is `Solid`, no mask tile is necessary; return `None`. The other -/// styles each have their own characteristic periods of repetition, so for each -/// one, this function returns a `LayoutSize` with the right aspect ratio and -/// whose specific size is convenient for the `cs_line_decoration.glsl` fragment -/// shader to work with. The shader uses a local coordinate space in which the -/// tile fills a rectangle with one corner at the origin, and with the size this -/// function returns. -/// -/// The returned size is not necessarily in pixels; device scaling and other -/// concerns can still affect the actual task size. -/// -/// Regardless of whether `orientation` is `Vertical` or `Horizontal`, the -/// `width` and `height` of the returned size are always horizontal and -/// vertical, respectively. -pub fn get_line_decoration_size( +/// Get the inline (horizontal) and block (vertical) sizes +/// for a given line decoration. +pub fn get_line_decoration_sizes( rect_size: &LayoutSize, orientation: LineOrientation, style: LineStyle, wavy_line_thickness: f32, -) -> Option<LayoutSize> { +) -> Option<(f32, f32)> { let h = match orientation { LineOrientation::Horizontal => rect_size.height, LineOrientation::Vertical => rect_size.width, }; // TODO(gw): The formulae below are based on the existing gecko and line // shader code. They give reasonable results for most inputs, // but could definitely do with a detailed pass to get better // quality on a wider range of inputs! // See nsCSSRendering::PaintDecorationLine in Gecko. - let (parallel, perpendicular) = match style { + match style { LineStyle::Solid => { - return None; + None } LineStyle::Dashed => { let dash_length = (3.0 * h).min(64.0).max(1.0); - (2.0 * dash_length, 4.0) + Some((2.0 * dash_length, 4.0)) } LineStyle::Dotted => { let diameter = h.min(64.0).max(1.0); let period = 2.0 * diameter; - (period, diameter) + Some((period, diameter)) } LineStyle::Wavy => { let line_thickness = wavy_line_thickness.max(1.0); let slope_length = h - line_thickness; let flat_length = ((line_thickness - 1.0) * 2.0).max(1.0); let approx_period = 2.0 * (slope_length + flat_length); - (approx_period, h) + Some((approx_period, h)) } - }; - - Some(match orientation { - LineOrientation::Horizontal => LayoutSize::new(parallel, perpendicular), - LineOrientation::Vertical => LayoutSize::new(perpendicular, parallel), - }) + } } fn update_opacity_binding( opacity_bindings: &mut OpacityBindingStorage, opacity_binding_index: OpacityBindingIndex, scene_properties: &SceneProperties, ) -> f32 { if opacity_binding_index == OpacityBindingIndex::INVALID {
--- a/gfx/wr/webrender/src/render_target.rs +++ b/gfx/wr/webrender/src/render_target.rs @@ -768,20 +768,17 @@ impl TextureCacheRenderTarget { match task.kind { RenderTaskKind::LineDecoration(ref info) => { self.clears.push(target_rect.0); self.line_decorations.push(LineDecorationJob { task_rect: target_rect.0.to_f32(), local_size: info.local_size, style: info.style as i32, - axis_select: match info.orientation { - LineOrientation::Horizontal => 0.0, - LineOrientation::Vertical => 1.0, - }, + orientation: info.orientation as i32, wavy_line_thickness: info.wavy_line_thickness, }); } RenderTaskKind::HorizontalBlur(..) => { add_blur_instances( &mut self.horizontal_blurs, BlurDirection::Horizontal, task_address, @@ -1054,17 +1051,17 @@ pub struct BlitJob { #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] #[derive(Debug)] pub struct LineDecorationJob { pub task_rect: DeviceRect, pub local_size: LayoutSize, pub wavy_line_thickness: f32, pub style: i32, - pub axis_select: f32, + pub orientation: i32, } #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] #[repr(C)] pub struct GradientJob { pub task_rect: DeviceRect, pub stops: [f32; GRADIENT_FP_STOPS],
--- a/gfx/wr/webrender/src/renderer.rs +++ b/gfx/wr/webrender/src/renderer.rs @@ -449,19 +449,19 @@ pub(crate) mod desc { kind: VertexAttributeKind::F32, }, VertexAttribute { name: "aStyle", count: 1, kind: VertexAttributeKind::I32, }, VertexAttribute { - name: "aAxisSelect", + name: "aOrientation", count: 1, - kind: VertexAttributeKind::F32, + kind: VertexAttributeKind::I32, }, ], }; pub const GRADIENT: VertexDescriptor = VertexDescriptor { vertex_attributes: &[ VertexAttribute { name: "aPosition",
--- a/gfx/wr/webrender/src/scene_building.rs +++ b/gfx/wr/webrender/src/scene_building.rs @@ -22,17 +22,17 @@ use crate::image::simplify_repeated_prim use crate::intern::Interner; use crate::internal_types::{FastHashMap, FastHashSet, LayoutPrimitiveInfo, Filter}; use crate::picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureOptions}; use crate::picture::{BlitReason, OrderedPictureChild, PrimitiveList, TileCacheInstance, ClusterFlags}; use crate::prim_store::{PrimitiveInstance, PrimitiveSceneData}; use crate::prim_store::{PrimitiveInstanceKind, NinePatchDescriptor, PrimitiveStore}; use crate::prim_store::{ScrollNodeAndClipChain, PictureIndex}; use crate::prim_store::{InternablePrimitive, SegmentInstanceIndex}; -use crate::prim_store::{register_prim_chase_id, get_line_decoration_size}; +use crate::prim_store::{register_prim_chase_id, get_line_decoration_sizes}; use crate::prim_store::{SpaceSnapper}; use crate::prim_store::backdrop::Backdrop; use crate::prim_store::borders::{ImageBorder, NormalBorderPrim}; use crate::prim_store::gradient::{GradientStopKey, LinearGradient, RadialGradient, RadialGradientParams}; use crate::prim_store::image::{Image, YuvImage}; use crate::prim_store::line_dec::{LineDecoration, LineDecorationCacheKey}; use crate::prim_store::picture::{Picture, PictureCompositeKey, PictureKey}; use crate::prim_store::text_run::TextRun; @@ -2744,38 +2744,43 @@ impl<'a> SceneBuilder<'a> { color: ColorF, style: LineStyle, ) { // For line decorations, we can construct the render task cache key // here during scene building, since it doesn't depend on device // pixel ratio or transform. let mut info = info.clone(); - let size = get_line_decoration_size( + let size = get_line_decoration_sizes( &info.rect.size, orientation, style, wavy_line_thickness, ); - let cache_key = size.map(|size| { + let cache_key = size.map(|(inline_size, block_size)| { + let size = match orientation { + LineOrientation::Horizontal => LayoutSize::new(inline_size, block_size), + LineOrientation::Vertical => LayoutSize::new(block_size, inline_size), + }; + // If dotted, adjust the clip rect to ensure we don't draw a final // partial dot. if style == LineStyle::Dotted { let clip_size = match orientation { LineOrientation::Horizontal => { LayoutSize::new( - size.width * (info.rect.size.width / size.width).floor(), + inline_size * (info.rect.size.width / inline_size).floor(), info.rect.size.height, ) } LineOrientation::Vertical => { LayoutSize::new( info.rect.size.width, - size.height * (info.rect.size.height / size.height).floor(), + inline_size * (info.rect.size.height / inline_size).floor(), ) } }; let clip_rect = LayoutRect::new( info.rect.origin, clip_size, ); info.clip_rect = clip_rect