mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 1734346 - Support backdrops with simple rounded-rect clip cases. r=gfx-reviewers,nical
This allows picture slice backdrops to be supported when they contain rounded-rect clip(s) that are in the same coordinate system as the primitive. This is the common case, and allows subpixel AA to be used in bookmark menu and other popups that are part of the current Gecko UI. Differential Revision: https://phabricator.services.mozilla.com/D128156
This commit is contained in:
parent
2570aaff04
commit
601f48038d
@ -1228,6 +1228,66 @@ impl ClipStore {
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a clip-chain instance, return a safe rect within the visible region
|
||||
/// that can be assumed to be unaffected by clip radii. Returns None if it
|
||||
/// encounters any complex cases, just handling rounded rects in the same
|
||||
/// coordinate system as the clip-chain for now.
|
||||
pub fn get_inner_rect_for_clip_chain(
|
||||
&self,
|
||||
clip_chain: &ClipChainInstance,
|
||||
clip_data_store: &ClipDataStore,
|
||||
spatial_tree: &SpatialTree,
|
||||
) -> Option<PictureRect> {
|
||||
let mut inner_rect = clip_chain.pic_clip_rect;
|
||||
let clip_instances = &self
|
||||
.clip_node_instances[clip_chain.clips_range.to_range()];
|
||||
|
||||
for clip_instance in clip_instances {
|
||||
// Don't handle mapping between coord systems for now
|
||||
if !clip_instance.flags.contains(ClipNodeFlags::SAME_COORD_SYSTEM) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let clip_node = &clip_data_store[clip_instance.handle];
|
||||
|
||||
match clip_node.item.kind {
|
||||
// Ignore any clips which are complex or impossible to calculate
|
||||
// inner rects for now
|
||||
ClipItemKind::Rectangle { mode: ClipMode::ClipOut, .. } |
|
||||
ClipItemKind::Image { .. } |
|
||||
ClipItemKind::BoxShadow { .. } |
|
||||
ClipItemKind::RoundedRectangle { mode: ClipMode::ClipOut, .. } => {
|
||||
return None;
|
||||
}
|
||||
// Normal Clip rects are already handled by the clip-chain pic_clip_rect,
|
||||
// no need to do anything here
|
||||
ClipItemKind::Rectangle { mode: ClipMode::Clip, .. } => {}
|
||||
ClipItemKind::RoundedRectangle { mode: ClipMode::Clip, rect, radius } => {
|
||||
// Get an inner rect for the rounded-rect clip
|
||||
let local_inner_rect = match extract_inner_rect_safe(&rect, &radius) {
|
||||
Some(rect) => rect,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
// Map it from local -> picture space
|
||||
let mapper = SpaceMapper::new_with_target(
|
||||
clip_chain.pic_spatial_node_index,
|
||||
clip_instance.spatial_node_index,
|
||||
PictureRect::max_rect(),
|
||||
spatial_tree,
|
||||
);
|
||||
|
||||
// Accumulate in to the inner_rect, in case there are multiple rounded-rect clips
|
||||
if let Some(pic_inner_rect) = mapper.map(&local_inner_rect) {
|
||||
inner_rect = inner_rect.intersection(&pic_inner_rect).unwrap_or(PictureRect::zero());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(inner_rect)
|
||||
}
|
||||
|
||||
/// The main interface external code uses. Given a local primitive, positioning
|
||||
/// information, and a clip chain id, build an optimized clip chain instance.
|
||||
pub fn build_clip_chain_instance(
|
||||
|
@ -3706,7 +3706,7 @@ impl TileCacheInstance {
|
||||
|
||||
let sub_slice = &mut self.sub_slices[sub_slice_index];
|
||||
|
||||
if let Some(backdrop_candidate) = backdrop_candidate {
|
||||
if let Some(mut backdrop_candidate) = backdrop_candidate {
|
||||
let is_suitable_backdrop = match backdrop_candidate.kind {
|
||||
Some(BackdropKind::Clear) => {
|
||||
// Clear prims are special - they always end up in their own slice,
|
||||
@ -3739,8 +3739,19 @@ impl TileCacheInstance {
|
||||
|
||||
if sub_slice_index == 0 &&
|
||||
is_suitable_backdrop &&
|
||||
sub_slice.compositor_surfaces.is_empty() &&
|
||||
!prim_clip_chain.needs_mask {
|
||||
sub_slice.compositor_surfaces.is_empty() {
|
||||
|
||||
// If the backdrop candidate has a clip-mask, try to extract an opaque inner
|
||||
// rect that is safe to use for subpixel rendering
|
||||
if prim_clip_chain.needs_mask {
|
||||
backdrop_candidate.opaque_rect = clip_store
|
||||
.get_inner_rect_for_clip_chain(
|
||||
prim_clip_chain,
|
||||
&data_stores.clip,
|
||||
frame_context.spatial_tree,
|
||||
)
|
||||
.unwrap_or(PictureRect::zero());
|
||||
}
|
||||
|
||||
if backdrop_candidate.opaque_rect.contains_box(&self.backdrop.opaque_rect) {
|
||||
self.backdrop.opaque_rect = backdrop_candidate.opaque_rect;
|
||||
|
@ -82,3 +82,4 @@ fuzzy(1,15) platform(linux) force_subpixel_aa_where_possible(false) == text-fixe
|
||||
# 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-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
|
||||
|
8
gfx/wr/wrench/reftests/text/subpx-bg-mask-ref.yaml
Normal file
8
gfx/wr/wrench/reftests/text/subpx-bg-mask-ref.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- text: "A"
|
||||
origin: 20 190
|
||||
size: 180
|
||||
color: black
|
||||
font: "FreeSans.ttf"
|
27
gfx/wr/wrench/reftests/text/subpx-bg-mask.yaml
Normal file
27
gfx/wr/wrench/reftests/text/subpx-bg-mask.yaml
Normal file
@ -0,0 +1,27 @@
|
||||
# Verify that text on a picture cache slice where the background
|
||||
# has a rounded-rect clip correct enables subpixel AA
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: rect
|
||||
bounds: [0, 0, 100, 100]
|
||||
color: white
|
||||
- type: scroll-frame
|
||||
bounds: [0, 0, 200, 200]
|
||||
content-size: [200, 200]
|
||||
scroll-offset: [0, 0]
|
||||
items:
|
||||
- type: clip
|
||||
bounds: [0, 0, 200, 200]
|
||||
complex:
|
||||
- rect: [0, 0, 200, 200]
|
||||
radius: 4
|
||||
items:
|
||||
- type: rect
|
||||
bounds: [0, 0, 200, 200]
|
||||
color: white
|
||||
- text: "A"
|
||||
origin: 20 190
|
||||
size: 180
|
||||
color: black
|
||||
font: "FreeSans.ttf"
|
Loading…
Reference in New Issue
Block a user