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)
|
@ -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]
|
Двоичные данные
gfx/wr/wrench/reftests/blend/mix-blend-complex-transform.png
До Ширина: | Высота: | Размер: 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
|
||||
|
|
Двоичные данные
gfx/wr/wrench/reftests/filters/blend-clipped-raster-root.png
До Ширина: | Высота: | Размер: 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 |
Двоичные данные
gfx/wr/wrench/reftests/filters/filter-drop-shadow-clip-2.png
До Ширина: | Высота: | Размер: 2.9 KiB После Ширина: | Высота: | Размер: 3.0 KiB |
Двоичные данные
gfx/wr/wrench/reftests/filters/filter-drop-shadow-clip-3.png
До Ширина: | Высота: | Размер: 42 KiB После Ширина: | Высота: | Размер: 32 KiB |
Двоичные данные
gfx/wr/wrench/reftests/filters/filter-drop-shadow-clip.png
До Ширина: | Высота: | Размер: 12 KiB После Ширина: | Высота: | Размер: 12 KiB |
До Ширина: | Высота: | Размер: 11 KiB После Ширина: | Высота: | Размер: 10 KiB |
Двоичные данные
gfx/wr/wrench/reftests/filters/filter-drop-shadow.png
До Ширина: | Высота: | Размер: 77 KiB После Ширина: | Высота: | Размер: 77 KiB |
Двоичные данные
gfx/wr/wrench/reftests/filters/filter-large-blur-radius.png
До Ширина: | Высота: | Размер: 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
|
||||
|
|
Двоичные данные
gfx/wr/wrench/reftests/text/shadow-transforms.png
До Ширина: | Высота: | Размер: 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 ]
|
||||
|
|
Двоичные данные
gfx/wr/wrench/reftests/transforms/screen-space-blur.png
До Ширина: | Высота: | Размер: 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
|
||||
|
|