mirror of
https://github.com/servo/servo.git
synced 2025-06-25 09:34:32 +01:00
This pull request refactors existing tracing annotations to leverage the new `servo_tracing::instrument` macro introduced in #36573. Specifically, the following transformations were applied: - Removed `#[cfg_attr(feature = "tracing", ...)]` wrappers. - Replaced `tracing::instrument` with `servo_tracing::instrument`. - Removed `level = "trace"` - Removed `fields(servo_profiling = true)` from tracing attributes however retained others like `name`. `skip type` Closes: #36661 --------- Signed-off-by: Bhuwan Pandit <bhuwanpandit109@gmail.com> Signed-off-by: Jonathan Schwender <55576758+jschwe@users.noreply.github.com> Co-authored-by: Jonathan Schwender <55576758+jschwe@users.noreply.github.com>
268 lines
11 KiB
Rust
268 lines
11 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
use app_units::Au;
|
|
use base::id::ScrollTreeNodeId;
|
|
use style::values::computed::basic_shape::{BasicShape, ClipPath};
|
|
use style::values::computed::length_percentage::NonNegativeLengthPercentage;
|
|
use style::values::computed::position::Position;
|
|
use style::values::generics::basic_shape::{GenericShapeRadius, ShapeBox, ShapeGeometryBox};
|
|
use style::values::generics::position::GenericPositionOrAuto;
|
|
use webrender_api::BorderRadius;
|
|
use webrender_api::units::{LayoutRect, LayoutSideOffsets, LayoutSize};
|
|
|
|
use super::{BuilderForBoxFragment, compute_margin_box_radius, normalize_radii};
|
|
|
|
/// An identifier for a clip used during StackingContextTree construction. This is a simple index in
|
|
/// a [`ClipStore`]s vector of clips.
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
pub(crate) struct ClipId(pub usize);
|
|
|
|
impl ClipId {
|
|
/// Equivalent to [`ClipChainId::INVALID`]. This means "no clip."
|
|
pub(crate) const INVALID: ClipId = ClipId(usize::MAX);
|
|
}
|
|
|
|
/// All the information needed to create a clip on a WebRender display list. These are created at
|
|
/// two times: during `StackingContextTree` creation and during WebRender display list construction.
|
|
/// Only the former are stored in a [`ClipStore`].
|
|
#[derive(Clone)]
|
|
pub(crate) struct Clip {
|
|
pub id: ClipId,
|
|
pub radii: BorderRadius,
|
|
pub rect: LayoutRect,
|
|
pub parent_scroll_node_id: ScrollTreeNodeId,
|
|
pub parent_clip_id: ClipId,
|
|
}
|
|
|
|
/// A simple vector of [`Clip`] that is built during `StackingContextTree` construction.
|
|
/// These are later turned into WebRender clips and clip chains during WebRender display
|
|
/// list construction.
|
|
#[derive(Clone, Default)]
|
|
pub(crate) struct StackingContextTreeClipStore(pub Vec<Clip>);
|
|
|
|
impl StackingContextTreeClipStore {
|
|
pub(crate) fn add(
|
|
&mut self,
|
|
radii: webrender_api::BorderRadius,
|
|
rect: LayoutRect,
|
|
parent_scroll_node_id: ScrollTreeNodeId,
|
|
parent_clip_id: ClipId,
|
|
) -> ClipId {
|
|
let id = ClipId(self.0.len());
|
|
self.0.push(Clip {
|
|
id,
|
|
radii,
|
|
rect,
|
|
parent_scroll_node_id,
|
|
parent_clip_id,
|
|
});
|
|
id
|
|
}
|
|
|
|
pub(super) fn add_for_clip_path(
|
|
&mut self,
|
|
clip_path: ClipPath,
|
|
parent_scroll_node_id: &ScrollTreeNodeId,
|
|
parent_clip_chain_id: &ClipId,
|
|
fragment_builder: BuilderForBoxFragment,
|
|
) -> Option<ClipId> {
|
|
let geometry_box = match clip_path {
|
|
ClipPath::Shape(_, ShapeGeometryBox::ShapeBox(shape_box)) => shape_box,
|
|
ClipPath::Shape(_, ShapeGeometryBox::ElementDependent) => ShapeBox::BorderBox,
|
|
ClipPath::Box(ShapeGeometryBox::ShapeBox(shape_box)) => shape_box,
|
|
ClipPath::Box(ShapeGeometryBox::ElementDependent) => ShapeBox::BorderBox,
|
|
_ => return None,
|
|
};
|
|
let layout_rect = match geometry_box {
|
|
ShapeBox::BorderBox => fragment_builder.border_rect,
|
|
ShapeBox::ContentBox => *fragment_builder.content_rect(),
|
|
ShapeBox::PaddingBox => *fragment_builder.padding_rect(),
|
|
ShapeBox::MarginBox => *fragment_builder.margin_rect(),
|
|
};
|
|
if let ClipPath::Shape(shape, _) = clip_path {
|
|
match *shape {
|
|
BasicShape::Circle(_) | BasicShape::Ellipse(_) | BasicShape::Rect(_) => self
|
|
.add_for_basic_shape(
|
|
*shape,
|
|
layout_rect,
|
|
parent_scroll_node_id,
|
|
parent_clip_chain_id,
|
|
),
|
|
BasicShape::Polygon(_) | BasicShape::PathOrShape(_) => None,
|
|
}
|
|
} else {
|
|
Some(self.add(
|
|
match geometry_box {
|
|
ShapeBox::MarginBox => compute_margin_box_radius(
|
|
fragment_builder.border_radius,
|
|
layout_rect.size(),
|
|
fragment_builder.fragment,
|
|
),
|
|
_ => fragment_builder.border_radius,
|
|
},
|
|
layout_rect,
|
|
*parent_scroll_node_id,
|
|
*parent_clip_chain_id,
|
|
))
|
|
}
|
|
}
|
|
|
|
#[servo_tracing::instrument(name = "StackingContextClipStore::add_for_basic_shape", skip_all)]
|
|
fn add_for_basic_shape(
|
|
&mut self,
|
|
shape: BasicShape,
|
|
layout_box: LayoutRect,
|
|
parent_scroll_node_id: &ScrollTreeNodeId,
|
|
parent_clip_chain_id: &ClipId,
|
|
) -> Option<ClipId> {
|
|
match shape {
|
|
BasicShape::Rect(rect) => {
|
|
let box_height = Au::from_f32_px(layout_box.height());
|
|
let box_width = Au::from_f32_px(layout_box.width());
|
|
let insets = LayoutSideOffsets::new(
|
|
rect.rect.0.to_used_value(box_height).to_f32_px(),
|
|
rect.rect.1.to_used_value(box_width).to_f32_px(),
|
|
rect.rect.2.to_used_value(box_height).to_f32_px(),
|
|
rect.rect.3.to_used_value(box_width).to_f32_px(),
|
|
);
|
|
|
|
// `inner_rect()` will cause an assertion failure if the insets are larger than the
|
|
// rectangle dimension.
|
|
let shape_rect = if insets.left + insets.right >= layout_box.width() ||
|
|
insets.top + insets.bottom > layout_box.height()
|
|
{
|
|
LayoutRect::from_origin_and_size(layout_box.min, LayoutSize::zero())
|
|
} else {
|
|
layout_box.to_rect().inner_rect(insets).to_box2d()
|
|
};
|
|
|
|
let corner = |corner: &style::values::computed::BorderCornerRadius| {
|
|
LayoutSize::new(
|
|
corner.0.width.0.to_used_value(box_width).to_f32_px(),
|
|
corner.0.height.0.to_used_value(box_height).to_f32_px(),
|
|
)
|
|
};
|
|
let mut radii = webrender_api::BorderRadius {
|
|
top_left: corner(&rect.round.top_left),
|
|
top_right: corner(&rect.round.top_right),
|
|
bottom_left: corner(&rect.round.bottom_left),
|
|
bottom_right: corner(&rect.round.bottom_right),
|
|
};
|
|
normalize_radii(&layout_box, &mut radii);
|
|
Some(self.add(
|
|
radii,
|
|
shape_rect,
|
|
*parent_scroll_node_id,
|
|
*parent_clip_chain_id,
|
|
))
|
|
},
|
|
BasicShape::Circle(circle) => {
|
|
let center = match circle.position {
|
|
GenericPositionOrAuto::Position(position) => position,
|
|
GenericPositionOrAuto::Auto => Position::center(),
|
|
};
|
|
let anchor_x = center
|
|
.horizontal
|
|
.to_used_value(Au::from_f32_px(layout_box.width()));
|
|
let anchor_y = center
|
|
.vertical
|
|
.to_used_value(Au::from_f32_px(layout_box.height()));
|
|
let center = layout_box
|
|
.min
|
|
.add_size(&LayoutSize::new(anchor_x.to_f32_px(), anchor_y.to_f32_px()));
|
|
|
|
let horizontal = compute_shape_radius(
|
|
center.x,
|
|
&circle.radius,
|
|
layout_box.min.x,
|
|
layout_box.max.x,
|
|
);
|
|
let vertical = compute_shape_radius(
|
|
center.y,
|
|
&circle.radius,
|
|
layout_box.min.y,
|
|
layout_box.max.y,
|
|
);
|
|
|
|
// If the value is `Length` then both values should be the same at this point.
|
|
let radius = match circle.radius {
|
|
GenericShapeRadius::FarthestSide => horizontal.max(vertical),
|
|
GenericShapeRadius::ClosestSide => horizontal.min(vertical),
|
|
GenericShapeRadius::Length(_) => horizontal,
|
|
};
|
|
let radius = LayoutSize::new(radius, radius);
|
|
let mut radii = webrender_api::BorderRadius {
|
|
top_left: radius,
|
|
top_right: radius,
|
|
bottom_left: radius,
|
|
bottom_right: radius,
|
|
};
|
|
let start = center.add_size(&-radius);
|
|
let rect = LayoutRect::from_origin_and_size(start, radius * 2.);
|
|
normalize_radii(&layout_box, &mut radii);
|
|
Some(self.add(radii, rect, *parent_scroll_node_id, *parent_clip_chain_id))
|
|
},
|
|
BasicShape::Ellipse(ellipse) => {
|
|
let center = match ellipse.position {
|
|
GenericPositionOrAuto::Position(position) => position,
|
|
GenericPositionOrAuto::Auto => Position::center(),
|
|
};
|
|
let anchor_x = center
|
|
.horizontal
|
|
.to_used_value(Au::from_f32_px(layout_box.width()));
|
|
let anchor_y = center
|
|
.vertical
|
|
.to_used_value(Au::from_f32_px(layout_box.height()));
|
|
let center = layout_box
|
|
.min
|
|
.add_size(&LayoutSize::new(anchor_x.to_f32_px(), anchor_y.to_f32_px()));
|
|
|
|
let width = compute_shape_radius(
|
|
center.x,
|
|
&ellipse.semiaxis_x,
|
|
layout_box.min.x,
|
|
layout_box.max.x,
|
|
);
|
|
let height = compute_shape_radius(
|
|
center.y,
|
|
&ellipse.semiaxis_y,
|
|
layout_box.min.y,
|
|
layout_box.max.y,
|
|
);
|
|
|
|
let mut radii = webrender_api::BorderRadius {
|
|
top_left: LayoutSize::new(width, height),
|
|
top_right: LayoutSize::new(width, height),
|
|
bottom_left: LayoutSize::new(width, height),
|
|
bottom_right: LayoutSize::new(width, height),
|
|
};
|
|
let size = LayoutSize::new(width, height);
|
|
let start = center.add_size(&-size);
|
|
let rect = LayoutRect::from_origin_and_size(start, size * 2.);
|
|
normalize_radii(&rect, &mut radii);
|
|
Some(self.add(radii, rect, *parent_scroll_node_id, *parent_clip_chain_id))
|
|
},
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn compute_shape_radius(
|
|
center: f32,
|
|
radius: &GenericShapeRadius<NonNegativeLengthPercentage>,
|
|
min_edge: f32,
|
|
max_edge: f32,
|
|
) -> f32 {
|
|
let distance_from_min_edge = (min_edge - center).abs();
|
|
let distance_from_max_edge = (max_edge - center).abs();
|
|
match radius {
|
|
GenericShapeRadius::FarthestSide => distance_from_min_edge.max(distance_from_max_edge),
|
|
GenericShapeRadius::ClosestSide => distance_from_min_edge.min(distance_from_max_edge),
|
|
GenericShapeRadius::Length(length) => length
|
|
.0
|
|
.to_used_value(Au::from_f32_px(max_edge - min_edge))
|
|
.to_f32_px(),
|
|
}
|
|
}
|