tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 1e163710b0012b1b79466b875f482c772ee9dfe9
parent 96837ab7824d38825845fa93dfaac2d6cae3d078
Author: Sotaro Ikeda <sotaro.ikeda.g@gmail.com>
Date:   Mon, 15 Dec 2025 02:39:25 +0000

Bug 2003698 - Drop overlapped rounded corner in composite_simple() r=gfx-reviewers,gw

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

Diffstat:
Mgfx/wr/webrender/src/composite.rs | 24+++++++++++++++++++++++-
Mgfx/wr/webrender/src/renderer/mod.rs | 44++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/gfx/wr/webrender/src/composite.rs b/gfx/wr/webrender/src/composite.rs @@ -15,11 +15,12 @@ use crate::tile_cache::{TileCacheInstance, TileSurface}; use crate::tile_cache::TileId; use crate::prim_store::DeferredResolve; use crate::resource_cache::{ImageRequest, ResourceCache}; +use crate::segment::EdgeAaSegmentMask; use crate::util::{extract_inner_rect_safe, Preallocator, ScaleOffset}; use crate::tile_cache::PictureCacheDebugInfo; use crate::device::Device; use crate::space::SpaceMapper; -use std::{ops, u64, os::raw::c_void}; +use std::{ops, u64, os::raw::c_void, hash}; use std::num::NonZeroUsize; /* @@ -621,6 +622,27 @@ pub struct CompositorClip { pub radius: BorderRadius, } +#[derive(PartialEq, Debug)] +pub struct CompositeRoundedCorner { + pub rect: LayoutRect, + pub radius: LayoutSize, + pub edge_flags: EdgeAaSegmentMask, +} + +impl Eq for CompositeRoundedCorner {} + +impl hash::Hash for CompositeRoundedCorner { + fn hash<H: hash::Hasher>(&self, state: &mut H) { + self.rect.min.x.to_bits().hash(state); + self.rect.min.y.to_bits().hash(state); + self.rect.max.x.to_bits().hash(state); + self.rect.max.y.to_bits().hash(state); + self.radius.width.to_bits().hash(state); + self.radius.height.to_bits().hash(state); + self.edge_flags.bits().hash(state); + } +} + /// The list of tiles to be drawn this frame #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs @@ -57,10 +57,10 @@ use crate::capture::{CaptureConfig, ExternalCaptureImage, PlainExternalImage}; use crate::composite::{CompositeState, CompositeTileSurface, CompositorInputLayer, CompositorSurfaceTransform, ResolvedExternalSurface}; use crate::composite::{CompositorKind, Compositor, NativeTileId, CompositeFeatures, CompositeSurfaceFormat, ResolvedExternalSurfaceColorData}; use crate::composite::{CompositorConfig, NativeSurfaceOperationDetails, NativeSurfaceId, NativeSurfaceOperation, ClipRadius}; -use crate::composite::TileKind; +use crate::composite::{CompositeRoundedCorner, TileKind}; #[cfg(feature = "debugger")] use api::debugger::{CompositorDebugInfo, DebuggerTextureContent}; -use crate::segment::SegmentBuilder; +use crate::segment::{EdgeAaSegmentMask, SegmentBuilder}; use crate::{debug_colors, CompositorInputConfig, CompositorSurfaceUsage}; use crate::device::{DepthFunction, Device, DrawTarget, ExternalTexture, GpuFrameId, UploadPBOPool}; use crate::device::{ReadTarget, ShaderError, Texture, TextureFilter, TextureFlags, TextureSlot, Texel}; @@ -108,6 +108,7 @@ use std::sync::Arc; use std::{ cell::RefCell, + collections::HashSet, collections::VecDeque, f32, ffi::c_void, @@ -4082,6 +4083,8 @@ impl Renderer { // Check tiles handling with partial_present_mode + let mut opaque_rounded_corners: HashSet<CompositeRoundedCorner> = HashSet::new(); + // NOTE: Tiles here are being iterated in front-to-back order by // z-id, due to the sort in composite_state.end_frame() for (idx, tile) in composite_state.tiles.iter().enumerate() { @@ -4142,6 +4145,43 @@ impl Renderer { segment_builder.build(|segment| { let key = OcclusionItemKey { tile_index: idx, needs_mask: segment.has_mask }; + let radius = if segment.edge_flags == + EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::LEFT && + !clip.radius.top_left.is_empty() { + Some(clip.radius.top_left) + } else if segment.edge_flags == + EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::RIGHT && + !clip.radius.top_right.is_empty() { + Some(clip.radius.top_right) + } else if segment.edge_flags == + EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::LEFT && + !clip.radius.bottom_left.is_empty() { + Some(clip.radius.bottom_left) + } else if segment.edge_flags == + EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::RIGHT && + !clip.radius.bottom_right.is_empty() { + Some(clip.radius.bottom_right) + } else { + None + }; + + if let Some(radius) = radius { + let rounded_corner = CompositeRoundedCorner { + rect: segment.rect.cast_unit(), + radius: radius, + edge_flags: segment.edge_flags, + }; + + // Drop overdraw rounded rect + if opaque_rounded_corners.contains(&rounded_corner) { + return; + } + + if is_opaque { + opaque_rounded_corners.insert(rounded_corner); + } + } + layer.occlusion.add( &segment.rect.cast_unit(), is_opaque && !segment.has_mask,