Bug 1726388 - Disable AA between parts of a decomposed linear gradient. r=gfx-reviewers,lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D145937
This commit is contained in:
Nicolas Silva 2022-05-17 13:46:32 +00:00
Родитель 0c97ec67ec
Коммит 69c61a4aad
2 изменённых файлов: 40 добавлений и 3 удалений

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

@ -25,6 +25,7 @@ use crate::prim_store::{NinePatchDescriptor, PointKey, SizeKey, InternablePrimit
use crate::render_task::{RenderTask, RenderTaskKind};
use crate::render_task_graph::RenderTaskId;
use crate::render_task_cache::{RenderTaskCacheKeyKind, RenderTaskCacheKey, RenderTaskParent};
use crate::segment::EdgeAaSegmentMask;
use crate::picture::{SurfaceIndex};
use crate::util::pack_as_float;
use super::{stops_and_min_alpha, GradientStopKey, GradientGpuBlockBuilder, apply_gradient_local_clip};
@ -48,6 +49,7 @@ pub struct LinearGradientKey {
pub reverse_stops: bool,
pub cached: bool,
pub nine_patch: Option<Box<NinePatchDescriptor>>,
pub edge_aa_mask: EdgeAaSegmentMask,
}
impl LinearGradientKey {
@ -66,6 +68,7 @@ impl LinearGradientKey {
reverse_stops: linear_grad.reverse_stops,
cached: linear_grad.cached,
nine_patch: linear_grad.nine_patch,
edge_aa_mask: linear_grad.edge_aa_mask,
}
}
}
@ -121,7 +124,7 @@ pub fn optimize_linear_gradient(
extend_mode: ExtendMode,
stops: &mut [GradientStopKey],
// Callback called for each fast-path segment (rect, start end, stops).
callback: &mut dyn FnMut(&LayoutRect, LayoutPoint, LayoutPoint, &[GradientStopKey])
callback: &mut dyn FnMut(&LayoutRect, LayoutPoint, LayoutPoint, &[GradientStopKey], EdgeAaSegmentMask)
) -> bool {
// First sanitize the gradient parameters. See if we can remove repetitions,
// tighten the primitive bounds, etc.
@ -250,6 +253,22 @@ pub fn optimize_linear_gradient(
last.offset = 1.0 - last.offset;
}
let (side_edges, first_edge, last_edge) = if vertical {
(
EdgeAaSegmentMask::LEFT | EdgeAaSegmentMask::RIGHT,
EdgeAaSegmentMask::TOP,
EdgeAaSegmentMask::BOTTOM
)
} else {
(
EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::BOTTOM,
EdgeAaSegmentMask::LEFT,
EdgeAaSegmentMask::RIGHT
)
};
let mut is_first = true;
let last_offset = last.offset;
for stop in stops.iter().chain((&[last]).iter()) {
let prev_stop = prev;
prev = *stop;
@ -295,6 +314,15 @@ pub fn optimize_linear_gradient(
start -= offset;
end -= offset;
let mut edge_flags = side_edges;
if is_first {
edge_flags |= first_edge;
is_first = false;
}
if stop.offset == last_offset {
edge_flags |= last_edge;
}
callback(
&segment_rect,
start,
@ -303,6 +331,7 @@ pub fn optimize_linear_gradient(
GradientStopKey { offset: 0.0, .. prev_stop },
GradientStopKey { offset: 1.0, .. *stop },
],
edge_flags,
);
}
@ -312,7 +341,8 @@ pub fn optimize_linear_gradient(
impl From<LinearGradientKey> for LinearGradientTemplate {
fn from(item: LinearGradientKey) -> Self {
let common = PrimTemplateCommonData::with_key_common(item.common);
let mut common = PrimTemplateCommonData::with_key_common(item.common);
common.edge_aa_mask = item.edge_aa_mask;
let (mut stops, min_alpha) = stops_and_min_alpha(&item.stops);
@ -573,6 +603,7 @@ pub struct LinearGradient {
pub reverse_stops: bool,
pub nine_patch: Option<Box<NinePatchDescriptor>>,
pub cached: bool,
pub edge_aa_mask: EdgeAaSegmentMask,
}
impl Internable for LinearGradient {

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

@ -50,6 +50,7 @@ use crate::image_tiling::simplify_repeated_primitive;
use crate::clip::{ClipChainId, ClipItemKey, ClipStore, ClipItemKeyKind};
use crate::clip::{ClipInternData, ClipNodeKind, ClipInstance, SceneClipInstance};
use crate::clip::{PolygonDataHandle};
use crate::segment::EdgeAaSegmentMask;
use crate::spatial_tree::{SceneSpatialTree, SpatialNodeIndex, get_external_scroll_offset};
use crate::frame_builder::{ChasePrimitive, FrameBuilderConfig};
use crate::glyph_rasterizer::{FontInstance, SharedFontResources};
@ -1428,7 +1429,7 @@ impl<'a> SceneBuilder<'a> {
&mut end,
info.gradient.extend_mode,
&mut stops,
&mut |rect, start, end, stops| {
&mut |rect, start, end, stops, edge_aa_mask| {
let layout = LayoutPrimitiveInfo { rect: *rect, clip_rect: *rect, flags };
if let Some(prim_key_kind) = self.create_linear_gradient_prim(
&layout,
@ -1439,6 +1440,7 @@ impl<'a> SceneBuilder<'a> {
rect.size(),
LayoutSize::zero(),
None,
edge_aa_mask,
) {
self.add_nonshadowable_primitive(
spatial_node_index,
@ -1461,6 +1463,7 @@ impl<'a> SceneBuilder<'a> {
tile_size,
info.tile_spacing,
None,
EdgeAaSegmentMask::all(),
) {
self.add_nonshadowable_primitive(
spatial_node_index,
@ -3196,6 +3199,7 @@ impl<'a> SceneBuilder<'a> {
LayoutSize::new(border.height as f32, border.width as f32),
LayoutSize::zero(),
Some(Box::new(nine_patch)),
EdgeAaSegmentMask::all(),
) {
Some(prim) => prim,
None => return,
@ -3277,6 +3281,7 @@ impl<'a> SceneBuilder<'a> {
stretch_size: LayoutSize,
mut tile_spacing: LayoutSize,
nine_patch: Option<Box<NinePatchDescriptor>>,
edge_aa_mask: EdgeAaSegmentMask,
) -> Option<LinearGradient> {
let mut prim_rect = info.rect;
simplify_repeated_primitive(&stretch_size, &mut tile_spacing, &mut prim_rect);
@ -3341,6 +3346,7 @@ impl<'a> SceneBuilder<'a> {
reverse_stops,
nine_patch,
cached,
edge_aa_mask,
})
}