From 8583afad61d535eed4f61f941d46c18185e442c1 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa Date: Sat, 14 Sep 2013 03:58:50 +0000 Subject: [PATCH] CSSPropertyAnimation::ensurePropertyMap() is large https://bugs.webkit.org/show_bug.cgi?id=121199 Reviewed by Darin Adler. The bug was caused by repeated calls to Vector::append. Avoid it by storing pointers in a local array and then adding them as we traverse them through to fill m_propertyToIdMap. Also reserve the full initial capacity at once to avoid repeated calls to FastMalloc and FastFree. * page/animation/CSSPropertyAnimation.cpp: (WebCore::CSSPropertyAnimationWrapperMap::instance): (WebCore::CSSPropertyAnimationWrapperMap::wrapperForProperty): (WebCore::CSSPropertyAnimationWrapperMap::wrapperForIndex): (WebCore::CSSPropertyAnimationWrapperMap::indexFromPropertyID): (WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap): Renamed from ensurePropertyMap. Also merged addShorthandProperties into it since they have to access local variables of the other. Canonical link: https://commits.webkit.org/139300@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@155743 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 19 + .../page/animation/CSSPropertyAnimation.cpp | 388 +++++++++--------- 2 files changed, 209 insertions(+), 198 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 57db63f28e7d..fcb0395e60e5 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,22 @@ +2013-09-12 Ryosuke Niwa + + CSSPropertyAnimation::ensurePropertyMap() is large + https://bugs.webkit.org/show_bug.cgi?id=121199 + + Reviewed by Darin Adler. + + The bug was caused by repeated calls to Vector::append. Avoid it by storing pointers in a local array + and then adding them as we traverse them through to fill m_propertyToIdMap. Also reserve the full + initial capacity at once to avoid repeated calls to FastMalloc and FastFree. + + * page/animation/CSSPropertyAnimation.cpp: + (WebCore::CSSPropertyAnimationWrapperMap::instance): + (WebCore::CSSPropertyAnimationWrapperMap::wrapperForProperty): + (WebCore::CSSPropertyAnimationWrapperMap::wrapperForIndex): + (WebCore::CSSPropertyAnimationWrapperMap::indexFromPropertyID): + (WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap): Renamed from ensurePropertyMap. + Also merged addShorthandProperties into it since they have to access local variables of the other. + 2013-09-13 Ryuan Choi Unreviewed build fix for EFL port. diff --git a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp index ef08d6817d9f..275f2f8c671a 100644 --- a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp +++ b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp @@ -1081,30 +1081,27 @@ class CSSPropertyAnimationWrapperMap { { // 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, map, ()); - if (!map) { + if (!map) map = adoptPtr(new CSSPropertyAnimationWrapperMap); - map->ensurePropertyMap(); // FIXME: ensurePropertyMap() calls instance() inside addShorthandProperties(). - } return *map; } AnimationPropertyWrapperBase* wrapperForProperty(CSSPropertyID propertyID) { - int propIndex = propertyID - firstCSSProperty; if (propertyID < firstCSSProperty || propertyID > lastCSSProperty) return 0; - unsigned wrapperIndex = m_propertyToIdMap[propIndex]; + unsigned wrapperIndex = indexFromPropertyID(propertyID); if (wrapperIndex == cInvalidPropertyWrapperIndex) return 0; - return m_propertyWrappers[wrapperIndex]; + return m_propertyWrappers[wrapperIndex].get(); } AnimationPropertyWrapperBase* wrapperForIndex(unsigned index) { ASSERT(index < m_propertyWrappers.size()); - return m_propertyWrappers[index]; + return m_propertyWrappers[index].get(); } unsigned size() @@ -1112,224 +1109,197 @@ class CSSPropertyAnimationWrapperMap { return m_propertyWrappers.size(); } - private: - void addShorthandProperties(); - void ensurePropertyMap(); - - void addPropertyWrapper(CSSPropertyID propertyID, AnimationPropertyWrapperBase* wrapper) + CSSPropertyAnimationWrapperMap(); + unsigned char& indexFromPropertyID(CSSPropertyID propertyID) { - int propIndex = propertyID - firstCSSProperty; - - ASSERT(m_propertyToIdMap[propIndex] == cInvalidPropertyWrapperIndex); - - unsigned wrapperIndex = m_propertyWrappers.size(); - m_propertyWrappers.append(wrapper); - m_propertyToIdMap[propIndex] = wrapperIndex; + return m_propertyToIdMap[propertyID - firstCSSProperty]; } - Vector m_propertyWrappers; - unsigned m_propertyToIdMap[numCSSProperties]; + Vector> m_propertyWrappers; + unsigned char m_propertyToIdMap[numCSSProperties]; - static const unsigned cInvalidPropertyWrapperIndex = UINT_MAX; + static const unsigned char cInvalidPropertyWrapperIndex = UCHAR_MAX; }; -void CSSPropertyAnimationWrapperMap::addShorthandProperties() +CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap() { - static const CSSPropertyID animatableShorthandProperties[] = { - CSSPropertyBackground, // for background-color, background-position, background-image - CSSPropertyBackgroundPosition, - CSSPropertyFont, // for font-size, font-weight - CSSPropertyWebkitMask, // for mask-position - CSSPropertyWebkitMaskPosition, - CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft, - CSSPropertyBorderColor, - CSSPropertyBorderRadius, - CSSPropertyBorderWidth, - CSSPropertyBorder, - CSSPropertyBorderImage, - CSSPropertyBorderSpacing, - CSSPropertyListStyle, // for list-style-image - CSSPropertyMargin, - CSSPropertyOutline, - CSSPropertyPadding, - CSSPropertyWebkitTextStroke, - CSSPropertyWebkitColumnRule, - CSSPropertyWebkitBorderRadius, - CSSPropertyWebkitTransformOrigin - }; - - CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::instance(); - - for (size_t i = 0; i < WTF_ARRAY_LENGTH(animatableShorthandProperties); ++i) { - CSSPropertyID propertyID = animatableShorthandProperties[i]; - StylePropertyShorthand shorthand = shorthandForProperty(propertyID); - if (!shorthand.length()) - continue; - - Vector longhandWrappers; - for (unsigned i = 0; i < shorthand.length(); ++i) { - if (AnimationPropertyWrapperBase* wrapper = map.wrapperForProperty(shorthand.properties()[i])) - longhandWrappers.append(wrapper); - } - - map.addPropertyWrapper(propertyID, new ShorthandPropertyWrapper(propertyID, longhandWrappers)); - } -} - -void CSSPropertyAnimationWrapperMap::ensurePropertyMap() -{ - Vector* gPropertyWrappers = &m_propertyWrappers; // FIXME: Remove this aliasing. - // build the list of property wrappers to do the comparisons and blends - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyLeft, &RenderStyle::left, &RenderStyle::setLeft)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyRight, &RenderStyle::right, &RenderStyle::setRight)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyTop, &RenderStyle::top, &RenderStyle::setTop)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBottom, &RenderStyle::bottom, &RenderStyle::setBottom)); - - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWidth, &RenderStyle::width, &RenderStyle::setWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyMinWidth, &RenderStyle::minWidth, &RenderStyle::setMinWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyMaxWidth, &RenderStyle::maxWidth, &RenderStyle::setMaxWidth)); - - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyHeight, &RenderStyle::height, &RenderStyle::setHeight)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyMinHeight, &RenderStyle::minHeight, &RenderStyle::setMinHeight)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyMaxHeight, &RenderStyle::maxHeight, &RenderStyle::setMaxHeight)); - - gPropertyWrappers->append(new PropertyWrapperFlex()); - - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyMarginLeft, &RenderStyle::marginLeft, &RenderStyle::setMarginLeft)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyMarginRight, &RenderStyle::marginRight, &RenderStyle::setMarginRight)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyMarginTop, &RenderStyle::marginTop, &RenderStyle::setMarginTop)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyMarginBottom, &RenderStyle::marginBottom, &RenderStyle::setMarginBottom)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyPaddingLeft, &RenderStyle::paddingLeft, &RenderStyle::setPaddingLeft)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyPaddingRight, &RenderStyle::paddingRight, &RenderStyle::setPaddingRight)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyPaddingTop, &RenderStyle::paddingTop, &RenderStyle::setPaddingTop)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom, &RenderStyle::setPaddingBottom)); - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor, &RenderStyle::visitedLinkColor, &RenderStyle::setVisitedLinkColor)); - - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor, &RenderStyle::visitedLinkBackgroundColor, &RenderStyle::setVisitedLinkBackgroundColor)); - - gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundImage, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers)); - gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyListStyleImage, &RenderStyle::listStyleImage, &RenderStyle::setListStyleImage)); - gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage, &RenderStyle::setMaskImage)); - - gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyBorderImageSource, &RenderStyle::borderImageSource, &RenderStyle::setBorderImageSource)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderImageSlice, &RenderStyle::borderImageSlices, &RenderStyle::setBorderImageSlices)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderImageWidth, &RenderStyle::borderImageWidth, &RenderStyle::setBorderImageWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderImageOutset, &RenderStyle::borderImageOutset, &RenderStyle::setBorderImageOutset)); - - gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource, &RenderStyle::setMaskBoxImageSource)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage)); - - gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers)); - gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers)); - gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers)); - gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers)); - - gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers)); - gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers)); - gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers)); - - gPropertyWrappers->append(new PropertyWrapper(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. + AnimationPropertyWrapperBase* animatableLonghandPropertyWrappers[] = { + new PropertyWrapper(CSSPropertyLeft, &RenderStyle::left, &RenderStyle::setLeft), + new PropertyWrapper(CSSPropertyRight, &RenderStyle::right, &RenderStyle::setRight), + new PropertyWrapper(CSSPropertyTop, &RenderStyle::top, &RenderStyle::setTop), + new PropertyWrapper(CSSPropertyBottom, &RenderStyle::bottom, &RenderStyle::setBottom), + + new PropertyWrapper(CSSPropertyWidth, &RenderStyle::width, &RenderStyle::setWidth), + new PropertyWrapper(CSSPropertyMinWidth, &RenderStyle::minWidth, &RenderStyle::setMinWidth), + new PropertyWrapper(CSSPropertyMaxWidth, &RenderStyle::maxWidth, &RenderStyle::setMaxWidth), + + new PropertyWrapper(CSSPropertyHeight, &RenderStyle::height, &RenderStyle::setHeight), + new PropertyWrapper(CSSPropertyMinHeight, &RenderStyle::minHeight, &RenderStyle::setMinHeight), + new PropertyWrapper(CSSPropertyMaxHeight, &RenderStyle::maxHeight, &RenderStyle::setMaxHeight), + + new PropertyWrapperFlex(), + + new PropertyWrapper(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth), + new PropertyWrapper(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth), + new PropertyWrapper(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth), + new PropertyWrapper(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth), + new PropertyWrapper(CSSPropertyMarginLeft, &RenderStyle::marginLeft, &RenderStyle::setMarginLeft), + new PropertyWrapper(CSSPropertyMarginRight, &RenderStyle::marginRight, &RenderStyle::setMarginRight), + new PropertyWrapper(CSSPropertyMarginTop, &RenderStyle::marginTop, &RenderStyle::setMarginTop), + new PropertyWrapper(CSSPropertyMarginBottom, &RenderStyle::marginBottom, &RenderStyle::setMarginBottom), + new PropertyWrapper(CSSPropertyPaddingLeft, &RenderStyle::paddingLeft, &RenderStyle::setPaddingLeft), + new PropertyWrapper(CSSPropertyPaddingRight, &RenderStyle::paddingRight, &RenderStyle::setPaddingRight), + new PropertyWrapper(CSSPropertyPaddingTop, &RenderStyle::paddingTop, &RenderStyle::setPaddingTop), + new PropertyWrapper(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom, &RenderStyle::setPaddingBottom), + new PropertyWrapperVisitedAffectedColor(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor, &RenderStyle::visitedLinkColor, &RenderStyle::setVisitedLinkColor), + + new PropertyWrapperVisitedAffectedColor(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor, &RenderStyle::visitedLinkBackgroundColor, &RenderStyle::setVisitedLinkBackgroundColor), + + new FillLayersPropertyWrapper(CSSPropertyBackgroundImage, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers), + new StyleImagePropertyWrapper(CSSPropertyListStyleImage, &RenderStyle::listStyleImage, &RenderStyle::setListStyleImage), + new StyleImagePropertyWrapper(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage, &RenderStyle::setMaskImage), + + new StyleImagePropertyWrapper(CSSPropertyBorderImageSource, &RenderStyle::borderImageSource, &RenderStyle::setBorderImageSource), + new PropertyWrapper(CSSPropertyBorderImageSlice, &RenderStyle::borderImageSlices, &RenderStyle::setBorderImageSlices), + new PropertyWrapper(CSSPropertyBorderImageWidth, &RenderStyle::borderImageWidth, &RenderStyle::setBorderImageWidth), + new PropertyWrapper(CSSPropertyBorderImageOutset, &RenderStyle::borderImageOutset, &RenderStyle::setBorderImageOutset), + + new StyleImagePropertyWrapper(CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource, &RenderStyle::setMaskBoxImageSource), + new PropertyWrapper(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(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, + &RenderStyle::specifiedFontSize, #else - &RenderStyle::computedFontSize, + &RenderStyle::computedFontSize, #endif - &RenderStyle::setFontSize)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitBorderVerticalSpacing, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyZIndex, &RenderStyle::zIndex, &RenderStyle::setZIndex)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyOrphans, &RenderStyle::orphans, &RenderStyle::setOrphans)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWidows, &RenderStyle::widows, &RenderStyle::setWidows)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyLineHeight, &RenderStyle::specifiedLineHeight, &RenderStyle::setLineHeight)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyTextIndent, &RenderStyle::textIndent, &RenderStyle::setTextIndent)); - - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitPerspective, &RenderStyle::perspective, &RenderStyle::setPerspective)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitTransformOriginZ, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius, &RenderStyle::setBorderBottomRightRadius)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyVisibility, &RenderStyle::visibility, &RenderStyle::setVisibility)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyZoom, &RenderStyle::zoom, &RenderStyle::setZoomWithoutReturnValue)); - - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyClip, &RenderStyle::clip, &RenderStyle::setClip)); + &RenderStyle::setFontSize), + new PropertyWrapper(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth), + new PropertyWrapper(CSSPropertyWebkitColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap), + new PropertyWrapper(CSSPropertyWebkitColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount), + new PropertyWrapper(CSSPropertyWebkitColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth), + new PropertyWrapper(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing), + new PropertyWrapper(CSSPropertyWebkitBorderVerticalSpacing, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing), + new PropertyWrapper(CSSPropertyZIndex, &RenderStyle::zIndex, &RenderStyle::setZIndex), + new PropertyWrapper(CSSPropertyOrphans, &RenderStyle::orphans, &RenderStyle::setOrphans), + new PropertyWrapper(CSSPropertyWidows, &RenderStyle::widows, &RenderStyle::setWidows), + new PropertyWrapper(CSSPropertyLineHeight, &RenderStyle::specifiedLineHeight, &RenderStyle::setLineHeight), + new PropertyWrapper(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset), + new PropertyWrapper(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth), + new PropertyWrapper(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing), + new PropertyWrapper(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing), + new PropertyWrapper(CSSPropertyTextIndent, &RenderStyle::textIndent, &RenderStyle::setTextIndent), + + new PropertyWrapper(CSSPropertyWebkitPerspective, &RenderStyle::perspective, &RenderStyle::setPerspective), + new PropertyWrapper(CSSPropertyWebkitPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX), + new PropertyWrapper(CSSPropertyWebkitPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY), + new PropertyWrapper(CSSPropertyWebkitTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX), + new PropertyWrapper(CSSPropertyWebkitTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY), + new PropertyWrapper(CSSPropertyWebkitTransformOriginZ, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ), + new PropertyWrapper(CSSPropertyBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius), + new PropertyWrapper(CSSPropertyBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius), + new PropertyWrapper(CSSPropertyBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius), + new PropertyWrapper(CSSPropertyBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius, &RenderStyle::setBorderBottomRightRadius), + new PropertyWrapper(CSSPropertyVisibility, &RenderStyle::visibility, &RenderStyle::setVisibility), + new PropertyWrapper(CSSPropertyZoom, &RenderStyle::zoom, &RenderStyle::setZoomWithoutReturnValue), + + new PropertyWrapper(CSSPropertyClip, &RenderStyle::clip, &RenderStyle::setClip), #if USE(ACCELERATED_COMPOSITING) - gPropertyWrappers->append(new PropertyWrapperAcceleratedOpacity()); - gPropertyWrappers->append(new PropertyWrapperAcceleratedTransform()); + new PropertyWrapperAcceleratedOpacity(), + new PropertyWrapperAcceleratedTransform(), #if ENABLE(CSS_FILTERS) - gPropertyWrappers->append(new PropertyWrapperAcceleratedFilter()); + new PropertyWrapperAcceleratedFilter(), #endif #else - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform)); + new PropertyWrapper(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity), + new PropertyWrapper(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform), #if ENABLE(CSS_FILTERS) - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter)); + new PropertyWrapper(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter), #endif #endif - gPropertyWrappers->append(new PropertyWrapperClipPath(CSSPropertyWebkitClipPath, &RenderStyle::clipPath, &RenderStyle::setClipPath)); + new PropertyWrapperClipPath(CSSPropertyWebkitClipPath, &RenderStyle::clipPath, &RenderStyle::setClipPath), #if ENABLE(CSS_SHAPES) - gPropertyWrappers->append(new PropertyWrapperShape(CSSPropertyWebkitShapeInside, &RenderStyle::shapeInside, &RenderStyle::setShapeInside)); + new PropertyWrapperShape(CSSPropertyWebkitShapeInside, &RenderStyle::shapeInside, &RenderStyle::setShapeInside), #endif - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitColumnRuleColor, MaybeInvalidColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor, &RenderStyle::visitedLinkColumnRuleColor, &RenderStyle::setVisitedLinkColumnRuleColor)); - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitTextStrokeColor, MaybeInvalidColor, &RenderStyle::textStrokeColor, &RenderStyle::setTextStrokeColor, &RenderStyle::visitedLinkTextStrokeColor, &RenderStyle::setVisitedLinkTextStrokeColor)); - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitTextFillColor, MaybeInvalidColor, &RenderStyle::textFillColor, &RenderStyle::setTextFillColor, &RenderStyle::visitedLinkTextFillColor, &RenderStyle::setVisitedLinkTextFillColor)); - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderLeftColor, MaybeInvalidColor, &RenderStyle::borderLeftColor, &RenderStyle::setBorderLeftColor, &RenderStyle::visitedLinkBorderLeftColor, &RenderStyle::setVisitedLinkBorderLeftColor)); - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderRightColor, MaybeInvalidColor, &RenderStyle::borderRightColor, &RenderStyle::setBorderRightColor, &RenderStyle::visitedLinkBorderRightColor, &RenderStyle::setVisitedLinkBorderRightColor)); - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderTopColor, MaybeInvalidColor, &RenderStyle::borderTopColor, &RenderStyle::setBorderTopColor, &RenderStyle::visitedLinkBorderTopColor, &RenderStyle::setVisitedLinkBorderTopColor)); - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderBottomColor, MaybeInvalidColor, &RenderStyle::borderBottomColor, &RenderStyle::setBorderBottomColor, &RenderStyle::visitedLinkBorderBottomColor, &RenderStyle::setVisitedLinkBorderBottomColor)); - gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyOutlineColor, MaybeInvalidColor, &RenderStyle::outlineColor, &RenderStyle::setOutlineColor, &RenderStyle::visitedLinkOutlineColor, &RenderStyle::setVisitedLinkOutlineColor)); + new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitColumnRuleColor, 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), + new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderRightColor, MaybeInvalidColor, &RenderStyle::borderRightColor, &RenderStyle::setBorderRightColor, &RenderStyle::visitedLinkBorderRightColor, &RenderStyle::setVisitedLinkBorderRightColor), + new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderTopColor, MaybeInvalidColor, &RenderStyle::borderTopColor, &RenderStyle::setBorderTopColor, &RenderStyle::visitedLinkBorderTopColor, &RenderStyle::setVisitedLinkBorderTopColor), + new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderBottomColor, MaybeInvalidColor, &RenderStyle::borderBottomColor, &RenderStyle::setBorderBottomColor, &RenderStyle::visitedLinkBorderBottomColor, &RenderStyle::setVisitedLinkBorderBottomColor), + new PropertyWrapperVisitedAffectedColor(CSSPropertyOutlineColor, MaybeInvalidColor, &RenderStyle::outlineColor, &RenderStyle::setOutlineColor, &RenderStyle::visitedLinkOutlineColor, &RenderStyle::setVisitedLinkOutlineColor), - gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow)); - gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow)); - gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow)); + new PropertyWrapperShadow(CSSPropertyBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow), + new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow), + new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow), #if ENABLE(SVG) - gPropertyWrappers->append(new PropertyWrapperSVGPaint(CSSPropertyFill, &RenderStyle::fillPaintType, &RenderStyle::fillPaintColor, &RenderStyle::setFillPaintColor)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyFillOpacity, &RenderStyle::fillOpacity, &RenderStyle::setFillOpacity)); + new PropertyWrapperSVGPaint(CSSPropertyFill, &RenderStyle::fillPaintType, &RenderStyle::fillPaintColor, &RenderStyle::setFillPaintColor), + new PropertyWrapper(CSSPropertyFillOpacity, &RenderStyle::fillOpacity, &RenderStyle::setFillOpacity), - gPropertyWrappers->append(new PropertyWrapperSVGPaint(CSSPropertyStroke, &RenderStyle::strokePaintType, &RenderStyle::strokePaintColor, &RenderStyle::setStrokePaintColor)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyStrokeOpacity, &RenderStyle::strokeOpacity, &RenderStyle::setStrokeOpacity)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth, &RenderStyle::setStrokeWidth)); - gPropertyWrappers->append(new PropertyWrapper< Vector >(CSSPropertyStrokeDasharray, &RenderStyle::strokeDashArray, &RenderStyle::setStrokeDashArray)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset, &RenderStyle::setStrokeDashOffset)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyStrokeMiterlimit, &RenderStyle::strokeMiterLimit, &RenderStyle::setStrokeMiterLimit)); + new PropertyWrapperSVGPaint(CSSPropertyStroke, &RenderStyle::strokePaintType, &RenderStyle::strokePaintColor, &RenderStyle::setStrokePaintColor), + new PropertyWrapper(CSSPropertyStrokeOpacity, &RenderStyle::strokeOpacity, &RenderStyle::setStrokeOpacity), + new PropertyWrapper(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth, &RenderStyle::setStrokeWidth), + new PropertyWrapper< Vector >(CSSPropertyStrokeDasharray, &RenderStyle::strokeDashArray, &RenderStyle::setStrokeDashArray), + new PropertyWrapper(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset, &RenderStyle::setStrokeDashOffset), + new PropertyWrapper(CSSPropertyStrokeMiterlimit, &RenderStyle::strokeMiterLimit, &RenderStyle::setStrokeMiterLimit), - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyFloodOpacity, &RenderStyle::floodOpacity, &RenderStyle::setFloodOpacity)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyFloodColor, &RenderStyle::floodColor, &RenderStyle::setFloodColor)); + new PropertyWrapper(CSSPropertyFloodOpacity, &RenderStyle::floodOpacity, &RenderStyle::setFloodOpacity), + new PropertyWrapperMaybeInvalidColor(CSSPropertyFloodColor, &RenderStyle::floodColor, &RenderStyle::setFloodColor), - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyStopOpacity, &RenderStyle::stopOpacity, &RenderStyle::setStopOpacity)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyStopColor, &RenderStyle::stopColor, &RenderStyle::setStopColor)); + new PropertyWrapper(CSSPropertyStopOpacity, &RenderStyle::stopOpacity, &RenderStyle::setStopOpacity), + new PropertyWrapperMaybeInvalidColor(CSSPropertyStopColor, &RenderStyle::stopColor, &RenderStyle::setStopColor), - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyLightingColor, &RenderStyle::lightingColor, &RenderStyle::setLightingColor)); + new PropertyWrapperMaybeInvalidColor(CSSPropertyLightingColor, &RenderStyle::lightingColor, &RenderStyle::setLightingColor), - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyBaselineShift, &RenderStyle::baselineShiftValue, &RenderStyle::setBaselineShiftValue)); - gPropertyWrappers->append(new PropertyWrapper(CSSPropertyKerning, &RenderStyle::kerning, &RenderStyle::setKerning)); + new PropertyWrapper(CSSPropertyBaselineShift, &RenderStyle::baselineShiftValue, &RenderStyle::setBaselineShiftValue), + new PropertyWrapper(CSSPropertyKerning, &RenderStyle::kerning, &RenderStyle::setKerning), #endif + }; + const unsigned animatableLonghandPropertiesCount = WTF_ARRAY_LENGTH(animatableLonghandPropertyWrappers); + + static const CSSPropertyID animatableShorthandProperties[] = { + CSSPropertyBackground, // for background-color, background-position, background-image + CSSPropertyBackgroundPosition, + CSSPropertyFont, // for font-size, font-weight + CSSPropertyWebkitMask, // for mask-position + CSSPropertyWebkitMaskPosition, + CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft, + CSSPropertyBorderColor, + CSSPropertyBorderRadius, + CSSPropertyBorderWidth, + CSSPropertyBorder, + CSSPropertyBorderImage, + CSSPropertyBorderSpacing, + CSSPropertyListStyle, // for list-style-image + CSSPropertyMargin, + CSSPropertyOutline, + CSSPropertyPadding, + CSSPropertyWebkitTextStroke, + CSSPropertyWebkitColumnRule, + CSSPropertyWebkitBorderRadius, + CSSPropertyWebkitTransformOrigin + }; + const unsigned animatableShorthandPropertiesCount = WTF_ARRAY_LENGTH(animatableShorthandProperties); // TODO: // @@ -1341,19 +1311,41 @@ void CSSPropertyAnimationWrapperMap::ensurePropertyMap() // CSSPropertyWebkitBoxReflect // Make sure unused slots have a value - for (unsigned int i = 0; i < static_cast(numCSSProperties); ++i) + for (int i = 0; i < numCSSProperties; ++i) m_propertyToIdMap[i] = cInvalidPropertyWrapperIndex; + COMPILE_ASSERT(animatableLonghandPropertiesCount + animatableShorthandPropertiesCount < UCHAR_MAX, numberOfAnimatablePropertiesMustBeLessThanUCharMax); + m_propertyWrappers.reserveInitialCapacity(animatableLonghandPropertiesCount + animatableShorthandPropertiesCount); + // First we put the non-shorthand property wrappers into the map, so the shorthand-building // code can find them. - size_t n = gPropertyWrappers->size(); - for (unsigned int i = 0; i < n; ++i) { - ASSERT(m_propertyWrappers[i]->property() - firstCSSProperty < numCSSProperties); - m_propertyToIdMap[m_propertyWrappers[i]->property() - firstCSSProperty] = i; + + for (unsigned i = 0; i < animatableLonghandPropertiesCount; ++i) { + AnimationPropertyWrapperBase* wrapper = animatableLonghandPropertyWrappers[i]; + m_propertyWrappers.uncheckedAppend(adoptPtr(wrapper)); + indexFromPropertyID(wrapper->property()) = i; } - // Now add the shorthand wrappers. - addShorthandProperties(); + for (size_t i = 0; i < animatableShorthandPropertiesCount; ++i) { + CSSPropertyID propertyID = animatableShorthandProperties[i]; + StylePropertyShorthand shorthand = shorthandForProperty(propertyID); + if (!shorthand.length()) + continue; + + Vector longhandWrappers; + longhandWrappers.reserveInitialCapacity(shorthand.length()); + const CSSPropertyID* properties = shorthand.properties(); + for (unsigned i = 0; i < shorthand.length(); ++i) { + unsigned wrapperIndex = indexFromPropertyID(properties[i]); + if (wrapperIndex == cInvalidPropertyWrapperIndex) + continue; + ASSERT(m_propertyWrappers[wrapperIndex]); + longhandWrappers.uncheckedAppend(m_propertyWrappers[wrapperIndex].get()); + } + + m_propertyWrappers.uncheckedAppend(adoptPtr(new ShorthandPropertyWrapper(propertyID, longhandWrappers))); + indexFromPropertyID(propertyID) = animatableLonghandPropertiesCount + i; + } } static bool gatherEnclosingShorthandProperties(CSSPropertyID property, AnimationPropertyWrapperBase* wrapper, HashSet& propertySet)