diff --git a/cc/paint/paint_flags.cc b/cc/paint/paint_flags.cc index 660b17b83bd070..607174e437376d 100644 --- a/cc/paint/paint_flags.cc +++ b/cc/paint/paint_flags.cc @@ -5,6 +5,7 @@ #include "cc/paint/paint_flags.h" #include "cc/paint/paint_op_buffer.h" +#include "third_party/skia/include/core/SkFlattenableSerialization.h" namespace { @@ -128,6 +129,64 @@ bool PaintFlags::IsValid() const { return PaintOp::IsValidPaintFlagsSkBlendMode(getBlendMode()); } +static bool AreFlattenablesEqual(SkFlattenable* left, SkFlattenable* right) { + sk_sp left_data(SkValidatingSerializeFlattenable(left)); + sk_sp right_data(SkValidatingSerializeFlattenable(right)); + if (left_data->size() != right_data->size()) + return false; + if (!left_data->equals(right_data.get())) + return false; + return true; +} + +bool PaintFlags::operator==(const PaintFlags& other) const { + // Can't just ToSkPaint and operator== here as SkPaint does pointer + // comparisons on all the ref'd skia objects on the SkPaint, which + // is not true after serialization. + if (getTextSize() != other.getTextSize()) + return false; + if (getColor() != other.getColor()) + return false; + if (getStrokeWidth() != other.getStrokeWidth()) + return false; + if (getStrokeMiter() != other.getStrokeMiter()) + return false; + if (getBlendMode() != other.getBlendMode()) + return false; + if (getStrokeCap() != other.getStrokeCap()) + return false; + if (getStrokeJoin() != other.getStrokeJoin()) + return false; + if (getStyle() != other.getStyle()) + return false; + if (getTextEncoding() != other.getTextEncoding()) + return false; + if (getHinting() != other.getHinting()) + return false; + if (getFilterQuality() != other.getFilterQuality()) + return false; + + // TODO(enne): compare typeface too + if (!AreFlattenablesEqual(getPathEffect().get(), other.getPathEffect().get())) + return false; + if (!AreFlattenablesEqual(getMaskFilter().get(), other.getMaskFilter().get())) + return false; + if (!AreFlattenablesEqual(getColorFilter().get(), + other.getColorFilter().get())) + return false; + if (!AreFlattenablesEqual(getLooper().get(), other.getLooper().get())) + return false; + if (!AreFlattenablesEqual(getImageFilter().get(), + other.getImageFilter().get())) + return false; + + if (!getShader() != !other.getShader()) + return false; + if (getShader() && *getShader() != *other.getShader()) + return false; + return true; +} + bool PaintFlags::HasDiscardableImages() const { if (!shader_) return false; diff --git a/cc/paint/paint_flags.h b/cc/paint/paint_flags.h index 5b03d5235c2673..5e2da8f8f0165a 100644 --- a/cc/paint/paint_flags.h +++ b/cc/paint/paint_flags.h @@ -218,6 +218,8 @@ class CC_PAINT_EXPORT PaintFlags { SkPaint ToSkPaint() const; bool IsValid() const; + bool operator==(const PaintFlags& other) const; + bool operator!=(const PaintFlags& other) const { return !(*this == other); } bool HasDiscardableImages() const; diff --git a/cc/paint/paint_image.cc b/cc/paint/paint_image.cc index db04151a512647..25ca3a353e9f6d 100644 --- a/cc/paint/paint_image.cc +++ b/cc/paint/paint_image.cc @@ -31,15 +31,29 @@ PaintImage& PaintImage::operator=(const PaintImage& other) = default; PaintImage& PaintImage::operator=(PaintImage&& other) = default; bool PaintImage::operator==(const PaintImage& other) const { - return sk_image_ == other.sk_image_ && paint_record_ == other.paint_record_ && - paint_record_rect_ == other.paint_record_rect_ && - paint_record_content_id_ == other.paint_record_content_id_ && - paint_image_generator_ == other.paint_image_generator_ && - id_ == other.id_ && animation_type_ == other.animation_type_ && - completion_state_ == other.completion_state_ && - subset_rect_ == other.subset_rect_ && - frame_index_ == other.frame_index_ && - is_multipart_ == other.is_multipart_; + if (sk_image_ != other.sk_image_) + return false; + if (paint_record_ != other.paint_record_) + return false; + if (paint_record_rect_ != other.paint_record_rect_) + return false; + if (paint_record_content_id_ != other.paint_record_content_id_) + return false; + if (paint_image_generator_ != other.paint_image_generator_) + return false; + if (id_ != other.id_) + return false; + if (animation_type_ != other.animation_type_) + return false; + if (completion_state_ != other.completion_state_) + return false; + if (subset_rect_ != other.subset_rect_) + return false; + if (frame_index_ != other.frame_index_) + return false; + if (is_multipart_ != other.is_multipart_) + return false; + return true; } // static diff --git a/cc/paint/paint_image.h b/cc/paint/paint_image.h index 21df1d9ef047f1..5bc445b3c3302e 100644 --- a/cc/paint/paint_image.h +++ b/cc/paint/paint_image.h @@ -106,6 +106,7 @@ class CC_PAINT_EXPORT PaintImage { PaintImage& operator=(PaintImage&& other); bool operator==(const PaintImage& other) const; + bool operator!=(const PaintImage& other) const { return !(*this == other); } // Returns the smallest size that is at least as big as the requested_size // such that we can decode to exactly that scale. If the requested size is diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index c0004b2e17322e..6f75cc78d6bd4c 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc @@ -16,6 +16,7 @@ #include "third_party/skia/include/core/SkAnnotation.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkRegion.h" +#include "third_party/skia/include/core/SkWriteBuffer.h" namespace cc { namespace { @@ -157,6 +158,11 @@ static const DeserializeFunction g_deserialize_functions[kNumOpTypes] = { TYPES(M)}; #undef M +using EqualsFunction = bool (*)(const PaintOp* left, const PaintOp* right); +#define M(T) &T::AreEqual, +static const EqualsFunction g_equals_operator[kNumOpTypes] = {TYPES(M)}; +#undef M + // Most state ops (matrix, clip, save, restore) have a trivial destructor. // TODO(enne): evaluate if we need the nullptr optimization or if // we even need to differentiate trivial destructors here. @@ -1205,6 +1211,366 @@ void TranslateOp::Raster(const TranslateOp* op, canvas->translate(op->dx, op->dy); } +static bool AreSkMatricesEqual(const SkMatrix& left, const SkMatrix& right) { + // Compare the 3x3 matrix values. + if (left != right) + return false; + + // If a serialized matrix says it is identity, then the original must have + // those values, as the serialization process clobbers the matrix values. + if (left.isIdentity()) { + if (SkMatrix::I() != left) + return false; + if (SkMatrix::I() != right) + return false; + } + + if (left.getType() != right.getType()) + return false; + + return true; +} + +bool AnnotateOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->annotation_type != right->annotation_type) + return false; + if (left->rect != right->rect) + return false; + if (!left->data != !right->data) + return false; + if (left->data) { + if (left->data->size() != right->data->size()) + return false; + if (0 != + memcmp(left->data->data(), right->data->data(), right->data->size())) + return false; + } + return true; +} + +bool ClipPathOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->path != right->path) + return false; + if (left->op != right->op) + return false; + if (left->antialias != right->antialias) + return false; + return true; +} + +bool ClipRectOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->rect != right->rect) + return false; + if (left->op != right->op) + return false; + if (left->antialias != right->antialias) + return false; + return true; +} + +bool ClipRRectOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->rrect != right->rrect) + return false; + if (left->op != right->op) + return false; + if (left->antialias != right->antialias) + return false; + return true; +} + +bool ConcatOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + return AreSkMatricesEqual(left->matrix, right->matrix); +} + +bool DrawColorOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + return left->color == right->color; +} + +bool DrawDRRectOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + if (left->outer != right->outer) + return false; + if (left->inner != right->inner) + return false; + return true; +} + +bool DrawImageOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + // TODO(enne): Test PaintImage equality once implemented + if (left->left != right->left) + return false; + if (left->top != right->top) + return false; + return true; +} + +bool DrawImageRectOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + // TODO(enne): Test PaintImage equality once implemented + if (left->src != right->src) + return false; + if (left->dst != right->dst) + return false; + return true; +} + +bool DrawIRectOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + if (left->rect != right->rect) + return false; + return true; +} + +bool DrawLineOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + if (left->x0 != right->x0) + return false; + if (left->y0 != right->y0) + return false; + if (left->x1 != right->x1) + return false; + if (left->y1 != right->y1) + return false; + return true; +} + +bool DrawOvalOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + if (left->oval != right->oval) + return false; + return true; +} + +bool DrawPathOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + if (left->path != right->path) + return false; + return true; +} + +bool DrawRecordOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (!left->record != !right->record) + return false; + if (*left->record != *right->record) + return false; + return true; +} + +bool DrawRectOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + if (left->rect != right->rect) + return false; + return true; +} + +bool DrawRRectOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + if (left->rrect != right->rrect) + return false; + return true; +} + +bool DrawTextBlobOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + if (left->x != right->x) + return false; + if (left->y != right->y) + return false; + + DCHECK(*left->blob); + DCHECK(*right->blob); + + SkBinaryWriteBuffer left_flattened; + left->blob->ToSkTextBlob()->flatten(left_flattened); + std::vector left_mem(left_flattened.bytesWritten()); + left_flattened.writeToMemory(left_mem.data()); + + SkBinaryWriteBuffer right_flattened; + right->blob->ToSkTextBlob()->flatten(right_flattened); + std::vector right_mem(right_flattened.bytesWritten()); + right_flattened.writeToMemory(right_mem.data()); + + if (left_mem.size() != right_mem.size()) + return false; + if (left_mem != right_mem) + return false; + return true; +} + +bool NoopOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + return true; +} + +bool RestoreOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + return true; +} + +bool RotateOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->degrees != right->degrees) + return false; + return true; +} + +bool SaveOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + return true; +} + +bool SaveLayerOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->flags != right->flags) + return false; + if (left->bounds != right->bounds) + return false; + return true; +} + +bool SaveLayerAlphaOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->bounds != right->bounds) + return false; + if (left->alpha != right->alpha) + return false; + if (left->preserve_lcd_text_requests != right->preserve_lcd_text_requests) + return false; + return true; +} + +bool ScaleOp::AreEqual(const PaintOp* base_left, const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->sx != right->sx) + return false; + if (left->sy != right->sy) + return false; + return true; +} + +bool SetMatrixOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (!AreSkMatricesEqual(left->matrix, right->matrix)) + return false; + return true; +} + +bool TranslateOp::AreEqual(const PaintOp* base_left, + const PaintOp* base_right) { + auto* left = static_cast(base_left); + auto* right = static_cast(base_right); + DCHECK(left->IsValid()); + DCHECK(right->IsValid()); + if (left->dx != right->dx) + return false; + if (left->dy != right->dy) + return false; + return true; +} + bool PaintOp::IsDrawOp() const { return g_is_draw_op[type]; } @@ -1213,6 +1579,12 @@ bool PaintOp::IsPaintOpWithFlags() const { return g_has_paint_flags[type]; } +bool PaintOp::operator==(const PaintOp& other) const { + if (GetType() != other.GetType()) + return false; + return g_equals_operator[type](this, &other); +} + void PaintOp::Raster(SkCanvas* canvas, const PlaybackParams& params) const { g_raster_functions[type](this, canvas, params); } @@ -1827,4 +2199,29 @@ void PaintOpBuffer::ShrinkToFit() { } } +bool PaintOpBuffer::operator==(const PaintOpBuffer& other) const { + if (op_count_ != other.op_count_) + return false; + if (num_slow_paths_ != other.num_slow_paths_) + return false; + if (subrecord_bytes_used_ != other.subrecord_bytes_used_) + return false; + if (has_non_aa_paint_ != other.has_non_aa_paint_) + return false; + if (has_discardable_images_ != other.has_discardable_images_) + return false; + + auto left_iter = Iterator(this); + auto right_iter = Iterator(&other); + + for (; left_iter != left_iter.end(); ++left_iter, ++right_iter) { + if (**left_iter != **right_iter) + return false; + } + + DCHECK(left_iter == left_iter.end()); + DCHECK(right_iter == right_iter.end()); + return true; +} + } // namespace cc diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h index 93861ebc212bd6..d0aa90df9d2c52 100644 --- a/cc/paint/paint_op_buffer.h +++ b/cc/paint/paint_op_buffer.h @@ -110,7 +110,9 @@ class CC_PAINT_EXPORT PaintOp { void Raster(SkCanvas* canvas, const PlaybackParams& params) const; bool IsDrawOp() const; bool IsPaintOpWithFlags() const; - bool IsValid() const; + + bool operator==(const PaintOp& other) const; + bool operator!=(const PaintOp& other) const { return !(*this == other); } struct CC_PAINT_EXPORT SerializeOptions { SerializeOptions(); @@ -246,6 +248,7 @@ class CC_PAINT_EXPORT AnnotateOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return rect.isFinite(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); PaintCanvas::AnnotationType annotation_type; @@ -265,6 +268,7 @@ class CC_PAINT_EXPORT ClipPathOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return IsValidSkClipOp(op) && IsValidPath(path); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); int CountSlowPaths() const; bool HasNonAAPaint() const { return !antialias; } HAS_SERIALIZATION_FUNCTIONS(); @@ -286,6 +290,7 @@ class CC_PAINT_EXPORT ClipRectOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return IsValidSkClipOp(op) && rect.isFinite(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkRect rect; @@ -302,6 +307,7 @@ class CC_PAINT_EXPORT ClipRRectOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return IsValidSkClipOp(op) && rrect.isValid(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); bool HasNonAAPaint() const { return !antialias; } HAS_SERIALIZATION_FUNCTIONS(); @@ -318,6 +324,7 @@ class CC_PAINT_EXPORT ConcatOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return true; } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); ThreadsafeMatrix matrix; @@ -333,6 +340,7 @@ class CC_PAINT_EXPORT DrawColorOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return IsValidDrawColorSkBlendMode(mode); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkColor color; @@ -354,6 +362,7 @@ class CC_PAINT_EXPORT DrawDRRectOp final : public PaintOpWithFlags { bool IsValid() const { return flags.IsValid() && outer.isValid() && inner.isValid(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkRRect outer; @@ -377,6 +386,7 @@ class CC_PAINT_EXPORT DrawImageOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); bool HasDiscardableImages() const; bool HasNonAAPaint() const { return false; } HAS_SERIALIZATION_FUNCTIONS(); @@ -406,6 +416,7 @@ class CC_PAINT_EXPORT DrawImageRectOp final : public PaintOpWithFlags { bool IsValid() const { return flags.IsValid() && src.isFinite() && dst.isFinite(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); bool HasDiscardableImages() const; HAS_SERIALIZATION_FUNCTIONS(); @@ -429,6 +440,7 @@ class CC_PAINT_EXPORT DrawIRectOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); bool HasNonAAPaint() const { return false; } HAS_SERIALIZATION_FUNCTIONS(); @@ -453,6 +465,7 @@ class CC_PAINT_EXPORT DrawLineOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); int CountSlowPaths() const; @@ -477,6 +490,7 @@ class CC_PAINT_EXPORT DrawOvalOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid() && oval.isFinite(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkRect oval; @@ -496,6 +510,7 @@ class CC_PAINT_EXPORT DrawPathOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid() && IsValidPath(path); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); int CountSlowPaths() const; HAS_SERIALIZATION_FUNCTIONS(); @@ -515,6 +530,7 @@ class CC_PAINT_EXPORT DrawRecordOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return true; } + static bool AreEqual(const PaintOp* left, const PaintOp* right); size_t AdditionalBytesUsed() const; bool HasDiscardableImages() const; int CountSlowPaths() const; @@ -535,6 +551,7 @@ class CC_PAINT_EXPORT DrawRectOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid() && rect.isFinite(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkRect rect; @@ -554,6 +571,7 @@ class CC_PAINT_EXPORT DrawRRectOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid() && rrect.isValid(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkRRect rrect; @@ -576,6 +594,7 @@ class CC_PAINT_EXPORT DrawTextBlobOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid(); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); scoped_refptr blob; @@ -594,6 +613,7 @@ class CC_PAINT_EXPORT NoopOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params) {} bool IsValid() const { return true; } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); }; @@ -605,6 +625,7 @@ class CC_PAINT_EXPORT RestoreOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return true; } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); }; @@ -616,6 +637,7 @@ class CC_PAINT_EXPORT RotateOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return true; } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkScalar degrees; @@ -629,6 +651,7 @@ class CC_PAINT_EXPORT SaveOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return true; } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); }; @@ -643,6 +666,7 @@ class CC_PAINT_EXPORT SaveLayerOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid() && IsValidOrUnsetRect(bounds); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); bool HasNonAAPaint() const { return false; } HAS_SERIALIZATION_FUNCTIONS(); @@ -666,6 +690,7 @@ class CC_PAINT_EXPORT SaveLayerAlphaOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return IsValidOrUnsetRect(bounds); } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkRect bounds; @@ -681,6 +706,7 @@ class CC_PAINT_EXPORT ScaleOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return true; } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkScalar sx; @@ -705,6 +731,7 @@ class CC_PAINT_EXPORT SetMatrixOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return true; } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); ThreadsafeMatrix matrix; @@ -718,6 +745,7 @@ class CC_PAINT_EXPORT TranslateOp final : public PaintOp { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return true; } + static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); SkScalar dx; @@ -772,6 +800,11 @@ class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt { bool HasNonAAPaint() const { return has_non_aa_paint_; } bool HasDiscardableImages() const { return has_discardable_images_; } + bool operator==(const PaintOpBuffer& other) const; + bool operator!=(const PaintOpBuffer& other) const { + return !(*this == other); + } + // Resize the PaintOpBuffer to exactly fit the current amount of used space. void ShrinkToFit(); diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc index fa5bc1f830034e..2769143956aed3 100644 --- a/cc/paint/paint_op_buffer_unittest.cc +++ b/cc/paint/paint_op_buffer_unittest.cc @@ -13,6 +13,7 @@ #include "cc/paint/paint_op_reader.h" #include "cc/paint/paint_op_writer.h" #include "cc/test/geometry_test_utils.h" +#include "cc/test/paint_op_helper.h" #include "cc/test/skia_common.h" #include "cc/test/test_skcanvas.h" #include "testing/gtest/include/gtest/gtest.h" @@ -46,80 +47,6 @@ void ValidateOps(PaintOpBuffer* buffer) { class PaintOpSerializationTestUtils { public: - static void ExpectFlattenableEqual(SkFlattenable* expected, - SkFlattenable* actual) { - sk_sp expected_data(SkValidatingSerializeFlattenable(expected)); - sk_sp actual_data(SkValidatingSerializeFlattenable(actual)); - ASSERT_EQ(expected_data->size(), actual_data->size()); - EXPECT_TRUE(expected_data->equals(actual_data.get())); - } - - static void ExpectPaintShadersEqual(const PaintShader* one, - const PaintShader* two) { - if (!one) { - EXPECT_FALSE(two); - return; - } - - ASSERT_TRUE(one); - ASSERT_TRUE(two); - - EXPECT_EQ(one->shader_type_, two->shader_type_); - EXPECT_EQ(one->flags_, two->flags_); - EXPECT_EQ(one->end_radius_, two->end_radius_); - EXPECT_EQ(one->start_radius_, two->start_radius_); - EXPECT_EQ(one->tx_, two->tx_); - EXPECT_EQ(one->ty_, two->ty_); - EXPECT_EQ(one->fallback_color_, two->fallback_color_); - EXPECT_EQ(one->scaling_behavior_, two->scaling_behavior_); - if (one->local_matrix_) { - EXPECT_TRUE(two->local_matrix_.has_value()); - EXPECT_TRUE(*one->local_matrix_ == *two->local_matrix_); - } else { - EXPECT_FALSE(two->local_matrix_.has_value()); - } - EXPECT_EQ(one->center_, two->center_); - EXPECT_EQ(one->tile_, two->tile_); - EXPECT_EQ(one->start_point_, two->start_point_); - EXPECT_EQ(one->end_point_, two->end_point_); - EXPECT_EQ(one->start_degrees_, two->start_degrees_); - EXPECT_EQ(one->end_degrees_, two->end_degrees_); - EXPECT_THAT(one->colors_, testing::ElementsAreArray(two->colors_)); - EXPECT_THAT(one->positions_, testing::ElementsAreArray(two->positions_)); - } - - static void ExpectPaintFlagsEqual(const PaintFlags& expected, - const PaintFlags& actual) { - // Can't just ToSkPaint and operator== here as SkPaint does pointer - // comparisons on all the ref'd skia objects on the SkPaint, which - // is not true after serialization. - EXPECT_EQ(expected.getTextSize(), actual.getTextSize()); - EXPECT_EQ(expected.getColor(), actual.getColor()); - EXPECT_EQ(expected.getStrokeWidth(), actual.getStrokeWidth()); - EXPECT_EQ(expected.getStrokeMiter(), actual.getStrokeMiter()); - EXPECT_EQ(expected.getBlendMode(), actual.getBlendMode()); - EXPECT_EQ(expected.getStrokeCap(), actual.getStrokeCap()); - EXPECT_EQ(expected.getStrokeJoin(), actual.getStrokeJoin()); - EXPECT_EQ(expected.getStyle(), actual.getStyle()); - EXPECT_EQ(expected.getTextEncoding(), actual.getTextEncoding()); - EXPECT_EQ(expected.getHinting(), actual.getHinting()); - EXPECT_EQ(expected.getFilterQuality(), actual.getFilterQuality()); - - // TODO(enne): compare typeface too - ExpectFlattenableEqual(expected.getPathEffect().get(), - actual.getPathEffect().get()); - ExpectFlattenableEqual(expected.getMaskFilter().get(), - actual.getMaskFilter().get()); - ExpectFlattenableEqual(expected.getColorFilter().get(), - actual.getColorFilter().get()); - ExpectFlattenableEqual(expected.getLooper().get(), - actual.getLooper().get()); - ExpectFlattenableEqual(expected.getImageFilter().get(), - actual.getImageFilter().get()); - - ExpectPaintShadersEqual(expected.getShader(), actual.getShader()); - } - static void FillArbitraryShaderValues(PaintShader* shader, bool use_matrix) { shader->shader_type_ = PaintShader::Type::kTwoPointConicalGradient; shader->flags_ = 12345; @@ -190,8 +117,7 @@ class PaintOpAppendTest : public ::testing::Test { ASSERT_EQ(iter->GetType(), PaintOpType::SaveLayer); SaveLayerOp* save_op = static_cast(*iter); EXPECT_EQ(save_op->bounds, rect_); - PaintOpSerializationTestUtils::ExpectPaintFlagsEqual(save_op->flags, - flags_); + EXPECT_EQ(save_op->flags, flags_); ++iter; ASSERT_EQ(iter->GetType(), PaintOpType::Save); @@ -237,7 +163,6 @@ TEST_F(PaintOpAppendTest, MoveThenDestruct) { // Original should be empty, and safe to destruct. EXPECT_EQ(original.size(), 0u); EXPECT_EQ(original.bytes_used(), sizeof(PaintOpBuffer)); - EXPECT_EQ(PaintOpBuffer::Iterator(&original), false); } TEST_F(PaintOpAppendTest, MoveThenDestructOperatorEq) { @@ -264,6 +189,7 @@ TEST_F(PaintOpAppendTest, MoveThenReappend) { // Should be possible to reappend to the original and get the same result. PushOps(&original); VerifyOps(&original); + EXPECT_EQ(original, destination); } TEST_F(PaintOpAppendTest, MoveThenReappendOperatorEq) { @@ -276,6 +202,7 @@ TEST_F(PaintOpAppendTest, MoveThenReappendOperatorEq) { // Should be possible to reappend to the original and get the same result. PushOps(&original); VerifyOps(&original); + EXPECT_EQ(original, destination); } // Verify that a SaveLayerAlpha / Draw / Restore can be optimized to just @@ -1628,242 +1555,6 @@ void PushTranslateOps(PaintOpBuffer* buffer) { ValidateOps(buffer); } -void CompareFlags(const PaintFlags& original, const PaintFlags& written) { - PaintOpSerializationTestUtils::ExpectPaintFlagsEqual(original, written); -} - -void CompareImages(const PaintImage& original, const PaintImage& written) {} - -void CompareMatrices(const SkMatrix& original, const SkMatrix& written) { - // Compare the 3x3 matrix values. - EXPECT_EQ(original, written); - - // If a serialized matrix says it is identity, then the original must have - // those values, as the serialization process clobbers the matrix values. - if (original.isIdentity()) { - EXPECT_EQ(SkMatrix::I(), original); - EXPECT_EQ(SkMatrix::I(), written); - } - - EXPECT_EQ(original.getType(), written.getType()); -} - -void CompareAnnotateOp(const AnnotateOp* original, const AnnotateOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - EXPECT_EQ(original->annotation_type, written->annotation_type); - EXPECT_EQ(original->rect, written->rect); - EXPECT_EQ(!!original->data, !!written->data); - if (original->data) { - EXPECT_EQ(original->data->size(), written->data->size()); - EXPECT_EQ(0, memcmp(original->data->data(), written->data->data(), - written->data->size())); - } -} - -void CompareClipPathOp(const ClipPathOp* original, const ClipPathOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - EXPECT_TRUE(original->path == written->path); - EXPECT_EQ(original->op, written->op); - EXPECT_EQ(original->antialias, written->antialias); -} - -void CompareClipRectOp(const ClipRectOp* original, const ClipRectOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - EXPECT_EQ(original->rect, written->rect); - EXPECT_EQ(original->op, written->op); - EXPECT_EQ(original->antialias, written->antialias); -} - -void CompareClipRRectOp(const ClipRRectOp* original, - const ClipRRectOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - EXPECT_EQ(original->rrect, written->rrect); - EXPECT_EQ(original->op, written->op); - EXPECT_EQ(original->antialias, written->antialias); -} - -void CompareConcatOp(const ConcatOp* original, const ConcatOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareMatrices(original->matrix, written->matrix); -} - -void CompareDrawColorOp(const DrawColorOp* original, - const DrawColorOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - EXPECT_EQ(original->color, written->color); -} - -void CompareDrawDRRectOp(const DrawDRRectOp* original, - const DrawDRRectOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - EXPECT_EQ(original->outer, written->outer); - EXPECT_EQ(original->inner, written->inner); -} - -void CompareDrawImageOp(const DrawImageOp* original, - const DrawImageOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - CompareImages(original->image, written->image); - EXPECT_EQ(original->left, written->left); - EXPECT_EQ(original->top, written->top); -} - -void CompareDrawImageRectOp(const DrawImageRectOp* original, - const DrawImageRectOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - CompareImages(original->image, written->image); - EXPECT_EQ(original->src, written->src); - EXPECT_EQ(original->dst, written->dst); -} - -void CompareDrawIRectOp(const DrawIRectOp* original, - const DrawIRectOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - EXPECT_EQ(original->rect, written->rect); -} - -void CompareDrawLineOp(const DrawLineOp* original, const DrawLineOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - EXPECT_EQ(original->x0, written->x0); - EXPECT_EQ(original->y0, written->y0); - EXPECT_EQ(original->x1, written->x1); - EXPECT_EQ(original->y1, written->y1); -} - -void CompareDrawOvalOp(const DrawOvalOp* original, const DrawOvalOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - EXPECT_EQ(original->oval, written->oval); -} - -void CompareDrawPathOp(const DrawPathOp* original, const DrawPathOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - EXPECT_TRUE(original->path == written->path); -} - -void CompareDrawRectOp(const DrawRectOp* original, const DrawRectOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - EXPECT_EQ(original->rect, written->rect); -} - -void CompareDrawRRectOp(const DrawRRectOp* original, - const DrawRRectOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - EXPECT_EQ(original->rrect, written->rrect); -} - -void CompareDrawTextBlobOp(const DrawTextBlobOp* original, - const DrawTextBlobOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - EXPECT_EQ(original->x, written->x); - EXPECT_EQ(original->y, written->y); - - ASSERT_TRUE(*original->blob); - ASSERT_TRUE(*written->blob); - - SkBinaryWriteBuffer original_flattened; - original->blob->ToSkTextBlob()->flatten(original_flattened); - std::vector original_mem(original_flattened.bytesWritten()); - original_flattened.writeToMemory(original_mem.data()); - - SkBinaryWriteBuffer written_flattened; - written->blob->ToSkTextBlob()->flatten(written_flattened); - std::vector written_mem(written_flattened.bytesWritten()); - written_flattened.writeToMemory(written_mem.data()); - - ASSERT_EQ(original_mem.size(), written_mem.size()); - EXPECT_EQ(original_mem, written_mem); -} - -void CompareNoopOp(const NoopOp* original, const NoopOp* written) { - // Nothing to compare. - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); -} - -void CompareRestoreOp(const RestoreOp* original, const RestoreOp* written) { - // Nothing to compare. - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); -} - -void CompareRotateOp(const RotateOp* original, const RotateOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - EXPECT_EQ(original->degrees, written->degrees); -} - -void CompareSaveOp(const SaveOp* original, const SaveOp* written) { - // Nothing to compare. - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); -} - -void CompareSaveLayerOp(const SaveLayerOp* original, - const SaveLayerOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareFlags(original->flags, written->flags); - EXPECT_EQ(original->bounds, written->bounds); -} - -void CompareSaveLayerAlphaOp(const SaveLayerAlphaOp* original, - const SaveLayerAlphaOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - EXPECT_EQ(original->bounds, written->bounds); - EXPECT_EQ(original->alpha, written->alpha); - EXPECT_EQ(original->preserve_lcd_text_requests, - written->preserve_lcd_text_requests); -} - -void CompareScaleOp(const ScaleOp* original, const ScaleOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - EXPECT_EQ(original->sx, written->sx); - EXPECT_EQ(original->sy, written->sy); -} - -void CompareSetMatrixOp(const SetMatrixOp* original, - const SetMatrixOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - CompareMatrices(original->matrix, written->matrix); -} - -void CompareTranslateOp(const TranslateOp* original, - const TranslateOp* written) { - EXPECT_TRUE(original->IsValid()); - EXPECT_TRUE(written->IsValid()); - EXPECT_EQ(original->dx, written->dx); - EXPECT_EQ(original->dy, written->dy); -} - class PaintOpSerializationTest : public ::testing::TestWithParam { public: PaintOpType GetParamType() const { @@ -1953,119 +1644,6 @@ class PaintOpSerializationTest : public ::testing::TestWithParam { } } - static void ExpectOpsEqual(const PaintOp* original, const PaintOp* written) { - ASSERT_TRUE(original); - ASSERT_TRUE(written); - ASSERT_EQ(original->GetType(), written->GetType()); - EXPECT_EQ(original->skip, written->skip); - - switch (original->GetType()) { - case PaintOpType::Annotate: - CompareAnnotateOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::ClipPath: - CompareClipPathOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::ClipRect: - CompareClipRectOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::ClipRRect: - CompareClipRRectOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::Concat: - CompareConcatOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawColor: - CompareDrawColorOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawDRRect: - CompareDrawDRRectOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawImage: - CompareDrawImageOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawImageRect: - CompareDrawImageRectOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawIRect: - CompareDrawIRectOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawLine: - CompareDrawLineOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawOval: - CompareDrawOvalOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawPath: - CompareDrawPathOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawRecord: - // Not supported. - break; - case PaintOpType::DrawRect: - CompareDrawRectOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawRRect: - CompareDrawRRectOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::DrawTextBlob: - CompareDrawTextBlobOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::Noop: - CompareNoopOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::Restore: - CompareRestoreOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::Rotate: - CompareRotateOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::Save: - CompareSaveOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::SaveLayer: - CompareSaveLayerOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::SaveLayerAlpha: - CompareSaveLayerAlphaOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::Scale: - CompareScaleOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::SetMatrix: - CompareSetMatrixOp(static_cast(original), - static_cast(written)); - break; - case PaintOpType::Translate: - CompareTranslateOp(static_cast(original), - static_cast(written)); - break; - } - } - void ResizeOutputBuffer() { // An arbitrary deserialization buffer size that should fit all the ops // in the buffer_. @@ -2118,7 +1696,7 @@ TEST_P(PaintOpSerializationTest, SmokeTest) { DeserializerIterator(output_.get(), serializer.TotalBytesWritten())) { SCOPED_TRACE(base::StringPrintf( "%s #%zu", PaintOpTypeToString(GetParamType()).c_str(), i)); - ExpectOpsEqual(*iter, base_written); + EXPECT_EQ(**iter, *base_written); ++iter; ++i; } @@ -2296,7 +1874,7 @@ TEST(PaintOpSerializationTest, CompleteBufferSerialization) { // Root buffer. ASSERT_EQ(op->GetType(), (*serialized_iter)->GetType()) << PaintOpTypeToString(op->GetType()); - PaintOpSerializationTest::ExpectOpsEqual(op, *serialized_iter); + EXPECT_EQ(*op, **serialized_iter); ++serialized_iter; continue; } @@ -2384,7 +1962,7 @@ TEST(PaintOpSerializationTest, Preamble) { if (i == 6) { // Buffer. - PaintOpSerializationTest::ExpectOpsEqual(op, buffer.GetFirstOp()); + EXPECT_EQ(*op, *buffer.GetFirstOp()); continue; } @@ -2431,7 +2009,7 @@ TEST(PaintOpSerializationTest, SerializesNestedRecords) { // Nested buffer. ASSERT_EQ(op->GetType(), (*serialized_iter)->GetType()) << PaintOpTypeToString(op->GetType()); - PaintOpSerializationTest::ExpectOpsEqual(op, *serialized_iter); + EXPECT_EQ(*op, **serialized_iter); ++serialized_iter; continue; } @@ -2481,7 +2059,7 @@ TEST(PaintOpBufferTest, ClipsImagesDuringSerialization) { // Root buffer. ASSERT_EQ(op->GetType(), (*serialized_iter)->GetType()) << PaintOpTypeToString(op->GetType()); - PaintOpSerializationTest::ExpectOpsEqual(op, *serialized_iter); + EXPECT_EQ(*op, **serialized_iter); ++serialized_iter; continue; } diff --git a/cc/paint/paint_shader.cc b/cc/paint/paint_shader.cc index 0904ad06fc4e9e..e5610e6200b37e 100644 --- a/cc/paint/paint_shader.cc +++ b/cc/paint/paint_shader.cc @@ -394,4 +394,53 @@ bool PaintShader::IsValid() const { return false; } +bool PaintShader::operator==(const PaintShader& other) const { + if (shader_type_ != other.shader_type_) + return false; + if (flags_ != other.flags_) + return false; + if (end_radius_ != other.end_radius_) + return false; + if (start_radius_ != other.start_radius_) + return false; + if (tx_ != other.tx_) + return false; + if (ty_ != other.ty_) + return false; + if (fallback_color_ != other.fallback_color_) + return false; + if (scaling_behavior_ != other.scaling_behavior_) + return false; + if (local_matrix_) { + if (!other.local_matrix_.has_value()) + return false; + if (*local_matrix_ != *other.local_matrix_) + return false; + } else { + if (other.local_matrix_.has_value()) + return false; + } + if (center_ != other.center_) + return false; + if (tile_ != other.tile_) + return false; + if (start_point_ != other.start_point_) + return false; + if (end_point_ != other.end_point_) + return false; + if (start_degrees_ != other.start_degrees_) + return false; + if (end_degrees_ != other.end_degrees_) + return false; + + // TODO(enne): add comparison of records once those are serialized. + // TODO(enne): add comparison of images once those are serialized. + + if (colors_ != other.colors_) + return false; + if (positions_ != other.positions_) + return false; + return true; +} + } // namespace cc diff --git a/cc/paint/paint_shader.h b/cc/paint/paint_shader.h index 0c76dde2f5009e..6c720742d2a1e9 100644 --- a/cc/paint/paint_shader.h +++ b/cc/paint/paint_shader.h @@ -126,6 +126,9 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt { // shader is correct is hard. bool IsValid() const; + bool operator==(const PaintShader& other) const; + bool operator!=(const PaintShader& other) const { return !(*this == other); } + private: friend class PaintFlags; friend class PaintOpReader; diff --git a/cc/test/paint_op_helper.h b/cc/test/paint_op_helper.h index 5a0810d4582335..fcd95176b34811 100644 --- a/cc/test/paint_op_helper.h +++ b/cc/test/paint_op_helper.h @@ -19,7 +19,7 @@ namespace cc { // implementation should be limited ot the header. class PaintOpHelper { public: - static std::string ToString(PaintOp* base_op) { + static std::string ToString(const PaintOp* base_op) { std::ostringstream str; str << std::boolalpha; switch (base_op->GetType()) { @@ -378,4 +378,8 @@ class PaintOpHelper { } // namespace cc +inline ::std::ostream& operator<<(::std::ostream& os, const cc::PaintOp& op) { + return os << cc::PaintOpHelper::ToString(&op); +} + #endif // CC_TEST_PAINT_OP_HELPER_H_