diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/page/animation/CSSPropertyAnimation.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/page/animation/CSSPropertyAnimation.cpp')
-rw-r--r-- | Source/WebCore/page/animation/CSSPropertyAnimation.cpp | 824 |
1 files changed, 503 insertions, 321 deletions
diff --git a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp index 291129e93..98b87c947 100644 --- a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp +++ b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2013, 2016 Apple Inc. All rights reserved. * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -41,7 +41,9 @@ #include "CachedImage.h" #include "ClipPathOperation.h" #include "FloatConversion.h" +#include "FontTaggedSettings.h" #include "IdentityTransformOperation.h" +#include "Logging.h" #include "Matrix3DTransformOperation.h" #include "MatrixTransformOperation.h" #include "RenderBox.h" @@ -50,9 +52,13 @@ #include "StyleGeneratedImage.h" #include "StylePropertyShorthand.h" #include "StyleResolver.h" +#include "TextStream.h" #include <algorithm> +#include <memory> #include <wtf/MathExtras.h> +#include <wtf/NeverDestroyed.h> #include <wtf/Noncopyable.h> +#include <wtf/PointerComparison.h> #include <wtf/RefCounted.h> namespace WebCore { @@ -62,11 +68,6 @@ static inline int blendFunc(const AnimationBase*, int from, int to, double progr return blend(from, to, progress); } -static inline unsigned blendFunc(const AnimationBase*, unsigned from, unsigned to, double progress) -{ - return blend(from, to, progress); -} - static inline double blendFunc(const AnimationBase*, double from, double to, double progress) { return blend(from, to, progress); @@ -84,13 +85,12 @@ static inline Color blendFunc(const AnimationBase*, const Color& from, const Col static inline Length blendFunc(const AnimationBase*, const Length& from, const Length& to, double progress) { - return to.blend(from, narrowPrecisionToFloat(progress)); + return blend(from, to, progress); } static inline LengthSize blendFunc(const AnimationBase* anim, const LengthSize& from, const LengthSize& to, double progress) { - return LengthSize(blendFunc(anim, from.width(), to.width(), progress), - blendFunc(anim, from.height(), to.height(), progress)); + return { blendFunc(anim, from.width, to.width, progress), blendFunc(anim, from.height, to.height, progress) }; } static inline ShadowStyle blendFunc(const AnimationBase* anim, ShadowStyle from, ShadowStyle to, double progress) @@ -104,28 +104,28 @@ static inline ShadowStyle blendFunc(const AnimationBase* anim, ShadowStyle from, return result > 0 ? Normal : Inset; } -static inline PassOwnPtr<ShadowData> blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress) +static inline std::unique_ptr<ShadowData> blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress) { ASSERT(from && to); if (from->style() != to->style()) - return adoptPtr(new ShadowData(*to)); - - return adoptPtr(new ShadowData(blend(from->location(), to->location(), progress), - blend(from->radius(), to->radius(), progress), - blend(from->spread(), to->spread(), progress), - blendFunc(anim, from->style(), to->style(), progress), - from->isWebkitBoxShadow(), - blend(from->color(), to->color(), progress))); + return std::make_unique<ShadowData>(*to); + + return std::make_unique<ShadowData>(blend(from->location(), to->location(), progress), + blend(from->radius(), to->radius(), progress), + blend(from->spread(), to->spread(), progress), + blendFunc(anim, from->style(), to->style(), progress), + from->isWebkitBoxShadow(), + blend(from->color(), to->color(), progress)); } -static inline TransformOperations blendFunc(const AnimationBase* anim, const TransformOperations& from, const TransformOperations& to, double progress) +static inline TransformOperations blendFunc(const AnimationBase* animation, const TransformOperations& from, const TransformOperations& to, double progress) { - if (anim->isTransformFunctionListValid()) + if (animation->transformFunctionListsMatch()) return to.blendByMatchingOperations(from, progress); - return to.blendByUsingMatrixInterpolation(from, progress, anim->renderer()->isBox() ? toRenderBox(anim->renderer())->borderBoxRect().size() : LayoutSize()); + return to.blendByUsingMatrixInterpolation(from, progress, is<RenderBox>(*animation->renderer()) ? downcast<RenderBox>(*animation->renderer()).borderBoxRect().size() : LayoutSize()); } -static inline PassRefPtr<ClipPathOperation> blendFunc(const AnimationBase*, ClipPathOperation* from, ClipPathOperation* to, double progress) +static inline RefPtr<ClipPathOperation> blendFunc(const AnimationBase*, ClipPathOperation* from, ClipPathOperation* to, double progress) { if (!from || !to) return to; @@ -134,44 +134,40 @@ static inline PassRefPtr<ClipPathOperation> blendFunc(const AnimationBase*, Clip if (from->type() != ClipPathOperation::Shape || to->type() != ClipPathOperation::Shape) return to; - const BasicShape* fromShape = static_cast<ShapeClipPathOperation*>(from)->basicShape(); - const BasicShape* toShape = static_cast<ShapeClipPathOperation*>(to)->basicShape(); + const BasicShape& fromShape = downcast<ShapeClipPathOperation>(*from).basicShape(); + const BasicShape& toShape = downcast<ShapeClipPathOperation>(*to).basicShape(); - if (!fromShape->canBlend(toShape)) + if (!fromShape.canBlend(toShape)) return to; - return ShapeClipPathOperation::create(toShape->blend(fromShape, progress)); + return ShapeClipPathOperation::create(toShape.blend(fromShape, progress)); } -#if ENABLE(CSS_SHAPES) -static inline PassRefPtr<ShapeValue> blendFunc(const AnimationBase*, ShapeValue* from, ShapeValue* to, double progress) +static inline RefPtr<ShapeValue> blendFunc(const AnimationBase*, ShapeValue* from, ShapeValue* to, double progress) { if (!from || !to) return to; - // FIXME Bug 102723: Shape-inside should be able to animate a value of 'outside-shape' when shape-outside is set to a BasicShape - if (from->type() != ShapeValue::Shape || to->type() != ShapeValue::Shape) + if (from->type() != ShapeValue::Type::Shape || to->type() != ShapeValue::Type::Shape) return to; - if (from->layoutBox() != to->layoutBox()) + if (from->cssBox() != to->cssBox()) return to; - const BasicShape* fromShape = from->shape(); - const BasicShape* toShape = to->shape(); + const BasicShape& fromShape = *from->shape(); + const BasicShape& toShape = *to->shape(); - if (!fromShape->canBlend(toShape)) + if (!fromShape.canBlend(toShape)) return to; - return ShapeValue::createShapeValue(toShape->blend(fromShape, progress), to->layoutBox()); + return ShapeValue::create(toShape.blend(fromShape, progress), to->cssBox()); } -#endif -#if ENABLE(CSS_FILTERS) -static inline PassRefPtr<FilterOperation> blendFunc(const AnimationBase* anim, FilterOperation* fromOp, FilterOperation* toOp, double progress, bool blendToPassthrough = false) +static inline RefPtr<FilterOperation> blendFunc(const AnimationBase* animation, FilterOperation* fromOp, FilterOperation* toOp, double progress, bool blendToPassthrough = false) { ASSERT(toOp); if (toOp->blendingNeedsRendererSize()) { - LayoutSize size = anim->renderer()->isBox() ? toRenderBox(anim->renderer())->borderBoxRect().size() : LayoutSize(); + LayoutSize size = is<RenderBox>(*animation->renderer()) ? downcast<RenderBox>(*animation->renderer()).borderBoxRect().size() : LayoutSize(); return toOp->blend(fromOp, progress, size, blendToPassthrough); } return toOp->blend(fromOp, progress, blendToPassthrough); @@ -200,12 +196,18 @@ static inline FilterOperations blendFilterOperations(const AnimationBase* anim, return result; } -static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations& from, const FilterOperations& to, double progress) +static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations& from, const FilterOperations& to, double progress, bool animatingBackdropFilter = false) { FilterOperations result; // If we have a filter function list, use that to do a per-function animation. +#if ENABLE(FILTERS_LEVEL_2) + if ((!animatingBackdropFilter && anim->filterFunctionListsMatch()) || (animatingBackdropFilter && anim->backdropFilterFunctionListsMatch())) +#else + UNUSED_PARAM(animatingBackdropFilter); if (anim->filterFunctionListsMatch()) +#endif + result = blendFilterOperations(anim, from, to, progress); else { // If the filter function lists don't match, we could try to cross-fade, but don't yet have a way to represent that in CSS. @@ -216,20 +218,18 @@ static inline FilterOperations blendFunc(const AnimationBase* anim, const Filter return result; } -static inline PassRefPtr<StyleImage> blendFilter(const AnimationBase* anim, CachedImage* image, const FilterOperations& from, const FilterOperations& to, double progress) +static inline RefPtr<StyleImage> blendFilter(const AnimationBase* anim, CachedImage* image, const FilterOperations& from, const FilterOperations& to, double progress) { ASSERT(image); FilterOperations filterResult = blendFilterOperations(anim, from, to, progress); - RefPtr<StyleCachedImage> styledImage = StyleCachedImage::create(image); - auto imageValue = CSSImageValue::create(image->url(), styledImage.get()); - auto filterValue = ComputedStyleExtractor::valueForFilter(&anim->renderer()->style(), filterResult, DoNotAdjustPixelValues); + auto imageValue = CSSImageValue::create(*image); + auto filterValue = ComputedStyleExtractor::valueForFilter(anim->renderer()->style(), filterResult, DoNotAdjustPixelValues); - auto result = CSSFilterImageValue::create(std::move(imageValue), std::move(filterValue)); + auto result = CSSFilterImageValue::create(WTFMove(imageValue), WTFMove(filterValue)); result.get().setFilterOperations(filterResult); - return StyleGeneratedImage::create(std::move(result)); + return StyleGeneratedImage::create(WTFMove(result)); } -#endif // ENABLE(CSS_FILTERS) static inline EVisibility blendFunc(const AnimationBase* anim, EVisibility from, EVisibility to, double progress) { @@ -252,12 +252,12 @@ static inline LengthBox blendFunc(const AnimationBase* anim, const LengthBox& fr return result; } -#if ENABLE(SVG) -static inline SVGLength blendFunc(const AnimationBase*, const SVGLength& from, const SVGLength& to, double progress) +static inline SVGLengthValue blendFunc(const AnimationBase*, const SVGLengthValue& from, const SVGLengthValue& to, double progress) { return to.blend(from, narrowPrecisionToFloat(progress)); } -static inline Vector<SVGLength> blendFunc(const AnimationBase*, const Vector<SVGLength>& from, const Vector<SVGLength>& to, double progress) + +static inline Vector<SVGLengthValue> blendFunc(const AnimationBase*, const Vector<SVGLengthValue>& from, const Vector<SVGLengthValue>& to, double progress) { size_t fromLength = from.size(); size_t toLength = to.size(); @@ -272,14 +272,13 @@ static inline Vector<SVGLength> blendFunc(const AnimationBase*, const Vector<SVG else resultLength = fromLength * toLength; } - Vector<SVGLength> result(resultLength); + Vector<SVGLengthValue> result(resultLength); for (size_t i = 0; i < resultLength; ++i) result[i] = to[i % toLength].blend(from[i % fromLength], narrowPrecisionToFloat(progress)); return result; } -#endif -static inline PassRefPtr<StyleImage> crossfadeBlend(const AnimationBase*, StyleCachedImage* fromStyleImage, StyleCachedImage* toStyleImage, double progress) +static inline RefPtr<StyleImage> crossfadeBlend(const AnimationBase*, StyleCachedImage* fromStyleImage, StyleCachedImage* toStyleImage, double progress) { // If progress is at one of the extremes, we want getComputedStyle to show the image, // not a completed cross-fade, so we hand back one of the existing images. @@ -287,69 +286,69 @@ static inline PassRefPtr<StyleImage> crossfadeBlend(const AnimationBase*, StyleC return fromStyleImage; if (progress == 1) return toStyleImage; + if (!fromStyleImage->cachedImage() || !toStyleImage->cachedImage()) + return toStyleImage; - auto fromImageValue = CSSImageValue::create(fromStyleImage->cachedImage()->url(), fromStyleImage); - auto toImageValue = CSSImageValue::create(toStyleImage->cachedImage()->url(), toStyleImage); + auto fromImageValue = CSSImageValue::create(*fromStyleImage->cachedImage()); + auto toImageValue = CSSImageValue::create(*toStyleImage->cachedImage()); + auto percentageValue = CSSPrimitiveValue::create(progress, CSSPrimitiveValue::CSS_NUMBER); - auto crossfadeValue = CSSCrossfadeValue::create(std::move(fromImageValue), std::move(toImageValue)); - crossfadeValue.get().setPercentage(CSSPrimitiveValue::create(progress, CSSPrimitiveValue::CSS_NUMBER)); - return StyleGeneratedImage::create(std::move(crossfadeValue)); + auto crossfadeValue = CSSCrossfadeValue::create(WTFMove(fromImageValue), WTFMove(toImageValue), WTFMove(percentageValue)); + return StyleGeneratedImage::create(WTFMove(crossfadeValue)); } -static inline PassRefPtr<StyleImage> blendFunc(const AnimationBase* anim, StyleImage* from, StyleImage* to, double progress) +static inline RefPtr<StyleImage> blendFunc(const AnimationBase* anim, StyleImage* from, StyleImage* to, double progress) { if (!from || !to) return to; // Animation between two generated images. Cross fade for all other cases. - if (from->isGeneratedImage() && to->isGeneratedImage()) { - CSSImageGeneratorValue& fromGenerated = toStyleGeneratedImage(from)->imageValue(); - CSSImageGeneratorValue& toGenerated = toStyleGeneratedImage(to)->imageValue(); + if (is<StyleGeneratedImage>(*from) && is<StyleGeneratedImage>(*to)) { + CSSImageGeneratorValue& fromGenerated = downcast<StyleGeneratedImage>(*from).imageValue(); + CSSImageGeneratorValue& toGenerated = downcast<StyleGeneratedImage>(*to).imageValue(); -#if ENABLE(CSS_FILTERS) - if (fromGenerated.isFilterImageValue() && toGenerated.isFilterImageValue()) { + if (is<CSSFilterImageValue>(fromGenerated) && is<CSSFilterImageValue>(toGenerated)) { // Animation of generated images just possible if input images are equal. // Otherwise fall back to cross fade animation. - CSSFilterImageValue& fromFilter = toCSSFilterImageValue(fromGenerated); - CSSFilterImageValue& toFilter = toCSSFilterImageValue(toGenerated); + CSSFilterImageValue& fromFilter = downcast<CSSFilterImageValue>(fromGenerated); + CSSFilterImageValue& toFilter = downcast<CSSFilterImageValue>(toGenerated); if (fromFilter.equalInputImages(toFilter) && fromFilter.cachedImage()) return blendFilter(anim, fromFilter.cachedImage(), fromFilter.filterOperations(), toFilter.filterOperations(), progress); } -#endif - if (fromGenerated.isCrossfadeValue() && toGenerated.isCrossfadeValue()) { - CSSCrossfadeValue& fromCrossfade = toCSSCrossfadeValue(fromGenerated); - CSSCrossfadeValue& toCrossfade = toCSSCrossfadeValue(toGenerated); - if (fromCrossfade.equalInputImages(toCrossfade)) - return StyleGeneratedImage::create(*toCrossfade.blend(fromCrossfade, progress)); + if (is<CSSCrossfadeValue>(fromGenerated) && is<CSSCrossfadeValue>(toGenerated)) { + CSSCrossfadeValue& fromCrossfade = downcast<CSSCrossfadeValue>(fromGenerated); + CSSCrossfadeValue& toCrossfade = downcast<CSSCrossfadeValue>(toGenerated); + if (fromCrossfade.equalInputImages(toCrossfade)) { + if (auto crossfadeBlend = toCrossfade.blend(fromCrossfade, progress)) + return StyleGeneratedImage::create(*crossfadeBlend); + } } // FIXME: Add support for animation between two *gradient() functions. // https://bugs.webkit.org/show_bug.cgi?id=119956 -#if ENABLE(CSS_FILTERS) - } else if (from->isGeneratedImage() && to->isCachedImage()) { - CSSImageGeneratorValue& fromGenerated = toStyleGeneratedImage(from)->imageValue(); - if (fromGenerated.isFilterImageValue()) { - CSSFilterImageValue& fromFilter = toCSSFilterImageValue(fromGenerated); - if (fromFilter.cachedImage() && static_cast<StyleCachedImage*>(to)->cachedImage() == fromFilter.cachedImage()) + } else if (is<StyleGeneratedImage>(*from) && is<StyleCachedImage>(*to)) { + CSSImageGeneratorValue& fromGenerated = downcast<StyleGeneratedImage>(*from).imageValue(); + if (is<CSSFilterImageValue>(fromGenerated)) { + CSSFilterImageValue& fromFilter = downcast<CSSFilterImageValue>(fromGenerated); + if (fromFilter.cachedImage() && downcast<StyleCachedImage>(*to).cachedImage() == fromFilter.cachedImage()) return blendFilter(anim, fromFilter.cachedImage(), fromFilter.filterOperations(), FilterOperations(), progress); } // FIXME: Add interpolation between cross-fade and image source. - } else if (from->isCachedImage() && to->isGeneratedImage()) { - CSSImageGeneratorValue& toGenerated = toStyleGeneratedImage(to)->imageValue(); - if (toGenerated.isFilterImageValue()) { - CSSFilterImageValue& toFilter = toCSSFilterImageValue(toGenerated); - if (toFilter.cachedImage() && static_cast<StyleCachedImage*>(from)->cachedImage() == toFilter.cachedImage()) + } else if (is<StyleCachedImage>(*from) && is<StyleGeneratedImage>(*to)) { + CSSImageGeneratorValue& toGenerated = downcast<StyleGeneratedImage>(*to).imageValue(); + if (is<CSSFilterImageValue>(toGenerated)) { + CSSFilterImageValue& toFilter = downcast<CSSFilterImageValue>(toGenerated); + if (toFilter.cachedImage() && downcast<StyleCachedImage>(*from).cachedImage() == toFilter.cachedImage()) return blendFilter(anim, toFilter.cachedImage(), FilterOperations(), toFilter.filterOperations(), progress); } -#endif // FIXME: Add interpolation between image source and cross-fade. } // FIXME: Add support cross fade between cached and generated images. // https://bugs.webkit.org/show_bug.cgi?id=78293 - if (from->isCachedImage() && to->isCachedImage()) - return crossfadeBlend(anim, static_cast<StyleCachedImage*>(from), static_cast<StyleCachedImage*>(to), progress); + if (is<StyleCachedImage>(*from) && is<StyleCachedImage>(*to)) + return crossfadeBlend(anim, downcast<StyleCachedImage>(from), downcast<StyleCachedImage>(to), progress); return to; } @@ -367,11 +366,31 @@ static inline NinePieceImage blendFunc(const AnimationBase* anim, const NinePiec if (from.image()->imageSize(anim->renderer(), 1.0) != to.image()->imageSize(anim->renderer(), 1.0)) return to; - RefPtr<StyleImage> newContentImage = blendFunc(anim, from.image(), to.image(), progress); + return NinePieceImage(blendFunc(anim, from.image(), to.image(), progress), + from.imageSlices(), from.fill(), from.borderSlices(), from.outset(), from.horizontalRule(), from.verticalRule()); +} + +#if ENABLE(VARIATION_FONTS) - return NinePieceImage(newContentImage, from.imageSlices(), from.fill(), from.borderSlices(), from.outset(), from.horizontalRule(), from.verticalRule()); +static inline FontVariationSettings blendFunc(const AnimationBase* anim, const FontVariationSettings& from, const FontVariationSettings& to, double progress) +{ + if (from.size() != to.size()) + return FontVariationSettings(); + FontVariationSettings result; + unsigned size = from.size(); + for (unsigned i = 0; i < size; ++i) { + auto& fromItem = from.at(i); + auto& toItem = to.at(i); + if (fromItem.tag() != toItem.tag()) + return FontVariationSettings(); + float interpolated = blendFunc(anim, fromItem.value(), toItem.value(), progress); + result.insert({ fromItem.tag(), interpolated }); + } + return result; } +#endif + class AnimationPropertyWrapperBase { WTF_MAKE_NONCOPYABLE(AnimationPropertyWrapperBase); WTF_MAKE_FAST_ALLOCATED; @@ -386,12 +405,14 @@ public: virtual bool isShorthandWrapper() const { return false; } virtual bool equals(const RenderStyle* a, const RenderStyle* b) const = 0; virtual void blend(const AnimationBase*, RenderStyle*, const RenderStyle*, const RenderStyle*, double) const = 0; + +#if !LOG_DISABLED + virtual void logBlend(const RenderStyle* a, const RenderStyle* b, const RenderStyle* result, double) const = 0; +#endif CSSPropertyID property() const { return m_prop; } -#if USE(ACCELERATED_COMPOSITING) virtual bool animationIsAccelerated() const { return false; } -#endif private: CSSPropertyID m_prop; @@ -399,6 +420,7 @@ private: template <typename T> class PropertyWrapperGetter : public AnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; public: PropertyWrapperGetter(CSSPropertyID prop, T (RenderStyle::*getter)() const) : AnimationPropertyWrapperBase(prop) @@ -406,23 +428,34 @@ public: { } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + bool equals(const RenderStyle* a, const RenderStyle* b) const override { - // If the style pointers are the same, don't bother doing the test. - // If either is null, return false. If both are null, return true. - if ((!a && !b) || a == b) + if (a == b) return true; if (!a || !b) return false; return (a->*m_getter)() == (b->*m_getter)(); } + T value(const RenderStyle* a) const + { + return (a->*m_getter)(); + } + +#if !LOG_DISABLED + void logBlend(const RenderStyle* a, const RenderStyle* b, const RenderStyle* result, double progress) const final + { + LOG_WITH_STREAM(Animations, stream << " blending " << getPropertyName(property()) << " from " << value(a) << " to " << value(b) << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << value(result)); + } +#endif + protected: T (RenderStyle::*m_getter)() const; }; template <typename T> class PropertyWrapper : public PropertyWrapperGetter<T> { + WTF_MAKE_FAST_ALLOCATED; public: PropertyWrapper(CSSPropertyID prop, T (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T)) : PropertyWrapperGetter<T>(prop, getter) @@ -430,7 +463,7 @@ public: { } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<T>::m_getter)(), (b->*PropertyWrapperGetter<T>::m_getter)(), progress)); } @@ -441,69 +474,131 @@ protected: template <typename T> class RefCountedPropertyWrapper : public PropertyWrapperGetter<T*> { + WTF_MAKE_FAST_ALLOCATED; public: - RefCountedPropertyWrapper(CSSPropertyID prop, T* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<T>)) + RefCountedPropertyWrapper(CSSPropertyID prop, T* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(RefPtr<T>&&)) : PropertyWrapperGetter<T*>(prop, getter) , m_setter(setter) { } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<T*>::m_getter)(), (b->*PropertyWrapperGetter<T*>::m_getter)(), progress)); } protected: - void (RenderStyle::*m_setter)(PassRefPtr<T>); + void (RenderStyle::*m_setter)(RefPtr<T>&&); }; template <typename T> class LengthPropertyWrapper : public PropertyWrapperGetter<const T&> { + WTF_MAKE_FAST_ALLOCATED; public: - LengthPropertyWrapper(CSSPropertyID prop, const T& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T)) + LengthPropertyWrapper(CSSPropertyID prop, const T& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T&&)) : PropertyWrapperGetter<const T&>(prop, getter) , m_setter(setter) { } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<const T&>::m_getter)(), (b->*PropertyWrapperGetter<const T&>::m_getter)(), progress)); } protected: - void (RenderStyle::*m_setter)(T); + void (RenderStyle::*m_setter)(T&&); }; class PropertyWrapperClipPath : public RefCountedPropertyWrapper<ClipPathOperation> { + WTF_MAKE_FAST_ALLOCATED; public: - PropertyWrapperClipPath(CSSPropertyID prop, ClipPathOperation* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<ClipPathOperation>)) + PropertyWrapperClipPath(CSSPropertyID prop, ClipPathOperation* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(RefPtr<ClipPathOperation>&&)) : RefCountedPropertyWrapper<ClipPathOperation>(prop, getter, setter) { } + + bool equals(const RenderStyle* a, const RenderStyle* b) const override + { + // If the style pointers are the same, don't bother doing the test. + // If either is null, return false. If both are null, return true. + if (a == b) + return true; + if (!a || !b) + return false; + + ClipPathOperation* clipPathA = (a->*m_getter)(); + ClipPathOperation* clipPathB = (b->*m_getter)(); + if (clipPathA == clipPathB) + return true; + if (!clipPathA || !clipPathB) + return false; + return *clipPathA == *clipPathB; + } +}; + +#if ENABLE(VARIATION_FONTS) +class PropertyWrapperFontVariationSettings : public PropertyWrapper<FontVariationSettings> { + WTF_MAKE_FAST_ALLOCATED; +public: + PropertyWrapperFontVariationSettings(CSSPropertyID prop, FontVariationSettings (RenderStyle::*getter)() const, void (RenderStyle::*setter)(FontVariationSettings)) + : PropertyWrapper<FontVariationSettings>(prop, getter, setter) + { + } + + bool equals(const RenderStyle* a, const RenderStyle* b) const override + { + // If the style pointers are the same, don't bother doing the test. + // If either is null, return false. If both are null, return true. + if (a == b) + return true; + if (!a || !b) + return false; + + const FontVariationSettings& variationSettingsA = (a->*m_getter)(); + const FontVariationSettings& variationSettingsB = (b->*m_getter)(); + return variationSettingsA == variationSettingsB; + } }; +#endif -#if ENABLE(CSS_SHAPES) class PropertyWrapperShape : public RefCountedPropertyWrapper<ShapeValue> { + WTF_MAKE_FAST_ALLOCATED; public: - PropertyWrapperShape(CSSPropertyID prop, ShapeValue* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<ShapeValue>)) + PropertyWrapperShape(CSSPropertyID prop, ShapeValue* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(RefPtr<ShapeValue>&&)) : RefCountedPropertyWrapper<ShapeValue>(prop, getter, setter) { } + + bool equals(const RenderStyle* a, const RenderStyle* b) const override + { + // If the style pointers are the same, don't bother doing the test. + // If either is null, return false. If both are null, return true. + if (a == b) + return true; + if (!a || !b) + return false; + + ShapeValue* shapeA = (a->*m_getter)(); + ShapeValue* shapeB = (b->*m_getter)(); + if (shapeA == shapeB) + return true; + if (!shapeA || !shapeB) + return false; + return *shapeA == *shapeB; + } }; -#endif class StyleImagePropertyWrapper : public RefCountedPropertyWrapper<StyleImage> { + WTF_MAKE_FAST_ALLOCATED; public: - StyleImagePropertyWrapper(CSSPropertyID prop, StyleImage* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<StyleImage>)) + StyleImagePropertyWrapper(CSSPropertyID prop, StyleImage* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(RefPtr<StyleImage>&&)) : RefCountedPropertyWrapper<StyleImage>(prop, getter, setter) { } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + bool equals(const RenderStyle* a, const RenderStyle* b) const override { - // If the style pointers are the same, don't bother doing the test. - // If either is null, return false. If both are null, return true. if (a == b) return true; if (!a || !b) @@ -511,67 +606,82 @@ public: StyleImage* imageA = (a->*m_getter)(); StyleImage* imageB = (b->*m_getter)(); - return StyleImage::imagesEquivalent(imageA, imageB); + return arePointingToEqualData(imageA, imageB); } }; -class PropertyWrapperColor : public PropertyWrapperGetter<Color> { +class PropertyWrapperColor : public PropertyWrapperGetter<const Color&> { + WTF_MAKE_FAST_ALLOCATED; public: - PropertyWrapperColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&)) - : PropertyWrapperGetter<Color>(prop, getter) + PropertyWrapperColor(CSSPropertyID prop, const Color& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&)) + : PropertyWrapperGetter<const Color&>(prop, getter) , m_setter(setter) { } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { - (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<Color>::m_getter)(), (b->*PropertyWrapperGetter<Color>::m_getter)(), progress)); + (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<const Color&>::m_getter)(), (b->*PropertyWrapperGetter<const Color&>::m_getter)(), progress)); } protected: void (RenderStyle::*m_setter)(const Color&); }; - -#if USE(ACCELERATED_COMPOSITING) class PropertyWrapperAcceleratedOpacity : public PropertyWrapper<float> { + WTF_MAKE_FAST_ALLOCATED; public: PropertyWrapperAcceleratedOpacity() : PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity) { } - virtual bool animationIsAccelerated() const { return true; } + bool animationIsAccelerated() const override { return true; } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { - float fromOpacity = a->opacity(); - - // This makes sure we put the object being animated into a RenderLayer during the animation - dst->setOpacity(blendFunc(anim, (fromOpacity == 1) ? 0.999999f : fromOpacity, b->opacity(), progress)); + dst->setOpacity(blendFunc(anim, a->opacity(), b->opacity(), progress)); } }; class PropertyWrapperAcceleratedTransform : public PropertyWrapper<const TransformOperations&> { + WTF_MAKE_FAST_ALLOCATED; public: PropertyWrapperAcceleratedTransform() - : PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform) + : PropertyWrapper<const TransformOperations&>(CSSPropertyTransform, &RenderStyle::transform, &RenderStyle::setTransform) { } - virtual bool animationIsAccelerated() const { return true; } + bool animationIsAccelerated() const override { return true; } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { dst->setTransform(blendFunc(anim, a->transform(), b->transform(), progress)); } }; -#if ENABLE(CSS_FILTERS) class PropertyWrapperAcceleratedFilter : public PropertyWrapper<const FilterOperations&> { + WTF_MAKE_FAST_ALLOCATED; public: PropertyWrapperAcceleratedFilter() - : PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter) + : PropertyWrapper<const FilterOperations&>(CSSPropertyFilter, &RenderStyle::filter, &RenderStyle::setFilter) + { + } + + bool animationIsAccelerated() const override { return true; } + + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override + { + dst->setFilter(blendFunc(anim, a->filter(), b->filter(), progress)); + } +}; + +#if ENABLE(FILTERS_LEVEL_2) +class PropertyWrapperAcceleratedBackdropFilter : public PropertyWrapper<const FilterOperations&> { + WTF_MAKE_FAST_ALLOCATED; +public: + PropertyWrapperAcceleratedBackdropFilter() + : PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitBackdropFilter, &RenderStyle::backdropFilter, &RenderStyle::setBackdropFilter) { } @@ -579,11 +689,10 @@ public: virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const { - dst->setFilter(blendFunc(anim, a->filter(), b->filter(), progress)); + dst->setBackdropFilter(blendFunc(anim, a->backdropFilter(), b->backdropFilter(), progress, true)); } }; #endif -#endif // USE(ACCELERATED_COMPOSITING) static inline size_t shadowListLength(const ShadowData* shadow) { @@ -595,32 +704,37 @@ static inline size_t shadowListLength(const ShadowData* shadow) static inline const ShadowData* shadowForBlending(const ShadowData* srcShadow, const ShadowData* otherShadow) { - DEFINE_STATIC_LOCAL(ShadowData, defaultShadowData, (IntPoint(), 0, 0, Normal, false, Color::transparent)); - DEFINE_STATIC_LOCAL(ShadowData, defaultInsetShadowData, (IntPoint(), 0, 0, Inset, false, Color::transparent)); - - DEFINE_STATIC_LOCAL(ShadowData, defaultWebKitBoxShadowData, (IntPoint(), 0, 0, Normal, true, Color::transparent)); - DEFINE_STATIC_LOCAL(ShadowData, defaultInsetWebKitBoxShadowData, (IntPoint(), 0, 0, Inset, true, Color::transparent)); + static NeverDestroyed<ShadowData> defaultShadowData(IntPoint(), 0, 0, Normal, false, Color::transparent); + static NeverDestroyed<ShadowData> defaultInsetShadowData(IntPoint(), 0, 0, Inset, false, Color::transparent); + static NeverDestroyed<ShadowData> defaultWebKitBoxShadowData(IntPoint(), 0, 0, Normal, true, Color::transparent); + static NeverDestroyed<ShadowData> defaultInsetWebKitBoxShadowData(IntPoint(), 0, 0, Inset, true, Color::transparent); if (srcShadow) return srcShadow; if (otherShadow->style() == Inset) - return otherShadow->isWebkitBoxShadow() ? &defaultInsetWebKitBoxShadowData : &defaultInsetShadowData; + return otherShadow->isWebkitBoxShadow() ? &defaultInsetWebKitBoxShadowData.get() : &defaultInsetShadowData.get(); - return otherShadow->isWebkitBoxShadow() ? &defaultWebKitBoxShadowData : &defaultShadowData; + return otherShadow->isWebkitBoxShadow() ? &defaultWebKitBoxShadowData.get() : &defaultShadowData.get(); } class PropertyWrapperShadow : public AnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; public: - PropertyWrapperShadow(CSSPropertyID prop, const ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassOwnPtr<ShadowData>, bool)) + PropertyWrapperShadow(CSSPropertyID prop, const ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(std::unique_ptr<ShadowData>, bool)) : AnimationPropertyWrapperBase(prop) , m_getter(getter) , m_setter(setter) { } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + bool equals(const RenderStyle* a, const RenderStyle* b) const override { + if (a == b) + return true; + if (!a || !b) + return false; + const ShadowData* shadowA = (a->*m_getter)(); const ShadowData* shadowB = (b->*m_getter)(); @@ -643,7 +757,7 @@ public: return true; } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { const ShadowData* shadowA = (a->*m_getter)(); const ShadowData* shadowB = (b->*m_getter)(); @@ -659,23 +773,31 @@ public: (dst->*m_setter)(blendMismatchedShadowLists(anim, progress, shadowA, shadowB, fromLength, toLength), false); } +#if !LOG_DISABLED + void logBlend(const RenderStyle*, const RenderStyle*, const RenderStyle*, double progress) const final + { + // FIXME: better logging. + LOG_WITH_STREAM(Animations, stream << " blending ShadowData at " << TextStream::FormatNumberRespectingIntegers(progress)); + } +#endif + private: - PassOwnPtr<ShadowData> blendSimpleOrMatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB) const + std::unique_ptr<ShadowData> blendSimpleOrMatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB) const { - OwnPtr<ShadowData> newShadowData; + std::unique_ptr<ShadowData> newShadowData; ShadowData* lastShadow = 0; while (shadowA || shadowB) { const ShadowData* srcShadow = shadowForBlending(shadowA, shadowB); const ShadowData* dstShadow = shadowForBlending(shadowB, shadowA); - OwnPtr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress); + std::unique_ptr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress); ShadowData* blendedShadowPtr = blendedShadow.get(); if (!lastShadow) - newShadowData = blendedShadow.release(); + newShadowData = WTFMove(blendedShadow); else - lastShadow->setNext(blendedShadow.release()); + lastShadow->setNext(WTFMove(blendedShadow)); lastShadow = blendedShadowPtr; @@ -683,10 +805,10 @@ private: shadowB = shadowB ? shadowB->next() : 0; } - return newShadowData.release(); + return newShadowData; } - PassOwnPtr<ShadowData> blendMismatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB, int fromLength, int toLength) const + std::unique_ptr<ShadowData> blendMismatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB, int fromLength, int toLength) const { // The shadows in ShadowData are stored in reverse order, so when animating mismatched lists, // reverse them and match from the end. @@ -702,7 +824,7 @@ private: shadowB = shadowB->next(); } - OwnPtr<ShadowData> newShadowData; + std::unique_ptr<ShadowData> newShadowData; int maxLength = std::max(fromLength, toLength); for (int i = 0; i < maxLength; ++i) { @@ -712,32 +834,38 @@ private: const ShadowData* srcShadow = shadowForBlending(fromShadow, toShadow); const ShadowData* dstShadow = shadowForBlending(toShadow, fromShadow); - OwnPtr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress); + std::unique_ptr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress); // Insert at the start of the list to preserve the order. - blendedShadow->setNext(newShadowData.release()); - newShadowData = blendedShadow.release(); + blendedShadow->setNext(WTFMove(newShadowData)); + newShadowData = WTFMove(blendedShadow); } - return newShadowData.release(); + return newShadowData; } const ShadowData* (RenderStyle::*m_getter)() const; - void (RenderStyle::*m_setter)(PassOwnPtr<ShadowData>, bool); + void (RenderStyle::*m_setter)(std::unique_ptr<ShadowData>, bool); }; class PropertyWrapperMaybeInvalidColor : public AnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; public: - PropertyWrapperMaybeInvalidColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&)) + PropertyWrapperMaybeInvalidColor(CSSPropertyID prop, const Color& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&)) : AnimationPropertyWrapperBase(prop) , m_getter(getter) , m_setter(setter) { } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + bool equals(const RenderStyle* a, const RenderStyle* b) const override { - Color fromColor = (a->*m_getter)(); - Color toColor = (b->*m_getter)(); + if (a == b) + return true; + if (!a || !b) + return false; + + Color fromColor = value(a); + Color toColor = value(b); if (!fromColor.isValid() && !toColor.isValid()) return true; @@ -750,10 +878,10 @@ public: return fromColor == toColor; } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { - Color fromColor = (a->*m_getter)(); - Color toColor = (b->*m_getter)(); + Color fromColor = value(a); + Color toColor = value(b); if (!fromColor.isValid() && !toColor.isValid()) return; @@ -765,46 +893,69 @@ public: (dst->*m_setter)(blendFunc(anim, fromColor, toColor, progress)); } + Color value(const RenderStyle* a) const + { + return (a->*m_getter)(); + } + +#if !LOG_DISABLED + void logBlend(const RenderStyle* a, const RenderStyle* b, const RenderStyle* result, double progress) const final + { + // FIXME: better logging. + LOG_WITH_STREAM(Animations, stream << " blending " << getPropertyName(property()) << " from " << value(a) << " to " << value(b) << " at " << TextStream::FormatNumberRespectingIntegers(progress) << " -> " << value(result)); + } +#endif + private: - Color (RenderStyle::*m_getter)() const; + const Color& (RenderStyle::*m_getter)() const; void (RenderStyle::*m_setter)(const Color&); }; enum MaybeInvalidColorTag { MaybeInvalidColor }; class PropertyWrapperVisitedAffectedColor : public AnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; public: - PropertyWrapperVisitedAffectedColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&), - Color (RenderStyle::*visitedGetter)() const, void (RenderStyle::*visitedSetter)(const Color&)) + PropertyWrapperVisitedAffectedColor(CSSPropertyID prop, const Color& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&), + const Color& (RenderStyle::*visitedGetter)() const, void (RenderStyle::*visitedSetter)(const Color&)) : AnimationPropertyWrapperBase(prop) - , m_wrapper(adoptPtr(new PropertyWrapperColor(prop, getter, setter))) - , m_visitedWrapper(adoptPtr(new PropertyWrapperColor(prop, visitedGetter, visitedSetter))) + , m_wrapper(std::make_unique<PropertyWrapperColor>(prop, getter, setter)) + , m_visitedWrapper(std::make_unique<PropertyWrapperColor>(prop, visitedGetter, visitedSetter)) { } - PropertyWrapperVisitedAffectedColor(CSSPropertyID prop, MaybeInvalidColorTag, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&), - Color (RenderStyle::*visitedGetter)() const, void (RenderStyle::*visitedSetter)(const Color&)) + PropertyWrapperVisitedAffectedColor(CSSPropertyID prop, MaybeInvalidColorTag, const Color& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&), + const Color& (RenderStyle::*visitedGetter)() const, void (RenderStyle::*visitedSetter)(const Color&)) : AnimationPropertyWrapperBase(prop) - , m_wrapper(adoptPtr(new PropertyWrapperMaybeInvalidColor(prop, getter, setter))) - , m_visitedWrapper(adoptPtr(new PropertyWrapperMaybeInvalidColor(prop, visitedGetter, visitedSetter))) + , m_wrapper(std::make_unique<PropertyWrapperMaybeInvalidColor>(prop, getter, setter)) + , m_visitedWrapper(std::make_unique<PropertyWrapperMaybeInvalidColor>(prop, visitedGetter, visitedSetter)) { } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + bool equals(const RenderStyle* a, const RenderStyle* b) const override { return m_wrapper->equals(a, b) && m_visitedWrapper->equals(a, b); } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { m_wrapper->blend(anim, dst, a, b, progress); m_visitedWrapper->blend(anim, dst, a, b, progress); } +#if !LOG_DISABLED + void logBlend(const RenderStyle* a, const RenderStyle* b, const RenderStyle* result, double progress) const final + { + m_wrapper->logBlend(a, b, result, progress); + m_visitedWrapper->logBlend(a, b, result, progress); + } +#endif + private: - OwnPtr<AnimationPropertyWrapperBase> m_wrapper; - OwnPtr<AnimationPropertyWrapperBase> m_visitedWrapper; + std::unique_ptr<AnimationPropertyWrapperBase> m_wrapper; + std::unique_ptr<AnimationPropertyWrapperBase> m_visitedWrapper; }; // Wrapper base class for an animatable property in a FillLayer class FillLayerAnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; public: FillLayerAnimationPropertyWrapperBase() { @@ -818,6 +969,7 @@ public: template <typename T> class FillLayerPropertyWrapperGetter : public FillLayerAnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(FillLayerPropertyWrapperGetter); public: FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const) @@ -825,13 +977,11 @@ public: { } - virtual bool equals(const FillLayer* a, const FillLayer* b) const + bool equals(const FillLayer* a, const FillLayer* b) const override { - // If the style pointers are the same, don't bother doing the test. - // If either is null, return false. If both are null, return true. - if ((!a && !b) || a == b) - return true; - if (!a || !b) + if (a == b) + return true; + if (!a || !b) return false; return (a->*m_getter)() == (b->*m_getter)(); } @@ -842,6 +992,7 @@ protected: template <typename T> class FillLayerPropertyWrapper : public FillLayerPropertyWrapperGetter<const T&> { + WTF_MAKE_FAST_ALLOCATED; public: FillLayerPropertyWrapper(const T& (FillLayer::*getter)() const, void (FillLayer::*setter)(T)) : FillLayerPropertyWrapperGetter<const T&>(getter) @@ -849,7 +1000,7 @@ public: { } - virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const + void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const override { (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<const T&>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<const T&>::m_getter)(), progress)); } @@ -860,33 +1011,33 @@ protected: template <typename T> class FillLayerRefCountedPropertyWrapper : public FillLayerPropertyWrapperGetter<T*> { + WTF_MAKE_FAST_ALLOCATED; public: - FillLayerRefCountedPropertyWrapper(T* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<T>)) + FillLayerRefCountedPropertyWrapper(T* (FillLayer::*getter)() const, void (FillLayer::*setter)(RefPtr<T>&&)) : FillLayerPropertyWrapperGetter<T*>(getter) , m_setter(setter) { } - virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const + void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const override { (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<T*>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<T*>::m_getter)(), progress)); } protected: - void (FillLayer::*m_setter)(PassRefPtr<T>); + void (FillLayer::*m_setter)(RefPtr<T>&&); }; class FillLayerStyleImagePropertyWrapper : public FillLayerRefCountedPropertyWrapper<StyleImage> { + WTF_MAKE_FAST_ALLOCATED; public: - FillLayerStyleImagePropertyWrapper(StyleImage* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<StyleImage>)) + FillLayerStyleImagePropertyWrapper(StyleImage* (FillLayer::*getter)() const, void (FillLayer::*setter)(RefPtr<StyleImage>&&)) : FillLayerRefCountedPropertyWrapper<StyleImage>(getter, setter) { } - virtual bool equals(const FillLayer* a, const FillLayer* b) const + bool equals(const FillLayer* a, const FillLayer* b) const override { - // If the style pointers are the same, don't bother doing the test. - // If either is null, return false. If both are null, return true. if (a == b) return true; if (!a || !b) @@ -894,14 +1045,15 @@ public: StyleImage* imageA = (a->*m_getter)(); StyleImage* imageB = (b->*m_getter)(); - return StyleImage::imagesEquivalent(imageA, imageB); + return arePointingToEqualData(imageA, imageB); } }; class FillLayersPropertyWrapper : public AnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; public: - typedef const FillLayer* (RenderStyle::*LayersGetter)() const; - typedef FillLayer* (RenderStyle::*LayersAccessor)(); + typedef const FillLayer& (RenderStyle::*LayersGetter)() const; + typedef FillLayer& (RenderStyle::*LayersAccessor)(); FillLayersPropertyWrapper(CSSPropertyID prop, LayersGetter getter, LayersAccessor accessor) : AnimationPropertyWrapperBase(prop) @@ -911,29 +1063,34 @@ public: switch (prop) { case CSSPropertyBackgroundPositionX: case CSSPropertyWebkitMaskPositionX: - m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::xPosition, &FillLayer::setXPosition); + m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<Length>>(&FillLayer::xPosition, &FillLayer::setXPosition); break; case CSSPropertyBackgroundPositionY: case CSSPropertyWebkitMaskPositionY: - m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::yPosition, &FillLayer::setYPosition); + m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<Length>>(&FillLayer::yPosition, &FillLayer::setYPosition); break; case CSSPropertyBackgroundSize: case CSSPropertyWebkitBackgroundSize: case CSSPropertyWebkitMaskSize: - m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<LengthSize>(&FillLayer::sizeLength, &FillLayer::setSizeLength); + m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<LengthSize>>(&FillLayer::sizeLength, &FillLayer::setSizeLength); break; case CSSPropertyBackgroundImage: - m_fillLayerPropertyWrapper = new FillLayerStyleImagePropertyWrapper(&FillLayer::image, &FillLayer::setImage); + m_fillLayerPropertyWrapper = std::make_unique<FillLayerStyleImagePropertyWrapper>(&FillLayer::image, &FillLayer::setImage); break; default: break; } } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + bool equals(const RenderStyle* a, const RenderStyle* b) const override { - const FillLayer* fromLayer = (a->*m_layersGetter)(); - const FillLayer* toLayer = (b->*m_layersGetter)(); + if (a == b) + return true; + if (!a || !b) + return false; + + auto* fromLayer = &(a->*m_layersGetter)(); + auto* toLayer = &(b->*m_layersGetter)(); while (fromLayer && toLayer) { if (!m_fillLayerPropertyWrapper->equals(fromLayer, toLayer)) @@ -946,11 +1103,11 @@ public: return true; } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { - const FillLayer* aLayer = (a->*m_layersGetter)(); - const FillLayer* bLayer = (b->*m_layersGetter)(); - FillLayer* dstLayer = (dst->*m_layersAccessor)(); + auto* aLayer = &(a->*m_layersGetter)(); + auto* bLayer = &(b->*m_layersGetter)(); + auto* dstLayer = &(dst->*m_layersAccessor)(); while (aLayer && bLayer && dstLayer) { m_fillLayerPropertyWrapper->blend(anim, dstLayer, aLayer, bLayer, progress); @@ -960,57 +1117,77 @@ public: } } +#if !LOG_DISABLED + void logBlend(const RenderStyle*, const RenderStyle*, const RenderStyle*, double progress) const final + { + // FIXME: better logging. + LOG_WITH_STREAM(Animations, stream << " blending FillLayers at " << TextStream::FormatNumberRespectingIntegers(progress)); + } +#endif + private: - FillLayerAnimationPropertyWrapperBase* m_fillLayerPropertyWrapper; + std::unique_ptr<FillLayerAnimationPropertyWrapperBase> m_fillLayerPropertyWrapper; LayersGetter m_layersGetter; LayersAccessor m_layersAccessor; }; class ShorthandPropertyWrapper : public AnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; public: ShorthandPropertyWrapper(CSSPropertyID property, Vector<AnimationPropertyWrapperBase*> longhandWrappers) : AnimationPropertyWrapperBase(property) + , m_propertyWrappers(WTFMove(longhandWrappers)) { - m_propertyWrappers.swap(longhandWrappers); } - virtual bool isShorthandWrapper() const { return true; } + bool isShorthandWrapper() const override { return true; } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + bool equals(const RenderStyle* a, const RenderStyle* b) const override { - Vector<AnimationPropertyWrapperBase*>::const_iterator end = m_propertyWrappers.end(); - for (Vector<AnimationPropertyWrapperBase*>::const_iterator it = m_propertyWrappers.begin(); it != end; ++it) { - if (!(*it)->equals(a, b)) + if (a == b) + return true; + if (!a || !b) + return false; + + for (auto& wrapper : m_propertyWrappers) { + if (!wrapper->equals(a, b)) return false; } return true; } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override + { + for (auto& wrapper : m_propertyWrappers) + wrapper->blend(anim, dst, a, b, progress); + } + +#if !LOG_DISABLED + void logBlend(const RenderStyle*, const RenderStyle*, const RenderStyle*, double progress) const final { - Vector<AnimationPropertyWrapperBase*>::const_iterator end = m_propertyWrappers.end(); - for (Vector<AnimationPropertyWrapperBase*>::const_iterator it = m_propertyWrappers.begin(); it != end; ++it) - (*it)->blend(anim, dst, a, b, progress); + // FIXME: better logging. + LOG_WITH_STREAM(Animations, stream << " blending shorthand property " << getPropertyName(property()) << " at " << TextStream::FormatNumberRespectingIntegers(progress)); } +#endif - const Vector<AnimationPropertyWrapperBase*> propertyWrappers() const { return m_propertyWrappers; } + const Vector<AnimationPropertyWrapperBase*>& propertyWrappers() const { return m_propertyWrappers; } private: Vector<AnimationPropertyWrapperBase*> m_propertyWrappers; }; class PropertyWrapperFlex : public AnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; public: - PropertyWrapperFlex() : AnimationPropertyWrapperBase(CSSPropertyWebkitFlex) + PropertyWrapperFlex() + : AnimationPropertyWrapperBase(CSSPropertyFlex) { } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + bool equals(const RenderStyle* a, const RenderStyle* b) const override { - // If the style pointers are the same, don't bother doing the test. - // If either is null, return false. If both are null, return true. - if ((!a && !b) || a == b) + if (a == b) return true; if (!a || !b) return false; @@ -1018,18 +1195,26 @@ public: return a->flexBasis() == b->flexBasis() && a->flexGrow() == b->flexGrow() && a->flexShrink() == b->flexShrink(); } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { dst->setFlexBasis(blendFunc(anim, a->flexBasis(), b->flexBasis(), progress)); dst->setFlexGrow(blendFunc(anim, a->flexGrow(), b->flexGrow(), progress)); dst->setFlexShrink(blendFunc(anim, a->flexShrink(), b->flexShrink(), progress)); } + +#if !LOG_DISABLED + void logBlend(const RenderStyle*, const RenderStyle*, const RenderStyle*, double progress) const final + { + // FIXME: better logging. + LOG_WITH_STREAM(Animations, stream << " blending flex at " << TextStream::FormatNumberRespectingIntegers(progress)); + } +#endif }; -#if ENABLE(SVG) class PropertyWrapperSVGPaint : public AnimationPropertyWrapperBase { + WTF_MAKE_FAST_ALLOCATED; public: - PropertyWrapperSVGPaint(CSSPropertyID prop, const SVGPaint::SVGPaintType& (RenderStyle::*paintTypeGetter)() const, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&)) + PropertyWrapperSVGPaint(CSSPropertyID prop, const SVGPaintType& (RenderStyle::*paintTypeGetter)() const, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&)) : AnimationPropertyWrapperBase(prop) , m_paintTypeGetter(paintTypeGetter) , m_getter(getter) @@ -1037,15 +1222,20 @@ public: { } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + bool equals(const RenderStyle* a, const RenderStyle* b) const override { + if (a == b) + return true; + if (!a || !b) + return false; + if ((a->*m_paintTypeGetter)() != (b->*m_paintTypeGetter)()) return false; // We only support animations between SVGPaints that are pure Color values. // For everything else we must return true for this method, otherwise // we will try to animate between values forever. - if ((a->*m_paintTypeGetter)() == SVGPaint::SVG_PAINTTYPE_RGBCOLOR) { + if ((a->*m_paintTypeGetter)() == SVG_PAINTTYPE_RGBCOLOR) { Color fromColor = (a->*m_getter)(); Color toColor = (b->*m_getter)(); @@ -1062,10 +1252,10 @@ public: return true; } - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override { - if ((a->*m_paintTypeGetter)() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR - || (b->*m_paintTypeGetter)() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR) + if ((a->*m_paintTypeGetter)() != SVG_PAINTTYPE_RGBCOLOR + || (b->*m_paintTypeGetter)() != SVG_PAINTTYPE_RGBCOLOR) return; Color fromColor = (a->*m_getter)(); @@ -1081,32 +1271,38 @@ public: (dst->*m_setter)(blendFunc(anim, fromColor, toColor, progress)); } +#if !LOG_DISABLED + void logBlend(const RenderStyle*, const RenderStyle*, const RenderStyle*, double progress) const final + { + // FIXME: better logging. + LOG_WITH_STREAM(Animations, stream << " blending SVGPaint at " << TextStream::FormatNumberRespectingIntegers(progress)); + } +#endif + private: - const SVGPaint::SVGPaintType& (RenderStyle::*m_paintTypeGetter)() const; + const SVGPaintType& (RenderStyle::*m_paintTypeGetter)() const; Color (RenderStyle::*m_getter)() const; void (RenderStyle::*m_setter)(const Color&); }; -#endif class CSSPropertyAnimationWrapperMap { + WTF_MAKE_FAST_ALLOCATED; public: - static CSSPropertyAnimationWrapperMap& instance() + static CSSPropertyAnimationWrapperMap& singleton() { - // FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last AnimationController is destroyed? - DEFINE_STATIC_LOCAL(OwnPtr<CSSPropertyAnimationWrapperMap>, map, ()); - if (!map) - map = adoptPtr(new CSSPropertyAnimationWrapperMap); - return *map; + // FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last CSSAnimationController is destroyed? + static NeverDestroyed<CSSPropertyAnimationWrapperMap> map; + return map; } AnimationPropertyWrapperBase* wrapperForProperty(CSSPropertyID propertyID) { if (propertyID < firstCSSProperty || propertyID > lastCSSProperty) - return 0; + return nullptr; unsigned wrapperIndex = indexFromPropertyID(propertyID); if (wrapperIndex == cInvalidPropertyWrapperIndex) - return 0; + return nullptr; return m_propertyWrappers[wrapperIndex].get(); } @@ -1124,15 +1320,19 @@ public: private: CSSPropertyAnimationWrapperMap(); + ~CSSPropertyAnimationWrapperMap() = delete; + unsigned char& indexFromPropertyID(CSSPropertyID propertyID) { return m_propertyToIdMap[propertyID - firstCSSProperty]; } - Vector<OwnPtr<AnimationPropertyWrapperBase>> m_propertyWrappers; + Vector<std::unique_ptr<AnimationPropertyWrapperBase>> m_propertyWrappers; unsigned char m_propertyToIdMap[numCSSProperties]; static const unsigned char cInvalidPropertyWrapperIndex = UCHAR_MAX; + + friend class WTF::NeverDestroyed<CSSPropertyAnimationWrapperMap>; }; CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() @@ -1154,10 +1354,10 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() new PropertyWrapperFlex(), - new PropertyWrapper<unsigned>(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth), - new PropertyWrapper<unsigned>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth), - new PropertyWrapper<unsigned>(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth), - new PropertyWrapper<unsigned>(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth), + new PropertyWrapper<float>(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth), + new PropertyWrapper<float>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth), + new PropertyWrapper<float>(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth), + new PropertyWrapper<float>(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth), new LengthPropertyWrapper<Length>(CSSPropertyMarginLeft, &RenderStyle::marginLeft, &RenderStyle::setMarginLeft), new LengthPropertyWrapper<Length>(CSSPropertyMarginRight, &RenderStyle::marginRight, &RenderStyle::setMarginRight), new LengthPropertyWrapper<Length>(CSSPropertyMarginTop, &RenderStyle::marginTop, &RenderStyle::setMarginTop), @@ -1170,7 +1370,7 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() new PropertyWrapperVisitedAffectedColor(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor, &RenderStyle::visitedLinkBackgroundColor, &RenderStyle::setVisitedLinkBackgroundColor), - new FillLayersPropertyWrapper(CSSPropertyBackgroundImage, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers), + new FillLayersPropertyWrapper(CSSPropertyBackgroundImage, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers), new StyleImagePropertyWrapper(CSSPropertyListStyleImage, &RenderStyle::listStyleImage, &RenderStyle::setListStyleImage), new StyleImagePropertyWrapper(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage, &RenderStyle::setMaskImage), @@ -1182,47 +1382,38 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() new StyleImagePropertyWrapper(CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource, &RenderStyle::setMaskBoxImageSource), new PropertyWrapper<const NinePieceImage&>(CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage), - new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers), - new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers), - new FillLayersPropertyWrapper(CSSPropertyBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers), - new FillLayersPropertyWrapper(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers), - - new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers), - new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers), - new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers), - - new PropertyWrapper<float>(CSSPropertyFontSize, - // Must pass a specified size to setFontSize if Text Autosizing is enabled, but a computed size - // if text zoom is enabled (if neither is enabled it's irrelevant as they're probably the same). - // FIXME: Find some way to assert that text zoom isn't activated when Text Autosizing is compiled in. -#if ENABLE(TEXT_AUTOSIZING) - &RenderStyle::specifiedFontSize, -#else - &RenderStyle::computedFontSize, -#endif - &RenderStyle::setFontSize), - new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth), - new PropertyWrapper<float>(CSSPropertyWebkitColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap), - new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount), - new PropertyWrapper<float>(CSSPropertyWebkitColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth), - new PropertyWrapper<short>(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing), - new PropertyWrapper<short>(CSSPropertyWebkitBorderVerticalSpacing, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing), + new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers), + new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers), + new FillLayersPropertyWrapper(CSSPropertyBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers), + new FillLayersPropertyWrapper(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers), + + new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers, &RenderStyle::ensureMaskLayers), + new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers, &RenderStyle::ensureMaskLayers), + new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers, &RenderStyle::ensureMaskLayers), + + new PropertyWrapper<float>(CSSPropertyFontSize, &RenderStyle::computedFontSize, &RenderStyle::setFontSize), + new PropertyWrapper<unsigned short>(CSSPropertyColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth), + new PropertyWrapper<float>(CSSPropertyColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap), + new PropertyWrapper<unsigned short>(CSSPropertyColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount), + new PropertyWrapper<float>(CSSPropertyColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth), + new PropertyWrapper<float>(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing), + new PropertyWrapper<float>(CSSPropertyWebkitBorderVerticalSpacing, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing), new PropertyWrapper<int>(CSSPropertyZIndex, &RenderStyle::zIndex, &RenderStyle::setZIndex), new PropertyWrapper<short>(CSSPropertyOrphans, &RenderStyle::orphans, &RenderStyle::setOrphans), new PropertyWrapper<short>(CSSPropertyWidows, &RenderStyle::widows, &RenderStyle::setWidows), new LengthPropertyWrapper<Length>(CSSPropertyLineHeight, &RenderStyle::specifiedLineHeight, &RenderStyle::setLineHeight), - new PropertyWrapper<int>(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset), - new PropertyWrapper<unsigned short>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth), + new PropertyWrapper<float>(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset), + new PropertyWrapper<float>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth), new PropertyWrapper<float>(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing), new LengthPropertyWrapper<Length>(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing), new LengthPropertyWrapper<Length>(CSSPropertyTextIndent, &RenderStyle::textIndent, &RenderStyle::setTextIndent), - new PropertyWrapper<float>(CSSPropertyWebkitPerspective, &RenderStyle::perspective, &RenderStyle::setPerspective), - new LengthPropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX), - new LengthPropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY), - new LengthPropertyWrapper<Length>(CSSPropertyWebkitTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX), - new LengthPropertyWrapper<Length>(CSSPropertyWebkitTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY), - new PropertyWrapper<float>(CSSPropertyWebkitTransformOriginZ, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ), + new PropertyWrapper<float>(CSSPropertyPerspective, &RenderStyle::perspective, &RenderStyle::setPerspective), + new LengthPropertyWrapper<Length>(CSSPropertyPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX), + new LengthPropertyWrapper<Length>(CSSPropertyPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY), + new LengthPropertyWrapper<Length>(CSSPropertyTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX), + new LengthPropertyWrapper<Length>(CSSPropertyTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY), + new PropertyWrapper<float>(CSSPropertyTransformOriginZ, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ), new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius), new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius), new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius), @@ -1232,30 +1423,19 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() new LengthPropertyWrapper<LengthBox>(CSSPropertyClip, &RenderStyle::clip, &RenderStyle::setClip), -#if USE(ACCELERATED_COMPOSITING) new PropertyWrapperAcceleratedOpacity(), new PropertyWrapperAcceleratedTransform(), -#if ENABLE(CSS_FILTERS) new PropertyWrapperAcceleratedFilter(), +#if ENABLE(FILTERS_LEVEL_2) + new PropertyWrapperAcceleratedBackdropFilter(), #endif -#else - new PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity), - new PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform), -#if ENABLE(CSS_FILTERS) - new PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter), -#endif -#endif - new PropertyWrapperClipPath(CSSPropertyWebkitClipPath, &RenderStyle::clipPath, &RenderStyle::setClipPath), -#if ENABLE(CSS_SHAPES) - new PropertyWrapperShape(CSSPropertyWebkitShapeInside, &RenderStyle::shapeInside, &RenderStyle::setShapeInside), - new PropertyWrapperShape(CSSPropertyWebkitShapeOutside, &RenderStyle::shapeOutside, &RenderStyle::setShapeOutside), - new LengthPropertyWrapper<Length>(CSSPropertyWebkitShapeMargin, &RenderStyle::shapeMargin, &RenderStyle::setShapeMargin), - new PropertyWrapper<float>(CSSPropertyWebkitShapeImageThreshold, &RenderStyle::shapeImageThreshold, &RenderStyle::setShapeImageThreshold), -#endif + new PropertyWrapperShape(CSSPropertyShapeOutside, &RenderStyle::shapeOutside, &RenderStyle::setShapeOutside), + new LengthPropertyWrapper<Length>(CSSPropertyShapeMargin, &RenderStyle::shapeMargin, &RenderStyle::setShapeMargin), + new PropertyWrapper<float>(CSSPropertyShapeImageThreshold, &RenderStyle::shapeImageThreshold, &RenderStyle::setShapeImageThreshold), - new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitColumnRuleColor, MaybeInvalidColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor, &RenderStyle::visitedLinkColumnRuleColor, &RenderStyle::setVisitedLinkColumnRuleColor), + new PropertyWrapperVisitedAffectedColor(CSSPropertyColumnRuleColor, MaybeInvalidColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor, &RenderStyle::visitedLinkColumnRuleColor, &RenderStyle::setVisitedLinkColumnRuleColor), new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitTextStrokeColor, MaybeInvalidColor, &RenderStyle::textStrokeColor, &RenderStyle::setTextStrokeColor, &RenderStyle::visitedLinkTextStrokeColor, &RenderStyle::setVisitedLinkTextStrokeColor), new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitTextFillColor, MaybeInvalidColor, &RenderStyle::textFillColor, &RenderStyle::setTextFillColor, &RenderStyle::visitedLinkTextFillColor, &RenderStyle::setVisitedLinkTextFillColor), new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderLeftColor, MaybeInvalidColor, &RenderStyle::borderLeftColor, &RenderStyle::setBorderLeftColor, &RenderStyle::visitedLinkBorderLeftColor, &RenderStyle::setVisitedLinkBorderLeftColor), @@ -1268,17 +1448,24 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow), new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow), -#if ENABLE(SVG) new PropertyWrapperSVGPaint(CSSPropertyFill, &RenderStyle::fillPaintType, &RenderStyle::fillPaintColor, &RenderStyle::setFillPaintColor), new PropertyWrapper<float>(CSSPropertyFillOpacity, &RenderStyle::fillOpacity, &RenderStyle::setFillOpacity), new PropertyWrapperSVGPaint(CSSPropertyStroke, &RenderStyle::strokePaintType, &RenderStyle::strokePaintColor, &RenderStyle::setStrokePaintColor), new PropertyWrapper<float>(CSSPropertyStrokeOpacity, &RenderStyle::strokeOpacity, &RenderStyle::setStrokeOpacity), - new PropertyWrapper<SVGLength>(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth, &RenderStyle::setStrokeWidth), - new PropertyWrapper< Vector<SVGLength>>(CSSPropertyStrokeDasharray, &RenderStyle::strokeDashArray, &RenderStyle::setStrokeDashArray), - new PropertyWrapper<SVGLength>(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset, &RenderStyle::setStrokeDashOffset), + new PropertyWrapper<Vector<SVGLengthValue>>(CSSPropertyStrokeDasharray, &RenderStyle::strokeDashArray, &RenderStyle::setStrokeDashArray), new PropertyWrapper<float>(CSSPropertyStrokeMiterlimit, &RenderStyle::strokeMiterLimit, &RenderStyle::setStrokeMiterLimit), + new LengthPropertyWrapper<Length>(CSSPropertyCx, &RenderStyle::cx, &RenderStyle::setCx), + new LengthPropertyWrapper<Length>(CSSPropertyCy, &RenderStyle::cy, &RenderStyle::setCy), + new LengthPropertyWrapper<Length>(CSSPropertyR, &RenderStyle::r, &RenderStyle::setR), + new LengthPropertyWrapper<Length>(CSSPropertyRx, &RenderStyle::rx, &RenderStyle::setRx), + new LengthPropertyWrapper<Length>(CSSPropertyRy, &RenderStyle::ry, &RenderStyle::setRy), + new LengthPropertyWrapper<Length>(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset, &RenderStyle::setStrokeDashOffset), + new LengthPropertyWrapper<Length>(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth, &RenderStyle::setStrokeWidth), + new LengthPropertyWrapper<Length>(CSSPropertyX, &RenderStyle::x, &RenderStyle::setX), + new LengthPropertyWrapper<Length>(CSSPropertyY, &RenderStyle::y, &RenderStyle::setY), + new PropertyWrapper<float>(CSSPropertyFloodOpacity, &RenderStyle::floodOpacity, &RenderStyle::setFloodOpacity), new PropertyWrapperMaybeInvalidColor(CSSPropertyFloodColor, &RenderStyle::floodColor, &RenderStyle::setFloodColor), @@ -1287,8 +1474,10 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() new PropertyWrapperMaybeInvalidColor(CSSPropertyLightingColor, &RenderStyle::lightingColor, &RenderStyle::setLightingColor), - new PropertyWrapper<SVGLength>(CSSPropertyBaselineShift, &RenderStyle::baselineShiftValue, &RenderStyle::setBaselineShiftValue), - new PropertyWrapper<SVGLength>(CSSPropertyKerning, &RenderStyle::kerning, &RenderStyle::setKerning), + new PropertyWrapper<SVGLengthValue>(CSSPropertyBaselineShift, &RenderStyle::baselineShiftValue, &RenderStyle::setBaselineShiftValue), + new PropertyWrapper<SVGLengthValue>(CSSPropertyKerning, &RenderStyle::kerning, &RenderStyle::setKerning), +#if ENABLE(VARIATION_FONTS) + new PropertyWrapperFontVariationSettings(CSSPropertyFontVariationSettings, &RenderStyle::fontVariationSettings, &RenderStyle::setFontVariationSettings), #endif }; const unsigned animatableLonghandPropertiesCount = WTF_ARRAY_LENGTH(animatableLonghandPropertyWrappers); @@ -1311,9 +1500,9 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() CSSPropertyOutline, CSSPropertyPadding, CSSPropertyWebkitTextStroke, - CSSPropertyWebkitColumnRule, + CSSPropertyColumnRule, CSSPropertyWebkitBorderRadius, - CSSPropertyWebkitTransformOrigin + CSSPropertyTransformOrigin }; const unsigned animatableShorthandPropertiesCount = WTF_ARRAY_LENGTH(animatableShorthandProperties); @@ -1323,7 +1512,7 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() // // Compound properties that have components that should be animatable: // - // CSSPropertyWebkitColumns + // CSSPropertyColumns // CSSPropertyWebkitBoxReflect // Make sure unused slots have a value @@ -1338,7 +1527,7 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() for (unsigned i = 0; i < animatableLonghandPropertiesCount; ++i) { AnimationPropertyWrapperBase* wrapper = animatableLonghandPropertyWrappers[i]; - m_propertyWrappers.uncheckedAppend(adoptPtr(wrapper)); + m_propertyWrappers.uncheckedAppend(std::unique_ptr<AnimationPropertyWrapperBase>(wrapper)); indexFromPropertyID(wrapper->property()) = i; } @@ -1359,7 +1548,7 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() longhandWrappers.uncheckedAppend(m_propertyWrappers[wrapperIndex].get()); } - m_propertyWrappers.uncheckedAppend(adoptPtr(new ShorthandPropertyWrapper(propertyID, longhandWrappers))); + m_propertyWrappers.uncheckedAppend(std::make_unique<ShorthandPropertyWrapper>(propertyID, WTFMove(longhandWrappers))); indexFromPropertyID(propertyID) = animatableLonghandPropertiesCount + i; } } @@ -1370,11 +1559,8 @@ static bool gatherEnclosingShorthandProperties(CSSPropertyID property, Animation return false; ShorthandPropertyWrapper* shorthandWrapper = static_cast<ShorthandPropertyWrapper*>(wrapper); - bool contained = false; - for (size_t i = 0; i < shorthandWrapper->propertyWrappers().size(); ++i) { - AnimationPropertyWrapperBase* currWrapper = shorthandWrapper->propertyWrappers()[i]; - + for (auto& currWrapper : shorthandWrapper->propertyWrappers()) { if (gatherEnclosingShorthandProperties(property, currWrapper, propertySet) || currWrapper->property() == property) contained = true; } @@ -1390,31 +1576,27 @@ bool CSSPropertyAnimation::blendProperties(const AnimationBase* anim, CSSPropert { ASSERT(prop != CSSPropertyInvalid); - AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::instance().wrapperForProperty(prop); + AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(prop); if (wrapper) { wrapper->blend(anim, dst, a, b, progress); -#if USE(ACCELERATED_COMPOSITING) - return !wrapper->animationIsAccelerated() || !anim->isAccelerated(); -#else - return true; +#if !LOG_DISABLED + wrapper->logBlend(a, b, dst, progress); #endif + return !wrapper->animationIsAccelerated() || !anim->isAccelerated(); } - return false; } -#if USE(ACCELERATED_COMPOSITING) bool CSSPropertyAnimation::animationOfPropertyIsAccelerated(CSSPropertyID prop) { - AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::instance().wrapperForProperty(prop); + AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(prop); return wrapper ? wrapper->animationIsAccelerated() : false; } -#endif // Note: this is inefficient. It's only called from pauseTransitionAtTime(). HashSet<CSSPropertyID> CSSPropertyAnimation::animatableShorthandsAffectingProperty(CSSPropertyID property) { - CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::instance(); + CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::singleton(); HashSet<CSSPropertyID> foundProperties; for (unsigned i = 0; i < map.size(); ++i) @@ -1425,7 +1607,7 @@ HashSet<CSSPropertyID> CSSPropertyAnimation::animatableShorthandsAffectingProper bool CSSPropertyAnimation::propertiesEqual(CSSPropertyID prop, const RenderStyle* a, const RenderStyle* b) { - AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::instance().wrapperForProperty(prop); + AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(prop); if (wrapper) return wrapper->equals(a, b); return true; @@ -1433,7 +1615,7 @@ bool CSSPropertyAnimation::propertiesEqual(CSSPropertyID prop, const RenderStyle CSSPropertyID CSSPropertyAnimation::getPropertyAtIndex(int i, bool& isShorthand) { - CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::instance(); + CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::singleton(); if (i < 0 || static_cast<unsigned>(i) >= map.size()) return CSSPropertyInvalid; @@ -1445,7 +1627,7 @@ CSSPropertyID CSSPropertyAnimation::getPropertyAtIndex(int i, bool& isShorthand) int CSSPropertyAnimation::getNumProperties() { - return CSSPropertyAnimationWrapperMap::instance().size(); + return CSSPropertyAnimationWrapperMap::singleton().size(); } } |