Changeset 220382 in webkit


Ignore:
Timestamp:
Aug 7, 2017 7:52:08 PM (7 years ago)
Author:
Simon Fraser
Message:

Add a fast path for rotate() and rotateZ() transform parsing
https://bugs.webkit.org/show_bug.cgi?id=175308

Reviewed by Zalan Bujtas.

Fast paths only existed for translate-related functions, matrix3d() and scale3d(). Add
rotate() and rotateX(), which gives a small boost to one of the MotionMark tests.

  • css/parser/CSSParserFastPaths.cpp:

(WebCore::parseSimpleAngle):
(WebCore::parseTransformAngleArgument):
(WebCore::parseSimpleTransformValue):
(WebCore::transformCanLikelyUseFastPath):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r220381 r220382  
     12017-08-07  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Add a fast path for rotate() and rotateZ() transform parsing
     4        https://bugs.webkit.org/show_bug.cgi?id=175308
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        Fast paths only existed for translate-related functions, matrix3d() and scale3d(). Add
     9        rotate() and rotateX(), which gives a small boost to one of the MotionMark tests.
     10
     11        * css/parser/CSSParserFastPaths.cpp:
     12        (WebCore::parseSimpleAngle):
     13        (WebCore::parseTransformAngleArgument):
     14        (WebCore::parseSimpleTransformValue):
     15        (WebCore::transformCanLikelyUseFastPath):
     16
    1172017-08-07  Simon Fraser  <simon.fraser@apple.com>
    218
  • trunk/Source/WebCore/css/parser/CSSParserFastPaths.cpp

    r218890 r220382  
    105105        unit = CSSPrimitiveValue::UnitType::CSS_PERCENTAGE;
    106106    }
     107
     108    // We rely on charactersToDouble for validation as well. The function
     109    // will set "ok" to "false" if the entire passed-in character range does
     110    // not represent a double.
     111    bool ok;
     112    number = charactersToDouble(characters, length, &ok);
     113    if (!ok)
     114        return false;
     115    return true;
     116}
     117
     118template <typename CharacterType>
     119static inline bool parseSimpleAngle(const CharacterType* characters, unsigned length, CSSPrimitiveValue::UnitType& unit, double& number)
     120{
     121    // Just support deg and rad for now.
     122    if (length < 4)
     123        return false;
     124
     125    if ((characters[length - 3] | 0x20) == 'd' && (characters[length - 2] | 0x20) == 'e' && (characters[length - 1] | 0x20) == 'g') {
     126        length -= 3;
     127        unit = CSSPrimitiveValue::UnitType::CSS_DEG;
     128    } else if ((characters[length - 3] | 0x20) == 'r' && (characters[length - 2] | 0x20) == 'a' && (characters[length - 1] | 0x20) == 'd') {
     129        length -= 3;
     130        unit = CSSPrimitiveValue::UnitType::CSS_RAD;
     131    } else
     132        return false;
    107133
    108134    // We rely on charactersToDouble for validation as well. The function
     
    10511077
    10521078template <typename CharType>
     1079static bool parseTransformAngleArgument(CharType*& pos, CharType* end, CSSFunctionValue* transformValue)
     1080{
     1081    size_t delimiter = WTF::find(pos, end - pos, ')');
     1082    if (delimiter == notFound)
     1083        return false;
     1084
     1085    unsigned argumentLength = static_cast<unsigned>(delimiter);
     1086    CSSPrimitiveValue::UnitType unit = CSSPrimitiveValue::UnitType::CSS_NUMBER;
     1087    double number;
     1088    if (!parseSimpleAngle(pos, argumentLength, unit, number))
     1089        return false;
     1090    if (!number && unit == CSSPrimitiveValue::CSS_NUMBER)
     1091        unit = CSSPrimitiveValue::UnitType::CSS_DEG;
     1092
     1093    transformValue->append(CSSPrimitiveValue::create(number, unit));
     1094    pos += argumentLength + 1;
     1095
     1096    return true;
     1097}
     1098
     1099template <typename CharType>
    10531100static bool parseTransformNumberArguments(CharType*& pos, CharType* end, unsigned expectedCount, CSSFunctionValue* transformValue)
    10541101{
     
    11061153            expectedArgumentCount = 3;
    11071154            argumentStart = 12;
    1108         } else {
     1155        } else
    11091156            return nullptr;
    1110         }
     1157
    11111158        pos += argumentStart;
    11121159        RefPtr<CSSFunctionValue> transformValue = CSSFunctionValue::create(transformType);
     
    11471194        RefPtr<CSSFunctionValue> transformValue = CSSFunctionValue::create(CSSValueScale3d);
    11481195        if (!parseTransformNumberArguments(pos, end, 3, transformValue.get()))
     1196            return nullptr;
     1197        return transformValue;
     1198    }
     1199
     1200    const bool isRotate = toASCIILower(pos[0]) == 'r'
     1201        && toASCIILower(pos[1]) == 'o'
     1202        && toASCIILower(pos[2]) == 't'
     1203        && toASCIILower(pos[3]) == 'a'
     1204        && toASCIILower(pos[4]) == 't'
     1205        && toASCIILower(pos[5]) == 'e';
     1206
     1207    if (isRotate) {
     1208        CSSValueID transformType;
     1209        unsigned argumentStart = 7;
     1210        CharType c6 = toASCIILower(pos[6]);
     1211        if (c6 == '(') {
     1212            transformType = CSSValueRotate;
     1213        } else if (c6 == 'z' && pos[7] == '(') {
     1214            transformType = CSSValueRotateZ;
     1215            argumentStart = 8;
     1216        } else
     1217            return nullptr;
     1218
     1219        pos += argumentStart;
     1220        RefPtr<CSSFunctionValue> transformValue = CSSFunctionValue::create(transformType);
     1221        if (!parseTransformAngleArgument(pos, end, transformValue.get()))
    11491222            return nullptr;
    11501223        return transformValue;
     
    11881261            i += 7;
    11891262            break;
     1263        case 'r':
     1264            // rotate.
     1265            if (toASCIILower(chars[i + 5]) != 'e')
     1266                return false;
     1267            i += 6;
     1268            // rotateZ
     1269            if (toASCIILower(chars[i + 6]) == 'z')
     1270                ++i;
     1271            break;
     1272
    11901273        default:
    11911274            // All other things, ex. rotate.
Note: See TracChangeset for help on using the changeset viewer.