Commit 7855d607 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

Avoid length array conversion in CSSTransformInterpolationType

Currently, CSSTransformInterpolationType calls AccumulateLengthArray()
only to obtain the length unit types involved in a <length> value, which
is an overkill. Hence, this patch changes it into obtaining the types
only.

This also unblocks the code from working on <length> values involving
min/max, as these values cannot be converted into a length array.

Bug: 991672
Change-Id: Ib2865be502e2306fdbf2e1b5f4bafe26047ed5bc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1775424Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Reviewed-by: default avatarAlan Cutter <alancutter@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#691864}
parent e1830003
...@@ -222,27 +222,23 @@ InterpolationValue CSSTransformInterpolationType::MaybeConvertValue( ...@@ -222,27 +222,23 @@ InterpolationValue CSSTransformInterpolationType::MaybeConvertValue(
ConversionCheckers& conversion_checkers) const { ConversionCheckers& conversion_checkers) const {
DCHECK(state); DCHECK(state);
if (auto* list_value = DynamicTo<CSSValueList>(value)) { if (auto* list_value = DynamicTo<CSSValueList>(value)) {
CSSLengthArray length_array; CSSPrimitiveValue::LengthTypeFlags types;
for (const CSSValue* item : *list_value) { for (const CSSValue* item : *list_value) {
const auto& transform_function = To<CSSFunctionValue>(*item); const auto& transform_function = To<CSSFunctionValue>(*item);
if (transform_function.FunctionType() == CSSValueID::kMatrix || if (transform_function.FunctionType() == CSSValueID::kMatrix ||
transform_function.FunctionType() == CSSValueID::kMatrix3d) { transform_function.FunctionType() == CSSValueID::kMatrix3d) {
length_array.type_flags.set(CSSPrimitiveValue::kUnitTypePixels); types.set(CSSPrimitiveValue::kUnitTypePixels);
continue; continue;
} }
for (const CSSValue* argument : transform_function) { for (const CSSValue* argument : transform_function) {
const auto& primitive_value = To<CSSPrimitiveValue>(*argument); const auto& primitive_value = To<CSSPrimitiveValue>(*argument);
if (!primitive_value.IsLength()) if (!primitive_value.IsLength())
continue; continue;
if (!primitive_value.AccumulateLengthArray(length_array)) { primitive_value.AccumulateLengthUnitTypes(types);
// TODO(crbug.com/991672): Implement interpolation when CSS comparison
// functions min/max are involved.
return nullptr;
}
} }
} }
std::unique_ptr<InterpolationType::ConversionChecker> length_units_checker = std::unique_ptr<InterpolationType::ConversionChecker> length_units_checker =
LengthUnitsChecker::MaybeCreate(std::move(length_array), *state); LengthUnitsChecker::MaybeCreate(types, *state);
if (length_units_checker) if (length_units_checker)
conversion_checkers.push_back(std::move(length_units_checker)); conversion_checkers.push_back(std::move(length_units_checker));
......
...@@ -18,15 +18,16 @@ namespace blink { ...@@ -18,15 +18,16 @@ namespace blink {
class LengthUnitsChecker : public CSSInterpolationType::CSSConversionChecker { class LengthUnitsChecker : public CSSInterpolationType::CSSConversionChecker {
public: public:
static std::unique_ptr<LengthUnitsChecker> MaybeCreate( static std::unique_ptr<LengthUnitsChecker> MaybeCreate(
CSSLengthArray&& length_array, const CSSPrimitiveValue::LengthTypeFlags& length_types,
const StyleResolverState& state) { const StyleResolverState& state) {
bool create = false; bool create = false;
wtf_size_t last_index = 0; wtf_size_t last_index = 0;
for (wtf_size_t i = 0; i < length_array.values.size(); i++) { CSSLengthArray length_array;
if (i == CSSPrimitiveValue::kUnitTypePercentage || for (wtf_size_t i = 0; i < length_types.size(); ++i) {
!length_array.type_flags[i]) if (i == CSSPrimitiveValue::kUnitTypePercentage || !length_types[i])
continue; continue;
length_array.values[i] = LengthUnit(i, state.CssToLengthConversionData()); length_array.values[i] = LengthUnit(i, state.CssToLengthConversionData());
length_array.type_flags.set(i);
create = true; create = true;
last_index = i; last_index = i;
} }
......
...@@ -239,6 +239,11 @@ bool CSSMathExpressionNumericLiteral::AccumulateLengthArray( ...@@ -239,6 +239,11 @@ bool CSSMathExpressionNumericLiteral::AccumulateLengthArray(
return value_->AccumulateLengthArray(length_array, multiplier); return value_->AccumulateLengthArray(length_array, multiplier);
} }
void CSSMathExpressionNumericLiteral::AccumulateLengthUnitTypes(
CSSPrimitiveValue::LengthTypeFlags& types) const {
value_->AccumulateLengthUnitTypes(types);
}
bool CSSMathExpressionNumericLiteral::operator==( bool CSSMathExpressionNumericLiteral::operator==(
const CSSMathExpressionNode& other) const { const CSSMathExpressionNode& other) const {
if (!other.IsNumericLiteral()) if (!other.IsNumericLiteral())
...@@ -587,6 +592,12 @@ bool CSSMathExpressionBinaryOperation::AccumulateLengthArray( ...@@ -587,6 +592,12 @@ bool CSSMathExpressionBinaryOperation::AccumulateLengthArray(
} }
} }
void CSSMathExpressionBinaryOperation::AccumulateLengthUnitTypes(
CSSPrimitiveValue::LengthTypeFlags& types) const {
left_side_->AccumulateLengthUnitTypes(types);
right_side_->AccumulateLengthUnitTypes(types);
}
bool CSSMathExpressionBinaryOperation::IsComputationallyIndependent() const { bool CSSMathExpressionBinaryOperation::IsComputationallyIndependent() const {
if (Category() != kCalcLength && Category() != kCalcPercentLength) if (Category() != kCalcLength && Category() != kCalcPercentLength)
return true; return true;
...@@ -842,6 +853,12 @@ bool CSSMathExpressionVariadicOperation::AccumulateLengthArray(CSSLengthArray&, ...@@ -842,6 +853,12 @@ bool CSSMathExpressionVariadicOperation::AccumulateLengthArray(CSSLengthArray&,
return false; return false;
} }
void CSSMathExpressionVariadicOperation::AccumulateLengthUnitTypes(
CSSPrimitiveValue::LengthTypeFlags& types) const {
for (const auto& operand : operands_)
operand->AccumulateLengthUnitTypes(types);
}
bool CSSMathExpressionVariadicOperation::IsComputationallyIndependent() const { bool CSSMathExpressionVariadicOperation::IsComputationallyIndependent() const {
for (const auto& operand : operands_) { for (const auto& operand : operands_) {
if (!operand->IsComputationallyIndependent()) if (!operand->IsComputationallyIndependent())
......
...@@ -89,6 +89,8 @@ class CORE_EXPORT CSSMathExpressionNode ...@@ -89,6 +89,8 @@ class CORE_EXPORT CSSMathExpressionNode
virtual double ComputeLengthPx(const CSSToLengthConversionData&) const = 0; virtual double ComputeLengthPx(const CSSToLengthConversionData&) const = 0;
virtual bool AccumulateLengthArray(CSSLengthArray&, virtual bool AccumulateLengthArray(CSSLengthArray&,
double multiplier) const = 0; double multiplier) const = 0;
virtual void AccumulateLengthUnitTypes(
CSSPrimitiveValue::LengthTypeFlags& types) const = 0;
virtual scoped_refptr<const CalculationExpressionNode> virtual scoped_refptr<const CalculationExpressionNode>
ToCalculationExpression(const CSSToLengthConversionData&) const = 0; ToCalculationExpression(const CSSToLengthConversionData&) const = 0;
...@@ -167,6 +169,8 @@ class CORE_EXPORT CSSMathExpressionNumericLiteral final ...@@ -167,6 +169,8 @@ class CORE_EXPORT CSSMathExpressionNumericLiteral final
const CSSToLengthConversionData& conversion_data) const final; const CSSToLengthConversionData& conversion_data) const final;
bool AccumulateLengthArray(CSSLengthArray& length_array, bool AccumulateLengthArray(CSSLengthArray& length_array,
double multiplier) const final; double multiplier) const final;
void AccumulateLengthUnitTypes(
CSSPrimitiveValue::LengthTypeFlags& types) const final;
bool IsComputationallyIndependent() const final; bool IsComputationallyIndependent() const final;
bool operator==(const CSSMathExpressionNode& other) const final; bool operator==(const CSSMathExpressionNode& other) const final;
CSSPrimitiveValue::UnitType ResolvedUnitType() const final; CSSPrimitiveValue::UnitType ResolvedUnitType() const final;
...@@ -220,6 +224,8 @@ class CORE_EXPORT CSSMathExpressionBinaryOperation final ...@@ -220,6 +224,8 @@ class CORE_EXPORT CSSMathExpressionBinaryOperation final
const CSSToLengthConversionData& conversion_data) const final; const CSSToLengthConversionData& conversion_data) const final;
bool AccumulateLengthArray(CSSLengthArray& length_array, bool AccumulateLengthArray(CSSLengthArray& length_array,
double multiplier) const final; double multiplier) const final;
void AccumulateLengthUnitTypes(
CSSPrimitiveValue::LengthTypeFlags& types) const final;
bool IsComputationallyIndependent() const final; bool IsComputationallyIndependent() const final;
String CustomCSSText() const final; String CustomCSSText() const final;
bool operator==(const CSSMathExpressionNode& exp) const final; bool operator==(const CSSMathExpressionNode& exp) const final;
...@@ -285,6 +291,8 @@ class CSSMathExpressionVariadicOperation final : public CSSMathExpressionNode { ...@@ -285,6 +291,8 @@ class CSSMathExpressionVariadicOperation final : public CSSMathExpressionNode {
const CSSToLengthConversionData& conversion_data) const final; const CSSToLengthConversionData& conversion_data) const final;
bool AccumulateLengthArray(CSSLengthArray& length_array, bool AccumulateLengthArray(CSSLengthArray& length_array,
double multiplier) const final; double multiplier) const final;
void AccumulateLengthUnitTypes(
CSSPrimitiveValue::LengthTypeFlags& types) const final;
base::Optional<double> ComputeValueInCanonicalUnit() const final; base::Optional<double> ComputeValueInCanonicalUnit() const final;
bool IsComputationallyIndependent() const final; bool IsComputationallyIndependent() const final;
bool operator==(const CSSMathExpressionNode& other) const final; bool operator==(const CSSMathExpressionNode& other) const final;
......
...@@ -80,6 +80,10 @@ class CORE_EXPORT CSSMathFunctionValue : public CSSPrimitiveValue { ...@@ -80,6 +80,10 @@ class CORE_EXPORT CSSMathFunctionValue : public CSSPrimitiveValue {
Length ConvertToLength( Length ConvertToLength(
const CSSToLengthConversionData& conversion_data) const; const CSSToLengthConversionData& conversion_data) const;
void AccumulateLengthUnitTypes(LengthTypeFlags& types) const {
expression_->AccumulateLengthUnitTypes(types);
}
String CustomCSSText() const; String CustomCSSText() const;
bool Equals(const CSSMathFunctionValue& other) const; bool Equals(const CSSMathFunctionValue& other) const;
......
...@@ -126,6 +126,16 @@ bool CSSNumericLiteralValue::AccumulateLengthArray(CSSLengthArray& length_array, ...@@ -126,6 +126,16 @@ bool CSSNumericLiteralValue::AccumulateLengthArray(CSSLengthArray& length_array,
return true; return true;
} }
void CSSNumericLiteralValue::AccumulateLengthUnitTypes(
LengthTypeFlags& types) const {
if (!IsLength())
return;
LengthUnitType length_type;
bool conversion_success = UnitTypeToLengthUnitType(GetType(), length_type);
DCHECK(conversion_success);
types.set(length_type);
}
bool CSSNumericLiteralValue::IsComputationallyIndependent() const { bool CSSNumericLiteralValue::IsComputationallyIndependent() const {
if (!IsLength()) if (!IsLength())
return true; return true;
......
...@@ -58,6 +58,7 @@ class CORE_EXPORT CSSNumericLiteralValue : public CSSPrimitiveValue { ...@@ -58,6 +58,7 @@ class CORE_EXPORT CSSNumericLiteralValue : public CSSPrimitiveValue {
const CSSToLengthConversionData& conversion_data) const; const CSSToLengthConversionData& conversion_data) const;
bool AccumulateLengthArray(CSSLengthArray& length_array, bool AccumulateLengthArray(CSSLengthArray& length_array,
double multiplier) const; double multiplier) const;
void AccumulateLengthUnitTypes(LengthTypeFlags& types) const;
String CustomCSSText() const; String CustomCSSText() const;
bool Equals(const CSSNumericLiteralValue& other) const; bool Equals(const CSSNumericLiteralValue& other) const;
......
...@@ -289,6 +289,13 @@ bool CSSPrimitiveValue::AccumulateLengthArray(CSSLengthArray& length_array, ...@@ -289,6 +289,13 @@ bool CSSPrimitiveValue::AccumulateLengthArray(CSSLengthArray& length_array,
multiplier); multiplier);
} }
void CSSPrimitiveValue::AccumulateLengthUnitTypes(
LengthTypeFlags& types) const {
if (IsCalculated())
return To<CSSMathFunctionValue>(this)->AccumulateLengthUnitTypes(types);
To<CSSNumericLiteralValue>(this)->AccumulateLengthUnitTypes(types);
}
double CSSPrimitiveValue::ConversionToCanonicalUnitsScaleFactor( double CSSPrimitiveValue::ConversionToCanonicalUnitsScaleFactor(
UnitType unit_type) { UnitType unit_type) {
double factor = 1.0; double factor = 1.0;
......
...@@ -130,18 +130,22 @@ class CORE_EXPORT CSSPrimitiveValue : public CSSValue { ...@@ -130,18 +130,22 @@ class CORE_EXPORT CSSPrimitiveValue : public CSSValue {
kLengthUnitTypeCount, kLengthUnitTypeCount,
}; };
using LengthTypeFlags = std::bitset<kLengthUnitTypeCount>;
struct CSSLengthArray { struct CSSLengthArray {
CSSLengthArray() : values(kLengthUnitTypeCount) { CSSLengthArray() : values(kLengthUnitTypeCount) {
} }
Vector<double, CSSPrimitiveValue::kLengthUnitTypeCount> values; Vector<double, CSSPrimitiveValue::kLengthUnitTypeCount> values;
std::bitset<kLengthUnitTypeCount> type_flags; LengthTypeFlags type_flags;
}; };
// Returns false if the value cannot be represented as a length array, which // Returns false if the value cannot be represented as a length array, which
// happens when comparisons are involved (e.g., max(10px, 10%)). // happens when comparisons are involved (e.g., max(10px, 10%)).
bool AccumulateLengthArray(CSSLengthArray&, double multiplier = 1) const; bool AccumulateLengthArray(CSSLengthArray&, double multiplier = 1) const;
// Returns all types of length units involved in this value.
void AccumulateLengthUnitTypes(LengthTypeFlags& types) const;
enum UnitCategory { enum UnitCategory {
kUNumber, kUNumber,
kUPercent, kUPercent,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment