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;