mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 20:01:50 +00:00
Bug 1837305 - Part 6: Update AnimationValue for offset-path. r=emilio
We are using NonNegative now for offset-path, so just like clip-path, we have to make sure we don't get the negative radius for circle and ellipse, and don't get the negative border-radius for inset. Therefore, we have to convert the computed value into animated value when doing interpolation, and then clamp the value to make sure it is always >= 0 when converting it back to computed value, just like what we do for clip-path in Bug 1512883. Also drop the normalization of SVGPathData in AnimationInfo when preparing offset-path for compositor animations. It's useless because we "always" do normalization in SVGPathData::animate(). Differential Revision: https://phabricator.services.mozilla.com/D180284
This commit is contained in:
parent
0307742927
commit
4b8c77479a
@ -20,9 +20,11 @@
|
||||
#include "mozilla/layers/APZSampler.h" // for APZSampler
|
||||
#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
|
||||
#include "mozilla/LayerAnimationInfo.h" // for GetCSSPropertiesFor()
|
||||
#include "mozilla/Maybe.h" // for Maybe<>
|
||||
#include "mozilla/MotionPathUtils.h" // for ResolveMotionPath()
|
||||
#include "mozilla/ServoBindings.h" // for Servo_ComposeAnimationSegment, etc
|
||||
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
|
||||
#include "nsCSSPropertyID.h" // for eCSSProperty_offset_path, etc
|
||||
#include "nsDeviceContext.h" // for AppUnitsPerCSSPixel
|
||||
#include "nsDisplayList.h" // for nsDisplayTransform, etc
|
||||
|
||||
@ -498,8 +500,8 @@ AnimationStorageData AnimationHelper::ExtractAnimations(
|
||||
"Fixed offset-path should have base style");
|
||||
MOZ_ASSERT(HasTransformLikeAnimations(aAnimations));
|
||||
|
||||
AnimationValue value{currData->mBaseStyle};
|
||||
const StyleOffsetPath& offsetPath = value.GetOffsetPathProperty();
|
||||
const StyleOffsetPath& offsetPath =
|
||||
animation.baseStyle().get_StyleOffsetPath();
|
||||
// FIXME: Bug 1837042. Cache all basic shapes.
|
||||
if (offsetPath.IsOffsetPath() &&
|
||||
offsetPath.AsOffsetPath().path->IsShape() &&
|
||||
@ -618,7 +620,7 @@ gfx::Matrix4x4 AnimationHelper::ServoAnimationValueToMatrix4x4(
|
||||
const StyleRotate* rotate = nullptr;
|
||||
const StyleScale* scale = nullptr;
|
||||
const StyleTransform* transform = nullptr;
|
||||
const StyleOffsetPath* path = nullptr;
|
||||
Maybe<StyleOffsetPath> path;
|
||||
const StyleLengthPercentage* distance = nullptr;
|
||||
const StyleOffsetRotate* offsetRotate = nullptr;
|
||||
const StylePositionOrAuto* anchor = nullptr;
|
||||
@ -646,7 +648,8 @@ gfx::Matrix4x4 AnimationHelper::ServoAnimationValueToMatrix4x4(
|
||||
break;
|
||||
case eCSSProperty_offset_path:
|
||||
MOZ_ASSERT(!path);
|
||||
path = Servo_AnimationValue_GetOffsetPath(value);
|
||||
path.emplace(StyleOffsetPath::None());
|
||||
Servo_AnimationValue_GetOffsetPath(value, path.ptr());
|
||||
break;
|
||||
case eCSSProperty_offset_distance:
|
||||
MOZ_ASSERT(!distance);
|
||||
@ -671,7 +674,7 @@ gfx::Matrix4x4 AnimationHelper::ServoAnimationValueToMatrix4x4(
|
||||
|
||||
TransformReferenceBox refBox(nullptr, aTransformData.bounds());
|
||||
Maybe<ResolvedMotionPathData> motion = MotionPathUtils::ResolveMotionPath(
|
||||
path, distance, offsetRotate, anchor, position,
|
||||
path.ptrOr(nullptr), distance, offsetRotate, anchor, position,
|
||||
aTransformData.motionPathData(), refBox, aCachedMotionPath);
|
||||
|
||||
// We expect all our transform data to arrive in device pixels
|
||||
|
@ -333,18 +333,6 @@ static Maybe<ScrollTimelineOptions> GetScrollTimelineOptions(
|
||||
return Some(ScrollTimelineOptions(source, timeline->Axis()));
|
||||
}
|
||||
|
||||
static StyleOffsetPath NormalizeOffsetPath(const StyleOffsetPath& aOffsetPath) {
|
||||
// Named Return Value Optimization.
|
||||
StyleOffsetPath result(aOffsetPath);
|
||||
if (aOffsetPath.IsOffsetPath() &&
|
||||
aOffsetPath.AsOffsetPath().path->IsShape() &&
|
||||
aOffsetPath.AsOffsetPath().path->AsShape().IsPath()) {
|
||||
result.UpdateShapePath(MotionPathUtils::NormalizeSVGPathData(
|
||||
aOffsetPath.AsOffsetPath().path->AsShape().AsPath().path));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void SetAnimatable(nsCSSPropertyID aProperty,
|
||||
const AnimationValue& aAnimationValue,
|
||||
nsIFrame* aFrame, TransformReferenceBox& aRefBox,
|
||||
@ -383,8 +371,8 @@ static void SetAnimatable(nsCSSPropertyID aProperty,
|
||||
aAnimationValue.GetTransformProperty(), aRefBox);
|
||||
break;
|
||||
case eCSSProperty_offset_path:
|
||||
aAnimatable =
|
||||
NormalizeOffsetPath(aAnimationValue.GetOffsetPathProperty());
|
||||
aAnimatable = StyleOffsetPath::None();
|
||||
aAnimationValue.GetOffsetPathProperty(aAnimatable.get_StyleOffsetPath());
|
||||
break;
|
||||
case eCSSProperty_offset_distance:
|
||||
aAnimatable = aAnimationValue.GetOffsetDistanceProperty();
|
||||
@ -866,7 +854,7 @@ void AnimationInfo::AddNonAnimatingTransformLikePropertiesStyles(
|
||||
break;
|
||||
case eCSSProperty_offset_path:
|
||||
if (!display->mOffsetPath.IsNone()) {
|
||||
appendFakeAnimation(id, NormalizeOffsetPath(display->mOffsetPath));
|
||||
appendFakeAnimation(id, display->mOffsetPath);
|
||||
}
|
||||
break;
|
||||
case eCSSProperty_offset_distance:
|
||||
|
@ -486,14 +486,6 @@ Maybe<ResolvedMotionPathData> MotionPathUtils::ResolveMotionPath(
|
||||
aRefBox, aMotionPathData->anchorAdjustment());
|
||||
}
|
||||
|
||||
/* static */
|
||||
StyleSVGPathData MotionPathUtils::NormalizeSVGPathData(
|
||||
const StyleSVGPathData& aPath) {
|
||||
StyleSVGPathData n;
|
||||
Servo_SVGPathData_Normalize(&aPath, &n);
|
||||
return n;
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<gfx::Path> MotionPathUtils::BuildPath(
|
||||
const StyleSVGPathData& aPath, gfx::PathBuilder* aPathBuilder) {
|
||||
|
@ -204,17 +204,6 @@ class MotionPathUtils final {
|
||||
const Maybe<layers::MotionPathData>& aMotionPathData,
|
||||
TransformReferenceBox&, gfx::Path* aCachedMotionPath);
|
||||
|
||||
/**
|
||||
* Normalize StyleSVGPathData.
|
||||
*
|
||||
* The algorithm of normalization is the same as normalize() in
|
||||
* servo/components/style/values/specified/svg_path.rs
|
||||
* FIXME: Bug 1489392: We don't have to normalize the path here if we accept
|
||||
* the spec issue which would like to normalize svg paths at computed time.
|
||||
* https://github.com/w3c/svgwg/issues/321
|
||||
*/
|
||||
static StyleSVGPathData NormalizeSVGPathData(const StyleSVGPathData& aPath);
|
||||
|
||||
/**
|
||||
* Build a gfx::Path from the computed svg path. We should give it a path
|
||||
* builder. If |aPathBuilder| is nullptr, we return null path.
|
||||
|
@ -87,9 +87,9 @@ const StyleTransform& AnimationValue::GetTransformProperty() const {
|
||||
return *Servo_AnimationValue_GetTransform(mServo);
|
||||
}
|
||||
|
||||
const mozilla::StyleOffsetPath& AnimationValue::GetOffsetPathProperty() const {
|
||||
void AnimationValue::GetOffsetPathProperty(StyleOffsetPath& aOffsetPath) const {
|
||||
MOZ_ASSERT(mServo);
|
||||
return *Servo_AnimationValue_GetOffsetPath(mServo);
|
||||
Servo_AnimationValue_GetOffsetPath(mServo, &aOffsetPath);
|
||||
}
|
||||
|
||||
const mozilla::LengthPercentage& AnimationValue::GetOffsetDistanceProperty()
|
||||
|
@ -77,7 +77,10 @@ struct AnimationValue {
|
||||
const mozilla::StyleRotate& GetRotateProperty() const;
|
||||
|
||||
// Motion path properties.
|
||||
const mozilla::StyleOffsetPath& GetOffsetPathProperty() const;
|
||||
// Note: This clones the StyleOffsetPath object from its AnimatedValue, so
|
||||
// this may be expensive if the path is a complex SVG path or polygon. The
|
||||
// caller should be aware of this performance impact.
|
||||
void GetOffsetPathProperty(StyleOffsetPath& aOffsetPath) const;
|
||||
const mozilla::LengthPercentage& GetOffsetDistanceProperty() const;
|
||||
const mozilla::StyleOffsetRotate& GetOffsetRotateProperty() const;
|
||||
const mozilla::StylePositionOrAuto& GetOffsetAnchorProperty() const;
|
||||
|
@ -216,7 +216,7 @@ ${helpers.predefined_type(
|
||||
"OffsetPath",
|
||||
"computed::OffsetPath::none()",
|
||||
engines="gecko",
|
||||
animation_value_type="ComputedValue",
|
||||
animation_value_type="motion::OffsetPath",
|
||||
gecko_pref="layout.css.motion-path.enabled",
|
||||
flags="CAN_ANIMATE_ON_COMPOSITOR",
|
||||
spec="https://drafts.fxtf.org/motion-1/#offset-path-property",
|
||||
|
@ -367,7 +367,9 @@ pub struct PolygonCoord<LengthPercentage>(pub LengthPercentage, pub LengthPercen
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
ComputeSquaredDistance,
|
||||
Copy,
|
||||
Debug,
|
||||
Deserialize,
|
||||
@ -413,7 +415,6 @@ pub enum FillRule {
|
||||
pub struct Path {
|
||||
/// The filling rule for the svg path.
|
||||
#[css(skip_if = "is_default")]
|
||||
#[animation(constant)]
|
||||
pub fill: FillRule,
|
||||
/// The svg path data.
|
||||
pub path: SVGPathData,
|
||||
|
@ -26,6 +26,7 @@ use style_traits::{CssWriter, ToCss};
|
||||
PartialEq,
|
||||
Serialize,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
@ -53,6 +54,7 @@ pub enum RaySize {
|
||||
PartialEq,
|
||||
Serialize,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToComputedValue,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
@ -118,6 +120,7 @@ where
|
||||
PartialEq,
|
||||
Serialize,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
@ -150,6 +153,7 @@ pub use self::GenericOffsetPathFunction as OffsetPathFunction;
|
||||
PartialEq,
|
||||
Serialize,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
|
@ -45,6 +45,7 @@ pub type OffsetPosition = generics::GenericOffsetPosition<HorizontalPosition, Ve
|
||||
PartialEq,
|
||||
Serialize,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
ToResolvedValue,
|
||||
|
@ -975,12 +975,3 @@ renaming_overrides_prefixing = true
|
||||
return StyleFontPalette{StyleAtom(nsGkAtoms::normal->ToAddRefed())};
|
||||
}
|
||||
"""
|
||||
|
||||
"GenericOffsetPath" = """
|
||||
void UpdateShapePath(const StyleSVGPathData& aPath) {
|
||||
MOZ_ASSERT(IsOffsetPath() && AsOffsetPath().path->IsShape() &&
|
||||
AsOffsetPath().path->AsShape().IsPath(),
|
||||
"Only for path()");
|
||||
offset_path.path->shape._0.path._0.path = aPath;
|
||||
}
|
||||
"""
|
||||
|
@ -816,9 +816,13 @@ pub unsafe extern "C" fn Servo_AnimationValue_GetTransform(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_AnimationValue_GetOffsetPath(
|
||||
value: &AnimationValue,
|
||||
) -> *const computed::motion::OffsetPath {
|
||||
output: &mut computed::motion::OffsetPath,
|
||||
) {
|
||||
use style::values::animated::ToAnimatedValue;
|
||||
match *value {
|
||||
AnimationValue::OffsetPath(ref value) => value,
|
||||
AnimationValue::OffsetPath(ref value) => {
|
||||
*output = ToAnimatedValue::from_animated_value(value.clone())
|
||||
},
|
||||
_ => unreachable!("Expected offset-path"),
|
||||
}
|
||||
}
|
||||
@ -893,7 +897,8 @@ pub unsafe extern "C" fn Servo_AnimationValue_Transform(
|
||||
pub unsafe extern "C" fn Servo_AnimationValue_OffsetPath(
|
||||
p: &computed::motion::OffsetPath,
|
||||
) -> Strong<AnimationValue> {
|
||||
Arc::new(AnimationValue::OffsetPath(p.clone())).into()
|
||||
use style::values::animated::ToAnimatedValue;
|
||||
Arc::new(AnimationValue::OffsetPath(p.clone().to_animated_value())).into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -1054,14 +1059,6 @@ impl_basic_serde_funcs!(
|
||||
ComputedTimingFunction
|
||||
);
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_SVGPathData_Normalize(
|
||||
input: &specified::SVGPathData,
|
||||
output: &mut specified::SVGPathData,
|
||||
) {
|
||||
*output = input.normalize();
|
||||
}
|
||||
|
||||
// Return the ComputedValues by a base ComputedValues and the rules.
|
||||
fn resolve_rules_for_element_with_context<'a>(
|
||||
element: GeckoElement<'a>,
|
||||
|
@ -26,18 +26,6 @@
|
||||
[CSS Transitions: property <offset-path> from [initial\] to [ellipse()\] at (0.3) should be [initial\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <offset-path> from [inherit\] to [ellipse(40% 50% at 25% 25%)\] at (-0.3) should be [ellipse(1% 0% at 57.5% 57.5%)\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <offset-path> from [inherit\] to [ellipse(40% 50% at 25% 25%)\] at (-0.3) should be [ellipse(1% 0% at 57.5% 57.5%)\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <offset-path> from [inherit\] to [ellipse(40% 50% at 25% 25%)\] at (-0.3) should be [ellipse(1% 0% at 57.5% 57.5%)\]]
|
||||
expected: FAIL
|
||||
|
||||
[Web Animations: property <offset-path> from [inherit\] to [ellipse(40% 50% at 25% 25%)\] at (-0.3) should be [ellipse(1% 0% at 57.5% 57.5%)\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <offset-path> from [unset\] to [inset(10%)\] at (-0.3) should be [unset\]]
|
||||
expected: FAIL
|
||||
|
||||
@ -131,18 +119,6 @@
|
||||
[Web Animations: property <offset-path> from [none\] to [rect(10px 10px 10px 10px)\] at (1.5) should be [rect(10px 10px 10px 10px)\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <offset-path> from [inset(10px)\] to [inset(20px round 50%)\] at (-1) should be [inset(0px round 0%)\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions with transition: all: property <offset-path> from [inset(10px)\] to [inset(20px round 50%)\] at (-1) should be [inset(0px round 0%)\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Animations: property <offset-path> from [inset(10px)\] to [inset(20px round 50%)\] at (-1) should be [inset(0px round 0%)\]]
|
||||
expected: FAIL
|
||||
|
||||
[Web Animations: property <offset-path> from [inset(10px)\] to [inset(20px round 50%)\] at (-1) should be [inset(0px round 0%)\]]
|
||||
expected: FAIL
|
||||
|
||||
[CSS Transitions: property <offset-path> from [xywh(5px 5px 150% 150%)\] to [xywh(10px 10px 100% 100%)\] at (-1) should be [xywh(0px 0px 200% 200%)\]]
|
||||
expected: FAIL
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user