Backed out 3 changesets (bug 1749380) for causing webrender crashes a=backout DONTBUILD

Backed out changeset 1762adb371d4 (bug 1749380)
Backed out changeset 2b42abbdb0df (bug 1749380)
Backed out changeset 9fa6f71111d0 (bug 1749380)
This commit is contained in:
Norisz Fay 2022-02-21 11:35:49 +02:00
Родитель 0053146585
Коммит 44a6c895e2
55 изменённых файлов: 1672 добавлений и 1180 удалений

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

@ -20,7 +20,7 @@ fails-if(useDrawSnapshot) == 1501195.html 1501195-ref.html
== 1519754.html 1519754-ref.html
skip-if(!asyncPan) == 1524261.html 1524261-ref.html
fuzzy-if(!useDrawSnapshot,14-14,44-95) == 1524353.html 1524353-ref.html
== 1523776.html 1523776-ref.html
fuzzy-if(!useDrawSnapshot,2-7,17500-36908) == 1523776.html 1523776-ref.html
== bug1523410-translate-scale-snap.html bug1523410-translate-scale-snap-ref.html
== 1523080.html 1523080-ref.html
== 1616444-same-color-different-paths.html 1616444-same-color-different-paths-ref.html
@ -28,7 +28,7 @@ skip-if(!asyncPan||Android) fuzzy-if(winWidget,54-94,2713-3419) fuzzy-if(cocoaWi
pref(apz.allow_zooming,true) fails-if(useDrawSnapshot) == 1662062-1-no-blurry.html 1662062-1-ref.html
# Bug 1715676: nsBulletFrame has been removed and the new rendering does not use PushRoundedRect that this test is for:
# == 1681610.html 1681610-ref.html
skip-if(geckoview) fuzzy-if(!useDrawSnapshot,0-255,0-1050) fuzzy-if(useDrawSnapshot,0-255,0-3601) == 1687157-1.html 1687157-1-ref.html
skip-if(geckoview) fuzzy-if(!useDrawSnapshot,0-255,0-897) fuzzy-if(useDrawSnapshot,0-255,0-3601) == 1687157-1.html 1687157-1-ref.html
fuzzy(64-99,512-523) == 1696439-1.html 1696439-1-ref.html
random-if(gtkWidget) == 1722689-1.html 1722689-1-ref.html
fuzzy-if(useDrawSnapshot,255-255,5-5) == 1724901-1.html 1724901-1-ref.html

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

@ -953,14 +953,8 @@ impl BatchBuilder {
render_tasks,
).unwrap();
let prim_rect = ctx.data_stores.get_local_prim_rect(
child_prim_instance,
&ctx.prim_store.pictures,
ctx.surfaces,
);
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_rect: pic.precise_local_rect,
local_clip_rect: child_prim_info.combined_local_clip_rect,
specific_prim_address: GpuCacheAddress::INVALID,
transform_id: transforms
@ -971,6 +965,11 @@ impl BatchBuilder {
),
};
let raster_config = pic
.raster_config
.as_ref()
.expect("BUG: 3d primitive was not assigned a surface");
let child_pic_task_id = pic
.primary_render_task_id
.unwrap();
@ -990,7 +989,7 @@ impl BatchBuilder {
let prim_header_index = prim_headers.push(&prim_header, z_id, [
uv_rect_address.as_int(),
BrushFlags::PERSPECTIVE_INTERPOLATION.bits() as i32,
if raster_config.establishes_raster_root { 1 } else { 0 },
0,
child_clip_task_address.0 as i32,
]);
@ -1073,8 +1072,7 @@ impl BatchBuilder {
let prim_rect = ctx.data_stores.get_local_prim_rect(
prim_instance,
&ctx.prim_store.pictures,
ctx.surfaces,
ctx.prim_store,
);
let mut batch_features = BatchFeatures::empty();
@ -1542,7 +1540,7 @@ impl BatchBuilder {
let prim_cache_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_rect: picture.precise_local_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
specific_prim_address: prim_cache_address,
transform_id,
@ -1564,12 +1562,16 @@ impl BatchBuilder {
Some(ref raster_config) => {
// If the child picture was rendered in local space, we can safely
// interpolate the UV coordinates with perspective correction.
let brush_flags = BrushFlags::PERSPECTIVE_INTERPOLATION;
let brush_flags = if raster_config.establishes_raster_root {
BrushFlags::PERSPECTIVE_INTERPOLATION
} else {
BrushFlags::empty()
};
let surface = &ctx.surfaces[raster_config.surface_index.0];
let mut is_opaque = prim_info.clip_task_index == ClipTaskIndex::INVALID
&& surface.is_opaque
&& surface.opaque_rect.contains_box(&surface.rect)
&& transform_kind == TransformedRectKind::AxisAligned;
let pic_task_id = picture.primary_render_task_id.unwrap();
@ -1584,7 +1586,7 @@ impl BatchBuilder {
PictureCompositeMode::Filter(ref filter) => {
assert!(filter.is_visible());
match filter {
Filter::Blur { .. } => {
Filter::Blur(..) => {
let (clip_task_address, clip_mask_texture_id) = ctx.get_prim_clip_task_and_texture(
prim_info.clip_task_index,
render_tasks,
@ -1823,7 +1825,7 @@ impl BatchBuilder {
// These filters are handled via different paths.
Filter::ComponentTransfer |
Filter::Blur { .. } |
Filter::Blur(..) |
Filter::DropShadows(..) |
Filter::Opacity(..) => unreachable!(),
};
@ -2110,7 +2112,7 @@ impl BatchBuilder {
};
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_rect: picture.precise_local_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
specific_prim_address: prim_cache_address,
transform_id,
@ -3041,8 +3043,9 @@ impl BatchBuilder {
);
let prim_cache_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
let backdrop_picture = &ctx.prim_store.pictures[backdrop_pic_index.0];
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_rect: backdrop_picture.precise_local_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
transform_id,
specific_prim_address: prim_cache_address,

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

@ -32,7 +32,7 @@ use crate::space::SpaceMapper;
use crate::segment::SegmentBuilder;
use std::{f32, mem};
use crate::util::{VecHelper, Preallocator};
use crate::visibility::{update_prim_visibility, FrameVisibilityState, FrameVisibilityContext};
use crate::visibility::{update_primitive_visibility, FrameVisibilityState, FrameVisibilityContext};
use plane_split::Splitter;
@ -125,7 +125,7 @@ impl FrameGlobalResources {
pub struct FrameScratchBuffer {
dirty_region_stack: Vec<DirtyRegion>,
surface_stack: Vec<(PictureIndex, SurfaceIndex)>,
surface_stack: Vec<SurfaceIndex>,
clip_chain_stack: ClipChainStack,
}
@ -204,13 +204,12 @@ impl<'a> FrameBuildingState<'a> {
&mut self,
surface_index: SurfaceIndex,
tasks: Vec<RenderTaskId>,
clipping_rect: PictureRect,
raster_rect: DeviceRect,
) {
let surface = &mut self.surfaces[surface_index.0];
assert!(surface.render_tasks.is_none());
surface.render_tasks = Some(SurfaceRenderTasks::Tiled(tasks));
// TODO(gw): Include the dirty rect here, to reduce child surface sizes
surface.clipping_rect = clipping_rect;
surface.raster_rect = Some(raster_rect);
}
/// Initialize render tasks for a simple surface, that contains only a
@ -220,12 +219,12 @@ impl<'a> FrameBuildingState<'a> {
surface_index: SurfaceIndex,
task_id: RenderTaskId,
parent_surface_index: SurfaceIndex,
clipping_rect: PictureRect,
raster_rect: DeviceRect,
) {
let surface = &mut self.surfaces[surface_index.0];
assert!(surface.render_tasks.is_none());
surface.render_tasks = Some(SurfaceRenderTasks::Simple(task_id));
surface.clipping_rect = clipping_rect;
surface.raster_rect = Some(raster_rect);
self.add_child_render_task(
parent_surface_index,
@ -242,12 +241,12 @@ impl<'a> FrameBuildingState<'a> {
root_task_id: RenderTaskId,
port_task_id: RenderTaskId,
parent_surface_index: SurfaceIndex,
clipping_rect: PictureRect,
raster_rect: DeviceRect,
) {
let surface = &mut self.surfaces[surface_index.0];
assert!(surface.render_tasks.is_none());
surface.render_tasks = Some(SurfaceRenderTasks::Chained { root_task_id, port_task_id });
surface.clipping_rect = clipping_rect;
surface.raster_rect = Some(raster_rect);
self.add_child_render_task(
parent_surface_index,
@ -288,6 +287,8 @@ pub struct PictureContext {
pub struct PictureState {
pub map_local_to_pic: SpaceMapper<LayoutPixel, PicturePixel>,
pub map_pic_to_world: SpaceMapper<PicturePixel, WorldPixel>,
pub map_pic_to_raster: SpaceMapper<PicturePixel, RasterPixel>,
pub map_raster_to_world: SpaceMapper<RasterPixel, WorldPixel>,
}
impl FrameBuilder {
@ -374,6 +375,7 @@ impl FrameBuilder {
global_device_pixel_scale,
spatial_tree,
global_screen_world_rect,
surfaces: &mut scene.surfaces,
debug_flags,
scene_properties,
config: scene.config,
@ -403,9 +405,8 @@ impl FrameBuilder {
// If we have a tile cache for this picture, see if any of the
// relative transforms have changed, which means we need to
// re-map the dependencies of any child primitives.
let surface = &scene.surfaces[surface_index.0];
let world_culling_rect = tile_cache.pre_update(
surface.local_rect,
layout_rect_as_picture_rect(&pic.estimated_local_rect),
surface_index,
&visibility_context,
&mut visibility_state,
@ -414,23 +415,21 @@ impl FrameBuilder {
// Push a new surface, supplying the list of clips that should be
// ignored, since they are handled by clipping when drawing this surface.
visibility_state.push_surface(
*pic_index,
surface_index,
&tile_cache.shared_clips,
frame_context.spatial_tree,
);
update_prim_visibility(
update_primitive_visibility(
&mut scene.prim_store,
*pic_index,
None,
&world_culling_rect,
&mut scene.prim_store,
&mut scene.prim_instances,
&mut scene.surfaces,
true,
&visibility_context,
&mut visibility_state,
tile_cache,
true,
&mut scene.prim_instances,
);
// Build the dirty region(s) for this tile cache.

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

@ -208,11 +208,7 @@ const OPACITY_EPSILON: f32 = 0.001;
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum Filter {
Identity,
Blur {
width: f32,
height: f32,
should_inflate: bool,
},
Blur(f32, f32),
Brightness(f32),
Contrast(f32),
Grayscale(f32),
@ -233,7 +229,7 @@ impl Filter {
pub fn is_visible(&self) -> bool {
match *self {
Filter::Identity |
Filter::Blur { .. } |
Filter::Blur(..) |
Filter::Brightness(..) |
Filter::Contrast(..) |
Filter::Grayscale(..) |
@ -258,7 +254,7 @@ impl Filter {
pub fn is_noop(&self) -> bool {
match *self {
Filter::Identity => false, // this is intentional
Filter::Blur { width, height, .. } => width == 0.0 && height == 0.0,
Filter::Blur(width, height) => width == 0.0 && height == 0.0,
Filter::Brightness(amount) => amount == 1.0,
Filter::Contrast(amount) => amount == 1.0,
Filter::Grayscale(amount) => amount == 0.0,
@ -310,7 +306,7 @@ impl Filter {
Filter::LinearToSrgb => 9,
Filter::Flood(..) => 10,
Filter::ComponentTransfer => 11,
Filter::Blur { .. } => 12,
Filter::Blur(..) => 12,
Filter::DropShadows(..) => 13,
Filter::Opacity(..) => 14,
}
@ -321,7 +317,7 @@ impl From<FilterOp> for Filter {
fn from(op: FilterOp) -> Self {
match op {
FilterOp::Identity => Filter::Identity,
FilterOp::Blur(width, height) => Filter::Blur { width, height, should_inflate: true },
FilterOp::Blur(w, h) => Filter::Blur(w, h),
FilterOp::Brightness(b) => Filter::Brightness(b),
FilterOp::Contrast(c) => Filter::Contrast(c),
FilterOp::Grayscale(g) => Filter::Grayscale(g),

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -106,19 +106,12 @@ impl PictureGraph {
let info = &mut self.pic_info[pic_index.0];
match pictures[pic_index.0].assign_surface(
info.surface_index = Some(pictures[pic_index.0].assign_surface(
frame_context,
parent_surface_index,
tile_caches,
parent_surface_index,
surfaces,
) {
Some(surface_index) => {
info.surface_index = Some(surface_index);
}
None => {
info.surface_index = Some(parent_surface_index.unwrap());
}
}
));
}
}
}

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

@ -31,7 +31,8 @@ use crate::render_task_cache::RenderTaskCacheKeyKind;
use crate::render_task_cache::{RenderTaskCacheKey, to_cache_size, RenderTaskParent};
use crate::render_task::{RenderTaskKind, RenderTask};
use crate::segment::SegmentBuilder;
use crate::util::{clamp_to_scale_factor, pack_as_float};
use crate::space::SpaceMapper;
use crate::util::{clamp_to_scale_factor, pack_as_float, raster_rect_to_device_pixels};
use crate::visibility::{compute_conservative_visible_rect, PrimitiveVisibility, VisibilityState};
@ -63,6 +64,8 @@ pub fn prepare_primitives(
frame_context.spatial_tree,
);
frame_state.surfaces[pic_context.surface_index.0].opaque_rect = PictureRect::zero();
for prim_instance_index in cluster.prim_range() {
// First check for coarse visibility (if this primitive was completely off-screen)
let prim_instance = &mut prim_instances[prim_instance_index];
@ -124,6 +127,14 @@ pub fn prepare_primitives(
prim_instances[prim_instance_index].clear_visibility();
}
}
if !cluster.opaque_rect.is_empty() {
let surface = &mut frame_state.surfaces[pic_context.surface_index.0];
if let Some(cluster_opaque_rect) = surface.map_local_to_surface.map_inner_bounds(&cluster.opaque_rect) {
surface.opaque_rect = crate::util::conservative_union_rect(&surface.opaque_rect, &cluster_opaque_rect);
}
}
}
}
@ -148,14 +159,9 @@ fn prepare_prim_for_render(
// For example, scrolling may affect the location of an item in
// local space, which may force us to render this item on a larger
// picture target, if being composited.
let mut is_passthrough = false;
if let PrimitiveInstanceKind::Picture { pic_index, .. } = prim_instances[prim_instance_index].kind {
let pic = &mut store.pictures[pic_index.0];
// TODO(gw): Plan to remove pictures with no composite mode, so that we don't need
// to special case for pass through pictures.
is_passthrough = pic.composite_mode.is_none();
match pic.take_context(
pic_index,
pic_context.surface_spatial_node_index,
@ -197,35 +203,32 @@ fn prepare_prim_for_render(
let prim_instance = &mut prim_instances[prim_instance_index];
if !is_passthrough {
let prim_rect = data_stores.get_local_prim_rect(
prim_instance,
&store.pictures,
frame_state.surfaces,
);
if !update_clip_task(
prim_instance,
&prim_rect.min,
cluster.spatial_node_index,
pic_context.raster_spatial_node_index,
pic_context,
pic_state,
frame_context,
frame_state,
store,
data_stores,
scratch,
) {
if prim_instance.is_chased() {
info!("\tconsidered invisible");
}
return false;
}
let prim_rect = data_stores.get_local_prim_rect(
prim_instance,
store,
);
if !update_clip_task(
prim_instance,
&prim_rect.min,
cluster.spatial_node_index,
pic_context.raster_spatial_node_index,
pic_context,
pic_state,
frame_context,
frame_state,
store,
data_stores,
scratch,
) {
if prim_instance.is_chased() {
info!("\tconsidered visible and ready with local pos {:?}", prim_rect.min);
info!("\tconsidered invisible");
}
return false;
}
if prim_instance.is_chased() {
info!("\tconsidered visible and ready with local pos {:?}", prim_rect.min);
}
#[cfg(debug_assertions)]
@ -265,6 +268,7 @@ fn prepare_interned_prim_for_render(
let prim_spatial_node_index = cluster.spatial_node_index;
let is_chased = prim_instance.is_chased();
let device_pixel_scale = frame_state.surfaces[pic_context.surface_index.0].device_pixel_scale;
let mut is_opaque = false;
match &mut prim_instance.kind {
PrimitiveInstanceKind::LineDecoration { data_handle, ref mut render_task, .. } => {
@ -285,27 +289,9 @@ fn prepare_interned_prim_for_render(
// If we have a cache key, it's a wavy / dashed / dotted line. Otherwise, it's
// a simple solid line.
if let Some(cache_key) = line_dec_data.cache_key.as_ref() {
// TODO(gw): These scale factors don't do a great job if the world transform
// contains perspective
let scale = frame_context
.spatial_tree
.get_world_transform(prim_spatial_node_index)
.scale_factors();
// Scale factors are normalized to a power of 2 to reduce the number of
// resolution changes.
// For frames with a changing scale transform round scale factors up to
// nearest power-of-2 boundary so that we don't keep having to redraw
// the content as it scales up and down. Rounding up to nearest
// power-of-2 boundary ensures we never scale up, only down --- avoiding
// jaggies. It also ensures we never scale down by more than a factor of
// 2, avoiding bad downscaling quality.
let scale_width = clamp_to_scale_factor(scale.0, false);
let scale_height = clamp_to_scale_factor(scale.1, false);
// Pick the maximum dimension as scale
let world_scale = LayoutToWorldScale::new(scale_width.max(scale_height));
let scale_factor = world_scale * Scale::new(1.0);
// TODO(gw): Do we ever need / want to support scales for text decorations
// based on the current transform?
let scale_factor = Scale::new(1.0) * device_pixel_scale;
let mut task_size = (LayoutSize::from_au(cache_key.size) * scale_factor).ceil().to_i32();
if task_size.width > MAX_LINE_DECORATION_RESOLUTION as i32 ||
task_size.height > MAX_LINE_DECORATION_RESOLUTION as i32 {
@ -362,7 +348,12 @@ fn prepare_interned_prim_for_render(
.into_fast_transform();
let prim_offset = prim_data.common.prim_rect.min.to_vector() - run.reference_frame_relative_offset;
let pic = &store.pictures[pic_context.pic_index.0];
let surface = &frame_state.surfaces[pic_context.surface_index.0];
let root_scaling_factor = match pic.raster_config {
Some(ref raster_config) => raster_config.root_scaling_factor,
None => 1.0
};
// If subpixel AA is disabled due to the backing surface the glyphs
// are being drawn onto, disable it (unless we are using the
@ -400,6 +391,7 @@ fn prepare_interned_prim_for_render(
&transform.to_transform().with_destination::<_>(),
surface,
prim_spatial_node_index,
root_scaling_factor,
allow_subpixel,
frame_context.fb_config.low_quality_pinch_zoom,
frame_state.resource_cache,
@ -552,6 +544,8 @@ fn prepare_interned_prim_for_render(
frame_context.scene_properties,
);
is_opaque = prim_data.common.opacity.is_opaque;
write_segment(
*segment_instance_index,
frame_state,
@ -570,6 +564,7 @@ fn prepare_interned_prim_for_render(
let prim_data = &mut data_stores.yuv_image[*data_handle];
let common_data = &mut prim_data.common;
let yuv_image_data = &mut prim_data.kind;
is_opaque = true;
common_data.may_need_repetition = false;
@ -607,6 +602,9 @@ fn prepare_interned_prim_for_render(
&mut prim_instance.vis,
);
// common_data.opacity.is_opaque is computed in the above update call.
is_opaque = common_data.opacity.is_opaque;
write_segment(
image_instance.segment_instance_index,
frame_state,
@ -779,15 +777,12 @@ fn prepare_interned_prim_for_render(
if let Picture3DContext::In { root_data: None, plane_splitter_index, .. } = pic.context_3d {
let dirty_rect = frame_state.current_dirty_region().combined;
let splitter = &mut frame_state.plane_splitters[plane_splitter_index.0];
let surface_index = pic.raster_config.as_ref().unwrap().surface_index;
let surface = &frame_state.surfaces[surface_index.0];
let local_prim_rect = surface.local_rect.cast_unit();
PicturePrimitive::add_split_plane(
splitter,
frame_context.spatial_tree,
prim_spatial_node_index,
local_prim_rect,
pic.precise_local_rect,
&prim_instance.vis.combined_local_clip_rect,
dirty_rect,
plane_split_anchor,
@ -847,6 +842,26 @@ fn prepare_interned_prim_for_render(
}
}
};
// If the primitive is opaque, see if it can contribut to it's picture surface's opaque rect.
is_opaque = is_opaque && {
let clip = prim_instance.vis.clip_task_index;
clip == ClipTaskIndex::INVALID
};
is_opaque = is_opaque && !frame_context.spatial_tree.is_relative_transform_complex(
prim_spatial_node_index,
pic_context.raster_spatial_node_index,
);
if is_opaque {
let prim_local_rect = data_stores.get_local_prim_rect(
prim_instance,
store,
);
cluster.opaque_rect = crate::util::conservative_union_rect(&cluster.opaque_rect, &prim_local_rect);
}
}
@ -947,6 +962,7 @@ fn update_clip_task_for_brush(
segments_store: &mut SegmentStorage,
segment_instances_store: &mut SegmentInstanceStorage,
clip_mask_instances: &mut Vec<ClipMaskKind>,
unclipped: &DeviceRect,
device_pixel_scale: DevicePixelScale,
) -> Option<ClipTaskIndex> {
let segments = match instance.kind {
@ -1062,11 +1078,14 @@ fn update_clip_task_for_brush(
let clip_mask_kind = update_brush_segment_clip_task(
&segments[0],
Some(&instance.vis.clip_chain),
frame_state.current_dirty_region().combined,
root_spatial_node_index,
pic_context.surface_index,
pic_state,
frame_context,
frame_state,
&mut data_stores.clip,
unclipped,
device_pixel_scale,
);
clip_mask_instances.push(clip_mask_kind);
@ -1103,11 +1122,14 @@ fn update_clip_task_for_brush(
let clip_mask_kind = update_brush_segment_clip_task(
&segment,
segment_clip_chain.as_ref(),
frame_state.current_dirty_region().combined,
root_spatial_node_index,
pic_context.surface_index,
pic_state,
frame_context,
frame_state,
&mut data_stores.clip,
unclipped,
device_pixel_scale,
);
clip_mask_instances.push(clip_mask_kind);
@ -1136,6 +1158,16 @@ pub fn update_clip_task(
info!("\tupdating clip task with pic rect {:?}", instance.vis.clip_chain.pic_coverage_rect);
}
// Get the device space rect for the primitive if it was unclipped.
let unclipped = match get_unclipped_device_rect(
instance.vis.clip_chain.pic_coverage_rect,
&pic_state.map_pic_to_raster,
device_pixel_scale,
) {
Some(rect) => rect,
None => return false,
};
build_segments_if_needed(
instance,
frame_state,
@ -1160,6 +1192,7 @@ pub fn update_clip_task(
&mut scratch.segments,
&mut scratch.segment_instances,
&mut scratch.clip_mask_instances,
&unclipped,
device_pixel_scale,
) {
if instance.is_chased() {
@ -1170,11 +1203,13 @@ pub fn update_clip_task(
// Get a minimal device space rect, clipped to the screen that we
// need to allocate for the clip mask, as well as interpolated
// snap offsets.
let unadjusted_device_rect = match frame_state.surfaces[pic_context.surface_index.0].get_surface_rect(
&instance.vis.clip_chain.pic_coverage_rect,
frame_context.spatial_tree,
let unadjusted_device_rect = match get_clipped_device_rect(
&unclipped,
&pic_state.map_raster_to_world,
frame_state.current_dirty_region().combined,
device_pixel_scale,
) {
Some(rect) => rect,
Some(device_rect) => device_rect,
None => return false,
};
@ -1223,11 +1258,14 @@ pub fn update_clip_task(
pub fn update_brush_segment_clip_task(
segment: &BrushSegment,
clip_chain: Option<&ClipChainInstance>,
world_clip_rect: WorldRect,
root_spatial_node_index: SpatialNodeIndex,
surface_index: SurfaceIndex,
pic_state: &mut PictureState,
frame_context: &FrameBuildingContext,
frame_state: &mut FrameBuildingState,
clip_data_store: &mut ClipDataStore,
unclipped: &DeviceRect,
device_pixel_scale: DevicePixelScale,
) -> ClipMaskKind {
let clip_chain = match clip_chain {
@ -1239,14 +1277,31 @@ pub fn update_brush_segment_clip_task(
return ClipMaskKind::None;
}
let device_rect = match frame_state.surfaces[surface_index.0].get_surface_rect(
&clip_chain.pic_coverage_rect,
frame_context.spatial_tree,
) {
let segment_world_rect = match pic_state.map_pic_to_world.map(&clip_chain.pic_coverage_rect) {
Some(rect) => rect,
None => return ClipMaskKind::Clipped,
};
let segment_world_rect = match segment_world_rect.intersection(&world_clip_rect) {
Some(rect) => rect,
None => return ClipMaskKind::Clipped,
};
// Get a minimal device space rect, clipped to the screen that we
// need to allocate for the clip mask, as well as interpolated
// snap offsets.
let device_rect = match get_clipped_device_rect(
unclipped,
&pic_state.map_raster_to_world,
segment_world_rect,
device_pixel_scale,
) {
Some(info) => info,
None => {
return ClipMaskKind::Clipped;
}
};
let (device_rect, device_pixel_scale) = adjust_mask_scale_for_max_size(device_rect, device_pixel_scale);
let clip_task_id = RenderTaskKind::new_mask(
@ -1369,8 +1424,7 @@ fn build_segments_if_needed(
// in the instance and primitive template.
let prim_local_rect = data_stores.get_local_prim_rect(
instance,
&prim_store.pictures,
frame_state.surfaces,
prim_store,
);
let segment_instance_index = match instance.kind {
@ -1477,6 +1531,56 @@ fn build_segments_if_needed(
}
}
/// Retrieve the exact unsnapped device space rectangle for a primitive.
fn get_unclipped_device_rect(
prim_rect: PictureRect,
map_to_raster: &SpaceMapper<PicturePixel, RasterPixel>,
device_pixel_scale: DevicePixelScale,
) -> Option<DeviceRect> {
let raster_rect = map_to_raster.map(&prim_rect)?;
let world_rect = raster_rect * Scale::new(1.0);
Some(world_rect * device_pixel_scale)
}
/// Given an unclipped device rect, try to find a minimal device space
/// rect to allocate a clip mask for, by clipping to the screen. This
/// function is very similar to picture::get_raster_rects. It is far from
/// ideal, and should be refactored as part of the support for setting
/// scale per-raster-root.
fn get_clipped_device_rect(
unclipped: &DeviceRect,
map_to_world: &SpaceMapper<RasterPixel, WorldPixel>,
world_clip_rect: WorldRect,
device_pixel_scale: DevicePixelScale,
) -> Option<DeviceRect> {
let unclipped_raster_rect = {
let world_rect = (*unclipped) * Scale::new(1.0);
let raster_rect = world_rect * device_pixel_scale.inverse();
raster_rect.cast_unit()
};
let unclipped_world_rect = map_to_world.map(&unclipped_raster_rect)?;
let clipped_world_rect = unclipped_world_rect.intersection(&world_clip_rect)?;
let clipped_raster_rect = map_to_world.unmap(&clipped_world_rect)?;
let clipped_raster_rect = clipped_raster_rect.intersection(&unclipped_raster_rect)?;
// Ensure that we won't try to allocate a zero-sized clip render task.
if clipped_raster_rect.is_empty() {
return None;
}
let clipped = raster_rect_to_device_pixels(
clipped_raster_rect,
device_pixel_scale,
);
Some(clipped)
}
// Ensures that the size of mask render tasks are within MAX_MASK_SIZE.
fn adjust_mask_scale_for_max_size(device_rect: DeviceRect, device_pixel_scale: DevicePixelScale) -> (DeviceRect, DevicePixelScale) {
if device_rect.width() > MAX_MASK_SIZE || device_rect.height() > MAX_MASK_SIZE {

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

@ -79,7 +79,7 @@ pub enum PictureCompositeKey {
Identity,
// FilterOp
Blur(Au, Au, bool),
Blur(Au, Au),
Brightness(Au),
Contrast(Au),
Grayscale(Au),
@ -142,8 +142,8 @@ impl From<Option<PictureCompositeMode>> for PictureCompositeKey {
}
Some(PictureCompositeMode::Filter(op)) => {
match op {
Filter::Blur { width, height, should_inflate } =>
PictureCompositeKey::Blur(Au::from_f32_px(width), Au::from_f32_px(height), should_inflate),
Filter::Blur(width, height) =>
PictureCompositeKey::Blur(Au::from_f32_px(width), Au::from_f32_px(height)),
Filter::Brightness(value) => PictureCompositeKey::Brightness(Au::from_f32_px(value)),
Filter::Contrast(value) => PictureCompositeKey::Contrast(Au::from_f32_px(value)),
Filter::Grayscale(value) => PictureCompositeKey::Grayscale(Au::from_f32_px(value)),

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

@ -246,6 +246,7 @@ impl TextRunPrimitive {
transform: &LayoutToWorldTransform,
mut allow_subpixel: bool,
raster_space: RasterSpace,
root_scaling_factor: f32,
spatial_tree: &SpatialTree,
) -> bool {
// If local raster space is specified, include that in the scale
@ -256,7 +257,10 @@ impl TextRunPrimitive {
// will no longer be required.
let raster_scale = raster_space.local_scale().unwrap_or(1.0).max(0.001);
let dps = surface.device_pixel_scale.0;
// root_scaling_factor is used to scale very large pictures that establish
// a raster root back to something sane, thus scale the device size accordingly.
// to the shader it looks like a change in DPI which it already supports.
let dps = surface.device_pixel_scale.0 * root_scaling_factor;
let font_size = specified_font.size.to_f32_px();
// Small floating point error can accumulate in the raster * device_pixel scale.
@ -438,6 +442,7 @@ impl TextRunPrimitive {
transform: &LayoutToWorldTransform,
surface: &SurfaceInfo,
spatial_node_index: SpatialNodeIndex,
root_scaling_factor: f32,
allow_subpixel: bool,
low_quality_pinch_zoom: bool,
resource_cache: &mut ResourceCache,
@ -459,13 +464,14 @@ impl TextRunPrimitive {
transform,
allow_subpixel,
raster_space,
root_scaling_factor,
spatial_tree,
);
if self.glyph_keys_range.is_empty() || cache_dirty {
let subpx_dir = self.used_font.get_subpx_dir();
let dps = surface.device_pixel_scale.0;
let dps = surface.device_pixel_scale.0 * root_scaling_factor;
let transform = match raster_space {
RasterSpace::Local(scale) => FontTransform::new(scale * dps, 0.0, 0.0, scale * dps),
RasterSpace::Screen => self.used_font.transform.scale(dps),

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

@ -31,13 +31,12 @@ use crate::gpu_cache::GpuCache;
use crate::hit_test::{HitTest, HitTester, SharedHitTester};
use crate::intern::DataStore;
#[cfg(any(feature = "capture", feature = "replay"))]
use crate::internal_types::{DebugOutput};
use crate::internal_types::DebugOutput;
use crate::internal_types::{FastHashMap, RenderedDocument, ResultMsg, FrameId, FrameStamp};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use crate::picture::{PictureScratchBuffer, SliceId, TileCacheInstance, TileCacheParams, SurfaceInfo, RasterConfig};
use crate::picture::{PicturePrimitive};
use crate::picture::{PictureScratchBuffer, SliceId, TileCacheInstance, TileCacheParams};
use crate::prim_store::{PrimitiveScratchBuffer, PrimitiveInstance};
use crate::prim_store::{PrimitiveInstanceKind, PrimTemplateCommonData};
use crate::prim_store::{PrimitiveInstanceKind, PrimTemplateCommonData, PrimitiveStore};
use crate::prim_store::interned::*;
use crate::profiler::{self, TransactionProfile};
use crate::render_task_graph::RenderTaskGraphBuilder;
@ -136,53 +135,12 @@ impl DataStores {
pub fn get_local_prim_rect(
&self,
prim_instance: &PrimitiveInstance,
pictures: &[PicturePrimitive],
surfaces: &[SurfaceInfo],
prim_store: &PrimitiveStore,
) -> LayoutRect {
match prim_instance.kind {
PrimitiveInstanceKind::Picture { pic_index, .. } => {
let pic = &pictures[pic_index.0];
match pic.raster_config {
Some(RasterConfig { surface_index, ref composite_mode, .. }) => {
let surface = &surfaces[surface_index.0];
composite_mode.get_rect(surface, None)
}
None => {
panic!("bug: get_local_prim_rect should not be called for pass-through pictures");
}
}
}
_ => {
self.as_common_data(prim_instance).prim_rect
}
}
}
/// Returns the local coverage (space occupied) for a primitive. For most primitives,
/// this is stored in the template. For pictures, this is stored inside the picture
/// primitive instance itself, since this is determined during frame building.
pub fn get_local_prim_coverage_rect(
&self,
prim_instance: &PrimitiveInstance,
pictures: &[PicturePrimitive],
surfaces: &[SurfaceInfo],
) -> LayoutRect {
match prim_instance.kind {
PrimitiveInstanceKind::Picture { pic_index, .. } => {
let pic = &pictures[pic_index.0];
match pic.raster_config {
Some(RasterConfig { surface_index, ref composite_mode, .. }) => {
let surface = &surfaces[surface_index.0];
composite_mode.get_coverage(surface, None)
}
None => {
panic!("bug: get_local_prim_coverage_rect should not be called for pass-through pictures");
}
}
let pic = &prim_store.pictures[pic_index.0];
pic.precise_local_rect
}
_ => {
self.as_common_data(prim_instance).prim_rect

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

@ -56,7 +56,7 @@ use crate::glyph_rasterizer::FontInstance;
use crate::hit_test::HitTestingScene;
use crate::intern::Interner;
use crate::internal_types::{FastHashMap, LayoutPrimitiveInfo, Filter, PlaneSplitter, PlaneSplitterIndex, PipelineInstanceId};
use crate::picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive};
use crate::picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureOptions};
use crate::picture::{BlitReason, OrderedPictureChild, PrimitiveList, SurfaceInfo};
use crate::picture_graph::PictureGraph;
use crate::prim_store::{PrimitiveInstance, register_prim_chase_id};
@ -268,6 +268,7 @@ impl PictureChainBuilder {
self,
composite_mode: PictureCompositeMode,
context_3d: Picture3DContext<OrderedPictureChild>,
options: PictureOptions,
interners: &mut Interners,
prim_store: &mut PrimitiveStore,
prim_instances: &mut Vec<PrimitiveInstance>,
@ -300,6 +301,7 @@ impl PictureChainBuilder {
self.flags,
prim_list,
self.spatial_node_index,
options,
))
);
@ -344,6 +346,7 @@ impl PictureChainBuilder {
self.flags,
prim_list,
self.spatial_node_index,
PictureOptions::default(),
))
);
@ -2159,6 +2162,7 @@ impl<'a> SceneBuilder<'a> {
stacking_context.prim_flags,
stacking_context.prim_list,
stacking_context.spatial_node_index,
PictureOptions::default(),
))
);
@ -2197,6 +2201,7 @@ impl<'a> SceneBuilder<'a> {
stacking_context.prim_flags,
stacking_context.prim_list,
stacking_context.spatial_node_index,
PictureOptions::default(),
))
);
@ -2295,6 +2300,7 @@ impl<'a> SceneBuilder<'a> {
stacking_context.prim_flags,
prim_list,
stacking_context.spatial_node_index,
PictureOptions::default(),
))
);
@ -2319,6 +2325,7 @@ impl<'a> SceneBuilder<'a> {
stacking_context.composite_ops.filters,
stacking_context.composite_ops.filter_primitives,
stacking_context.composite_ops.filter_datas,
true,
);
// Same for mix-blend-mode, except we can skip if this primitive is the first in the parent
@ -2344,6 +2351,7 @@ impl<'a> SceneBuilder<'a> {
source = source.add_picture(
composite_mode,
Picture3DContext::Out,
PictureOptions::default(),
&mut self.interners,
&mut self.prim_store,
&mut self.prim_instances,
@ -2700,11 +2708,7 @@ impl<'a> SceneBuilder<'a> {
// Add any primitives that come after this shadow in the item
// list to this shadow.
let mut prim_list = PrimitiveList::empty();
let blur_filter = Filter::Blur {
width: std_deviation,
height: std_deviation,
should_inflate: pending_shadow.should_inflate,
};
let blur_filter = Filter::Blur(std_deviation, std_deviation);
let blur_is_noop = blur_filter.is_noop();
for item in &items {
@ -2774,10 +2778,17 @@ impl<'a> SceneBuilder<'a> {
// blur radius is 0, the code in Picture::prepare_for_render will
// detect this and mark the picture to be drawn directly into the
// parent picture, which avoids an intermediate surface and blur.
let blur_filter = Filter::Blur(std_deviation, std_deviation);
assert!(!blur_filter.is_noop());
let composite_mode = Some(PictureCompositeMode::Filter(blur_filter));
let composite_mode_key = composite_mode.clone().into();
// Pass through configuration information about whether WR should
// do the bounding rect inflation for text shadows.
let options = PictureOptions {
inflate_if_required: pending_shadow.should_inflate,
};
// Create the primitive to draw the shadow picture into the scene.
let shadow_pic_index = PictureIndex(self.prim_store.pictures
.alloc()
@ -2788,6 +2799,7 @@ impl<'a> SceneBuilder<'a> {
PrimitiveFlags::IS_BACKFACE_VISIBLE,
prim_list,
pending_shadow.spatial_node_index,
options,
))
);
@ -3483,6 +3495,9 @@ impl<'a> SceneBuilder<'a> {
prim_flags,
prim_list,
backdrop_spatial_node_index,
PictureOptions {
inflate_if_required: false,
},
))
);
@ -3505,6 +3520,7 @@ impl<'a> SceneBuilder<'a> {
filters,
filter_primitives,
filter_datas,
false,
);
// Apply filters from all stacking contexts up to, but not including the backdrop root.
@ -3523,6 +3539,7 @@ impl<'a> SceneBuilder<'a> {
filters,
filter_primitives,
filter_datas,
false,
);
}
@ -3603,6 +3620,7 @@ impl<'a> SceneBuilder<'a> {
mut filter_ops: Vec<Filter>,
mut filter_primitives: Vec<FilterPrimitive>,
filter_datas: Vec<FilterData>,
inflate_if_required: bool,
) -> PictureChainBuilder {
// TODO(cbrewster): Currently CSS and SVG filters live side by side in WebRender, but unexpected results will
// happen if they are used simulataneously. Gecko only provides either filter ops or filter primitives.
@ -3654,6 +3672,7 @@ impl<'a> SceneBuilder<'a> {
source = source.add_picture(
composite_mode,
Picture3DContext::Out,
PictureOptions { inflate_if_required },
&mut self.interners,
&mut self.prim_store,
&mut self.prim_instances,
@ -3690,6 +3709,7 @@ impl<'a> SceneBuilder<'a> {
source = source.add_picture(
composite_mode,
Picture3DContext::Out,
PictureOptions { inflate_if_required },
&mut self.interners,
&mut self.prim_store,
&mut self.prim_instances,
@ -3852,6 +3872,7 @@ impl FlattenedStackingContext {
self.prim_flags,
mem::replace(&mut self.prim_list, PrimitiveList::empty()),
self.spatial_node_index,
PictureOptions::default(),
))
);

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

@ -1012,17 +1012,19 @@ impl SpatialTree {
CoordinateSpaceMapping::Transform(transform)
}
/// Returns true if both supplied spatial nodes are in the same coordinate system
/// (implies the relative transform produce axis-aligned rects).
pub fn is_matching_coord_system(
pub fn is_relative_transform_complex(
&self,
index0: SpatialNodeIndex,
index1: SpatialNodeIndex,
child_index: SpatialNodeIndex,
parent_index: SpatialNodeIndex,
) -> bool {
let node0 = self.get_spatial_node(index0);
let node1 = self.get_spatial_node(index1);
if child_index == parent_index {
return false;
}
node0.coordinate_system_id == node1.coordinate_system_id
let child = self.get_spatial_node(child_index);
let parent = self.get_spatial_node(parent_index);
child.coordinate_system_id != parent.coordinate_system_id
}
fn get_world_transform_impl(

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

@ -7,7 +7,7 @@ use api::units::*;
use crate::clip::{ClipChainId, ClipNodeKind, ClipStore, ClipInstance};
use crate::frame_builder::FrameBuilderConfig;
use crate::internal_types::{FastHashMap, FastHashSet};
use crate::picture::{PrimitiveList, PictureCompositeMode, PicturePrimitive, SliceId};
use crate::picture::{PrimitiveList, PictureCompositeMode, PictureOptions, PicturePrimitive, SliceId};
use crate::picture::{Picture3DContext, TileCacheParams, TileOffset};
use crate::prim_store::{PrimitiveInstance, PrimitiveStore, PictureIndex};
use crate::scene_building::SliceFlags;
@ -629,6 +629,7 @@ fn create_tile_cache(
PrimitiveFlags::IS_BACKFACE_VISIBLE,
prim_list,
scroll_root,
PictureOptions::default(),
));
PictureIndex(pic_index)

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

@ -4,7 +4,7 @@
use api::BorderRadius;
use api::units::*;
use euclid::{Point2D, Rect, Box2D, Size2D, Vector2D};
use euclid::{Point2D, Rect, Box2D, Size2D, Vector2D, point2};
use euclid::{default, Transform2D, Transform3D, Scale};
use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
use plane_split::{Clipper, Polygon};
@ -1240,6 +1240,15 @@ pub fn project_rect<F, T>(
}
}
pub fn raster_rect_to_device_pixels(
rect: RasterRect,
device_pixel_scale: DevicePixelScale,
) -> DeviceRect {
let world_rect = rect * Scale::new(1.0);
let device_rect = world_rect * device_pixel_scale;
device_rect.round_out()
}
/// Run the first callback over all elements in the array. If the callback returns true,
/// the element is removed from the array and moved to a second callback.
///
@ -1542,6 +1551,142 @@ macro_rules! c_str {
}
}
// Find a rectangle that is contained by the sum of r1 and r2.
pub fn conservative_union_rect<U>(r1: &Box2D<f32, U>, r2: &Box2D<f32, U>) -> Box2D<f32, U> {
// +---+---+ +--+-+--+
// | | | | | | |
// | | | | | | |
// +---+---+ +--+-+--+
if r1.min.y == r2.min.y && r1.max.y == r2.max.y {
if r2.min.x <= r1.max.x && r2.max.x >= r1.min.x {
let min_x = f32::min(r1.min.x, r2.min.x);
let max_x = f32::max(r1.max.x, r2.max.x);
return Box2D {
min: point2(min_x, r1.min.y),
max: point2(max_x, r1.max.y),
}
}
}
// +----+ +----+
// | | | |
// | | +----+
// +----+ | |
// | | +----+
// | | | |
// +----+ +----+
if r1.min.x == r2.min.x && r1.max.x == r2.max.x {
if r2.min.y <= r1.max.y && r2.max.y >= r1.min.y {
let min_y = f32::min(r1.min.y, r2.min.y);
let max_y = f32::max(r1.max.y, r2.max.y);
return Box2D {
min: point2(r1.min.x, min_y),
max: point2(r1.max.x, max_y),
}
}
}
if r1.area() >= r2.area() { *r1 } else {*r2 }
}
#[test]
fn test_conservative_union_rect() {
// Adjacent, x axis
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
&LayoutRect { min: point2(4.0, 2.0), max: point2(9.0, 6.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 2.0), max: point2(9.0, 6.0) });
let r = conservative_union_rect(
&LayoutRect { min: point2(4.0, 2.0), max: point2(9.0, 6.0) },
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 2.0), max: point2(9.0, 6.0) });
// Averlapping adjacent, x axis
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
&LayoutRect { min: point2(3.0, 2.0), max: point2(8.0, 6.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 2.0), max: point2(8.0, 6.0) });
let r = conservative_union_rect(
&LayoutRect { min: point2(5.0, 2.0), max: point2(8.0, 6.0) },
&LayoutRect { min: point2(1.0, 2.0), max: point2(6.0, 6.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 2.0), max: point2(8.0, 6.0) });
// Adjacent but not touching, x axis
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
&LayoutRect { min: point2(6.0, 2.0), max: point2(11.0, 6.0) },
);
assert_eq!(r, LayoutRect { min: point2(6.0, 2.0), max: point2(11.0, 6.0) });
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
&LayoutRect { min: point2(-6.0, 2.0), max: point2(-5.0, 6.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) });
// Adjacent, y axis
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
&LayoutRect { min: point2(1.0, 6.0), max: point2(4.0, 10.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 10.0) });
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 5.0), max: point2(4.0, 9.0) },
&LayoutRect { min: point2(1.0, 1.0), max: point2(4.0, 5.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 1.0), max: point2(4.0, 9.0) });
// Averlapping adjacent, y axis
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
&LayoutRect { min: point2(1.0, 3.0), max: point2(4.0, 7.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 7.0) });
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 4.0), max: point2(4.0, 8.0) },
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 8.0) });
// Adjacent but not touching, y axis
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
&LayoutRect { min: point2(1.0, 10.0), max: point2(4.0, 15.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 10.0), max: point2(4.0, 15.0) });
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 5.0), max: point2(4.0, 9.0) },
&LayoutRect { min: point2(1.0, 0.0), max: point2(4.0, 3.0) },
);
assert_eq!(r, LayoutRect { min: point2(1.0, 5.0), max: point2(4.0, 9.0) });
// Contained
let r = conservative_union_rect(
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
&LayoutRect { min: point2(0.0, 1.0), max: point2(10.0, 12.0) },
);
assert_eq!(r, LayoutRect { min: point2(0.0, 1.0), max: point2(10.0, 12.0) });
let r = conservative_union_rect(
&LayoutRect { min: point2(0.0, 1.0), max: point2(10.0, 12.0) },
&LayoutRect { min: point2(1.0, 2.0), max: point2(4.0, 6.0) },
);
assert_eq!(r, LayoutRect { min: point2(0.0, 1.0), max: point2(10.0, 12.0) });
}
/// This is inspired by the `weak-table` crate.
/// It holds a Vec of weak pointers that are garbage collected as the Vec
pub struct WeakTable {

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

@ -7,30 +7,34 @@
//! TODO: document what this pass does!
//!
use api::{DebugFlags};
use api::{ColorF, DebugFlags};
use api::units::*;
use std::{usize};
use euclid::Scale;
use std::{usize, mem};
use crate::batch::BatchFilter;
use crate::clip::{ClipStore, ClipChainStack};
use crate::composite::CompositeState;
use crate::spatial_tree::{SpatialTree, SpatialNodeIndex};
use crate::clip::{ClipInstance, ClipChainInstance};
use crate::debug_colors;
use crate::frame_builder::FrameBuilderConfig;
use crate::gpu_cache::GpuCache;
use crate::picture::{PictureCompositeMode, ClusterFlags, SurfaceInfo, TileCacheInstance};
use crate::picture::{SurfaceIndex, RasterConfig};
use crate::picture::{PrimitiveList, SurfaceIndex, RasterConfig};
use crate::prim_store::{ClipTaskIndex, PictureIndex, PrimitiveInstanceKind};
use crate::prim_store::{PrimitiveStore, PrimitiveInstance};
use crate::render_backend::{DataStores, ScratchBuffer};
use crate::resource_cache::ResourceCache;
use crate::scene::SceneProperties;
use crate::space::SpaceMapper;
use crate::internal_types::Filter;
use crate::util::{MaxRect};
pub struct FrameVisibilityContext<'a> {
pub spatial_tree: &'a SpatialTree,
pub global_screen_world_rect: WorldRect,
pub global_device_pixel_scale: DevicePixelScale,
pub surfaces: &'a [SurfaceInfo],
pub debug_flags: DebugFlags,
pub scene_properties: &'a SceneProperties,
pub config: FrameBuilderConfig,
@ -47,18 +51,17 @@ pub struct FrameVisibilityState<'a> {
pub composite_state: &'a mut CompositeState,
/// A stack of currently active off-screen surfaces during the
/// visibility frame traversal.
pub surface_stack: Vec<(PictureIndex, SurfaceIndex)>,
pub surface_stack: Vec<SurfaceIndex>,
}
impl<'a> FrameVisibilityState<'a> {
pub fn push_surface(
&mut self,
pic_index: PictureIndex,
surface_index: SurfaceIndex,
shared_clips: &[ClipInstance],
spatial_tree: &SpatialTree,
) {
self.surface_stack.push((pic_index, surface_index));
self.surface_stack.push(surface_index);
self.clip_chain_stack.push_surface(
shared_clips,
spatial_tree,
@ -161,52 +164,59 @@ impl PrimitiveVisibility {
}
}
pub fn update_prim_visibility(
/// Update visibility pass - update each primitive visibility struct, and
/// build the clip chain instance if appropriate.
pub fn update_primitive_visibility(
store: &mut PrimitiveStore,
pic_index: PictureIndex,
parent_surface_index: Option<SurfaceIndex>,
world_culling_rect: &WorldRect,
store: &PrimitiveStore,
prim_instances: &mut [PrimitiveInstance],
surfaces: &mut [SurfaceInfo],
is_root_tile_cache: bool,
frame_context: &FrameVisibilityContext,
frame_state: &mut FrameVisibilityState,
tile_cache: &mut TileCacheInstance,
) {
let pic = &store.pictures[pic_index.0];
is_root_tile_cache: bool,
prim_instances: &mut Vec<PrimitiveInstance>,
) -> Option<PictureRect> {
profile_scope!("update_visibility");
let (mut prim_list, surface_index, apply_local_clip_rect, world_culling_rect, pop_surface) = {
let pic = &mut store.pictures[pic_index.0];
let (surface_index, pop_surface) = match pic.raster_config {
Some(RasterConfig { surface_index, composite_mode: PictureCompositeMode::TileCache { .. }, .. }) => {
(surface_index, false)
}
Some(ref raster_config) => {
frame_state.push_surface(
pic_index,
raster_config.surface_index,
&[],
frame_context.spatial_tree,
);
let prim_list = mem::replace(&mut pic.prim_list, PrimitiveList::empty());
let (surface_index, pop_surface) = match pic.raster_config {
Some(RasterConfig { surface_index, composite_mode: PictureCompositeMode::TileCache { .. }, .. }) => {
(surface_index, false)
}
Some(ref raster_config) => {
frame_state.push_surface(
raster_config.surface_index,
&[],
frame_context.spatial_tree,
);
let surface_local_rect = surfaces[raster_config.surface_index.0].local_rect.cast_unit();
// Let the picture cache know that we are pushing an off-screen
// surface, so it can treat dependencies of surface atomically.
tile_cache.push_surface(
pic.estimated_local_rect,
pic.spatial_node_index,
frame_context.spatial_tree,
);
// Let the picture cache know that we are pushing an off-screen
// surface, so it can treat dependencies of surface atomically.
tile_cache.push_surface(
surface_local_rect,
pic.spatial_node_index,
frame_context.spatial_tree,
);
(raster_config.surface_index, true)
}
None => {
(parent_surface_index.expect("bug: pass-through with no parent"), false)
}
};
(raster_config.surface_index, true)
}
None => {
(parent_surface_index.expect("bug: pass-through with no parent"), false)
}
(prim_list, surface_index, pic.apply_local_clip_rect, world_culling_rect, pop_surface)
};
let surface = &surfaces[surface_index.0 as usize];
let device_pixel_scale = surface.device_pixel_scale;
let mut map_local_to_surface = surface.map_local_to_surface.clone();
let surface = &frame_context.surfaces[surface_index.0 as usize];
let mut map_local_to_surface = surface
.map_local_to_surface
.clone();
let map_surface_to_world = SpaceMapper::new_with_target(
frame_context.root_spatial_node_index,
surface.surface_spatial_node_index,
@ -214,7 +224,9 @@ pub fn update_prim_visibility(
frame_context.spatial_tree,
);
for cluster in &pic.prim_list.clusters {
let mut surface_rect = PictureRect::zero();
for cluster in &mut prim_list.clusters {
profile_scope!("cluster");
// Each prim instance must have reset called each frame, to clear
@ -244,141 +256,325 @@ pub fn update_prim_visibility(
);
for prim_instance_index in cluster.prim_range() {
if let PrimitiveInstanceKind::Picture { pic_index, .. } = prim_instances[prim_instance_index].kind {
if !store.pictures[pic_index.0].is_visible(frame_context.spatial_tree) {
continue;
}
let (is_passthrough, prim_local_rect, prim_shadowed_rect) = match prim_instances[prim_instance_index].kind {
PrimitiveInstanceKind::Picture { pic_index, .. } => {
let (is_visible, is_passthrough) = {
let pic = &store.pictures[pic_index.0];
(pic.is_visible(frame_context.spatial_tree), pic.raster_config.is_none())
};
let is_passthrough = match store.pictures[pic_index.0].raster_config {
Some(..) => false,
None => true,
};
if !is_visible {
continue;
}
if is_passthrough {
frame_state.clip_chain_stack.push_clip(
prim_instances[prim_instance_index].clip_set.clip_chain_id,
frame_state.clip_store,
if is_passthrough {
frame_state.clip_chain_stack.push_clip(
prim_instances[prim_instance_index].clip_set.clip_chain_id,
frame_state.clip_store,
);
}
let pic_surface_rect = update_primitive_visibility(
store,
pic_index,
Some(surface_index),
world_culling_rect,
frame_context,
frame_state,
tile_cache,
false,
prim_instances,
);
if is_passthrough {
frame_state.clip_chain_stack.pop_clip();
}
let pic = &store.pictures[pic_index.0];
let mut shadow_rect = pic.precise_local_rect;
match pic.raster_config {
Some(ref rc) => match rc.composite_mode {
// If we have a drop shadow filter, we also need to include the shadow in
// our shadowed local rect for the purpose of calculating the size of the
// picture.
PictureCompositeMode::Filter(Filter::DropShadows(ref shadows)) => {
for shadow in shadows {
shadow_rect = shadow_rect.union(&pic.precise_local_rect.translate(shadow.offset));
}
}
_ => {}
}
None => {
// If the primitive does not have its own raster config, we need to
// propogate the surface rect calculation to the parent.
if let Some(ref rect) = pic_surface_rect {
surface_rect = surface_rect.union(rect);
}
}
}
(is_passthrough, pic.precise_local_rect, shadow_rect)
}
_ => {
let prim_instance = &prim_instances[prim_instance_index];
let prim_data = &frame_state.data_stores.as_common_data(&prim_instance);
update_prim_visibility(
pic_index,
Some(surface_index),
world_culling_rect,
store,
prim_instances,
surfaces,
false,
frame_context,
frame_state,
tile_cache,
);
if is_passthrough {
frame_state.clip_chain_stack.pop_clip();
// Pass through pictures are always considered visible in all dirty tiles.
prim_instances[prim_instance_index].vis.state = VisibilityState::PassThrough;
continue;
(false, prim_data.prim_rect, prim_data.prim_rect)
}
}
};
let prim_instance = &mut prim_instances[prim_instance_index];
let local_coverage_rect = frame_state.data_stores.get_local_prim_coverage_rect(
prim_instance,
&store.pictures,
surfaces,
);
// Include the clip chain for this primitive in the current stack.
frame_state.clip_chain_stack.push_clip(
prim_instance.clip_set.clip_chain_id,
frame_state.clip_store,
);
frame_state.clip_store.set_active_clips(
prim_instance.clip_set.local_clip_rect,
cluster.spatial_node_index,
map_local_to_surface.ref_spatial_node_index,
frame_state.clip_chain_stack.current_clips_array(),
&frame_context.spatial_tree,
&frame_state.data_stores.clip,
);
let clip_chain = frame_state
.clip_store
.build_clip_chain_instance(
local_coverage_rect,
&map_local_to_surface,
&map_surface_to_world,
&frame_context.spatial_tree,
frame_state.gpu_cache,
frame_state.resource_cache,
device_pixel_scale,
&world_culling_rect,
&mut frame_state.data_stores.clip,
true,
prim_instance.is_chased(),
);
// Ensure the primitive clip is popped
frame_state.clip_chain_stack.pop_clip();
prim_instance.vis.clip_chain = match clip_chain {
Some(clip_chain) => clip_chain,
None => {
if is_passthrough {
// Pass through pictures are always considered visible in all dirty tiles.
prim_instance.vis.state = VisibilityState::PassThrough;
} else {
if prim_local_rect.width() <= 0.0 || prim_local_rect.height() <= 0.0 {
if prim_instance.is_chased() {
info!("\tunable to build the clip chain, skipping");
info!("\tculled for zero local rectangle");
}
continue;
}
};
if prim_instance.is_chased() {
info!("\teffective clip chain from {:?} {}",
prim_instance.vis.clip_chain.clips_range,
if pic.apply_local_clip_rect { "(applied)" } else { "" },
// Inflate the local rect for this primitive by the inflation factor of
// the picture context and include the shadow offset. This ensures that
// even if the primitive itstore is not visible, any effects from the
// blur radius or shadow will be correctly taken into account.
let inflation_factor = surface.inflation_factor;
let local_rect = prim_shadowed_rect
.inflate(inflation_factor, inflation_factor)
.intersection(&prim_instance.clip_set.local_clip_rect);
let local_rect = match local_rect {
Some(local_rect) => local_rect,
None => {
if prim_instance.is_chased() {
info!("\tculled for being out of the local clip rectangle: {:?}",
prim_instance.clip_set.local_clip_rect);
}
continue;
}
};
// Include the clip chain for this primitive in the current stack.
frame_state.clip_chain_stack.push_clip(
prim_instance.clip_set.clip_chain_id,
frame_state.clip_store,
);
info!("\tpicture rect {:?} @{:?}",
prim_instance.vis.clip_chain.pic_coverage_rect,
prim_instance.vis.clip_chain.pic_spatial_node_index,
frame_state.clip_store.set_active_clips(
prim_instance.clip_set.local_clip_rect,
cluster.spatial_node_index,
map_local_to_surface.ref_spatial_node_index,
frame_state.clip_chain_stack.current_clips_array(),
&frame_context.spatial_tree,
&frame_state.data_stores.clip,
);
let clip_chain = frame_state
.clip_store
.build_clip_chain_instance(
local_rect,
&map_local_to_surface,
&map_surface_to_world,
&frame_context.spatial_tree,
frame_state.gpu_cache,
frame_state.resource_cache,
surface.device_pixel_scale,
&world_culling_rect,
&mut frame_state.data_stores.clip,
true,
prim_instance.is_chased(),
);
// Ensure the primitive clip is popped
frame_state.clip_chain_stack.pop_clip();
prim_instance.vis.clip_chain = match clip_chain {
Some(clip_chain) => clip_chain,
None => {
if prim_instance.is_chased() {
info!("\tunable to build the clip chain, skipping");
}
continue;
}
};
if prim_instance.is_chased() {
info!("\teffective clip chain from {:?} {}",
prim_instance.vis.clip_chain.clips_range,
if apply_local_clip_rect { "(applied)" } else { "" },
);
info!("\tpicture rect {:?} @{:?}",
prim_instance.vis.clip_chain.pic_coverage_rect,
prim_instance.vis.clip_chain.pic_spatial_node_index,
);
}
prim_instance.vis.combined_local_clip_rect = if apply_local_clip_rect {
prim_instance.vis.clip_chain.local_clip_rect
} else {
prim_instance.clip_set.local_clip_rect
};
if prim_instance.vis.combined_local_clip_rect.is_empty() {
if prim_instance.is_chased() {
info!("\tculled for zero local clip rectangle");
}
continue;
}
// Include the visible area for primitive, including any shadows, in
// the area affected by the surface.
match prim_instance.vis.combined_local_clip_rect.intersection(&local_rect) {
Some(visible_rect) => {
if let Some(rect) = map_local_to_surface.map(&visible_rect) {
surface_rect = surface_rect.union(&rect);
}
}
None => {
if prim_instance.is_chased() {
info!("\tculled for zero visible rectangle");
}
continue;
}
}
tile_cache.update_prim_dependencies(
prim_instance,
cluster.spatial_node_index,
prim_local_rect,
frame_context,
frame_state.data_stores,
frame_state.clip_store,
&store.pictures,
frame_state.resource_cache,
&store.color_bindings,
&frame_state.surface_stack,
&mut frame_state.composite_state,
&mut frame_state.gpu_cache,
is_root_tile_cache,
);
// Skip post visibility prim update if this primitive was culled above.
match prim_instance.vis.state {
VisibilityState::Unset => panic!("bug: invalid state"),
VisibilityState::Culled => continue,
VisibilityState::Coarse { .. } | VisibilityState::Detailed { .. } | VisibilityState::PassThrough => {}
}
// When the debug display is enabled, paint a colored rectangle around each
// primitive.
if frame_context.debug_flags.contains(::api::DebugFlags::PRIMITIVE_DBG) {
let debug_color = match prim_instance.kind {
PrimitiveInstanceKind::Picture { .. } => ColorF::TRANSPARENT,
PrimitiveInstanceKind::TextRun { .. } => debug_colors::RED,
PrimitiveInstanceKind::LineDecoration { .. } => debug_colors::PURPLE,
PrimitiveInstanceKind::NormalBorder { .. } |
PrimitiveInstanceKind::ImageBorder { .. } => debug_colors::ORANGE,
PrimitiveInstanceKind::Rectangle { .. } => ColorF { r: 0.8, g: 0.8, b: 0.8, a: 0.5 },
PrimitiveInstanceKind::YuvImage { .. } => debug_colors::BLUE,
PrimitiveInstanceKind::Image { .. } => debug_colors::BLUE,
PrimitiveInstanceKind::LinearGradient { .. } => debug_colors::PINK,
PrimitiveInstanceKind::CachedLinearGradient { .. } => debug_colors::PINK,
PrimitiveInstanceKind::RadialGradient { .. } => debug_colors::PINK,
PrimitiveInstanceKind::ConicGradient { .. } => debug_colors::PINK,
PrimitiveInstanceKind::Clear { .. } => debug_colors::CYAN,
PrimitiveInstanceKind::Backdrop { .. } => debug_colors::MEDIUMAQUAMARINE,
};
if debug_color.a != 0.0 {
if let Some(rect) = calculate_prim_clipped_world_rect(
&prim_instance.vis.clip_chain.pic_coverage_rect,
&world_culling_rect,
&map_surface_to_world,
) {
let debug_rect = rect * frame_context.global_device_pixel_scale;
frame_state.scratch.primitive.push_debug_rect(debug_rect, debug_color, debug_color.scale_alpha(0.5));
}
}
} else if frame_context.debug_flags.contains(::api::DebugFlags::OBSCURE_IMAGES) {
let is_image = matches!(
prim_instance.kind,
PrimitiveInstanceKind::Image { .. } | PrimitiveInstanceKind::YuvImage { .. }
);
if is_image {
// We allow "small" images, since they're generally UI elements.
if let Some(rect) = calculate_prim_clipped_world_rect(
&prim_instance.vis.clip_chain.pic_coverage_rect,
&world_culling_rect,
&map_surface_to_world,
) {
let rect = rect * frame_context.global_device_pixel_scale;
if rect.width() > 70.0 && rect.height() > 70.0 {
frame_state.scratch.primitive.push_debug_rect(rect, debug_colors::PURPLE, debug_colors::PURPLE);
}
}
}
}
if prim_instance.is_chased() {
info!("\tvisible with {:?}", prim_instance.vis.combined_local_clip_rect);
}
// TODO(gw): This should probably be an instance method on PrimitiveInstance?
update_prim_post_visibility(
store,
prim_instance,
world_culling_rect,
&map_surface_to_world,
);
}
prim_instance.vis.combined_local_clip_rect = if pic.apply_local_clip_rect {
prim_instance.vis.clip_chain.local_clip_rect
} else {
prim_instance.clip_set.local_clip_rect
};
tile_cache.update_prim_dependencies(
prim_instance,
cluster.spatial_node_index,
// It's OK to pass the local_coverage_rect here as it's only used by primitives
// (for compositor surfaces) that don't have inflation anyway.
local_coverage_rect,
frame_context,
frame_state.data_stores,
frame_state.clip_store,
&store.pictures,
frame_state.resource_cache,
&store.color_bindings,
&frame_state.surface_stack,
&mut frame_state.composite_state,
&mut frame_state.gpu_cache,
is_root_tile_cache,
surfaces,
);
}
}
// Similar to above, pop either the clip chain or root entry off the current clip stack.
if pop_surface {
frame_state.pop_surface();
}
let pic = &mut store.pictures[pic_index.0];
pic.prim_list = prim_list;
// If the local rect changed (due to transforms in child primitives) then
// invalidate the GPU cache location to re-upload the new local rect
// and stretch size. Drop shadow filters also depend on the local rect
// size for the extra GPU cache data handle.
// TODO(gw): In future, if we support specifying a flag which gets the
// stretch size from the segment rect in the shaders, we can
// remove this invalidation here completely.
if let Some(ref rc) = pic.raster_config {
// Inflate the local bounding rect if required by the filter effect.
if pic.options.inflate_if_required {
surface_rect = rc.composite_mode.inflate_picture_rect(surface_rect, surface.scale_factors);
}
// Layout space for the picture is picture space from the
// perspective of its child primitives.
pic.precise_local_rect = surface_rect * Scale::new(1.0);
// If the precise rect changed since last frame, we need to invalidate
// any segments and gpu cache handles for drop-shadows.
// TODO(gw): Requiring storage of the `prev_precise_local_rect` here
// is a total hack. It's required because `prev_precise_local_rect`
// gets written to twice (during initial vis pass and also during
// prepare pass). The proper longer term fix for this is to make
// use of the conservative picture rect for segmenting (which should
// be done during scene building).
if pic.precise_local_rect != pic.prev_precise_local_rect {
match rc.composite_mode {
PictureCompositeMode::Filter(Filter::DropShadows(..)) => {
for handle in &pic.extra_gpu_data_handles {
frame_state.gpu_cache.invalidate(handle);
}
}
_ => {}
}
// Invalidate any segments built for this picture, since the local
// rect has changed.
pic.segments_are_valid = false;
pic.prev_precise_local_rect = pic.precise_local_rect;
}
match rc.composite_mode {
PictureCompositeMode::TileCache { .. } => {}
_ => {
@ -386,6 +582,50 @@ pub fn update_prim_visibility(
tile_cache.pop_surface();
}
}
None
} else {
let parent_surface = &frame_context.surfaces[parent_surface_index.expect("bug: no parent").0 as usize];
let map_surface_to_parent_surface = SpaceMapper::new_with_target(
parent_surface.surface_spatial_node_index,
surface.surface_spatial_node_index,
PictureRect::max_rect(),
frame_context.spatial_tree,
);
map_surface_to_parent_surface.map(&surface_rect)
}
}
fn update_prim_post_visibility(
store: &mut PrimitiveStore,
prim_instance: &mut PrimitiveInstance,
world_culling_rect: &WorldRect,
map_surface_to_world: &SpaceMapper<PicturePixel, WorldPixel>,
) {
profile_scope!("update_prim_post_visibility");
match prim_instance.kind {
PrimitiveInstanceKind::Picture { pic_index, .. } => {
let pic = &mut store.pictures[pic_index.0];
// If this picture has a surface, determine the clipped bounding rect for it to
// minimize the size of the render target that is required.
if let Some(ref mut raster_config) = pic.raster_config {
raster_config.clipped_bounding_rect = map_surface_to_world
.map(&prim_instance.vis.clip_chain.pic_coverage_rect)
.and_then(|rect| {
rect.intersection(world_culling_rect)
})
.unwrap_or(WorldRect::zero());
}
}
PrimitiveInstanceKind::TextRun { .. } => {
// Text runs can't request resources early here, as we don't
// know until TileCache::post_update() whether we are drawing
// on an opaque surface.
// TODO(gw): We might be able to detect simple cases of this earlier,
// during the picture traversal. But it's probably not worth it?
}
_ => {}
}
}
@ -436,3 +676,15 @@ pub fn compute_conservative_visible_rect(
None => clip_chain.local_clip_rect,
}
}
fn calculate_prim_clipped_world_rect(
pic_clip_rect: &PictureRect,
world_culling_rect: &WorldRect,
map_surface_to_world: &SpaceMapper<PicturePixel, WorldPixel>,
) -> Option<WorldRect> {
map_surface_to_world
.map(&pic_clip_rect)
.and_then(|world_rect| {
world_rect.intersection(world_culling_rect)
})
}

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

@ -1,14 +0,0 @@
# Ensure that we correctly calculate the UV sampling rect for the backdrop
# Similar to the mix-blend-mode-overflowing-child.html test in Gecko
---
root:
items:
- type: rect
bounds: [0, 0, 100, 100]
color: green
- type: rect
bounds: [50, 50, 100, 100]
color: green
- type: rect
bounds: [50, 50, 50, 50]
color: black

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

@ -1,18 +0,0 @@
# Ensure that we correctly calculate the UV sampling rect for the backdrop
# Similar to the mix-blend-mode-overflowing-child.html test in Gecko
---
root:
items:
- type: stacking-context
blend-container: true
items:
- type: rect
bounds: [0, 0, 100, 100]
color: green
- type: stacking-context
bounds: [50, 50, 100, 100]
mix-blend-mode: difference
items:
- type: rect
bounds: [0, 0, 100, 100]
color: green

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

@ -1,17 +0,0 @@
---
root:
items:
- type: stacking-context
blend-container: true
bounds: [0, 0, 100, 100]
items:
- type: rect
bounds: [0, 0, 100, 100]
color: [255, 0, 0]
- type: stacking-context
bounds: [0, 0, 100, 100]
mix-blend-mode: hue
items:
- type: rect
bounds: [0, 0, 100, 100]
color: [255, 255, 0]

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

@ -1,22 +0,0 @@
# verify that the clipping_rect of a child surface (caused by the identity filter)
# is corrected used to select the backdrop for a mix-blend child surface
---
root:
items:
- type: stacking-context
filters: [identity]
items:
- type: stacking-context
blend-container: true
bounds: [0, 0, 100, 100]
items:
- type: rect
bounds: [0, 0, 100, 100]
color: [255, 0, 0]
- type: stacking-context
bounds: [0, 0, 100, 100]
mix-blend-mode: hue
items:
- type: rect
bounds: [0, 0, 100, 100]
color: [255, 255, 0]

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 33 KiB

После

Ширина:  |  Высота:  |  Размер: 18 KiB

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

@ -25,5 +25,3 @@ fuzzy(2,420) == multi-mix-blend-mode.yaml multi-mix-blend-mode-ref.yaml
== mix-blend-invalid-backdrop.yaml mix-blend-invalid-backdrop-ref.yaml
platform(linux) == mix-blend-complex-transform.yaml mix-blend-complex-transform.png
== raster-roots-1.yaml raster-roots-1-ref.yaml
== child-surface.yaml child-surface-ref.yaml
== blend-overflow.yaml blend-overflow-ref.yaml

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

@ -10,7 +10,7 @@ platform(linux,mac) == segmentation-with-other-coordinate-system-clip.yaml segme
== segmentation-across-rotation.yaml segmentation-across-rotation-ref.yaml
skip_on(android,device) == color_targets(3) alpha_targets(1) stacking-context-clip.yaml stacking-context-clip-ref.yaml
== snapping.yaml snapping-ref.yaml
fuzzy(160,1055) == clip-and-filter-with-rotation.yaml clip-and-filter-with-rotation-ref.yaml
fuzzy(70,2400) == clip-and-filter-with-rotation.yaml clip-and-filter-with-rotation-ref.yaml
== clipped-occlusion.yaml clipped-occlusion-ref.yaml
== clip-empty-inner-rect.yaml clip-empty-inner-rect-ref.yaml
== iframe-nested-in-stacking-context.yaml iframe-nested-in-stacking-context-ref.yaml

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 16 KiB

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Двоичные данные
gfx/wr/wrench/reftests/filters/blend-clipped.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.1 KiB

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичные данные
gfx/wr/wrench/reftests/filters/filter-blur.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 54 KiB

После

Ширина:  |  Высота:  |  Размер: 53 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.9 KiB

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 42 KiB

После

Ширина:  |  Высота:  |  Размер: 32 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 12 KiB

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 11 KiB

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 77 KiB

После

Ширина:  |  Высота:  |  Размер: 77 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 116 KiB

После

Ширина:  |  Высота:  |  Размер: 107 KiB

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

@ -36,7 +36,7 @@ platform(linux,mac) == filter-drop-shadow-on-viewport-edge.yaml filter-drop-shad
platform(linux,mac) == blend-clipped.yaml blend-clipped.png
platform(linux,mac) == filter-drop-shadow-clip.yaml filter-drop-shadow-clip.png
fuzzy(2,10) platform(linux,mac) == filter-drop-shadow-clip-2.yaml filter-drop-shadow-clip-2.png
fuzzy(1,58) platform(linux) == filter-drop-shadow-clip-3.yaml filter-drop-shadow-clip-3.png
fuzzy(1,26) platform(linux) == filter-drop-shadow-clip-3.yaml filter-drop-shadow-clip-3.png
fuzzy(5,100000) == filter-drop-shadow-scaled.yaml filter-drop-shadow-scaled-ref.yaml
== filter-segments.yaml filter-segments-ref.yaml
== iframe-dropshadow.yaml iframe-dropshadow-ref.yaml
@ -46,10 +46,10 @@ skip_on(android,device) == filter-mix-blend-mode.yaml filter-mix-blend-mode-ref.
!= filter-blur-huge.yaml blank.yaml
!= filter-drop-shadow-huge.yaml blank.yaml
!= filter-drop-shadow-transform-huge.yaml blank.yaml
fuzzy(4,62000) == filter-drop-shadow-blur-clamping.yaml filter-drop-shadow-blur-clamping-ref.yaml
fuzzy(3,79400) == filter-drop-shadow-blur-clamping.yaml filter-drop-shadow-blur-clamping-ref.yaml
== filter-blur-scaled.yaml filter-blur-scaled-ref.yaml
fuzzy(5,72000) == filter-blur-clamping.yaml filter-blur-clamping-ref.yaml
skip_on(android,device) skip_on(win) fuzzy(1,104) fuzzy-if(platform(swgl),4,18484) == filter-blur-scaled-xonly.yaml filter-blur-scaled-xonly.png # fails on Pixel2
== filter-blur-clamping.yaml filter-blur-clamping-ref.yaml
skip_on(android,device) fuzzy(1,104) fuzzy-if(platform(swgl),4,18484) == filter-blur-scaled-xonly.yaml filter-blur-scaled-xonly.png # fails on Pixel2
== svg-filter-component-transfer.yaml filter-component-transfer-ref.yaml
== svg-filter-flood.yaml svg-filter-flood-ref.yaml
skip_on(android,device) == svg-filter-blend.yaml svg-filter-blend-ref.yaml
@ -57,7 +57,7 @@ skip_on(android,device) == svg-filter-color-matrix.yaml filter-color-matrix-ref.
platform(linux,mac) == draw_calls(8) color_targets(8) alpha_targets(0) svg-filter-blur.yaml filter-blur.png # Extra draw call is due to render task graph workaround
platform(linux,mac) == svg-filter-drop-shadow.yaml svg-filter-drop-shadow.png
== fuzzy(1,10000) svg-srgb-to-linear.yaml srgb-to-linear-ref.yaml
platform(linux,mac) == fuzzy(6,36790) svg-filter-drop-shadow-rotate.yaml svg-filter-drop-shadow-rotate-ref.yaml
platform(linux,mac) == fuzzy(5,35250) svg-filter-drop-shadow-rotate.yaml svg-filter-drop-shadow-rotate-ref.yaml
platform(linux,mac) fuzzy(3,3550) == svg-filter-blur-transforms.yaml svg-filter-blur-transforms.png
platform(linux,mac) == svg-filter-drop-shadow-on-viewport-edge.yaml svg-filter-drop-shadow-on-viewport-edge.png
fuzzy(1,1) platform(linux,mac) == svg-filter-drop-shadow-perspective.yaml svg-filter-drop-shadow-perspective.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 11 KiB

После

Ширина:  |  Высота:  |  Размер: 11 KiB

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

@ -1,13 +0,0 @@
root:
items:
- type: stacking-context
bounds: [0, 0, 1920, 1200]
transform: translate(-45, 7)
items:
- type: stacking-context
filters: [opacity(0.9)]
items:
- text: "This should be pixel aligned!"
origin: 416.543499 160.008325
size: 16

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

@ -1,14 +0,0 @@
# Verify that a fractional transform that is attached to an off-screen
# surface is able to snap correctly
root:
items:
- type: stacking-context
bounds: [0, 0, 1920, 1200]
transform: translate(-45, 7.491675)
items:
- type: stacking-context
filters: [opacity(0.9)]
items:
- text: "This should be pixel aligned!"
origin: 416.543499 160.008325
size: 16

Двоичные данные
gfx/wr/wrench/reftests/snap/preserve-3d.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 6.4 KiB

После

Ширина:  |  Высота:  |  Размер: 6.7 KiB

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

@ -2,4 +2,3 @@ platform(linux,mac) == snap.yaml snap.png
== transform.yaml transform.png
platform(linux,mac) == preserve-3d.yaml preserve-3d.png
fuzzy(128,200) == subpixel-raster-root.yaml subpixel-raster-root-ref.yaml
platform(linux,mac) == fractional-filter.yaml fractional-filter-ref.yaml

Двоичные данные
gfx/wr/wrench/reftests/split/same-plane.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 4.8 KiB

После

Ширина:  |  Высота:  |  Размер: 4.2 KiB

Двоичные данные
gfx/wr/wrench/reftests/text/raster-space.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 61 KiB

После

Ширина:  |  Высота:  |  Размер: 61 KiB

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

@ -81,5 +81,5 @@ fuzzy(1,15) platform(linux) force_subpixel_aa_where_possible(false) == text-fixe
# most pixels are off by a small amount, but a few pixels on the edge vary by a lot, pushing up the fuzzy max-diff;
# the main goal of the test is that everything is in the same place, at the same scale, clipped the same way,
# despite 4x on-the-fly scale change.
skip_on(android) fuzzy(215,7600) == raster_root_C_8192.yaml raster_root_C_ref.yaml
skip_on(android) fuzzy-range(<=3,*21700,<=20,*3500,<=119,*590) fuzzy-if(platform(swgl),108,24907) == raster_root_C_8192.yaml raster_root_C_ref.yaml
== subpx-bg-mask.yaml subpx-bg-mask-ref.yaml

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 93 KiB

После

Ширина:  |  Высота:  |  Размер: 93 KiB

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

@ -3,7 +3,7 @@ root:
items:
- type: stacking-context
transform-style: preserve-3d
transform: scale(-2, 44, 1)
transform: scale(-2, 44, 44727)
items:
- type: rect
bounds: [ -100, -100, 200, 101 ]

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 225 KiB

После

Ширина:  |  Высота:  |  Размер: 226 KiB

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

@ -1822,7 +1822,7 @@ pref(layout.css.caption-side-non-standard.enabled,true) == 1062963-floatmanager-
== 1069716-1.html 1069716-1-ref.html
== 1078262-1.html about:blank # bug 1656792
test-pref(layout.testing.overlay-scrollbars.always-visible,false) == 1081072-1.html 1081072-1-ref.html
fuzzy(15-32,500-650) fuzzy-if(useDrawSnapshot,33-33,218-218) == 1081185-1.html 1081185-1-ref.html
fuzzy(63-64,142-845) fuzzy-if(useDrawSnapshot,33-33,218-218) == 1081185-1.html 1081185-1-ref.html
== 1097437-1.html 1097437-1-ref.html
== 1103258-1.html 1103258-1-ref.html # assertion crash test with layers culling test
== 1105137-1.html 1105137-1-ref.html
@ -2058,7 +2058,7 @@ pref(layout.css.supports-selector.enabled,false) != 1499386.html 1499386-ref.htm
== 1513423-2.html 1513423-2-ref.html
== 1513423-3.html 1513423-3-ref.html
pref(layout.accessiblecaret.enabled,true) == 1517385.html 1517385-ref.html
fuzzy(0-5,0-2300) == 1529992-1.html 1529992-1-ref.html
fuzzy-if(winWidget&&swgl,1-1,12-16) fuzzy-if(cocoaWidget&&swgl,1-1,32-32) fuzzy-if(useDrawSnapshot,2-2,209-209) == 1529992-1.html 1529992-1-ref.html
fuzzy-if(Android,9-14,44-60) fails-if(!useDrawSnapshot) == 1529992-2.html 1529992-2-ref.html
== 1535040-1.html 1535040-1-ref.html
== 1545360-1.xhtml 1545360-1-ref.xhtml

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

@ -16,7 +16,7 @@ random-if(d2d) fuzzy-if(!useDrawSnapshot,255-255,39-42) == element-paint-transfo
fuzzy-if(d2d&&/^Windows\x20NT\x206\.1/.test(http.oscpu),0-16,0-90) == element-paint-background-size-01.html element-paint-background-size-01-ref.html
== element-paint-background-size-02.html element-paint-background-size-02-ref.html
fuzzy(0-255,0-4) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == element-paint-transform-repeated.html element-paint-transform-repeated-ref.html # Bug 1475907
fuzzy-if(d2d,0-255,0-24) fuzzy-if(!useDrawSnapshot,200-255,80-110) == element-paint-transform-03.html element-paint-transform-03-ref.html
fuzzy-if(d2d,0-255,0-24) fuzzy-if(!useDrawSnapshot,255-255,56-72) == element-paint-transform-03.html element-paint-transform-03-ref.html
# For !nativeThemePref: element() uses fallback / skia in WebRender, which antialiases differently from WR.
# For !nativeThemePref+Windows+WebRender: bug 1496542, the scrollframe snaps differently.

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

@ -2,6 +2,6 @@
# e.g. filter: blur(3px) grayscale(0.5) invert(0.2);
# Some platforms render this complex filter chain a little differently, and that's ok.
fuzzy(4-6,12000-19950) fuzzy-if(swgl,5-10,13600-20260) == long-chain.html long-chain-ref.html # Win10: Bug 1258241
fuzzy(4-6,12000-19484) fuzzy-if(swgl,5-10,13600-20088) == long-chain.html long-chain-ref.html # Win10: Bug 1258241
== moz-element.html moz-element-ref.html
fuzzy-if(!useDrawSnapshot,13-15,7670-7982) fuzzy-if(!useDrawSnapshot&&swgl,11-12,14052-14056) == same-filter.html same-filter-ref.html

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

@ -86,7 +86,7 @@ fails == filter-marked-line-01.svg pass.svg # bug 477704
== filter-marked-line-08.svg pass.svg
== filter-marked-line-09.svg pass.svg
== filter-nested-filtering-01.svg pass.svg
fuzzy(0-10,0-1200) == filter-nested-filtering-02.svg pass.svg
== filter-nested-filtering-02.svg pass.svg
== filter-patterned-rect-01.svg pass.svg
== filter-patterned-rect-02.svg pass.svg
== filter-region-01a.html pass.svg
@ -107,7 +107,7 @@ fuzzy(0-1,0-400) == feDisplacementMap-alpha-01.svg pass.svg
fuzzy(0-2,0-500) == feDisplacementMap-colour-01.svg feDisplacementMap-colour-01-ref.svg
== feDisplacementMap-scale-01.svg pass.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-2,0-25) fuzzy-if(!useDrawSnapshot,55-98,14033-16360) == feDropShadow-01.svg feDropShadow-01-ref.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-2,0-25) fuzzy-if(!useDrawSnapshot,55-98,14033-16345) == feDropShadow-01.svg feDropShadow-01-ref.svg
== feFlood-color-01.svg pass.svg

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

@ -4,13 +4,13 @@
== clip-input.svg clip-input-ref.svg
== clip-original-SourceGraphic.svg clip-original-SourceGraphic-ref.svg
== clip-output.svg clip-output-ref.svg
fuzzy(0-5,0-20300) == default-subregion.svg default-subregion-ref.svg
fuzzy(0-5,0-20155) == default-subregion.svg default-subregion-ref.svg
== different-FillPaint-filter-regions.svg different-FillPaint-filter-regions-ref.svg
== different-StrokePaint-filter-regions.svg different-StrokePaint-filter-regions-ref.svg
== dont-clip-previous-primitives.svg dont-clip-previous-primitives-ref.svg
== intersecting-filter-regions.svg intersecting-filter-regions-ref.svg
fuzzy-if(!useDrawSnapshot,9-9,5168-5536) fuzzy-if(!useDrawSnapshot&&swgl,7-7,13170-13184) == long-chain.svg simple-chain-ref.svg
fuzzy-if(!useDrawSnapshot,9-9,5168-5536) fuzzy-if(!useDrawSnapshot&&swgl,7-7,13170-13184) == multiple-primitives-per-filter.svg simple-chain-ref.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-173) fuzzy-if(!useDrawSnapshot||(winWidget&&isCoverageBuild),9-9,5128-5496) fuzzy-if(!useDrawSnapshot&&swgl,7-7,12820-12830) == second-filter-uses-SourceAlpha.svg second-filter-uses-SourceAlpha-ref.svg
fuzzy-if(!useDrawSnapshot,9-9,5168-5536) fuzzy-if(!useDrawSnapshot&&swgl,7-7,13170-13180) == second-filter-uses-SourceGraphic.svg simple-chain-ref.svg
fuzzy-if(!useDrawSnapshot,9-9,5168-5536) fuzzy-if(!useDrawSnapshot&&swgl,7-7,13184-13184) == long-chain.svg simple-chain-ref.svg
fuzzy-if(!useDrawSnapshot,9-9,5168-5536) fuzzy-if(!useDrawSnapshot&&swgl,7-7,13184-13184) == multiple-primitives-per-filter.svg simple-chain-ref.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-173) fuzzy-if(!useDrawSnapshot||(winWidget&&isCoverageBuild),9-9,5128-5496) fuzzy-if(!useDrawSnapshot&&swgl,7-7,12836-12836) == second-filter-uses-SourceAlpha.svg second-filter-uses-SourceAlpha-ref.svg
fuzzy-if(!useDrawSnapshot,9-9,5168-5536) fuzzy-if(!useDrawSnapshot&&swgl,7-7,13184-13184) == second-filter-uses-SourceGraphic.svg simple-chain-ref.svg
== simple-chain.svg simple-chain-ref.svg

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

@ -3,7 +3,7 @@ random-if(Android) == chrome://reftest/content/text-shadow/basic-negcoord.xhtml
!= chrome://reftest/content/text-shadow/blur.xhtml chrome://reftest/content/text-shadow/blur-notref.xhtml
== chrome://reftest/content/text-shadow/color-inherit.xhtml chrome://reftest/content/text-shadow/color-inherit-ref.xhtml
== chrome://reftest/content/text-shadow/multiple-noblur.xhtml chrome://reftest/content/text-shadow/multiple-noblur-ref.xhtml
fuzzy(0-2,0-6400) random-if(useDrawSnapshot) == blur-opacity.html blur-opacity-ref.html
fuzzy-if(swgl&&!Android,2-2,6320-6320) random-if(useDrawSnapshot) == blur-opacity.html blur-opacity-ref.html
fuzzy-if(cocoaWidget,0-27,0-2) fuzzy-if(winWidget,0-47,0-2) == overflow-clip.html overflow-clip-ref.html

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

@ -72,8 +72,8 @@ fuzzy(0-3,0-99) == animate-cube-degrees.html animate-cube-degrees-ref.html # sub
fails-if(useDrawSnapshot) == animate-cube-degrees-zoom.html animate-cube-degrees-zoom-ref.html
!= animate-cube-degrees-ref.html animate-cube-degrees-zoom-ref.html
fuzzy-if(gtkWidget,0-128,0-100) fuzzy-if(Android||OSX==1010||(gtkWidget&&layersGPUAccelerated),0-143,0-100) fuzzy-if(winWidget||OSX,0-141,0-100) == preserves3d-nested.html preserves3d-nested-ref.html
fuzzy(0-255,0-38) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == animate-preserve3d-parent.html animate-preserve3d-ref.html # intermittently fuzzy on Mac
fuzzy(0-255,0-38) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == animate-preserve3d-child.html animate-preserve3d-ref.html # intermittently fuzzy on Mac, bug 1461311 for Android
fuzzy(0-255,0-29) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == animate-preserve3d-parent.html animate-preserve3d-ref.html # intermittently fuzzy on Mac
fuzzy(0-255,0-29) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == animate-preserve3d-child.html animate-preserve3d-ref.html # intermittently fuzzy on Mac, bug 1461311 for Android
== animate-backface-hidden.html about:blank
== 1245450-1.html green-rect.html
fuzzy(0-1,0-2000) == opacity-preserve3d-1.html opacity-preserve3d-1-ref.html
@ -82,9 +82,9 @@ fuzzy(0-1,0-10000) == opacity-preserve3d-3.html opacity-preserve3d-3-ref.html
fuzzy(0-1,0-10000) == opacity-preserve3d-4.html opacity-preserve3d-4-ref.html
== opacity-preserve3d-5.html opacity-preserve3d-5-ref.html
== snap-perspective-1.html snap-perspective-1-ref.html
fuzzy(0-120,0-590) == mask-layer-1.html mask-layer-ref.html
fuzzy(0-120,0-590) == mask-layer-2.html mask-layer-ref.html
fuzzy(0-120,0-590) == mask-layer-3.html mask-layer-ref.html
fuzzy-if(Android,0-8,0-1) == mask-layer-1.html mask-layer-ref.html
fuzzy-if(Android,0-8,0-1) == mask-layer-2.html mask-layer-ref.html
fuzzy(0-16,0-132) == mask-layer-3.html mask-layer-ref.html
== split-intersect1.html split-intersect1-ref.html
fuzzy(0-255,0-150) fails-if(useDrawSnapshot) == split-intersect2.html split-intersect2-ref.html
fuzzy(0-255,0-100) fails-if(useDrawSnapshot) == split-non-ortho1.html split-non-ortho1-ref.html
@ -94,7 +94,7 @@ fuzzy-if(winWidget&&!nativeThemePref,0-4,0-51) == transform-geometry-1.html tran
== intermediate-1.html intermediate-1-ref.html
== preserves3d-nested-filter-1.html preserves3d-nested-filter-1-ref.html
!= preserve3d-scale.html about:blank
fuzzy(0-50,0-1550) == preserve3d-scale.html preserve3d-scale-ref.html
fuzzy(0-51,0-1154) == preserve3d-scale.html preserve3d-scale-ref.html
fuzzy(0-1,0-5) == perspective-overflow-1.html perspective-overflow-1-ref.html
== perspective-overflow-2.html perspective-overflow-2-ref.html
== 1544995-1.html 1544995-1-ref.html

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

@ -138,7 +138,7 @@ fuzzy(0-2,0-5) == stresstest-1.html stresstest-1-ref.html
== transform-origin-svg-2b.svg transform-origin-svg-2-ref.svg
# Bug 1122526
== animate-layer-scale-inherit-1.html animate-layer-scale-inherit-1-ref.html
fuzzy(0-150,0-10000) == animate-layer-scale-inherit-2.html animate-layer-scale-inherit-2-ref.html
fuzzy(0-1,0-4500) == animate-layer-scale-inherit-2.html animate-layer-scale-inherit-2-ref.html
== animate-layer-scale-inherit-3.html animate-layer-scale-inherit-1-ref.html
# Bug 1301500
== dynamic-add-without-change-cb-1.html dynamic-add-without-change-cb-1-ref.html
@ -159,13 +159,13 @@ test-pref(layout.css.zoom-transform-hack.enabled,true) == zoom-hack-2.html zoom-
== transform-anon-block-1.html transform-anon-block-1-ref.html
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) == partial-prerender-expansion-translate.html partial-prerender-expansion-ref.html
test-pref(layout.animation.prerender.partial,true) == partial-prerender-translate-1.html about:blank
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") fuzzy-if(Android,0-255,0-7000) == partial-prerender-translate-2.html partial-prerender-translate-2-ref.html
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-translate-2.html partial-prerender-translate-2-ref.html
fails-if(!useDrawSnapshot) test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-translate-3.html partial-prerender-translate-3-ref.html # bug 1642575
# This reftest doesn't fail on WebRender, this reftest fails only if there is a jank mechanism and the mechanism doesn't properly handle ancestor's transform values
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-translate-4.html partial-prerender-expansion-ref.html
# This reftest doesn't fail on WebRender, this reftest fails only if there is a jank mechanism and the mechanism does inproperly handle position:fixed scroll target
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-translate-5.html partial-prerender-translate-5-ref.html
random-if(useDrawSnapshot) test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") fuzzy-if(Android,0-255,0-9900) == partial-prerender-translate-6.html partial-prerender-translate-6-ref.html
random-if(useDrawSnapshot) test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-translate-6.html partial-prerender-translate-6-ref.html
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-translate-7.html partial-prerender-translate-2-ref.html
# This reftest doesn't fail on WebRender, this reftest fails only if there is a jank mechanism and the mechanism doesn't properly clip transform in iframes.
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-translate-8.html partial-prerender-translate-8-ref.html
@ -179,6 +179,6 @@ skip test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.an
skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)||Android) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") fuzzy-if(!layersGPUAccelerated,0-75,0-2683) == partial-prerender-expansion-rotate.html partial-prerender-expansion-ref.html
skip-if(useDrawSnapshot) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") pref(dom.meta-viewport.enabled,true) pref(apz.allow_zooming,true) == partial-prerender-expansion-with-resolution-1.html partial-prerender-expansion-with-resolution-ref.html
skip test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") pref(dom.meta-viewport.enabled,true) pref(apz.allow_zooming,true) == partial-prerender-expansion-with-resolution-2.html partial-prerender-expansion-with-resolution-ref.html # bug 1650039 for WebRender
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") fuzzy-if(Android,0-255,0-400) == partial-prerender-in-svg-1.html partial-prerender-in-svg-1-ref.html
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-in-svg-1.html partial-prerender-in-svg-1-ref.html
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-in-svg-2.html partial-prerender-in-svg-1-ref.html # Reuse partial-prerender-in-svg-1-ref.html since the result should look same as partial-prerender-in-svg-1.html
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") fuzzy-if(Android,0-255,0-2000) == partial-prerender-in-svg-3.html partial-prerender-in-svg-3-ref.html
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) test-pref(layout.animation.prerender.viewport-ratio-limit,"1.125") == partial-prerender-in-svg-3.html partial-prerender-in-svg-3-ref.html

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

@ -1,3 +0,0 @@
[mix-blend-mode-both-parent-and-blended-with-3D-transform.html]
fuzzy:
maxDifference=94-95;totalPixels=340-460

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

@ -1,3 +0,0 @@
[mix-blend-mode-parent-with-3D-transform.html]
fuzzy:
maxDifference=60-61;totalPixels=140-140

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

@ -0,0 +1,3 @@
[mix-blend-mode-rotated-clip.html]
expected:
FAIL

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

@ -1,5 +1,3 @@
[transform3d-preserve3d-001.html]
fuzzy:
if os == "android": maxDifference=4;totalPixels=185
if os == "mac": maxDifference=198;totalPixels=308
if os == "win": maxDifference=174;totalPixels=240
expected:
if os == "win": FAIL