Bug 1486405. Update webrender to commit 5fa5c46e167ca834d8fec3bf662bf420418698f4

--HG--
extra : rebase_source : cbd95125423ea2eb4c81dc34012ecd741866bd29
This commit is contained in:
Jeff Muizelaar 2018-08-30 11:00:17 -04:00
Родитель 42e72ffaa9
Коммит 819c34f560
12 изменённых файлов: 207 добавлений и 117 удалений

Просмотреть файл

@ -32,7 +32,10 @@ void brush_vs(
vec2 uv = snap_device_pos(vi) +
src_task.common_data.task_rect.p0 -
src_task.content_origin;
vUv = vec3(uv / texture_size, src_task.common_data.texture_layer_index);
vUv = vec3(
uv * gl_Position.w / texture_size, // multiply by W to compensate for perspective interpolation
src_task.common_data.texture_layer_index
);
vec2 uv0 = src_task.common_data.task_rect.p0;
vec2 uv1 = uv0 + src_task.common_data.task_rect.size;
@ -124,7 +127,8 @@ vec3 Brightness(vec3 Cs, float amount) {
}
Fragment brush_fs() {
vec4 Cs = texture(sColor0, vUv);
vec2 base_uv = vUv.xy * gl_FragCoord.w;
vec4 Cs = texture(sColor0, vec3(base_uv, vUv.z));
if (Cs.a == 0.0) {
return Fragment(vec4(0.0)); // could also `discard`
@ -155,7 +159,7 @@ Fragment brush_fs() {
// Fail-safe to ensure that we don't sample outside the rendered
// portion of a blend source.
alpha *= point_inside_rect(vUv.xy, vUvClipBounds.xy, vUvClipBounds.zw);
alpha *= point_inside_rect(base_uv, vUvClipBounds.xy, vUvClipBounds.zw);
// Pre-multiply the alpha into the output value.
return Fragment(alpha * vec4(color, 1.0));

Просмотреть файл

@ -829,6 +829,7 @@ impl AlphaBatchBuilder {
);
let filter_mode = match filter {
FilterOp::Identity => 1, // matches `Contrast(1)`
FilterOp::Blur(..) => 0,
FilterOp::Contrast(..) => 1,
FilterOp::Grayscale(..) => 2,
@ -843,6 +844,7 @@ impl AlphaBatchBuilder {
};
let user_data = match filter {
FilterOp::Identity => 0x10000i32, // matches `Contrast(1)`
FilterOp::Contrast(amount) |
FilterOp::Grayscale(amount) |
FilterOp::Invert(amount) |

Просмотреть файл

@ -324,6 +324,7 @@ pub struct ClipChainInstance {
pub clips_range: ClipNodeRange,
pub local_clip_rect: LayoutRect,
pub has_non_root_coord_system: bool,
pub has_non_local_clips: bool,
pub world_clip_rect: WorldRect,
}
@ -531,6 +532,7 @@ impl ClipStore {
let first_clip_node_index = self.clip_node_indices.len() as u32;
let mut has_non_root_coord_system = false;
let mut has_non_local_clips = false;
// For each potential clip node
for node_info in self.clip_node_info.drain(..) {
@ -542,9 +544,11 @@ impl ClipStore {
node.item.get_clip_result(&local_bounding_rect)
}
ClipSpaceConversion::Offset(offset) => {
has_non_local_clips = true;
node.item.get_clip_result(&local_bounding_rect.translate(&-offset))
}
ClipSpaceConversion::Transform(ref transform) => {
has_non_local_clips = true;
node.item.get_clip_result_complex(
transform,
&world_bounding_rect,
@ -603,6 +607,7 @@ impl ClipStore {
Some(ClipChainInstance {
clips_range,
has_non_root_coord_system,
has_non_local_clips,
local_clip_rect,
world_clip_rect,
})

Просмотреть файл

@ -2211,7 +2211,8 @@ impl Primitive {
match segment_clip_chain {
Some(segment_clip_chain) => {
if segment_clip_chain.clips_range.count == 0 {
if segment_clip_chain.clips_range.count == 0 ||
(!segment.may_need_clip_mask && !segment_clip_chain.has_non_local_clips) {
segment.clip_task_id = BrushSegmentTaskId::Opaque;
continue;
}

Просмотреть файл

@ -201,6 +201,7 @@ pub trait FilterOpHelpers {
impl FilterOpHelpers for FilterOp {
fn is_visible(&self) -> bool {
match *self {
FilterOp::Identity |
FilterOp::Blur(..) |
FilterOp::Brightness(..) |
FilterOp::Contrast(..) |
@ -219,6 +220,7 @@ impl FilterOpHelpers for FilterOp {
fn is_noop(&self) -> bool {
match *self {
FilterOp::Identity => false, // this is intentional
FilterOp::Blur(length) => length == 0.0,
FilterOp::Brightness(amount) => amount == 1.0,
FilterOp::Contrast(amount) => amount == 1.0,

Просмотреть файл

@ -543,6 +543,9 @@ pub enum MixBlendMode {
#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
pub enum FilterOp {
/// Filter that does no transformation of the colors, needed for
/// debug purposes only.
Identity,
Blur(f32),
Brightness(f32),
Contrast(f32),

Просмотреть файл

@ -16,7 +16,7 @@ use time::precise_time_ns;
use {AlphaType, BorderDetails, BorderDisplayItem, BorderRadius, BorderWidths, BoxShadowClipMode};
use {BoxShadowDisplayItem, ClipAndScrollInfo, ClipChainId, ClipChainItem, ClipDisplayItem, ClipId};
use {ColorF, ComplexClipRegion, DisplayItem, ExtendMode, ExternalScrollId, FilterOp};
use {FontInstanceKey, GlyphInstance, GlyphOptions, GlyphRasterSpace, Gradient};
use {FontInstanceKey, GlyphInstance, GlyphOptions, GlyphRasterSpace, Gradient, GradientBuilder};
use {GradientDisplayItem, GradientStop, IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask};
use {ImageRendering, LayoutPoint, LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform};
use {LayoutVector2D, LineDisplayItem, LineOrientation, LineStyle, MixBlendMode, PipelineId};
@ -947,7 +947,12 @@ impl DisplayListBuilder {
index
}
fn push_item(&mut self, item: SpecificDisplayItem, info: &LayoutPrimitiveInfo) {
/// Add an item to the display list.
///
/// NOTE: It is usually preferable to use the specialized methods to push
/// display items. Pushing unexpected or invalid items here may
/// result in WebRender panicking or behaving in unexpected ways.
pub fn push_item(&mut self, item: SpecificDisplayItem, info: &LayoutPrimitiveInfo) {
serialize_fast(
&mut self.data,
&DisplayItem {
@ -1018,7 +1023,11 @@ impl DisplayListBuilder {
debug_assert_eq!(len, count);
}
fn push_iter<I>(&mut self, iter: I)
/// Push items from an iterator to the display list.
///
/// NOTE: Pushing unexpected or invalid items to the display list
/// may result in panic and confusion.
pub fn push_iter<I>(&mut self, iter: I)
where
I: IntoIterator,
I::IntoIter: ExactSizeIterator + Clone,
@ -1112,129 +1121,34 @@ impl DisplayListBuilder {
}
}
// Gradients can be defined with stops outside the range of [0, 1]
// when this happens the gradient needs to be normalized by adjusting
// the gradient stops and gradient line into an equivalent gradient
// with stops in the range [0, 1]. this is done by moving the beginning
// of the gradient line to where stop[0] and the end of the gradient line
// to stop[n-1]. this function adjusts the stops in place, and returns
// the amount to adjust the gradient line start and stop
fn normalize_stops(stops: &mut Vec<GradientStop>, extend_mode: ExtendMode) -> (f32, f32) {
assert!(stops.len() >= 2);
let first = *stops.first().unwrap();
let last = *stops.last().unwrap();
assert!(first.offset <= last.offset);
let stops_delta = last.offset - first.offset;
if stops_delta > 0.000001 {
for stop in stops {
stop.offset = (stop.offset - first.offset) / stops_delta;
}
(first.offset, last.offset)
} else {
// We have a degenerate gradient and can't accurately transform the stops
// what happens here depends on the repeat behavior, but in any case
// we reconstruct the gradient stops to something simpler and equivalent
stops.clear();
match extend_mode {
ExtendMode::Clamp => {
// This gradient is two colors split at the offset of the stops,
// so create a gradient with two colors split at 0.5 and adjust
// the gradient line so 0.5 is at the offset of the stops
stops.push(GradientStop { color: first.color, offset: 0.0, });
stops.push(GradientStop { color: first.color, offset: 0.5, });
stops.push(GradientStop { color: last.color, offset: 0.5, });
stops.push(GradientStop { color: last.color, offset: 1.0, });
let offset = last.offset;
(offset - 0.5, offset + 0.5)
}
ExtendMode::Repeat => {
// A repeating gradient with stops that are all in the same
// position should just display the last color. I believe the
// spec says that it should be the average color of the gradient,
// but this matches what Gecko and Blink does
stops.push(GradientStop { color: last.color, offset: 0.0, });
stops.push(GradientStop { color: last.color, offset: 1.0, });
(0.0, 1.0)
}
}
}
}
// NOTE: gradients must be pushed in the order they're created
// because create_gradient stores the stops in anticipation
/// NOTE: gradients must be pushed in the order they're created
/// because create_gradient stores the stops in anticipation.
pub fn create_gradient(
&mut self,
start_point: LayoutPoint,
end_point: LayoutPoint,
mut stops: Vec<GradientStop>,
stops: Vec<GradientStop>,
extend_mode: ExtendMode,
) -> Gradient {
let (start_offset, end_offset) =
DisplayListBuilder::normalize_stops(&mut stops, extend_mode);
let start_to_end = end_point - start_point;
self.push_stops(&stops);
Gradient {
start_point: start_point + start_to_end * start_offset,
end_point: start_point + start_to_end * end_offset,
extend_mode,
}
let mut builder = GradientBuilder::with_stops(stops);
let gradient = builder.gradient(start_point, end_point, extend_mode);
self.push_stops(builder.stops());
gradient
}
// NOTE: gradients must be pushed in the order they're created
// because create_gradient stores the stops in anticipation
/// NOTE: gradients must be pushed in the order they're created
/// because create_gradient stores the stops in anticipation.
pub fn create_radial_gradient(
&mut self,
center: LayoutPoint,
radius: LayoutSize,
mut stops: Vec<GradientStop>,
stops: Vec<GradientStop>,
extend_mode: ExtendMode,
) -> RadialGradient {
if radius.width <= 0.0 || radius.height <= 0.0 {
// The shader cannot handle a non positive radius. So
// reuse the stops vector and construct an equivalent
// gradient.
let last_color = stops.last().unwrap().color;
let stops = [
GradientStop { offset: 0.0, color: last_color, },
GradientStop { offset: 1.0, color: last_color, },
];
self.push_stops(&stops);
return RadialGradient {
center,
radius: LayoutSize::new(1.0, 1.0),
start_offset: 0.0,
end_offset: 1.0,
extend_mode,
};
}
let (start_offset, end_offset) =
DisplayListBuilder::normalize_stops(&mut stops, extend_mode);
self.push_stops(&stops);
RadialGradient {
center,
radius,
start_offset,
end_offset,
extend_mode,
}
let mut builder = GradientBuilder::with_stops(stops);
let gradient = builder.radial_gradient(center, radius, extend_mode);
self.push_stops(builder.stops());
gradient
}
pub fn push_border(

Просмотреть файл

@ -0,0 +1,153 @@
/* 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/. */
use {ExtendMode, Gradient, GradientStop, LayoutPoint, LayoutSize, RadialGradient};
/// Construct a gradient to be used in display lists.
///
/// Each gradient needs at least two stops.
pub struct GradientBuilder {
stops: Vec<GradientStop>,
}
impl GradientBuilder {
/// Create a new gradient builder.
pub fn new() -> GradientBuilder {
GradientBuilder {
stops: Vec::new(),
}
}
/// Create a gradient builder with a list of stops.
pub fn with_stops(stops: Vec<GradientStop>) -> GradientBuilder {
GradientBuilder { stops }
}
/// Push an additional stop for the gradient.
pub fn push(&mut self, stop: GradientStop) {
self.stops.push(stop);
}
/// Get a reference to the list of stops.
pub fn stops(&self) -> &[GradientStop] {
self.stops.as_ref()
}
/// Produce a linear gradient, normalize the stops.
pub fn gradient(
&mut self,
start_point: LayoutPoint,
end_point: LayoutPoint,
extend_mode: ExtendMode,
) -> Gradient {
let (start_offset, end_offset) = self.normalize(extend_mode);
let start_to_end = end_point - start_point;
Gradient {
start_point: start_point + start_to_end * start_offset,
end_point: start_point + start_to_end * end_offset,
extend_mode,
}
}
/// Produce a radial gradient, normalize the stops.
///
/// Will replace the gradient with a single color
/// if the radius negative.
pub fn radial_gradient(
&mut self,
center: LayoutPoint,
radius: LayoutSize,
extend_mode: ExtendMode,
) -> RadialGradient {
if radius.width <= 0.0 || radius.height <= 0.0 {
// The shader cannot handle a non positive radius. So
// reuse the stops vector and construct an equivalent
// gradient.
let last_color = self.stops.last().unwrap().color;
self.stops.clear();
self.stops.push(GradientStop { offset: 0.0, color: last_color, });
self.stops.push(GradientStop { offset: 1.0, color: last_color, });
return RadialGradient {
center,
radius: LayoutSize::new(1.0, 1.0),
start_offset: 0.0,
end_offset: 1.0,
extend_mode,
};
}
let (start_offset, end_offset) =
self.normalize(extend_mode);
RadialGradient {
center,
radius,
start_offset,
end_offset,
extend_mode,
}
}
/// Gradients can be defined with stops outside the range of [0, 1]
/// when this happens the gradient needs to be normalized by adjusting
/// the gradient stops and gradient line into an equivalent gradient
/// with stops in the range [0, 1]. this is done by moving the beginning
/// of the gradient line to where stop[0] and the end of the gradient line
/// to stop[n-1]. this function adjusts the stops in place, and returns
/// the amount to adjust the gradient line start and stop.
fn normalize(&mut self, extend_mode: ExtendMode) -> (f32, f32) {
let stops = &mut self.stops;
assert!(stops.len() >= 2);
let first = *stops.first().unwrap();
let last = *stops.last().unwrap();
assert!(first.offset <= last.offset);
let stops_delta = last.offset - first.offset;
if stops_delta > 0.000001 {
for stop in stops {
stop.offset = (stop.offset - first.offset) / stops_delta;
}
(first.offset, last.offset)
} else {
// We have a degenerate gradient and can't accurately transform the stops
// what happens here depends on the repeat behavior, but in any case
// we reconstruct the gradient stops to something simpler and equivalent
stops.clear();
match extend_mode {
ExtendMode::Clamp => {
// This gradient is two colors split at the offset of the stops,
// so create a gradient with two colors split at 0.5 and adjust
// the gradient line so 0.5 is at the offset of the stops
stops.push(GradientStop { color: first.color, offset: 0.0, });
stops.push(GradientStop { color: first.color, offset: 0.5, });
stops.push(GradientStop { color: last.color, offset: 0.5, });
stops.push(GradientStop { color: last.color, offset: 1.0, });
let offset = last.offset;
(offset - 0.5, offset + 0.5)
}
ExtendMode::Repeat => {
// A repeating gradient with stops that are all in the same
// position should just display the last color. I believe the
// spec says that it should be the average color of the gradient,
// but this matches what Gecko and Blink does
stops.push(GradientStop { color: last.color, offset: 0.0, });
stops.push(GradientStop { color: last.color, offset: 1.0, });
(0.0, 1.0)
}
}
}
}
}

Просмотреть файл

@ -33,6 +33,7 @@ mod color;
mod display_item;
mod display_list;
mod font;
mod gradient_builder;
mod image;
mod units;
@ -41,5 +42,6 @@ pub use color::*;
pub use display_item::*;
pub use display_list::*;
pub use font::*;
pub use gradient_builder::*;
pub use image::*;
pub use units::*;

Просмотреть файл

@ -1 +1 @@
816ff14c1805c145ccd60d0227d82b1541fc24eb
5fa5c46e167ca834d8fec3bf662bf420418698f4

Просмотреть файл

@ -228,6 +228,7 @@ fn write_stacking_context(
let mut filters = vec![];
for filter in filter_iter {
match filter {
FilterOp::Identity => { filters.push(Yaml::String("identity".into())) }
FilterOp::Blur(x) => { filters.push(Yaml::String(format!("blur({})", x))) }
FilterOp::Brightness(x) => { filters.push(Yaml::String(format!("brightness({})", x))) }
FilterOp::Contrast(x) => { filters.push(Yaml::String(format!("contrast({})", x))) }

Просмотреть файл

@ -544,6 +544,9 @@ impl YamlHelper for Yaml {
fn as_filter_op(&self) -> Option<FilterOp> {
if let Some(s) = self.as_str() {
match parse_function(s) {
("identity", _, _) => {
Some(FilterOp::Identity)
}
("blur", ref args, _) if args.len() == 1 => {
Some(FilterOp::Blur(args[0].parse().unwrap()))
}