| author | Nicolas Silva <nsilva@mozilla.com> |
| Thu, 23 Jan 2020 14:24:11 +0000 | |
| changeset 511474 | 6b61867f80b123f11aa3e9252f0ac005a12787c0 |
| parent 511473 | 8b8a272428800614fcbc975c1ed93b663950ba89 |
| child 511475 | 834d49acd3c02a7e5ae75d0a4d01a55e69c8fdba |
| push id | 37048 |
| push user | rmaries@mozilla.com |
| push date | Thu, 23 Jan 2020 21:42:24 +0000 |
| treeherder | mozilla-central@fb6b61e49217 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| reviewers | jrmuizel, kvark |
| bugs | 1606771 |
| milestone | 74.0a1 |
| 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/brush.glsl +++ b/gfx/wr/webrender/res/brush.glsl @@ -107,17 +107,19 @@ void multi_brush_vs( ); #define VECS_PER_SEGMENT 2 #define BRUSH_FLAG_PERSPECTIVE_INTERPOLATION 1 #define BRUSH_FLAG_SEGMENT_RELATIVE 2 #define BRUSH_FLAG_SEGMENT_REPEAT_X 4 #define BRUSH_FLAG_SEGMENT_REPEAT_Y 8 -#define BRUSH_FLAG_TEXEL_RECT 16 +#define BRUSH_FLAG_SEGMENT_REPEAT_X_ROUND 16 +#define BRUSH_FLAG_SEGMENT_REPEAT_Y_ROUND 32 +#define BRUSH_FLAG_TEXEL_RECT 64 #define INVALID_SEGMENT_INDEX 0xffff void main(void) { // Load the brush instance from vertex attributes. Instance instance = decode_instance_attributes(); int edge_flags = instance.flags & 0xff; int brush_flags = (instance.flags >> 8) & 0xff;
--- a/gfx/wr/webrender/res/brush_image.glsl +++ b/gfx/wr/webrender/res/brush_image.glsl @@ -98,30 +98,45 @@ void image_brush_vs( // If the extra data is a texel rect, modify the UVs. if ((brush_flags & BRUSH_FLAG_TEXEL_RECT) != 0) { vec2 uv_size = res.uv_rect.p1 - res.uv_rect.p0; uv0 = res.uv_rect.p0 + segment_data.xy * uv_size; uv1 = res.uv_rect.p0 + segment_data.zw * uv_size; + #ifdef WR_FEATURE_REPETITION if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X) != 0) { stretch_size.x = local_rect.size.y / dy * dx; } if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y) != 0) { stretch_size.y = local_rect.size.x / dx * dy; } + #endif } else { + #ifdef WR_FEATURE_REPETITION if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X) != 0) { stretch_size.x = dx; } if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y) != 0) { stretch_size.y = dy; } + #endif } + + #ifdef WR_FEATURE_REPETITION + if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X_ROUND) != 0) { + float nx = max(1.0, round(segment_rect.size.x / stretch_size.x)); + stretch_size.x = segment_rect.size.x / nx; + } + if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y_ROUND) != 0) { + float ny = max(1.0, round(segment_rect.size.y / stretch_size.y)); + stretch_size.y = segment_rect.size.y / ny; + } + #endif } float perspective_interpolate = (brush_flags & BRUSH_FLAG_PERSPECTIVE_INTERPOLATION) != 0 ? 1.0 : 0.0; V_LAYER = res.layer; V_PERSPECTIVE = perspective_interpolate; // Handle case where the UV coords are inverted (e.g. from an // external image).
--- a/gfx/wr/webrender/src/border.rs +++ b/gfx/wr/webrender/src/border.rs @@ -1346,48 +1346,53 @@ impl NinePatchDescriptor { fn add_segment( segments: &mut Vec<BrushSegment>, rect: LayoutRect, uv_rect: TexelRect, repeat_horizontal: RepeatMode, repeat_vertical: RepeatMode ) { - if uv_rect.uv1.x > uv_rect.uv0.x && - uv_rect.uv1.y > uv_rect.uv0.y { + if uv_rect.uv1.x < uv_rect.uv0.x || uv_rect.uv1.y < uv_rect.uv0.y { + return; + } - // Use segment relative interpolation for all - // instances in this primitive. - let mut brush_flags = - BrushFlags::SEGMENT_RELATIVE | - BrushFlags::SEGMENT_TEXEL_RECT; + // Use segment relative interpolation for all + // instances in this primitive. + let mut brush_flags = + BrushFlags::SEGMENT_RELATIVE | + BrushFlags::SEGMENT_TEXEL_RECT; + + // Enable repeat modes on the segment. + if repeat_horizontal == RepeatMode::Repeat { + brush_flags |= BrushFlags::SEGMENT_REPEAT_X; + } else if repeat_horizontal == RepeatMode::Round { + brush_flags |= BrushFlags::SEGMENT_REPEAT_X | BrushFlags::SEGMENT_REPEAT_X_ROUND; + } - // Enable repeat modes on the segment. - if repeat_horizontal == RepeatMode::Repeat { - brush_flags |= BrushFlags::SEGMENT_REPEAT_X; - } - if repeat_vertical == RepeatMode::Repeat { - brush_flags |= BrushFlags::SEGMENT_REPEAT_Y; - } + if repeat_vertical == RepeatMode::Repeat { + brush_flags |= BrushFlags::SEGMENT_REPEAT_Y; + } else if repeat_vertical == RepeatMode::Round { + brush_flags |= BrushFlags::SEGMENT_REPEAT_Y | BrushFlags::SEGMENT_REPEAT_Y_ROUND; + } - let segment = BrushSegment::new( - rect, - true, - EdgeAaSegmentMask::empty(), - [ - uv_rect.uv0.x, - uv_rect.uv0.y, - uv_rect.uv1.x, - uv_rect.uv1.y, - ], - brush_flags, - ); + let segment = BrushSegment::new( + rect, + true, + EdgeAaSegmentMask::empty(), + [ + uv_rect.uv0.x, + uv_rect.uv0.y, + uv_rect.uv1.x, + uv_rect.uv1.y, + ], + brush_flags, + ); - segments.push(segment); - } + segments.push(segment); } // Build the list of image segments let mut segments = Vec::new(); // Top left add_segment( &mut segments,
--- a/gfx/wr/webrender/src/gpu_types.rs +++ b/gfx/wr/webrender/src/gpu_types.rs @@ -398,26 +398,30 @@ impl From<SplitCompositeInstance> for Pr bitflags! { /// Flags that define how the common brush shader /// code should process this instance. #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] #[derive(MallocSizeOf)] pub struct BrushFlags: u8 { /// Apply perspective interpolation to UVs - const PERSPECTIVE_INTERPOLATION = 0x1; + const PERSPECTIVE_INTERPOLATION = 1; /// Do interpolation relative to segment rect, /// rather than primitive rect. - const SEGMENT_RELATIVE = 0x2; + const SEGMENT_RELATIVE = 2; /// Repeat UVs horizontally. - const SEGMENT_REPEAT_X = 0x4; + const SEGMENT_REPEAT_X = 4; /// Repeat UVs vertically. - const SEGMENT_REPEAT_Y = 0x8; + const SEGMENT_REPEAT_Y = 8; + /// Horizontally follow border-image-repeat: round + const SEGMENT_REPEAT_X_ROUND = 16; + /// Vorizontally follow border-image-repeat: round + const SEGMENT_REPEAT_Y_ROUND = 32; /// The extra segment data is a texel rect. - const SEGMENT_TEXEL_RECT = 0x10; + const SEGMENT_TEXEL_RECT = 64; } } /// Convenience structure to encode into PrimitiveInstanceData. pub struct BrushInstance { pub prim_header_index: PrimitiveHeaderIndex, pub render_task_address: RenderTaskAddress, pub clip_task_address: RenderTaskAddress,
--- a/layout/painting/nsCSSRendering.cpp +++ b/layout/painting/nsCSSRendering.cpp @@ -710,19 +710,17 @@ ImgDrawResult nsCSSRendering::CreateWebR } // Next we try image and gradient borders. Gradients are not supported at // this very moment. if (type != eStyleImageType_Image) { return ImgDrawResult::NOT_SUPPORTED; } - if (aStyleBorder.mBorderImageRepeatH == StyleBorderImageRepeat::Round || - aStyleBorder.mBorderImageRepeatH == StyleBorderImageRepeat::Space || - aStyleBorder.mBorderImageRepeatV == StyleBorderImageRepeat::Round || + if (aStyleBorder.mBorderImageRepeatH == StyleBorderImageRepeat::Space || aStyleBorder.mBorderImageRepeatV == StyleBorderImageRepeat::Space) { return ImgDrawResult::NOT_SUPPORTED; } uint32_t flags = 0; if (aDisplayListBuilder->IsPaintingToWindow()) { flags |= nsImageRenderer::FLAG_PAINTING_TO_WINDOW; }