Bug 1575258 - Make text rasterize, render and snap glyphs consistently. r=lsalzman

The glyph pixel space in which we rasterized glyphs differed from how we
rendered the rasterized glyphs in the shader. They need to be in
agreement because the glyph subpixel offset selected during
rasterization depends on it. This patch should make the paths consistent
with each other.

Additionally, during animations, we now snap the reference frame
relative offset ignoring the impact of any animated transforms. This
helps with minimizing glyph wiggling during the transition.

Differential Revision: https://phabricator.services.mozilla.com/D51305

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrew Osmond 2019-11-06 12:17:43 +00:00
Родитель a5506dd31a
Коммит 7243a387ca
26 изменённых файлов: 184 добавлений и 96 удалений

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

@ -75,66 +75,40 @@ TextRun fetch_text_run(int address) {
VertexInfo write_text_vertex(RectWithSize local_clip_rect,
float z,
int raster_space,
#ifdef WR_FEATURE_GLYPH_TRANSFORM
mat2 glyph_transform,
#else
float glyph_scale,
#endif
Transform transform,
PictureTask task,
vec2 text_offset,
vec2 glyph_offset,
RectWithSize glyph_rect,
vec2 snap_bias) {
// The offset to snap the glyph rect to a device pixel
vec2 snap_offset = vec2(0.0);
// Transform from glyph space to local space
mat2 glyph_transform_inv = mat2(1.0);
// Glyph space refers to the pixel space used by glyph rasterization during frame
// building. If a non-identity transform was used, WR_FEATURE_GLYPH_TRANSFORM will
// be set. Otherwise, regardless of whether the raster space is LOCAL or SCREEN,
// we ignored the transform during glyph rasterization, and need to snap just using
// the device pixel scale and the raster scale.
#ifdef WR_FEATURE_GLYPH_TRANSFORM
bool remove_subpx_offset = true;
#else
bool remove_subpx_offset = transform.is_axis_aligned;
#endif
// Compute the snapping offset only if the scroll node transform is axis-aligned.
if (remove_subpx_offset) {
// Be careful to only snap with the transform when in screen raster space.
switch (raster_space) {
case RASTER_SCREEN: {
// Transform from local space to glyph space.
float device_scale = task.device_pixel_scale / transform.m[3].w;
mat2 glyph_transform = mat2(transform.m) * device_scale;
// Transform from glyph space back to local space.
mat2 glyph_transform_inv = inverse(glyph_transform);
// Ensure the transformed text offset does not contain a subpixel translation
// such that glyph snapping is stable for equivalent glyph subpixel positions.
vec2 device_text_pos = glyph_transform * text_offset + transform.m[3].xy * device_scale;
snap_offset = floor(device_text_pos + 0.5) - device_text_pos;
// Glyph raster pixels include the impact of the transform. This path can only be
// entered for 3d transforms that can be coerced into a 2d transform; they have no
// perspective, and have a 2d inverse. This is a looser condition than axis aligned
// transforms because it also allows 2d rotations.
vec2 raster_glyph_offset = glyph_transform * glyph_offset;
vec2 raster_snap_offset = floor(raster_glyph_offset + snap_bias) - raster_glyph_offset;
vec2 local_snap_offset = glyph_transform_inv * raster_snap_offset;
// Snap the glyph offset to a device pixel, using an appropriate bias depending
// on whether subpixel positioning is required.
vec2 device_glyph_offset = glyph_transform * glyph_offset;
snap_offset += floor(device_glyph_offset + snap_bias) - device_glyph_offset;
// We want to eliminate any subpixel translation in device space to ensure glyph
// snapping is stable for equivalent glyph subpixel positions. Note that we must use
// device pixels, and not glyph raster pixels for this purpose.
vec2 device_text_pos = (transform.m * vec4(text_offset, 0.0, 1.0)).xy * task.device_pixel_scale;
vec2 device_snap_offset = floor(device_text_pos + 0.5) - device_text_pos;
// Transform from glyph space back to local space.
glyph_transform_inv = inverse(glyph_transform);
#ifndef WR_FEATURE_GLYPH_TRANSFORM
// If not using transformed subpixels, the glyph rect is actually in local space.
// So convert the snap offset back to local space.
snap_offset = glyph_transform_inv * snap_offset;
#endif
break;
}
default: {
// Otherwise, when in local raster space, the transform may be animated, so avoid
// snapping with the transform to avoid oscillation.
snap_offset = floor(text_offset + 0.5) - text_offset;
snap_offset += floor(glyph_offset + snap_bias) - glyph_offset;
break;
}
}
}
// Actually translate the glyph rect to a device pixel using the snap offset.
glyph_rect.p0 += snap_offset;
#ifdef WR_FEATURE_GLYPH_TRANSFORM
// The glyph rect is in device space, so transform it back to local space.
RectWithSize local_rect = transform_rect(glyph_rect, glyph_transform_inv);
@ -148,6 +122,29 @@ VertexInfo write_text_vertex(RectWithSize local_clip_rect,
local_pos = glyph_transform_inv * (glyph_rect.p0 + glyph_rect.size * aPosition.xy);
}
#else
// Glyph raster pixels do not include the impact of the transform. Instead it was
// replaced with an identity transform during glyph rasterization. As such only the
// impact of the raster scale (if in local space) and the device pixel scale (for both
// local and screen space) are included.
//
// This implies one or more of the following conditions:
// - The transform is an identity. In that case, setting WR_FEATURE_GLYPH_TRANSFORM
// should have the same output result as not. We just distingush which path to use
// based on the transform used during glyph rasterization. (Screen space).
// - The transform contains an animation. We will imply local raster space in such
// cases to avoid constantly rerasterizing the glyphs.
// - The transform has perspective or does not have a 2d inverse (Screen or local space).
// - The transform's scale will result in result in very large rasterized glyphs and
// we clamped the size. This will imply local raster space.
vec2 raster_glyph_offset = glyph_offset * glyph_scale;
vec2 raster_snap_offset = floor(raster_glyph_offset + snap_bias) - raster_glyph_offset;
vec2 local_snap_offset = raster_snap_offset / glyph_scale;
// The transform may be animated, so we don't want to do any snapping here for the
// text offset to avoid glyphs wiggling. The text offset should have been snapped
// already for axis aligned transforms excluding any animations during frame building.
vec2 device_snap_offset = vec2(0.0);
// Select the corner of the glyph rect that we are processing.
vec2 local_pos = glyph_rect.p0 + glyph_rect.size * aPosition.xy;
#endif
@ -158,15 +155,17 @@ VertexInfo write_text_vertex(RectWithSize local_clip_rect,
// Map the clamped local space corner into device space.
vec4 world_pos = transform.m * vec4(local_pos, 0.0, 1.0);
vec2 device_pos = world_pos.xy * task.device_pixel_scale;
vec4 snapped_world_pos = transform.m * vec4(local_pos + local_snap_offset, 0.0, 1.0);
vec2 snapped_device_pos = snapped_world_pos.xy * task.device_pixel_scale + device_snap_offset * snapped_world_pos.w;
// Apply offsets for the render task to get correct screen location.
vec2 final_offset = -task.content_origin + task.common_data.task_rect.p0;
gl_Position = uTransform * vec4(device_pos + final_offset * world_pos.w, z * world_pos.w, world_pos.w);
gl_Position = uTransform * vec4(snapped_device_pos + final_offset * world_pos.w, z * world_pos.w, world_pos.w);
VertexInfo vi = VertexInfo(
local_pos,
snap_offset,
snapped_device_pos - device_pos,
world_pos
);
@ -186,8 +185,6 @@ void main(void) {
ClipArea clip_area = fetch_clip_area(instance.clip_address);
PictureTask task = fetch_picture_task(instance.picture_task_address);
int raster_space = ph.user_data.w;
TextRun text = fetch_text_run(ph.specific_prim_address);
vec2 text_offset = vec2(ph.user_data.xy) / 256.0;
@ -211,11 +208,12 @@ void main(void) {
float raster_scale = float(ph.user_data.z) / 65535.0;
// Scale from glyph space to local space.
float scale = res.scale / (raster_scale * task.device_pixel_scale);
float glyph_scale_inv = res.scale / (raster_scale * task.device_pixel_scale);
float glyph_scale = 1.0 / glyph_scale_inv;
// Compute the glyph rect in local space.
RectWithSize glyph_rect = RectWithSize(scale * res.offset + text_offset + glyph.offset,
scale * (res.uv_rect.zw - res.uv_rect.xy));
RectWithSize glyph_rect = RectWithSize(glyph_scale_inv * res.offset + text_offset + glyph.offset,
glyph_scale_inv * (res.uv_rect.zw - res.uv_rect.xy));
#endif
vec2 snap_bias;
@ -245,14 +243,17 @@ void main(void) {
VertexInfo vi = write_text_vertex(ph.local_clip_rect,
ph.z,
raster_space,
#ifdef WR_FEATURE_GLYPH_TRANSFORM
glyph_transform,
#else
glyph_scale,
#endif
transform,
task,
text_offset,
glyph.offset,
glyph_rect,
snap_bias);
glyph_rect.p0 += vi.snap_offset;
#ifdef WR_FEATURE_GLYPH_TRANSFORM
vec2 f = (glyph_transform * vi.local_pos - glyph_rect.p0) / glyph_rect.size;

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

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{AlphaType, ClipMode, ExternalImageType, ImageRendering};
use api::{YuvColorSpace, YuvFormat, ColorDepth, ColorRange, PremultipliedColorF, RasterSpace};
use api::{YuvColorSpace, YuvFormat, ColorDepth, ColorRange, PremultipliedColorF};
use api::units::*;
use crate::clip::{ClipDataStore, ClipNodeFlags, ClipNodeRange, ClipItemKind, ClipStore};
use crate::clip_scroll_tree::{ClipScrollTree, ROOT_SPATIAL_NODE_INDEX, SpatialNodeIndex, CoordinateSystemId};
@ -879,19 +879,15 @@ impl BatchBuilder {
};
let glyph_keys = &ctx.scratch.glyph_keys[run.glyph_keys_range];
let rasterization_space = match run.raster_space {
RasterSpace::Screen => RasterizationSpace::Screen,
RasterSpace::Local(..) => RasterizationSpace::Local,
};
let raster_scale = run.raster_space.local_scale().unwrap_or(1.0).max(0.001);
let prim_header_index = prim_headers.push(
&prim_header,
z_id,
[
(run.reference_frame_relative_offset.x * 256.0) as i32,
(run.reference_frame_relative_offset.y * 256.0) as i32,
(run.snapped_reference_frame_relative_offset.x * 256.0) as i32,
(run.snapped_reference_frame_relative_offset.y * 256.0) as i32,
(raster_scale * 65535.0).round() as i32,
(rasterization_space as i32),
0,
],
);
let base_instance = GlyphInstance::new(

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

@ -16,7 +16,7 @@ use crate::clip::{ClipDataStore, ClipNodeFlags, ClipChainId, ClipChainInstance,
use crate::debug_colors;
use crate::debug_render::DebugItem;
use crate::scene_building::{CreateShadow, IsVisible};
use euclid::{SideOffsets2D, Transform3D, Rect, Scale, Size2D, Point2D};
use euclid::{SideOffsets2D, Transform3D, Rect, Scale, Size2D, Point2D, Vector2D};
use euclid::approxeq::ApproxEq;
use crate::frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState};
use crate::frame_builder::{FrameVisibilityContext, FrameVisibilityState};
@ -52,7 +52,7 @@ use std::{cmp, fmt, hash, ops, u32, usize, mem};
use std::sync::atomic::{AtomicUsize, Ordering};
use crate::storage;
use crate::texture_cache::TEXTURE_REGION_DIMENSIONS;
use crate::util::{MatrixHelpers, MaxRect, Recycler, ScaleOffset, RectHelpers};
use crate::util::{MatrixHelpers, MaxRect, Recycler, ScaleOffset, RectHelpers, VectorHelpers};
use crate::util::{clamp_to_scale_factor, pack_as_float, project_rect, raster_rect_to_device_pixels};
use crate::internal_types::{LayoutPrimitiveInfo, Filter};
use smallvec::SmallVec;
@ -205,6 +205,17 @@ impl SpaceSnapper {
}
}
pub fn snap_vector<F>(&self, vector: &Vector2D<f32, F>) -> Vector2D<f32, F> where F: fmt::Debug {
debug_assert!(self.current_target_spatial_node_index != SpatialNodeIndex::INVALID);
match self.snapping_transform {
Some(ref scale_offset) => {
let snapped_device_vector : DeviceVector2D = scale_offset.map_vector(&vector).snap();
scale_offset.unmap_vector(&snapped_device_vector)
}
None => *vector,
}
}
pub fn snap_size<F>(&self, size: &Size2D<f32, F>) -> Size2D<f32, F> where F: fmt::Debug {
debug_assert!(self.current_target_spatial_node_index != SpatialNodeIndex::INVALID);
match self.snapping_transform {
@ -2911,11 +2922,13 @@ impl PrimitiveStore {
&prim_data.glyphs,
&transform.to_transform().with_destination::<_>(),
surface,
prim_spatial_node_index,
raster_space,
pic_context.subpixel_mode,
frame_state.resource_cache,
frame_state.gpu_cache,
frame_state.render_tasks,
frame_context.clip_scroll_tree,
scratch,
);

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

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{ColorF, GlyphInstance, RasterSpace, Shadow};
use api::units::{DevicePixelScale, LayoutToWorldTransform, LayoutVector2D};
use api::units::{LayoutToWorldTransform, LayoutVector2D};
use crate::scene_building::{CreateShadow, IsVisible};
use crate::frame_builder::FrameBuildingState;
use crate::glyph_rasterizer::{FontInstance, FontTransform, GlyphKey, FONT_SIZE_LIMIT};
@ -17,7 +17,8 @@ use crate::render_task_graph::RenderTaskGraph;
use crate::renderer::{MAX_VERTEX_TEXTURE_WIDTH};
use crate::resource_cache::{ResourceCache};
use crate::util::{MatrixHelpers};
use crate::prim_store::{InternablePrimitive, PrimitiveInstanceKind};
use crate::prim_store::{InternablePrimitive, PrimitiveInstanceKind, SpaceSnapper};
use crate::clip_scroll_tree::{ClipScrollTree, SpatialNodeIndex};
use std::ops;
use std::sync::Arc;
use crate::storage;
@ -174,6 +175,7 @@ impl InternablePrimitive for TextRun {
used_font: key.font.clone(),
glyph_keys_range: storage::Range::empty(),
reference_frame_relative_offset,
snapped_reference_frame_relative_offset: reference_frame_relative_offset,
shadow: key.shadow,
raster_space: RasterSpace::Screen,
});
@ -212,6 +214,7 @@ pub struct TextRunPrimitive {
pub used_font: FontInstance,
pub glyph_keys_range: storage::Range<GlyphKey>,
pub reference_frame_relative_offset: LayoutVector2D,
pub snapped_reference_frame_relative_offset: LayoutVector2D,
pub shadow: bool,
pub raster_space: RasterSpace,
}
@ -220,10 +223,12 @@ impl TextRunPrimitive {
pub fn update_font_instance(
&mut self,
specified_font: &FontInstance,
device_pixel_scale: DevicePixelScale,
surface: &SurfaceInfo,
spatial_node_index: SpatialNodeIndex,
transform: &LayoutToWorldTransform,
subpixel_mode: SubpixelMode,
raster_space: RasterSpace,
clip_scroll_tree: &ClipScrollTree,
) -> bool {
// If local raster space is specified, include that in the scale
// of the glyphs that get rasterized.
@ -235,7 +240,7 @@ impl TextRunPrimitive {
let raster_scale = raster_space.local_scale().unwrap_or(1.0).max(0.001);
// Get the current font size in device pixels
let mut device_font_size = specified_font.size.scale_by(device_pixel_scale.0 * raster_scale);
let mut device_font_size = specified_font.size.scale_by(surface.device_pixel_scale.0 * raster_scale);
// Determine if rasterizing glyphs in local or screen space.
let transform_glyphs = if raster_space != RasterSpace::Screen {
@ -266,6 +271,30 @@ impl TextRunPrimitive {
// Record the raster space the text needs to be snapped in.
self.raster_space = raster_space;
// TODO(aosmond): Snapping really ought to happen during scene building
// as much as possible. This will allow clips to be already adjusted
// based on the snapping requirements of the primitive. This may affect
// complex clips that create a different task, and when we rasterize
// glyphs without the transform (because the shader doesn't have the
// snap offsets to adjust its clip). These rects are fairly conservative
// to begin with and do not appear to be causing significant issues at
// this time.
self.snapped_reference_frame_relative_offset = if !font_transform.is_identity() {
// Don't touch the reference frame relative offset. We'll let the
// shader do the snapping in device pixels.
self.reference_frame_relative_offset
} else {
// There may be an animation, so snap the reference frame relative
// offset such that it excludes the impact, if any.
let snap_to_device = SpaceSnapper::new_with_target(
surface.raster_spatial_node_index,
spatial_node_index,
surface.device_pixel_scale,
clip_scroll_tree,
);
snap_to_device.snap_vector(&self.reference_frame_relative_offset)
};
// If the transform or device size is different, then the caller of
// this method needs to know to rebuild the glyphs.
let cache_dirty =
@ -299,21 +328,23 @@ impl TextRunPrimitive {
glyphs: &[GlyphInstance],
transform: &LayoutToWorldTransform,
surface: &SurfaceInfo,
spatial_node_index: SpatialNodeIndex,
raster_space: RasterSpace,
subpixel_mode: SubpixelMode,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
render_tasks: &mut RenderTaskGraph,
clip_scroll_tree: &ClipScrollTree,
scratch: &mut PrimitiveScratchBuffer,
) {
let device_pixel_scale = surface.device_pixel_scale;
let cache_dirty = self.update_font_instance(
specified_font,
device_pixel_scale,
surface,
spatial_node_index,
transform,
subpixel_mode,
raster_space,
clip_scroll_tree,
);
if self.glyph_keys_range.is_empty() || cache_dirty {
@ -323,7 +354,7 @@ impl TextRunPrimitive {
glyphs.iter().map(|src| {
let src_point = src.point + prim_offset;
let world_offset = self.used_font.transform.transform(&src_point);
let device_offset = device_pixel_scale.transform_point(world_offset);
let device_offset = surface.device_pixel_scale.transform_point(world_offset);
GlyphKey::new(src.index, device_offset, subpx_dir)
}));
}
@ -351,5 +382,5 @@ fn test_struct_sizes() {
assert_eq!(mem::size_of::<TextRun>(), 56, "TextRun size changed");
assert_eq!(mem::size_of::<TextRunTemplate>(), 72, "TextRunTemplate size changed");
assert_eq!(mem::size_of::<TextRunKey>(), 64, "TextRunKey size changed");
assert_eq!(mem::size_of::<TextRunPrimitive>(), 72, "TextRunPrimitive size changed");
assert_eq!(mem::size_of::<TextRunPrimitive>(), 80, "TextRunPrimitive size changed");
}

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

@ -1114,6 +1114,12 @@ impl<'a> SceneBuilder<'a> {
);
}
DisplayItem::Text(ref info) => {
// TODO(aosmond): Snapping text primitives does not make much sense, given the
// primitive bounds and clip are supposed to be conservative, not definitive.
// E.g. they should be able to grow and not impact the output. However there
// are subtle interactions between the primitive origin and the glyph offset
// which appear to be significant (presumably due to some sort of accumulated
// error throughout the layers). We should fix this at some point.
let (layout, _, clip_and_scroll) = self.process_common_properties_with_bounds(
&info.common,
&info.bounds,

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

@ -246,6 +246,20 @@ impl ScaleOffset {
)
}
pub fn map_vector<F, T>(&self, vector: &Vector2D<f32, F>) -> Vector2D<f32, T> {
Vector2D::new(
vector.x * self.scale.x + self.offset.x,
vector.y * self.scale.y + self.offset.y,
)
}
pub fn unmap_vector<F, T>(&self, vector: &Vector2D<f32, F>) -> Vector2D<f32, T> {
Vector2D::new(
(vector.x - self.offset.x) / self.scale.x,
(vector.y - self.offset.y) / self.scale.y,
)
}
pub fn to_transform<F, T>(&self) -> Transform3D<f32, F, T> {
Transform3D::row_major(
self.scale.x,

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

@ -65,7 +65,7 @@ fuzzy(1,113) platform(linux) == raster-space.yaml raster-space.png
skip_on(android) skip_on(mac,>=10.14) != allow-subpixel.yaml allow-subpixel-ref.yaml # Android: we don't enable sub-px aa on this platform.
skip_on(android,device) == bg-color.yaml bg-color-ref.yaml # Fails on Pixel2
!= large-glyphs.yaml blank.yaml
== snap-text-offset.yaml snap-text-offset-ref.yaml
skip_on(android,device) == snap-text-offset.yaml snap-text-offset-ref.yaml
fuzzy(5,4435) == shadow-border.yaml shadow-solid-ref.yaml
fuzzy(5,4435) == shadow-image.yaml shadow-solid-ref.yaml
options(disable-aa) == snap-clip.yaml snap-clip-ref.yaml

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

@ -98,8 +98,8 @@ fuzzy-if(webrender,0-52,0-14) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu
== 503957-1.html 503957-1-ref.html
== 525740-1.html 525740-1-ref.html
== 536963-1.html 536963-1-ref.html
fuzzy-if(webrender,0-122,0-1) == 562169-1.html 562169-1-ref.html
fuzzy-if(webrender,0-122,0-1) == 562169-1a.html 562169-1-ref.html
fuzzy-if(webrender,0-137,0-1) == 562169-1.html 562169-1-ref.html
fuzzy-if(webrender,0-137,0-1) == 562169-1a.html 562169-1-ref.html
== 562169-2.html 562169-2-ref.html
== 562169-2a.html 562169-2-ref.html
== 562169-3.html 562169-3-ref.html
@ -158,7 +158,7 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-1a-ltr.html bra
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-1a-rtl.html brackets-1a-rtl-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-1b-ltr.html brackets-1b-ltr-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-1b-rtl.html brackets-1b-rtl-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-1c-ltr.html brackets-1c-ltr-ref.html # Bug 1392106
fuzzy-if(geckoview&&webrender,22-22,44-46) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-1c-ltr.html brackets-1c-ltr-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-1c-rtl.html brackets-1c-rtl-ref.html # Bug 1392106
fuzzy-if(Android,0-1,0-6) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2a-ltr.html brackets-2a-ltr-ref.html # Bug 1392106
fuzzy-if(cocoaWidget,0-1,0-2) fuzzy-if(Android,0-254,0-557) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2a-rtl.html brackets-2a-rtl-ref.html # Bug 1392106

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

@ -1789,7 +1789,7 @@ fuzzy-if(skiaContent,0-1,0-5) == 956513-1.svg 956513-1-ref.svg
fuzzy-if(skiaContent,0-1,0-80) == 961887-1.html 961887-1-ref.html
== 961887-2.html 961887-2-ref.html
== 961887-3.html 961887-3-ref.html
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(0-50,0-145) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-102,0-3712) fuzzy-if(webrender,0-255,0-51) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 966992-1.html 966992-1-ref.html # Bug 1392106
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(0-50,0-145) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-102,0-3712) fuzzy-if(webrender,0-255,0-180) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 966992-1.html 966992-1-ref.html # Bug 1392106
== 966510-1.html 966510-1-ref.html
== 966510-2.html 966510-2-ref.html
fuzzy-if(skiaContent,0-1,0-123) == 978911-1.svg 978911-1-ref.svg
@ -2081,7 +2081,7 @@ pref(image.downscale-during-decode.enabled,true) == 1553571-1.html 1553571-1-ref
== 1558937-1.html 1558937-1-ref.html
!= 1563484.html 1563484-notref.html
== 1563484.html 1563484-ref.html
fuzzy-if(!webrender||!winWidget,251-255,464-1613) fuzzy-if(geckoview&&webrender,251-253,1392-1401) == 1562733-rotated-nastaliq-1.html 1562733-rotated-nastaliq-1-ref.html
fuzzy-if(!webrender||!winWidget,251-255,464-1613) fuzzy-if(webrender&&winWidget,255-255,6-6) fuzzy-if(geckoview&&webrender,251-255,1392-1401) == 1562733-rotated-nastaliq-1.html 1562733-rotated-nastaliq-1-ref.html
fuzzy-if(winWidget&&webrender,0-31,0-3) fuzzy-if(geckoview&&webrender,0-93,0-87) == 1562733-rotated-nastaliq-2.html 1562733-rotated-nastaliq-2-ref.html
test-pref(plain_text.wrap_long_lines,false) != 1565129.txt 1565129.txt
fuzzy(0-32,0-8) fuzzy-if(Android&&webrender,0-32,0-1458) == 1576553-1.html 1576553-1-ref.html

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

@ -288,7 +288,7 @@ pref(privacy.reduceTimerPrecision,false) == anim-display-in-g-element.svg lime.s
== anim-change-display-none-for-dynamically-appended-elem.html lime.html
== anim-change-display-block-for-dynamically-appended-elem.html anim-standard-ref.html
fuzzy(0-63,0-146) fuzzy-if(skiaContent,0-31,0-308) fuzzy-if(webrender,0-7,0-240) == anim-clipPath-viewBox.svg anim-clipPath-viewBox-ref.svg
fuzzy(0-63,0-146) fuzzy-if(skiaContent,0-31,0-308) fuzzy-if(webrender,0-7,0-241) == anim-clipPath-viewBox.svg anim-clipPath-viewBox-ref.svg
# Test animations for overflow.
== anim-overflow-shorthand.svg anim-overflow-shorthand-ref.svg

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

@ -28,14 +28,14 @@ fuzzy-if(webrender,35-70,699-715) == clip-path-circle-009.html clip-path-circle-
fuzzy-if(webrender,35-70,699-735) == clip-path-circle-010.html clip-path-circle-004-ref.html
fuzzy-if(webrender,35-70,699-725) == clip-path-circle-011.html clip-path-circle-005-ref.html
fuzzy-if(webrender,35-70,699-715) == clip-path-circle-012.html clip-path-circle-006-ref.html
fuzzy-if(webrender,35-70,699-715) == clip-path-circle-013.html clip-path-circle-002-ref.html
fuzzy-if(webrender,35-70,699-733) == clip-path-circle-013.html clip-path-circle-002-ref.html
fuzzy-if(webrender,34-70,699-885) == clip-path-circle-014.html clip-path-circle-007-ref.html
fuzzy-if(webrender,34-70,699-905) == clip-path-circle-015.html clip-path-circle-008-ref.html
fuzzy-if(webrender,34-70,699-840) == clip-path-circle-016.html clip-path-circle-009-ref.html
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-16,0-9) fuzzy-if(webrender,34-70,699-885) == clip-path-circle-017.html clip-path-circle-007-ref.html
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-16,0-9) fuzzy-if(webrender,34-70,699-893) == clip-path-circle-017.html clip-path-circle-007-ref.html
fuzzy-if(webrender,35-70,699-725) == clip-path-circle-018.html clip-path-circle-010-ref.html
fuzzy-if(webrender,35-70,699-715) == clip-path-circle-019.html clip-path-circle-002-ref.html
fuzzy-if(webrender,35-70,699-715) == clip-path-circle-020.html clip-path-circle-002-ref.html
fuzzy-if(webrender,35-70,699-733) == clip-path-circle-019.html clip-path-circle-002-ref.html
fuzzy-if(webrender,35-70,699-733) == clip-path-circle-020.html clip-path-circle-002-ref.html
fuzzy-if(webrender&&(winWidget||cocoaWidget),0-1,0-5) == clip-path-circle-021.html clip-path-circle-021-ref.html
fuzzy-if(webrender,36-36,1099-1100) == clip-path-ellipse-001.html clip-path-ellipse-001-ref.html

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

@ -5,7 +5,7 @@ fuzzy-if(Android,0-16,0-244) fuzzy-if(webrender,0-47,0-6) == marker-basic.html m
fuzzy-if(webrender,0-47,0-18) == bidi-simple.html bidi-simple-ref.html
skip-if(!gtkWidget) fuzzy-if(gtkWidget,0-124,0-289) == bidi-simple-scrolled.html bidi-simple-scrolled-ref.html # Fails on Windows and OSX due to anti-aliasing
fuzzy-if(Android,0-24,0-4000) fuzzy-if(cocoaWidget,0-1,0-40) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-149,0-1836) == scroll-rounding.html scroll-rounding-ref.html # bug 760264
fuzzy(0-16,0-454) fails-if(gtkWidget) fuzzy-if(webrender&&winWidget,50-85,454-499) fuzzy-if(webrender&&OSX,7-7,143-143) skip-if(OSX&&!isDebugBuild&&verify) == anonymous-block.html anonymous-block-ref.html # gtkWidget:bug 1309103, fuzzy: subpixel aa
fuzzy(0-16,0-454) fails-if(gtkWidget) fuzzy-if(webrender&&winWidget,50-85,454-499) fuzzy-if(webrender&&OSX,15-15,145-145) skip-if(OSX&&!isDebugBuild&&verify) == anonymous-block.html anonymous-block-ref.html # gtkWidget:bug 1309103, fuzzy: subpixel aa
fuzzy-if(webrender,0-47,0-3) == false-marker-overlap.html false-marker-overlap-ref.html
== visibility-hidden.html visibility-hidden-ref.html
fuzzy-if(asyncPan&&!layersGPUAccelerated,0-102,0-1724) fuzzy-if(gtkWidget,0-10,0-8) fuzzy-if(webrender,0-47,0-24) == block-padding.html block-padding-ref.html

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

@ -186,7 +186,7 @@ random-if(!winWidget) == arial-bold-lam-alef-1.html arial-bold-lam-alef-1-ref.ht
fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1320665-cmap-format-13.html 1320665-cmap-format-13-ref.html # see bug 1320665 comments 8-9
== 1331339-script-extensions-shaping-1.html 1331339-script-extensions-shaping-1-ref.html
skip-if(!cocoaWidget) != 1349308-1.html 1349308-notref.html # macOS-specific test for -apple-system glyph metrics
fuzzy-if(Android,0-128,0-230) fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 1463020-letter-spacing-text-transform-1.html 1463020-letter-spacing-text-transform-1-ref.html # Win10: regional indicators not supported by system emoji font
fuzzy-if(Android,0-128,0-233) fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 1463020-letter-spacing-text-transform-1.html 1463020-letter-spacing-text-transform-1-ref.html # Win10: regional indicators not supported by system emoji font
fails-if(Android) == 1463020-letter-spacing-text-transform-2.html 1463020-letter-spacing-text-transform-2-ref.html # missing font coverage on Android
== 1507661-spurious-hyphenation-after-explicit.html 1507661-spurious-hyphenation-after-explicit-ref.html
fuzzy-if(!webrender,12-66,288-1660) fails-if(gtkWidget&&!webrender) == 1522857-1.html 1522857-1-ref.html # antialiasing fuzz in non-webrender cases

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

@ -16,7 +16,7 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == descriptor-negative.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == descriptor-prefix.html descriptor-prefix-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == descriptor-suffix.html descriptor-suffix-ref.html # Bug 1392106
== descriptor-range.html descriptor-range-ref.html
fuzzy-if(webrender,0-22,0-3) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == descriptor-pad.html descriptor-pad-ref.html # Bug 1392106
fuzzy-if(webrender,0-92,0-3) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == descriptor-pad.html descriptor-pad-ref.html # Bug 1392106
== descriptor-fallback.html descriptor-fallback-ref.html
== descriptor-symbols.html descriptor-symbols-ref.html
== descriptor-negative-invalid.html descriptor-negative-invalid-ref.html

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

@ -1,8 +1,8 @@
needs-focus == focus-within-1.html focus-within-1-ref.html
needs-focus == focus-within-2.html focus-within-2-ref.html
needs-focus == focus-within-3.html focus-within-3-ref.html
fuzzy-if(webrender,0-122,0-1) == dir-style-01a.html dir-style-01-ref.html
fuzzy-if(webrender,0-122,0-1) == dir-style-01b.html dir-style-01-ref.html
fuzzy-if(webrender,0-137,0-1) == dir-style-01a.html dir-style-01-ref.html
fuzzy-if(webrender,0-137,0-1) == dir-style-01b.html dir-style-01-ref.html
== dir-style-02a.html dir-style-02-ref.html
== dir-style-02b.html dir-style-02-ref.html
== dir-style-03a.html dir-style-03-ref.html

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

@ -10,7 +10,7 @@
# rendering.) We could probably make them pass by implementing some quirks, if
# it turns out that the web depends on WebKit/Blink's behavior in these cases.
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == webkit-box-anon-flex-items-1a.html webkit-box-anon-flex-items-1-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == webkit-box-anon-flex-items-1b.html webkit-box-anon-flex-items-1-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(geckoview&&webrender,150-150,7-7) == webkit-box-anon-flex-items-1b.html webkit-box-anon-flex-items-1-ref.html # Bug 1392106
fails == webkit-box-anon-flex-items-2.html webkit-box-anon-flex-items-2-ref.html
fails == webkit-box-anon-flex-items-3.html webkit-box-anon-flex-items-3-ref.html

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

@ -31,7 +31,7 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1102175-1b.html 1102175-
== 1105268-2-min-max-dimensions.html 1105268-2-min-max-dimensions-ref.html
== 1106669-1-intrinsic-for-container.html 1106669-1-intrinsic-for-container-ref.html
== 1108923-1-percentage-margins.html 1108923-1-percentage-margins-ref.html
fuzzy-if(Android,0-128,0-78) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1111944-1-list-marker.html 1111944-1-list-marker-ref.html # Bug 1392106
fuzzy-if(Android,0-128,0-94) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1111944-1-list-marker.html 1111944-1-list-marker-ref.html # Bug 1392106
fuzzy(0-116,0-94) fuzzy-if(winWidget,0-135,0-124) == 1115916-1-vertical-metrics.html 1115916-1-vertical-metrics-ref.html
== 1117210-1-vertical-baseline-snap.html 1117210-1-vertical-baseline-snap-ref.html
== 1117227-1-text-overflow.html 1117227-1-text-overflow-ref.html

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

@ -0,0 +1,3 @@
[list-style-type-string-002.html]
fuzzy:
if webrender and (os == "win"): maxDifference=137;totalPixels=2

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

@ -0,0 +1,3 @@
[webkit-line-clamp-024.html]
fuzzy:
if webrender and (os == "win"): maxDifference=47;totalPixels=1

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

@ -0,0 +1,3 @@
[webkit-line-clamp-027.html]
fuzzy:
if webrender and (os == "win"): maxDifference=47;totalPixels=1

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

@ -0,0 +1,3 @@
[webkit-line-clamp-029.html]
fuzzy:
if webrender and (os == "win"): maxDifference=47;totalPixels=1

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

@ -0,0 +1,3 @@
[webkit-line-clamp-030.html]
fuzzy:
if webrender and (os == "win"): maxDifference=47;totalPixels=1

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

@ -0,0 +1,3 @@
[text-overflow-026.html]
fuzzy:
if webrender and (os == "win"): maxDifference=47;totalPixels=3

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

@ -0,0 +1,3 @@
[descriptor-pad.html]
fuzzy:
if webrender and (os == "win"): maxDifference=92;totalPixels=3

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

@ -0,0 +1,3 @@
[dir-style-01a.html]
fuzzy:
if webrender and (os == "win"): maxDifference=137;totalPixels=1

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

@ -0,0 +1,3 @@
[dir-style-01b.html]
fuzzy:
if webrender and (os == "win"): maxDifference=137;totalPixels=1