This is an automated email from the git hooks/post-receive script.
pierov pushed a commit to branch geckoview-99.0.1-11.0-1 in repository tor-browser.
commit 437b50f7a04fad0130f2e0f18a8857949d1267c0 Author: Glenn Watson git@intuitionlibrary.com AuthorDate: Tue Mar 22 10:07:58 2022 -0400
Bug 1759647 - Fix segments on snapped picture surface with clips + scale transform r=gfx-reviewers,nical a=dmeehan Differential Revision: https://phabricator.services.mozilla.com/D141182 --- gfx/wr/webrender/src/batch.rs | 52 ++++++++++++++++++--------------------- gfx/wr/webrender/src/gpu_types.rs | 17 +++++++++++++ gfx/wr/webrender/src/picture.rs | 18 +------------- gfx/wr/webrender/src/util.rs | 7 ++++++ 4 files changed, 49 insertions(+), 45 deletions(-)
diff --git a/gfx/wr/webrender/src/batch.rs b/gfx/wr/webrender/src/batch.rs index b5f2ee1f2019a..36f4a545cda75 100644 --- a/gfx/wr/webrender/src/batch.rs +++ b/gfx/wr/webrender/src/batch.rs @@ -32,7 +32,7 @@ use crate::space::SpaceMapper; use crate::visibility::{PrimitiveVisibilityFlags, VisibilityState}; use smallvec::SmallVec; use std::{f32, i32, usize}; -use crate::util::{project_rect, MaxRect, MatrixHelpers, TransformedRectKind}; +use crate::util::{project_rect, MaxRect, MatrixHelpers, TransformedRectKind, ScaleOffset}; use crate::segment::EdgeAaSegmentMask;
// Special sentinel value recognized by the shader. It is considered to be @@ -1561,43 +1561,39 @@ impl BatchBuilder {
let surface = &ctx.surfaces[raster_config.surface_index.0];
- // If we are drawing with snapping enabled, the local rect of the prim must be in the raster - // space, to avoid situations where there is a 180deg rotation in between the root and primitive - // space not being correctly applied. - let prim_header = if surface.surface_spatial_node_index == surface.raster_spatial_node_index { - PrimitiveHeader { - local_rect: prim_rect, - local_clip_rect: prim_info.combined_local_clip_rect, - specific_prim_address: prim_cache_address, - transform_id, - } + // If we are drawing with snapping enabled, form a simple transform that just applies + // the scale / translation from the raster transform. Otherwise, in edge cases where the + // intermediate surface has a non-identity but axis-aligned transform (e.g. a 180 degree + // rotation) it can be applied twice. + let transform_id = if surface.surface_spatial_node_index == surface.raster_spatial_node_index { + transform_id } else { let map_local_to_raster = SpaceMapper::new_with_target( - surface.raster_spatial_node_index, + root_spatial_node_index, surface.surface_spatial_node_index, LayoutRect::max_rect(), ctx.spatial_tree, );
- let prim_rect = map_local_to_raster + let raster_rect = map_local_to_raster .map(&prim_rect) .unwrap(); - let local_clip_rect = map_local_to_raster - .map(&prim_info.combined_local_clip_rect) - .unwrap(); - let transform_id = transforms - .get_id( - surface.raster_spatial_node_index, - root_spatial_node_index, - ctx.spatial_tree, - );
- PrimitiveHeader { - local_rect: prim_rect, - local_clip_rect, - specific_prim_address: prim_cache_address, - transform_id, - } + let sx = (raster_rect.max.x - raster_rect.min.x) / (prim_rect.max.x - prim_rect.min.x); + let sy = (raster_rect.max.y - raster_rect.min.y) / (prim_rect.max.y - prim_rect.min.y); + + let tx = raster_rect.min.x - sx * prim_rect.min.x; + let ty = raster_rect.min.y - sy * prim_rect.min.y; + + let transform = ScaleOffset::new(sx, sy, tx, ty); + transforms.get_custom(transform.to_transform()) + }; + + let prim_header = PrimitiveHeader { + local_rect: prim_rect, + local_clip_rect: prim_info.combined_local_clip_rect, + specific_prim_address: prim_cache_address, + transform_id, };
let mut is_opaque = prim_info.clip_task_index == ClipTaskIndex::INVALID diff --git a/gfx/wr/webrender/src/gpu_types.rs b/gfx/wr/webrender/src/gpu_types.rs index 3c739d27765ce..aabe6070a9955 100644 --- a/gfx/wr/webrender/src/gpu_types.rs +++ b/gfx/wr/webrender/src/gpu_types.rs @@ -785,6 +785,23 @@ impl TransformPalette { (transform_kind << 24) ) } + + pub fn get_custom( + &mut self, + transform: LayoutToPictureTransform, + ) -> TransformPaletteId { + let index = register_transform( + &mut self.metadata, + &mut self.transforms, + transform, + ); + + let transform_kind = self.metadata[index].transform_kind as u32; + TransformPaletteId( + (index as u32) | + (transform_kind << 24) + ) + } }
// Texture cache resources can be either a simple rect, or define diff --git a/gfx/wr/webrender/src/picture.rs b/gfx/wr/webrender/src/picture.rs index 1f601479f6dd2..00a14d40fe1d0 100644 --- a/gfx/wr/webrender/src/picture.rs +++ b/gfx/wr/webrender/src/picture.rs @@ -5896,27 +5896,11 @@ impl PicturePrimitive { shadow.blur_radius, );
- let mut shadow_rect = prim_rect.inflate( + let shadow_rect = prim_rect.inflate( blur_inflation_x * BLUR_SAMPLE_SCALE, blur_inflation_y * BLUR_SAMPLE_SCALE, ).translate(shadow.offset);
- // If we are drawing with snapping enabled, the local rect of the prim must be in the raster - // space, to avoid situations where there is a 180deg rotation in between the root and primitive - // space not being correctly applied. - if surface.surface_spatial_node_index != surface.raster_spatial_node_index { - let map_local_to_raster = SpaceMapper::new_with_target( - surface.raster_spatial_node_index, - surface.surface_spatial_node_index, - LayoutRect::max_rect(), - frame_context.spatial_tree, - ); - - shadow_rect = map_local_to_raster - .map(&shadow_rect) - .unwrap(); - } - // ImageBrush colors request.push(shadow.color.premultiplied()); request.push(PremultipliedColorF::WHITE); diff --git a/gfx/wr/webrender/src/util.rs b/gfx/wr/webrender/src/util.rs index 6f7b68677171b..ed0a38350f722 100644 --- a/gfx/wr/webrender/src/util.rs +++ b/gfx/wr/webrender/src/util.rs @@ -135,6 +135,13 @@ pub struct ScaleOffset { }
impl ScaleOffset { + pub fn new(sx: f32, sy: f32, tx: f32, ty: f32) -> Self { + ScaleOffset { + scale: Vector2D::new(sx, sy), + offset: Vector2D::new(tx, ty), + } + } + pub fn identity() -> Self { ScaleOffset { scale: Vector2D::new(1.0, 1.0),