Commit 997868f7 authored by Stephen McGruer's avatar Stephen McGruer Committed by Commit Bot

Implement logical equality on CrossThreadStyleValues

This CL adds support for comparing two CrossThreadStyleValues, handling
different subclasses via a type enum plus WTF::DowncastTraits. Comparing
CrossThreadStyleValues is required for deduplicating PaintWorkletInputs,
as we have to be able to compare PaintWorkletStylePropertyMaps for equality.

Bug: 933805
Change-Id: I40148516b060e323fa812a611fb8cd687284dc75
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1504229
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638137}
parent 19692dca
...@@ -12,4 +12,11 @@ CSSStyleValue* CrossThreadKeywordValue::ToCSSStyleValue() { ...@@ -12,4 +12,11 @@ CSSStyleValue* CrossThreadKeywordValue::ToCSSStyleValue() {
return CSSKeywordValue::Create(keyword_value_); return CSSKeywordValue::Create(keyword_value_);
} }
bool CrossThreadKeywordValue::operator==(
const CrossThreadStyleValue& other) const {
if (auto* o = DynamicTo<CrossThreadKeywordValue>(other))
return keyword_value_ == o->keyword_value_;
return false;
}
} // namespace blink } // namespace blink
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h" #include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink { namespace blink {
...@@ -20,8 +21,13 @@ class CORE_EXPORT CrossThreadKeywordValue final : public CrossThreadStyleValue { ...@@ -20,8 +21,13 @@ class CORE_EXPORT CrossThreadKeywordValue final : public CrossThreadStyleValue {
: keyword_value_(keyword) {} : keyword_value_(keyword) {}
~CrossThreadKeywordValue() override = default; ~CrossThreadKeywordValue() override = default;
StyleValueType GetType() const override {
return StyleValueType::kKeywordType;
}
CSSStyleValue* ToCSSStyleValue() override; CSSStyleValue* ToCSSStyleValue() override;
bool operator==(const CrossThreadStyleValue&) const override;
private: private:
friend class CrossThreadStyleValueTest; friend class CrossThreadStyleValueTest;
...@@ -29,6 +35,14 @@ class CORE_EXPORT CrossThreadKeywordValue final : public CrossThreadStyleValue { ...@@ -29,6 +35,14 @@ class CORE_EXPORT CrossThreadKeywordValue final : public CrossThreadStyleValue {
DISALLOW_COPY_AND_ASSIGN(CrossThreadKeywordValue); DISALLOW_COPY_AND_ASSIGN(CrossThreadKeywordValue);
}; };
template <>
struct DowncastTraits<CrossThreadKeywordValue> {
static bool AllowFrom(const CrossThreadStyleValue& keyword_value) {
return keyword_value.GetType() ==
CrossThreadStyleValue::StyleValueType::kKeywordType;
}
};
} // namespace blink } // namespace blink
#endif #endif
...@@ -16,10 +16,19 @@ class CSSStyleValue; ...@@ -16,10 +16,19 @@ class CSSStyleValue;
// passed cross threads. // passed cross threads.
class CORE_EXPORT CrossThreadStyleValue { class CORE_EXPORT CrossThreadStyleValue {
public: public:
enum class StyleValueType {
kUnknownType,
kKeywordType,
kUnitType,
};
virtual ~CrossThreadStyleValue() = default; virtual ~CrossThreadStyleValue() = default;
virtual StyleValueType GetType() const = 0;
virtual CSSStyleValue* ToCSSStyleValue() = 0; virtual CSSStyleValue* ToCSSStyleValue() = 0;
virtual bool operator==(const CrossThreadStyleValue&) const = 0;
protected: protected:
CrossThreadStyleValue() = default; CrossThreadStyleValue() = default;
......
...@@ -165,4 +165,93 @@ TEST_F(CrossThreadStyleValueTest, CrossThreadUnitValueToCSSStyleValue) { ...@@ -165,4 +165,93 @@ TEST_F(CrossThreadStyleValueTest, CrossThreadUnitValueToCSSStyleValue) {
EXPECT_EQ(static_cast<CSSUnitValue*>(style_value)->unit(), "deg"); EXPECT_EQ(static_cast<CSSUnitValue*>(style_value)->unit(), "deg");
} }
TEST_F(CrossThreadStyleValueTest, ComparingNullValues) {
// Two null values are equal to each other.
std::unique_ptr<CrossThreadStyleValue> null_value1(nullptr);
std::unique_ptr<CrossThreadStyleValue> null_value2(nullptr);
EXPECT_TRUE(DataEquivalent(null_value1, null_value2));
// If one argument is null and the other isn't they are never equal.
std::unique_ptr<CrossThreadStyleValue> keyword_value(
new CrossThreadKeywordValue("keyword"));
std::unique_ptr<CrossThreadStyleValue> unit_value(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
std::unique_ptr<CrossThreadStyleValue> unsupported_value(
new CrossThreadUnsupportedValue("unsupported"));
EXPECT_FALSE(DataEquivalent(null_value1, keyword_value));
EXPECT_FALSE(DataEquivalent(null_value1, unit_value));
EXPECT_FALSE(DataEquivalent(null_value1, unsupported_value));
EXPECT_FALSE(DataEquivalent(keyword_value, null_value1));
EXPECT_FALSE(DataEquivalent(unit_value, null_value1));
EXPECT_FALSE(DataEquivalent(unsupported_value, null_value1));
}
TEST_F(CrossThreadStyleValueTest, ComparingDifferentTypes) {
// Mismatching types are never equal.
std::unique_ptr<CrossThreadStyleValue> keyword_value(
new CrossThreadKeywordValue("keyword"));
std::unique_ptr<CrossThreadStyleValue> unit_value(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
std::unique_ptr<CrossThreadStyleValue> unsupported_value(
new CrossThreadUnsupportedValue("unsupported"));
EXPECT_FALSE(DataEquivalent(keyword_value, unit_value));
EXPECT_FALSE(DataEquivalent(keyword_value, unsupported_value));
EXPECT_FALSE(DataEquivalent(unit_value, unsupported_value));
EXPECT_FALSE(DataEquivalent(unit_value, keyword_value));
EXPECT_FALSE(DataEquivalent(unsupported_value, keyword_value));
EXPECT_FALSE(DataEquivalent(unsupported_value, unit_value));
}
TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadKeywordValue) {
// CrossThreadKeywordValues are compared on their keyword; if it is equal then
// so are they.
std::unique_ptr<CrossThreadStyleValue> keyword_value_1(
new CrossThreadKeywordValue("keyword"));
std::unique_ptr<CrossThreadStyleValue> keyword_value_2(
new CrossThreadKeywordValue("keyword"));
std::unique_ptr<CrossThreadStyleValue> keyword_value_3(
new CrossThreadKeywordValue("different"));
EXPECT_TRUE(DataEquivalent(keyword_value_1, keyword_value_2));
EXPECT_FALSE(DataEquivalent(keyword_value_1, keyword_value_3));
}
TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadUnitValue) {
// CrossThreadUnitValues are compared based on their value and unit type; both
// have to match. There are a lot of unit types; we just test a single sample.
std::unique_ptr<CrossThreadStyleValue> unit_value_1(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
// Same value, same unit.
std::unique_ptr<CrossThreadStyleValue> unit_value_2(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
EXPECT_TRUE(DataEquivalent(unit_value_1, unit_value_2));
// Same value, different unit.
std::unique_ptr<CrossThreadStyleValue> unit_value_3(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kPoints));
EXPECT_FALSE(DataEquivalent(unit_value_1, unit_value_3));
// Different value, same unit.
std::unique_ptr<CrossThreadStyleValue> unit_value_4(
new CrossThreadUnitValue(2, CSSPrimitiveValue::UnitType::kDegrees));
EXPECT_FALSE(DataEquivalent(unit_value_1, unit_value_4));
}
TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadUnsupportedValue) {
// CrossThreadUnsupportedValues are compared on their value; if it is equal
// then so are they.
std::unique_ptr<CrossThreadStyleValue> unsupported_value_1(
new CrossThreadUnsupportedValue("value"));
std::unique_ptr<CrossThreadStyleValue> unsupported_value_2(
new CrossThreadUnsupportedValue("value"));
std::unique_ptr<CrossThreadStyleValue> unsupported_value_3(
new CrossThreadUnsupportedValue("different"));
EXPECT_TRUE(DataEquivalent(unsupported_value_1, unsupported_value_2));
EXPECT_FALSE(DataEquivalent(unsupported_value_1, unsupported_value_3));
}
} // namespace blink } // namespace blink
...@@ -12,4 +12,11 @@ CSSStyleValue* CrossThreadUnitValue::ToCSSStyleValue() { ...@@ -12,4 +12,11 @@ CSSStyleValue* CrossThreadUnitValue::ToCSSStyleValue() {
return CSSUnitValue::Create(value_, unit_); return CSSUnitValue::Create(value_, unit_);
} }
bool CrossThreadUnitValue::operator==(
const CrossThreadStyleValue& other) const {
if (auto* o = DynamicTo<CrossThreadUnitValue>(other))
return value_ == o->value_ && unit_ == o->unit_;
return false;
}
} // namespace blink } // namespace blink
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h" #include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink { namespace blink {
...@@ -20,8 +21,11 @@ class CORE_EXPORT CrossThreadUnitValue final : public CrossThreadStyleValue { ...@@ -20,8 +21,11 @@ class CORE_EXPORT CrossThreadUnitValue final : public CrossThreadStyleValue {
: value_(value), unit_(unit) {} : value_(value), unit_(unit) {}
~CrossThreadUnitValue() override = default; ~CrossThreadUnitValue() override = default;
StyleValueType GetType() const override { return StyleValueType::kUnitType; }
CSSStyleValue* ToCSSStyleValue() override; CSSStyleValue* ToCSSStyleValue() override;
bool operator==(const CrossThreadStyleValue&) const override;
private: private:
friend class CrossThreadStyleValueTest; friend class CrossThreadStyleValueTest;
...@@ -30,6 +34,14 @@ class CORE_EXPORT CrossThreadUnitValue final : public CrossThreadStyleValue { ...@@ -30,6 +34,14 @@ class CORE_EXPORT CrossThreadUnitValue final : public CrossThreadStyleValue {
DISALLOW_COPY_AND_ASSIGN(CrossThreadUnitValue); DISALLOW_COPY_AND_ASSIGN(CrossThreadUnitValue);
}; };
template <>
struct DowncastTraits<CrossThreadUnitValue> {
static bool AllowFrom(const CrossThreadStyleValue& unit_value) {
return unit_value.GetType() ==
CrossThreadStyleValue::StyleValueType::kUnitType;
}
};
} // namespace blink } // namespace blink
#endif #endif
...@@ -12,4 +12,11 @@ CSSStyleValue* CrossThreadUnsupportedValue::ToCSSStyleValue() { ...@@ -12,4 +12,11 @@ CSSStyleValue* CrossThreadUnsupportedValue::ToCSSStyleValue() {
return CSSUnsupportedStyleValue::Create(value_); return CSSUnsupportedStyleValue::Create(value_);
} }
bool CrossThreadUnsupportedValue::operator==(
const CrossThreadStyleValue& other) const {
if (auto* o = DynamicTo<CrossThreadUnsupportedValue>(other))
return value_ == o->value_;
return false;
}
} // namespace blink } // namespace blink
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h" #include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink { namespace blink {
...@@ -20,8 +21,13 @@ class CORE_EXPORT CrossThreadUnsupportedValue final ...@@ -20,8 +21,13 @@ class CORE_EXPORT CrossThreadUnsupportedValue final
explicit CrossThreadUnsupportedValue(const String& value) : value_(value) {} explicit CrossThreadUnsupportedValue(const String& value) : value_(value) {}
~CrossThreadUnsupportedValue() override = default; ~CrossThreadUnsupportedValue() override = default;
StyleValueType GetType() const override {
return StyleValueType::kUnknownType;
}
CSSStyleValue* ToCSSStyleValue() override; CSSStyleValue* ToCSSStyleValue() override;
bool operator==(const CrossThreadStyleValue&) const override;
private: private:
friend class CrossThreadStyleValueTest; friend class CrossThreadStyleValueTest;
...@@ -29,6 +35,14 @@ class CORE_EXPORT CrossThreadUnsupportedValue final ...@@ -29,6 +35,14 @@ class CORE_EXPORT CrossThreadUnsupportedValue final
DISALLOW_COPY_AND_ASSIGN(CrossThreadUnsupportedValue); DISALLOW_COPY_AND_ASSIGN(CrossThreadUnsupportedValue);
}; };
template <>
struct DowncastTraits<CrossThreadUnsupportedValue> {
static bool AllowFrom(const CrossThreadStyleValue& unsupported_value) {
return unsupported_value.GetType() ==
CrossThreadStyleValue::StyleValueType::kUnknownType;
}
};
} // namespace blink } // namespace blink
#endif #endif
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