Title: [220382] trunk/Source/WebCore
Revision
220382
Author
simon.fra...@apple.com
Date
2017-08-07 19:52:08 -0700 (Mon, 07 Aug 2017)

Log 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):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (220381 => 220382)


--- trunk/Source/WebCore/ChangeLog	2017-08-08 02:52:06 UTC (rev 220381)
+++ trunk/Source/WebCore/ChangeLog	2017-08-08 02:52:08 UTC (rev 220382)
@@ -1,5 +1,21 @@
 2017-08-07  Simon Fraser  <simon.fra...@apple.com>
 
+        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):
+
+2017-08-07  Simon Fraser  <simon.fra...@apple.com>
+
         Re-order the tests in RenderLayerCompositor::requiresCompositingLayer() for performance
         https://bugs.webkit.org/show_bug.cgi?id=175306
 

Modified: trunk/Source/WebCore/css/parser/CSSParserFastPaths.cpp (220381 => 220382)


--- trunk/Source/WebCore/css/parser/CSSParserFastPaths.cpp	2017-08-08 02:52:06 UTC (rev 220381)
+++ trunk/Source/WebCore/css/parser/CSSParserFastPaths.cpp	2017-08-08 02:52:08 UTC (rev 220382)
@@ -115,6 +115,32 @@
     return true;
 }
 
+template <typename CharacterType>
+static inline bool parseSimpleAngle(const CharacterType* characters, unsigned length, CSSPrimitiveValue::UnitType& unit, double& number)
+{
+    // Just support deg and rad for now.
+    if (length < 4)
+        return false;
+
+    if ((characters[length - 3] | 0x20) == 'd' && (characters[length - 2] | 0x20) == 'e' && (characters[length - 1] | 0x20) == 'g') {
+        length -= 3;
+        unit = CSSPrimitiveValue::UnitType::CSS_DEG;
+    } else if ((characters[length - 3] | 0x20) == 'r' && (characters[length - 2] | 0x20) == 'a' && (characters[length - 1] | 0x20) == 'd') {
+        length -= 3;
+        unit = CSSPrimitiveValue::UnitType::CSS_RAD;
+    } else
+        return false;
+
+    // We rely on charactersToDouble for validation as well. The function
+    // will set "ok" to "false" if the entire passed-in character range does
+    // not represent a double.
+    bool ok;
+    number = charactersToDouble(characters, length, &ok);
+    if (!ok)
+        return false;
+    return true;
+}
+
 static RefPtr<CSSValue> parseSimpleLengthValue(CSSPropertyID propertyId, const String& string, CSSParserMode cssParserMode)
 {
     ASSERT(!string.isEmpty());
@@ -1050,6 +1076,27 @@
 }
 
 template <typename CharType>
+static bool parseTransformAngleArgument(CharType*& pos, CharType* end, CSSFunctionValue* transformValue)
+{
+    size_t delimiter = WTF::find(pos, end - pos, ')');
+    if (delimiter == notFound)
+        return false;
+
+    unsigned argumentLength = static_cast<unsigned>(delimiter);
+    CSSPrimitiveValue::UnitType unit = CSSPrimitiveValue::UnitType::CSS_NUMBER;
+    double number;
+    if (!parseSimpleAngle(pos, argumentLength, unit, number))
+        return false;
+    if (!number && unit == CSSPrimitiveValue::CSS_NUMBER)
+        unit = CSSPrimitiveValue::UnitType::CSS_DEG;
+
+    transformValue->append(CSSPrimitiveValue::create(number, unit));
+    pos += argumentLength + 1;
+
+    return true;
+}
+
+template <typename CharType>
 static bool parseTransformNumberArguments(CharType*& pos, CharType* end, unsigned expectedCount, CSSFunctionValue* transformValue)
 {
     while (expectedCount) {
@@ -1105,9 +1152,9 @@
             transformType = CSSValueTranslate3d;
             expectedArgumentCount = 3;
             argumentStart = 12;
-        } else {
+        } else
             return nullptr;
-        }
+
         pos += argumentStart;
         RefPtr<CSSFunctionValue> transformValue = CSSFunctionValue::create(transformType);
         if (!parseTransformTranslateArguments(pos, end, expectedArgumentCount, transformValue.get()))
@@ -1150,6 +1197,32 @@
         return transformValue;
     }
 
+    const bool isRotate = toASCIILower(pos[0]) == 'r'
+        && toASCIILower(pos[1]) == 'o'
+        && toASCIILower(pos[2]) == 't'
+        && toASCIILower(pos[3]) == 'a'
+        && toASCIILower(pos[4]) == 't'
+        && toASCIILower(pos[5]) == 'e';
+
+    if (isRotate) {
+        CSSValueID transformType;
+        unsigned argumentStart = 7;
+        CharType c6 = toASCIILower(pos[6]);
+        if (c6 == '(') {
+            transformType = CSSValueRotate;
+        } else if (c6 == 'z' && pos[7] == '(') {
+            transformType = CSSValueRotateZ;
+            argumentStart = 8;
+        } else
+            return nullptr;
+
+        pos += argumentStart;
+        RefPtr<CSSFunctionValue> transformValue = CSSFunctionValue::create(transformType);
+        if (!parseTransformAngleArgument(pos, end, transformValue.get()))
+            return nullptr;
+        return transformValue;
+    }
+
     return nullptr;
 }
 
@@ -1187,6 +1260,16 @@
                 return false;
             i += 7;
             break;
+        case 'r':
+            // rotate.
+            if (toASCIILower(chars[i + 5]) != 'e')
+                return false;
+            i += 6;
+            // rotateZ
+            if (toASCIILower(chars[i + 6]) == 'z')
+                ++i;
+            break;
+
         default:
             // All other things, ex. rotate.
             return false;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to