1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "cc/paint/paint_filter.h"
6 
7 #include "cc/paint/filter_operations.h"
8 #include "cc/paint/paint_image_builder.h"
9 #include "cc/paint/paint_op_writer.h"
10 #include "cc/paint/paint_record.h"
11 #include "third_party/skia/include/core/SkColorFilter.h"
12 #include "third_party/skia/include/core/SkMath.h"
13 #include "third_party/skia/include/effects/SkAlphaThresholdFilter.h"
14 #include "third_party/skia/include/effects/SkArithmeticImageFilter.h"
15 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
16 #include "third_party/skia/include/effects/SkComposeImageFilter.h"
17 #include "third_party/skia/include/effects/SkImageSource.h"
18 #include "third_party/skia/include/effects/SkLightingImageFilter.h"
19 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h"
20 #include "third_party/skia/include/effects/SkMergeImageFilter.h"
21 #include "third_party/skia/include/effects/SkMorphologyImageFilter.h"
22 #include "third_party/skia/include/effects/SkOffsetImageFilter.h"
23 #include "third_party/skia/include/effects/SkPaintImageFilter.h"
24 #include "third_party/skia/include/effects/SkPerlinNoiseShader.h"
25 #include "third_party/skia/include/effects/SkPictureImageFilter.h"
26 #include "third_party/skia/include/effects/SkTileImageFilter.h"
27 #include "third_party/skia/include/effects/SkXfermodeImageFilter.h"
28 
29 namespace cc {
30 namespace {
31 const bool kHasNoDiscardableImages = false;
32 
AreFiltersEqual(const PaintFilter * one,const PaintFilter * two)33 bool AreFiltersEqual(const PaintFilter* one, const PaintFilter* two) {
34   if (!one || !two)
35     return !one && !two;
36   return *one == *two;
37 }
38 
AreScalarsEqual(SkScalar one,SkScalar two)39 bool AreScalarsEqual(SkScalar one, SkScalar two) {
40   return PaintOp::AreEqualEvenIfNaN(one, two);
41 }
42 
HasDiscardableImages(const sk_sp<PaintFilter> & filter)43 bool HasDiscardableImages(const sk_sp<PaintFilter>& filter) {
44   return filter ? filter->has_discardable_images() : false;
45 }
46 
HasDiscardableImages(const sk_sp<PaintFilter> * const filters,int count)47 bool HasDiscardableImages(const sk_sp<PaintFilter>* const filters, int count) {
48   for (int i = 0; i < count; ++i) {
49     if (filters[i] && filters[i]->has_discardable_images())
50       return true;
51   }
52   return false;
53 }
54 
Snapshot(const sk_sp<PaintFilter> & filter,ImageProvider * image_provider)55 sk_sp<PaintFilter> Snapshot(const sk_sp<PaintFilter>& filter,
56                             ImageProvider* image_provider) {
57   if (!filter)
58     return nullptr;
59   return filter->SnapshotWithImages(image_provider);
60 }
61 
62 }  // namespace
63 
PaintFilter(Type type,const CropRect * crop_rect,bool has_discardable_images)64 PaintFilter::PaintFilter(Type type,
65                          const CropRect* crop_rect,
66                          bool has_discardable_images)
67     : type_(type), has_discardable_images_(has_discardable_images) {
68   if (crop_rect)
69     crop_rect_.emplace(*crop_rect);
70 }
71 
72 PaintFilter::~PaintFilter() = default;
73 
74 // static
TypeToString(Type type)75 std::string PaintFilter::TypeToString(Type type) {
76   switch (type) {
77     case Type::kNullFilter:
78       return "kNullFilter";
79     case Type::kColorFilter:
80       return "kColorFilter";
81     case Type::kBlur:
82       return "kBlur";
83     case Type::kDropShadow:
84       return "kDropShadow";
85     case Type::kMagnifier:
86       return "kMagnifier";
87     case Type::kCompose:
88       return "kCompose";
89     case Type::kAlphaThreshold:
90       return "kAlphaThreshold";
91     case Type::kXfermode:
92       return "kXfermode";
93     case Type::kArithmetic:
94       return "kArithmetic";
95     case Type::kMatrixConvolution:
96       return "kMatrixConvolution";
97     case Type::kDisplacementMapEffect:
98       return "kDisplacementMapEffect";
99     case Type::kImage:
100       return "kImage";
101     case Type::kPaintRecord:
102       return "kPaintRecord";
103     case Type::kMerge:
104       return "kMerge";
105     case Type::kMorphology:
106       return "kMorphology";
107     case Type::kOffset:
108       return "kOffset";
109     case Type::kTile:
110       return "kTile";
111     case Type::kTurbulence:
112       return "kTurbulence";
113     case Type::kPaintFlags:
114       return "kPaintFlags";
115     case Type::kMatrix:
116       return "kMatrix";
117     case Type::kLightingDistant:
118       return "kLightingDistant";
119     case Type::kLightingPoint:
120       return "kLightingPoint";
121     case Type::kLightingSpot:
122       return "kLightingSpot";
123   }
124   NOTREACHED();
125   return "Unknown";
126 }
127 
GetFilterSize(const PaintFilter * filter)128 size_t PaintFilter::GetFilterSize(const PaintFilter* filter) {
129   // A null type is used to indicate no filter.
130   if (!filter)
131     return sizeof(uint32_t);
132   return filter->SerializedSize() + PaintOpWriter::Alignment();
133 }
134 
BaseSerializedSize() const135 size_t PaintFilter::BaseSerializedSize() const {
136   size_t total_size = 0u;
137   // Filter type.
138   total_size += sizeof(uint32_t);
139   // Bool to indicate whether crop exists.
140   total_size += sizeof(uint32_t);
141   if (crop_rect_) {
142     // CropRect.
143     total_size += sizeof(crop_rect_->flags());
144     total_size += sizeof(crop_rect_->rect());
145   }
146   return total_size;
147 }
148 
SnapshotWithImages(ImageProvider * image_provider) const149 sk_sp<PaintFilter> PaintFilter::SnapshotWithImages(
150     ImageProvider* image_provider) const {
151   if (!has_discardable_images_)
152     return sk_ref_sp<PaintFilter>(this);
153   return SnapshotWithImagesInternal(image_provider);
154 }
155 
operator ==(const PaintFilter & other) const156 bool PaintFilter::operator==(const PaintFilter& other) const {
157   if (type_ != other.type_)
158     return false;
159   if (!!crop_rect_ != !!other.crop_rect_)
160     return false;
161   if (crop_rect_) {
162     if (crop_rect_->flags() != other.crop_rect_->flags() ||
163         !PaintOp::AreSkRectsEqual(crop_rect_->rect(),
164                                   other.crop_rect_->rect())) {
165       return false;
166     }
167   }
168 
169   switch (type_) {
170     case Type::kNullFilter:
171       return true;
172     case Type::kColorFilter:
173       return *static_cast<const ColorFilterPaintFilter*>(this) ==
174              static_cast<const ColorFilterPaintFilter&>(other);
175     case Type::kBlur:
176       return *static_cast<const BlurPaintFilter*>(this) ==
177              static_cast<const BlurPaintFilter&>(other);
178     case Type::kDropShadow:
179       return *static_cast<const DropShadowPaintFilter*>(this) ==
180              static_cast<const DropShadowPaintFilter&>(other);
181     case Type::kMagnifier:
182       return *static_cast<const MagnifierPaintFilter*>(this) ==
183              static_cast<const MagnifierPaintFilter&>(other);
184     case Type::kCompose:
185       return *static_cast<const ComposePaintFilter*>(this) ==
186              static_cast<const ComposePaintFilter&>(other);
187     case Type::kAlphaThreshold:
188       return *static_cast<const AlphaThresholdPaintFilter*>(this) ==
189              static_cast<const AlphaThresholdPaintFilter&>(other);
190     case Type::kXfermode:
191       return *static_cast<const XfermodePaintFilter*>(this) ==
192              static_cast<const XfermodePaintFilter&>(other);
193     case Type::kArithmetic:
194       return *static_cast<const ArithmeticPaintFilter*>(this) ==
195              static_cast<const ArithmeticPaintFilter&>(other);
196     case Type::kMatrixConvolution:
197       return *static_cast<const MatrixConvolutionPaintFilter*>(this) ==
198              static_cast<const MatrixConvolutionPaintFilter&>(other);
199     case Type::kDisplacementMapEffect:
200       return *static_cast<const DisplacementMapEffectPaintFilter*>(this) ==
201              static_cast<const DisplacementMapEffectPaintFilter&>(other);
202     case Type::kImage:
203       return *static_cast<const ImagePaintFilter*>(this) ==
204              static_cast<const ImagePaintFilter&>(other);
205     case Type::kPaintRecord:
206       return *static_cast<const RecordPaintFilter*>(this) ==
207              static_cast<const RecordPaintFilter&>(other);
208     case Type::kMerge:
209       return *static_cast<const MergePaintFilter*>(this) ==
210              static_cast<const MergePaintFilter&>(other);
211     case Type::kMorphology:
212       return *static_cast<const MorphologyPaintFilter*>(this) ==
213              static_cast<const MorphologyPaintFilter&>(other);
214     case Type::kOffset:
215       return *static_cast<const OffsetPaintFilter*>(this) ==
216              static_cast<const OffsetPaintFilter&>(other);
217     case Type::kTile:
218       return *static_cast<const TilePaintFilter*>(this) ==
219              static_cast<const TilePaintFilter&>(other);
220     case Type::kTurbulence:
221       return *static_cast<const TurbulencePaintFilter*>(this) ==
222              static_cast<const TurbulencePaintFilter&>(other);
223     case Type::kPaintFlags:
224       return *static_cast<const PaintFlagsPaintFilter*>(this) ==
225              static_cast<const PaintFlagsPaintFilter&>(other);
226     case Type::kMatrix:
227       return *static_cast<const MatrixPaintFilter*>(this) ==
228              static_cast<const MatrixPaintFilter&>(other);
229     case Type::kLightingDistant:
230       return *static_cast<const LightingDistantPaintFilter*>(this) ==
231              static_cast<const LightingDistantPaintFilter&>(other);
232     case Type::kLightingPoint:
233       return *static_cast<const LightingPointPaintFilter*>(this) ==
234              static_cast<const LightingPointPaintFilter&>(other);
235     case Type::kLightingSpot:
236       return *static_cast<const LightingSpotPaintFilter*>(this) ==
237              static_cast<const LightingSpotPaintFilter&>(other);
238   }
239   NOTREACHED();
240   return true;
241 }
242 
ColorFilterPaintFilter(sk_sp<SkColorFilter> color_filter,sk_sp<PaintFilter> input,const CropRect * crop_rect)243 ColorFilterPaintFilter::ColorFilterPaintFilter(
244     sk_sp<SkColorFilter> color_filter,
245     sk_sp<PaintFilter> input,
246     const CropRect* crop_rect)
247     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
248       color_filter_(std::move(color_filter)),
249       input_(std::move(input)) {
250   DCHECK(color_filter_);
251   cached_sk_filter_ = SkColorFilterImageFilter::Make(
252       color_filter_, GetSkFilter(input_.get()), crop_rect);
253 }
254 
255 ColorFilterPaintFilter::~ColorFilterPaintFilter() = default;
256 
SerializedSize() const257 size_t ColorFilterPaintFilter::SerializedSize() const {
258   base::CheckedNumeric<size_t> total_size = 0u;
259   total_size += BaseSerializedSize();
260   total_size += PaintOpWriter::GetFlattenableSize(color_filter_.get());
261   total_size += GetFilterSize(input_.get());
262   return total_size.ValueOrDefault(0u);
263 }
264 
SnapshotWithImagesInternal(ImageProvider * image_provider) const265 sk_sp<PaintFilter> ColorFilterPaintFilter::SnapshotWithImagesInternal(
266     ImageProvider* image_provider) const {
267   return sk_make_sp<ColorFilterPaintFilter>(
268       color_filter_, Snapshot(input_, image_provider), crop_rect());
269 }
270 
operator ==(const ColorFilterPaintFilter & other) const271 bool ColorFilterPaintFilter::operator==(
272     const ColorFilterPaintFilter& other) const {
273   return PaintOp::AreSkFlattenablesEqual(color_filter_.get(),
274                                          other.color_filter_.get()) &&
275          AreFiltersEqual(input_.get(), other.input_.get());
276 }
277 
BlurPaintFilter(SkScalar sigma_x,SkScalar sigma_y,TileMode tile_mode,sk_sp<PaintFilter> input,const CropRect * crop_rect)278 BlurPaintFilter::BlurPaintFilter(SkScalar sigma_x,
279                                  SkScalar sigma_y,
280                                  TileMode tile_mode,
281                                  sk_sp<PaintFilter> input,
282                                  const CropRect* crop_rect)
283     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
284       sigma_x_(sigma_x),
285       sigma_y_(sigma_y),
286       tile_mode_(tile_mode),
287       input_(std::move(input)) {
288   cached_sk_filter_ = SkBlurImageFilter::Make(
289       sigma_x_, sigma_y_, GetSkFilter(input_.get()), crop_rect, tile_mode_);
290 }
291 
292 BlurPaintFilter::~BlurPaintFilter() = default;
293 
SerializedSize() const294 size_t BlurPaintFilter::SerializedSize() const {
295   base::CheckedNumeric<size_t> total_size =
296       BaseSerializedSize() + sizeof(sigma_x_) + sizeof(sigma_y_) +
297       sizeof(tile_mode_);
298   total_size += GetFilterSize(input_.get());
299   return total_size.ValueOrDefault(0u);
300 }
301 
SnapshotWithImagesInternal(ImageProvider * image_provider) const302 sk_sp<PaintFilter> BlurPaintFilter::SnapshotWithImagesInternal(
303     ImageProvider* image_provider) const {
304   return sk_make_sp<BlurPaintFilter>(sigma_x_, sigma_y_, tile_mode_,
305                                      Snapshot(input_, image_provider),
306                                      crop_rect());
307 }
308 
operator ==(const BlurPaintFilter & other) const309 bool BlurPaintFilter::operator==(const BlurPaintFilter& other) const {
310   return PaintOp::AreEqualEvenIfNaN(sigma_x_, other.sigma_x_) &&
311          PaintOp::AreEqualEvenIfNaN(sigma_y_, other.sigma_y_) &&
312          tile_mode_ == other.tile_mode_ &&
313          AreFiltersEqual(input_.get(), other.input_.get());
314 }
315 
DropShadowPaintFilter(SkScalar dx,SkScalar dy,SkScalar sigma_x,SkScalar sigma_y,SkColor color,ShadowMode shadow_mode,sk_sp<PaintFilter> input,const CropRect * crop_rect)316 DropShadowPaintFilter::DropShadowPaintFilter(SkScalar dx,
317                                              SkScalar dy,
318                                              SkScalar sigma_x,
319                                              SkScalar sigma_y,
320                                              SkColor color,
321                                              ShadowMode shadow_mode,
322                                              sk_sp<PaintFilter> input,
323                                              const CropRect* crop_rect)
324     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
325       dx_(dx),
326       dy_(dy),
327       sigma_x_(sigma_x),
328       sigma_y_(sigma_y),
329       color_(color),
330       shadow_mode_(shadow_mode),
331       input_(std::move(input)) {
332   cached_sk_filter_ = SkDropShadowImageFilter::Make(
333       dx_, dy_, sigma_x_, sigma_y_, color_, shadow_mode_,
334       GetSkFilter(input_.get()), crop_rect);
335 }
336 
337 DropShadowPaintFilter::~DropShadowPaintFilter() = default;
338 
SerializedSize() const339 size_t DropShadowPaintFilter::SerializedSize() const {
340   base::CheckedNumeric<size_t> total_size =
341       BaseSerializedSize() + sizeof(dx_) + sizeof(dy_) + sizeof(sigma_x_) +
342       sizeof(sigma_y_) + sizeof(color_) + sizeof(shadow_mode_);
343   total_size += GetFilterSize(input_.get());
344   return total_size.ValueOrDefault(0u);
345 }
346 
SnapshotWithImagesInternal(ImageProvider * image_provider) const347 sk_sp<PaintFilter> DropShadowPaintFilter::SnapshotWithImagesInternal(
348     ImageProvider* image_provider) const {
349   return sk_make_sp<DropShadowPaintFilter>(
350       dx_, dy_, sigma_x_, sigma_y_, color_, shadow_mode_,
351       Snapshot(input_, image_provider), crop_rect());
352 }
353 
operator ==(const DropShadowPaintFilter & other) const354 bool DropShadowPaintFilter::operator==(
355     const DropShadowPaintFilter& other) const {
356   return PaintOp::AreEqualEvenIfNaN(dx_, other.dx_) &&
357          PaintOp::AreEqualEvenIfNaN(dy_, other.dy_) &&
358          PaintOp::AreEqualEvenIfNaN(sigma_x_, other.sigma_x_) &&
359          PaintOp::AreEqualEvenIfNaN(sigma_y_, other.sigma_y_) &&
360          color_ == other.color_ && shadow_mode_ == other.shadow_mode_ &&
361          AreFiltersEqual(input_.get(), other.input_.get());
362 }
363 
MagnifierPaintFilter(const SkRect & src_rect,SkScalar inset,sk_sp<PaintFilter> input,const CropRect * crop_rect)364 MagnifierPaintFilter::MagnifierPaintFilter(const SkRect& src_rect,
365                                            SkScalar inset,
366                                            sk_sp<PaintFilter> input,
367                                            const CropRect* crop_rect)
368     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
369       src_rect_(src_rect),
370       inset_(inset),
371       input_(std::move(input)) {
372   cached_sk_filter_ = SkMagnifierImageFilter::Make(
373       src_rect_, inset_, GetSkFilter(input_.get()), crop_rect);
374 }
375 
376 MagnifierPaintFilter::~MagnifierPaintFilter() = default;
377 
SerializedSize() const378 size_t MagnifierPaintFilter::SerializedSize() const {
379   base::CheckedNumeric<size_t> total_size =
380       BaseSerializedSize() + sizeof(src_rect_) + sizeof(inset_);
381   total_size += GetFilterSize(input_.get());
382   return total_size.ValueOrDefault(0u);
383 }
384 
SnapshotWithImagesInternal(ImageProvider * image_provider) const385 sk_sp<PaintFilter> MagnifierPaintFilter::SnapshotWithImagesInternal(
386     ImageProvider* image_provider) const {
387   return sk_make_sp<MagnifierPaintFilter>(
388       src_rect_, inset_, Snapshot(input_, image_provider), crop_rect());
389 }
390 
operator ==(const MagnifierPaintFilter & other) const391 bool MagnifierPaintFilter::operator==(const MagnifierPaintFilter& other) const {
392   return PaintOp::AreSkRectsEqual(src_rect_, other.src_rect_) &&
393          PaintOp::AreEqualEvenIfNaN(inset_, other.inset_) &&
394          AreFiltersEqual(input_.get(), other.input_.get());
395 }
396 
ComposePaintFilter(sk_sp<PaintFilter> outer,sk_sp<PaintFilter> inner)397 ComposePaintFilter::ComposePaintFilter(sk_sp<PaintFilter> outer,
398                                        sk_sp<PaintFilter> inner)
399     : PaintFilter(Type::kCompose,
400                   nullptr,
401                   HasDiscardableImages(outer) || HasDiscardableImages(inner)),
402       outer_(std::move(outer)),
403       inner_(std::move(inner)) {
404   cached_sk_filter_ = SkComposeImageFilter::Make(GetSkFilter(outer_.get()),
405                                                  GetSkFilter(inner_.get()));
406 }
407 
408 ComposePaintFilter::~ComposePaintFilter() = default;
409 
SerializedSize() const410 size_t ComposePaintFilter::SerializedSize() const {
411   base::CheckedNumeric<size_t> total_size = BaseSerializedSize();
412   total_size += GetFilterSize(outer_.get());
413   total_size += GetFilterSize(inner_.get());
414   return total_size.ValueOrDefault(0u);
415 }
416 
SnapshotWithImagesInternal(ImageProvider * image_provider) const417 sk_sp<PaintFilter> ComposePaintFilter::SnapshotWithImagesInternal(
418     ImageProvider* image_provider) const {
419   return sk_make_sp<ComposePaintFilter>(Snapshot(outer_, image_provider),
420                                         Snapshot(inner_, image_provider));
421 }
422 
operator ==(const ComposePaintFilter & other) const423 bool ComposePaintFilter::operator==(const ComposePaintFilter& other) const {
424   return AreFiltersEqual(outer_.get(), other.outer_.get()) &&
425          AreFiltersEqual(inner_.get(), other.inner_.get());
426 }
427 
AlphaThresholdPaintFilter(const SkRegion & region,SkScalar inner_min,SkScalar outer_max,sk_sp<PaintFilter> input,const CropRect * crop_rect)428 AlphaThresholdPaintFilter::AlphaThresholdPaintFilter(const SkRegion& region,
429                                                      SkScalar inner_min,
430                                                      SkScalar outer_max,
431                                                      sk_sp<PaintFilter> input,
432                                                      const CropRect* crop_rect)
433     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
434       region_(region),
435       inner_min_(inner_min),
436       outer_max_(outer_max),
437       input_(std::move(input)) {
438   cached_sk_filter_ = SkAlphaThresholdFilter::Make(
439       region_, inner_min_, outer_max_, GetSkFilter(input_.get()), crop_rect);
440 }
441 
442 AlphaThresholdPaintFilter::~AlphaThresholdPaintFilter() = default;
443 
SerializedSize() const444 size_t AlphaThresholdPaintFilter::SerializedSize() const {
445   size_t region_size = region_.writeToMemory(nullptr);
446   base::CheckedNumeric<size_t> total_size;
447   total_size = BaseSerializedSize() + sizeof(uint64_t) + region_size +
448                sizeof(inner_min_) + sizeof(outer_max_);
449   total_size += GetFilterSize(input_.get());
450   return total_size.ValueOrDefault(0u);
451 }
452 
SnapshotWithImagesInternal(ImageProvider * image_provider) const453 sk_sp<PaintFilter> AlphaThresholdPaintFilter::SnapshotWithImagesInternal(
454     ImageProvider* image_provider) const {
455   return sk_make_sp<AlphaThresholdPaintFilter>(region_, inner_min_, outer_max_,
456                                                Snapshot(input_, image_provider),
457                                                crop_rect());
458 }
459 
operator ==(const AlphaThresholdPaintFilter & other) const460 bool AlphaThresholdPaintFilter::operator==(
461     const AlphaThresholdPaintFilter& other) const {
462   return region_ == other.region_ &&
463          PaintOp::AreEqualEvenIfNaN(inner_min_, other.inner_min_) &&
464          PaintOp::AreEqualEvenIfNaN(outer_max_, other.outer_max_) &&
465          AreFiltersEqual(input_.get(), other.input_.get());
466 }
467 
XfermodePaintFilter(SkBlendMode blend_mode,sk_sp<PaintFilter> background,sk_sp<PaintFilter> foreground,const CropRect * crop_rect)468 XfermodePaintFilter::XfermodePaintFilter(SkBlendMode blend_mode,
469                                          sk_sp<PaintFilter> background,
470                                          sk_sp<PaintFilter> foreground,
471                                          const CropRect* crop_rect)
472     : PaintFilter(
473           kType,
474           crop_rect,
475           HasDiscardableImages(background) || HasDiscardableImages(foreground)),
476       blend_mode_(blend_mode),
477       background_(std::move(background)),
478       foreground_(std::move(foreground)) {
479   cached_sk_filter_ =
480       SkXfermodeImageFilter::Make(blend_mode_, GetSkFilter(background_.get()),
481                                   GetSkFilter(foreground_.get()), crop_rect);
482 }
483 
484 XfermodePaintFilter::~XfermodePaintFilter() = default;
485 
SerializedSize() const486 size_t XfermodePaintFilter::SerializedSize() const {
487   base::CheckedNumeric<size_t> total_size =
488       BaseSerializedSize() + sizeof(blend_mode_);
489   total_size += GetFilterSize(background_.get());
490   total_size += GetFilterSize(foreground_.get());
491   return total_size.ValueOrDefault(0u);
492 }
493 
SnapshotWithImagesInternal(ImageProvider * image_provider) const494 sk_sp<PaintFilter> XfermodePaintFilter::SnapshotWithImagesInternal(
495     ImageProvider* image_provider) const {
496   return sk_make_sp<XfermodePaintFilter>(
497       blend_mode_, Snapshot(background_, image_provider),
498       Snapshot(foreground_, image_provider), crop_rect());
499 }
500 
operator ==(const XfermodePaintFilter & other) const501 bool XfermodePaintFilter::operator==(const XfermodePaintFilter& other) const {
502   return blend_mode_ == other.blend_mode_ &&
503          AreFiltersEqual(background_.get(), other.background_.get()) &&
504          AreFiltersEqual(foreground_.get(), other.foreground_.get());
505 }
506 
ArithmeticPaintFilter(float k1,float k2,float k3,float k4,bool enforce_pm_color,sk_sp<PaintFilter> background,sk_sp<PaintFilter> foreground,const CropRect * crop_rect)507 ArithmeticPaintFilter::ArithmeticPaintFilter(float k1,
508                                              float k2,
509                                              float k3,
510                                              float k4,
511                                              bool enforce_pm_color,
512                                              sk_sp<PaintFilter> background,
513                                              sk_sp<PaintFilter> foreground,
514                                              const CropRect* crop_rect)
515     : PaintFilter(
516           kType,
517           crop_rect,
518           HasDiscardableImages(background) || HasDiscardableImages(foreground)),
519       k1_(k1),
520       k2_(k2),
521       k3_(k3),
522       k4_(k4),
523       enforce_pm_color_(enforce_pm_color),
524       background_(std::move(background)),
525       foreground_(std::move(foreground)) {
526   cached_sk_filter_ = SkArithmeticImageFilter::Make(
527       k1_, k2_, k3_, k4_, enforce_pm_color_, GetSkFilter(background_.get()),
528       GetSkFilter(foreground_.get()), crop_rect);
529 }
530 
531 ArithmeticPaintFilter::~ArithmeticPaintFilter() = default;
532 
SerializedSize() const533 size_t ArithmeticPaintFilter::SerializedSize() const {
534   base::CheckedNumeric<size_t> total_size =
535       BaseSerializedSize() + sizeof(k1_) + sizeof(k2_) + sizeof(k3_) +
536       sizeof(k4_) + sizeof(enforce_pm_color_);
537   total_size += GetFilterSize(background_.get());
538   total_size += GetFilterSize(foreground_.get());
539   return total_size.ValueOrDefault(0u);
540 }
541 
SnapshotWithImagesInternal(ImageProvider * image_provider) const542 sk_sp<PaintFilter> ArithmeticPaintFilter::SnapshotWithImagesInternal(
543     ImageProvider* image_provider) const {
544   return sk_make_sp<ArithmeticPaintFilter>(
545       k1_, k2_, k3_, k4_, enforce_pm_color_,
546       Snapshot(background_, image_provider),
547       Snapshot(foreground_, image_provider), crop_rect());
548 }
549 
operator ==(const ArithmeticPaintFilter & other) const550 bool ArithmeticPaintFilter::operator==(
551     const ArithmeticPaintFilter& other) const {
552   return PaintOp::AreEqualEvenIfNaN(k1_, other.k1_) &&
553          PaintOp::AreEqualEvenIfNaN(k2_, other.k2_) &&
554          PaintOp::AreEqualEvenIfNaN(k3_, other.k3_) &&
555          PaintOp::AreEqualEvenIfNaN(k4_, other.k4_) &&
556          enforce_pm_color_ == other.enforce_pm_color_ &&
557          AreFiltersEqual(background_.get(), other.background_.get()) &&
558          AreFiltersEqual(foreground_.get(), other.foreground_.get());
559 }
560 
MatrixConvolutionPaintFilter(const SkISize & kernel_size,const SkScalar * kernel,SkScalar gain,SkScalar bias,const SkIPoint & kernel_offset,TileMode tile_mode,bool convolve_alpha,sk_sp<PaintFilter> input,const CropRect * crop_rect)561 MatrixConvolutionPaintFilter::MatrixConvolutionPaintFilter(
562     const SkISize& kernel_size,
563     const SkScalar* kernel,
564     SkScalar gain,
565     SkScalar bias,
566     const SkIPoint& kernel_offset,
567     TileMode tile_mode,
568     bool convolve_alpha,
569     sk_sp<PaintFilter> input,
570     const CropRect* crop_rect)
571     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
572       kernel_size_(kernel_size),
573       gain_(gain),
574       bias_(bias),
575       kernel_offset_(kernel_offset),
576       tile_mode_(tile_mode),
577       convolve_alpha_(convolve_alpha),
578       input_(std::move(input)) {
579   auto len = static_cast<size_t>(
580       sk_64_mul(kernel_size_.width(), kernel_size_.height()));
581   kernel_->reserve(len);
582   for (size_t i = 0; i < len; ++i)
583     kernel_->push_back(kernel[i]);
584 
585   cached_sk_filter_ = SkMatrixConvolutionImageFilter::Make(
586       kernel_size_, kernel, gain_, bias_, kernel_offset_, tile_mode_,
587       convolve_alpha_, GetSkFilter(input_.get()), crop_rect);
588 }
589 
590 MatrixConvolutionPaintFilter::~MatrixConvolutionPaintFilter() = default;
591 
SerializedSize() const592 size_t MatrixConvolutionPaintFilter::SerializedSize() const {
593   base::CheckedNumeric<size_t> total_size =
594       BaseSerializedSize() + sizeof(kernel_size_) + sizeof(size_t) +
595       kernel_->size() * sizeof(SkScalar) + sizeof(gain_) + sizeof(bias_) +
596       sizeof(kernel_offset_) + sizeof(tile_mode_) + sizeof(convolve_alpha_);
597   total_size += GetFilterSize(input_.get());
598   return total_size.ValueOrDefault(0u);
599 }
600 
SnapshotWithImagesInternal(ImageProvider * image_provider) const601 sk_sp<PaintFilter> MatrixConvolutionPaintFilter::SnapshotWithImagesInternal(
602     ImageProvider* image_provider) const {
603   return sk_make_sp<MatrixConvolutionPaintFilter>(
604       kernel_size_, &kernel_[0], gain_, bias_, kernel_offset_, tile_mode_,
605       convolve_alpha_, Snapshot(input_, image_provider), crop_rect());
606 }
607 
operator ==(const MatrixConvolutionPaintFilter & other) const608 bool MatrixConvolutionPaintFilter::operator==(
609     const MatrixConvolutionPaintFilter& other) const {
610   return kernel_size_ == other.kernel_size_ &&
611          std::equal(kernel_.container().begin(), kernel_.container().end(),
612                     other.kernel_.container().begin(), AreScalarsEqual) &&
613          PaintOp::AreEqualEvenIfNaN(gain_, other.gain_) &&
614          PaintOp::AreEqualEvenIfNaN(bias_, other.bias_) &&
615          kernel_offset_ == other.kernel_offset_ &&
616          tile_mode_ == other.tile_mode_ &&
617          convolve_alpha_ == other.convolve_alpha_ &&
618          AreFiltersEqual(input_.get(), other.input_.get());
619 }
620 
DisplacementMapEffectPaintFilter(ChannelSelectorType channel_x,ChannelSelectorType channel_y,SkScalar scale,sk_sp<PaintFilter> displacement,sk_sp<PaintFilter> color,const CropRect * crop_rect)621 DisplacementMapEffectPaintFilter::DisplacementMapEffectPaintFilter(
622     ChannelSelectorType channel_x,
623     ChannelSelectorType channel_y,
624     SkScalar scale,
625     sk_sp<PaintFilter> displacement,
626     sk_sp<PaintFilter> color,
627     const CropRect* crop_rect)
628     : PaintFilter(
629           kType,
630           crop_rect,
631           HasDiscardableImages(displacement) || HasDiscardableImages(color)),
632       channel_x_(channel_x),
633       channel_y_(channel_y),
634       scale_(scale),
635       displacement_(std::move(displacement)),
636       color_(std::move(color)) {
637   cached_sk_filter_ = SkDisplacementMapEffect::Make(
638       channel_x_, channel_y_, scale_, GetSkFilter(displacement_.get()),
639       GetSkFilter(color_.get()), crop_rect);
640 }
641 
642 DisplacementMapEffectPaintFilter::~DisplacementMapEffectPaintFilter() = default;
643 
SerializedSize() const644 size_t DisplacementMapEffectPaintFilter::SerializedSize() const {
645   base::CheckedNumeric<size_t> total_size = BaseSerializedSize() +
646                                             sizeof(uint32_t) +
647                                             sizeof(uint32_t) + sizeof(scale_);
648   total_size += GetFilterSize(displacement_.get());
649   total_size += GetFilterSize(color_.get());
650   return total_size.ValueOrDefault(0u);
651 }
652 
SnapshotWithImagesInternal(ImageProvider * image_provider) const653 sk_sp<PaintFilter> DisplacementMapEffectPaintFilter::SnapshotWithImagesInternal(
654     ImageProvider* image_provider) const {
655   return sk_make_sp<DisplacementMapEffectPaintFilter>(
656       channel_x_, channel_y_, scale_, Snapshot(displacement_, image_provider),
657       Snapshot(color_, image_provider), crop_rect());
658 }
659 
operator ==(const DisplacementMapEffectPaintFilter & other) const660 bool DisplacementMapEffectPaintFilter::operator==(
661     const DisplacementMapEffectPaintFilter& other) const {
662   return channel_x_ == other.channel_x_ && channel_y_ == other.channel_y_ &&
663          PaintOp::AreEqualEvenIfNaN(scale_, other.scale_) &&
664          AreFiltersEqual(displacement_.get(), other.displacement_.get()) &&
665          AreFiltersEqual(color_.get(), other.color_.get());
666 }
667 
ImagePaintFilter(PaintImage image,const SkRect & src_rect,const SkRect & dst_rect,SkFilterQuality filter_quality)668 ImagePaintFilter::ImagePaintFilter(PaintImage image,
669                                    const SkRect& src_rect,
670                                    const SkRect& dst_rect,
671                                    SkFilterQuality filter_quality)
672     : PaintFilter(kType, nullptr, !image.IsTextureBacked()),
673       image_(std::move(image)),
674       src_rect_(src_rect),
675       dst_rect_(dst_rect),
676       filter_quality_(filter_quality) {
677   cached_sk_filter_ = SkImageSource::Make(image_.GetSkImage(), src_rect_,
678                                           dst_rect_, filter_quality_);
679 }
680 
681 ImagePaintFilter::~ImagePaintFilter() = default;
682 
SerializedSize() const683 size_t ImagePaintFilter::SerializedSize() const {
684   base::CheckedNumeric<size_t> total_size =
685       BaseSerializedSize() + sizeof(src_rect_) + sizeof(dst_rect_) +
686       sizeof(filter_quality_);
687   total_size += PaintOpWriter::GetImageSize(image_);
688   return total_size.ValueOrDefault(0u);
689 }
690 
SnapshotWithImagesInternal(ImageProvider * image_provider) const691 sk_sp<PaintFilter> ImagePaintFilter::SnapshotWithImagesInternal(
692     ImageProvider* image_provider) const {
693   DrawImage draw_image(image_, false,
694                        SkIRect::MakeWH(image_.width(), image_.height()),
695                        filter_quality_, SkMatrix::I());
696   auto scoped_result = image_provider->GetRasterContent(draw_image);
697   if (!scoped_result)
698     return nullptr;
699 
700   auto decoded_sk_image = sk_ref_sp<SkImage>(
701       const_cast<SkImage*>(scoped_result.decoded_image().image().get()));
702   PaintImage decoded_paint_image =
703       PaintImageBuilder::WithDefault()
704           .set_id(image_.stable_id())
705           .set_texture_image(decoded_sk_image, PaintImage::GetNextContentId())
706           .TakePaintImage();
707 
708   return sk_make_sp<ImagePaintFilter>(std::move(decoded_paint_image), src_rect_,
709                                       dst_rect_, filter_quality_);
710 }
711 
operator ==(const ImagePaintFilter & other) const712 bool ImagePaintFilter::operator==(const ImagePaintFilter& other) const {
713   return !!image_ == !!other.image_ &&
714          PaintOp::AreSkRectsEqual(src_rect_, other.src_rect_) &&
715          PaintOp::AreSkRectsEqual(dst_rect_, other.dst_rect_) &&
716          filter_quality_ == other.filter_quality_;
717 }
718 
RecordPaintFilter(sk_sp<PaintRecord> record,const SkRect & record_bounds)719 RecordPaintFilter::RecordPaintFilter(sk_sp<PaintRecord> record,
720                                      const SkRect& record_bounds)
721     : RecordPaintFilter(std::move(record), record_bounds, nullptr) {}
722 
RecordPaintFilter(sk_sp<PaintRecord> record,const SkRect & record_bounds,ImageProvider * image_provider)723 RecordPaintFilter::RecordPaintFilter(sk_sp<PaintRecord> record,
724                                      const SkRect& record_bounds,
725                                      ImageProvider* image_provider)
726     : PaintFilter(kType, nullptr, record->HasDiscardableImages()),
727       record_(std::move(record)),
728       record_bounds_(record_bounds) {
729   cached_sk_filter_ = SkPictureImageFilter::Make(
730       ToSkPicture(record_, record_bounds_, image_provider));
731 }
732 
733 RecordPaintFilter::~RecordPaintFilter() = default;
734 
SerializedSize() const735 size_t RecordPaintFilter::SerializedSize() const {
736   base::CheckedNumeric<size_t> total_size =
737       BaseSerializedSize() + sizeof(record_bounds_);
738   total_size += PaintOpWriter::GetRecordSize(record_.get());
739   return total_size.ValueOrDefault(0u);
740 }
741 
SnapshotWithImagesInternal(ImageProvider * image_provider) const742 sk_sp<PaintFilter> RecordPaintFilter::SnapshotWithImagesInternal(
743     ImageProvider* image_provider) const {
744   return sk_sp<RecordPaintFilter>(
745       new RecordPaintFilter(record_, record_bounds_, image_provider));
746 }
747 
operator ==(const RecordPaintFilter & other) const748 bool RecordPaintFilter::operator==(const RecordPaintFilter& other) const {
749   return !!record_ == !!other.record_ &&
750          PaintOp::AreSkRectsEqual(record_bounds_, other.record_bounds_);
751 }
752 
MergePaintFilter(const sk_sp<PaintFilter> * const filters,int count,const CropRect * crop_rect)753 MergePaintFilter::MergePaintFilter(const sk_sp<PaintFilter>* const filters,
754                                    int count,
755                                    const CropRect* crop_rect)
756     : MergePaintFilter(filters, count, crop_rect, nullptr) {}
757 
MergePaintFilter(const sk_sp<PaintFilter> * const filters,int count,const CropRect * crop_rect,ImageProvider * image_provider)758 MergePaintFilter::MergePaintFilter(const sk_sp<PaintFilter>* const filters,
759                                    int count,
760                                    const CropRect* crop_rect,
761                                    ImageProvider* image_provider)
762     : PaintFilter(kType, crop_rect, HasDiscardableImages(filters, count)) {
763   std::vector<sk_sp<SkImageFilter>> sk_filters;
764   sk_filters.reserve(count);
765 
766   for (int i = 0; i < count; ++i) {
767     auto filter =
768         image_provider ? Snapshot(filters[i], image_provider) : filters[i];
769     inputs_->push_back(std::move(filter));
770     sk_filters.push_back(GetSkFilter(inputs_->back().get()));
771   }
772 
773   cached_sk_filter_ = SkMergeImageFilter::Make(
774       static_cast<sk_sp<SkImageFilter>*>(sk_filters.data()), count, crop_rect);
775 }
776 
777 MergePaintFilter::~MergePaintFilter() = default;
778 
SerializedSize() const779 size_t MergePaintFilter::SerializedSize() const {
780   base::CheckedNumeric<size_t> total_size = 0u;
781   for (size_t i = 0; i < input_count(); ++i)
782     total_size += GetFilterSize(input_at(i));
783   total_size += BaseSerializedSize();
784   total_size += sizeof(input_count());
785   return total_size.ValueOrDefault(0u);
786 }
787 
SnapshotWithImagesInternal(ImageProvider * image_provider) const788 sk_sp<PaintFilter> MergePaintFilter::SnapshotWithImagesInternal(
789     ImageProvider* image_provider) const {
790   return sk_sp<MergePaintFilter>(new MergePaintFilter(
791       &inputs_[0], inputs_->size(), crop_rect(), image_provider));
792 }
793 
operator ==(const MergePaintFilter & other) const794 bool MergePaintFilter::operator==(const MergePaintFilter& other) const {
795   if (inputs_->size() != other.inputs_->size())
796     return false;
797   for (size_t i = 0; i < inputs_->size(); ++i) {
798     if (!AreFiltersEqual(inputs_[i].get(), other.inputs_[i].get()))
799       return false;
800   }
801   return true;
802 }
803 
MorphologyPaintFilter(MorphType morph_type,float radius_x,float radius_y,sk_sp<PaintFilter> input,const CropRect * crop_rect)804 MorphologyPaintFilter::MorphologyPaintFilter(MorphType morph_type,
805                                              float radius_x,
806                                              float radius_y,
807                                              sk_sp<PaintFilter> input,
808                                              const CropRect* crop_rect)
809     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
810       morph_type_(morph_type),
811       radius_x_(radius_x),
812       radius_y_(radius_y),
813       input_(std::move(input)) {
814   switch (morph_type_) {
815     case MorphType::kDilate:
816       cached_sk_filter_ = SkDilateImageFilter::Make(
817           radius_x_, radius_y_, GetSkFilter(input_.get()), crop_rect);
818       break;
819     case MorphType::kErode:
820       cached_sk_filter_ = SkErodeImageFilter::Make(
821           radius_x_, radius_y_, GetSkFilter(input_.get()), crop_rect);
822       break;
823   }
824 }
825 
826 MorphologyPaintFilter::~MorphologyPaintFilter() = default;
827 
SerializedSize() const828 size_t MorphologyPaintFilter::SerializedSize() const {
829   base::CheckedNumeric<size_t> total_size =
830       BaseSerializedSize() + sizeof(morph_type_) + sizeof(radius_x_) +
831       sizeof(radius_y_);
832   total_size += GetFilterSize(input_.get());
833   return total_size.ValueOrDefault(0u);
834 }
835 
SnapshotWithImagesInternal(ImageProvider * image_provider) const836 sk_sp<PaintFilter> MorphologyPaintFilter::SnapshotWithImagesInternal(
837     ImageProvider* image_provider) const {
838   return sk_make_sp<MorphologyPaintFilter>(morph_type_, radius_x_, radius_y_,
839                                            Snapshot(input_, image_provider),
840                                            crop_rect());
841 }
842 
operator ==(const MorphologyPaintFilter & other) const843 bool MorphologyPaintFilter::operator==(
844     const MorphologyPaintFilter& other) const {
845   return morph_type_ == other.morph_type_ && radius_x_ == other.radius_x_ &&
846          radius_y_ == other.radius_y_ &&
847          AreFiltersEqual(input_.get(), other.input_.get());
848 }
849 
OffsetPaintFilter(SkScalar dx,SkScalar dy,sk_sp<PaintFilter> input,const CropRect * crop_rect)850 OffsetPaintFilter::OffsetPaintFilter(SkScalar dx,
851                                      SkScalar dy,
852                                      sk_sp<PaintFilter> input,
853                                      const CropRect* crop_rect)
854     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
855       dx_(dx),
856       dy_(dy),
857       input_(std::move(input)) {
858   cached_sk_filter_ =
859       SkOffsetImageFilter::Make(dx_, dy_, GetSkFilter(input_.get()), crop_rect);
860 }
861 
862 OffsetPaintFilter::~OffsetPaintFilter() = default;
863 
SerializedSize() const864 size_t OffsetPaintFilter::SerializedSize() const {
865   base::CheckedNumeric<size_t> total_size =
866       BaseSerializedSize() + sizeof(dx_) + sizeof(dy_);
867   total_size += GetFilterSize(input_.get());
868   return total_size.ValueOrDefault(0u);
869 }
870 
SnapshotWithImagesInternal(ImageProvider * image_provider) const871 sk_sp<PaintFilter> OffsetPaintFilter::SnapshotWithImagesInternal(
872     ImageProvider* image_provider) const {
873   return sk_make_sp<OffsetPaintFilter>(
874       dx_, dy_, Snapshot(input_, image_provider), crop_rect());
875 }
876 
operator ==(const OffsetPaintFilter & other) const877 bool OffsetPaintFilter::operator==(const OffsetPaintFilter& other) const {
878   return PaintOp::AreEqualEvenIfNaN(dx_, other.dx_) &&
879          PaintOp::AreEqualEvenIfNaN(dy_, other.dy_) &&
880          AreFiltersEqual(input_.get(), other.input_.get());
881 }
882 
TilePaintFilter(const SkRect & src,const SkRect & dst,sk_sp<PaintFilter> input)883 TilePaintFilter::TilePaintFilter(const SkRect& src,
884                                  const SkRect& dst,
885                                  sk_sp<PaintFilter> input)
886     : PaintFilter(kType, nullptr, HasDiscardableImages(input)),
887       src_(src),
888       dst_(dst),
889       input_(std::move(input)) {
890   cached_sk_filter_ =
891       SkTileImageFilter::Make(src_, dst_, GetSkFilter(input_.get()));
892 }
893 
894 TilePaintFilter::~TilePaintFilter() = default;
895 
SerializedSize() const896 size_t TilePaintFilter::SerializedSize() const {
897   base::CheckedNumeric<size_t> total_size =
898       BaseSerializedSize() + sizeof(src_) + sizeof(dst_);
899   total_size += GetFilterSize(input_.get());
900   return total_size.ValueOrDefault(0u);
901 }
902 
SnapshotWithImagesInternal(ImageProvider * image_provider) const903 sk_sp<PaintFilter> TilePaintFilter::SnapshotWithImagesInternal(
904     ImageProvider* image_provider) const {
905   return sk_make_sp<TilePaintFilter>(src_, dst_,
906                                      Snapshot(input_, image_provider));
907 }
908 
operator ==(const TilePaintFilter & other) const909 bool TilePaintFilter::operator==(const TilePaintFilter& other) const {
910   return PaintOp::AreSkRectsEqual(src_, other.src_) &&
911          PaintOp::AreSkRectsEqual(dst_, other.dst_) &&
912          AreFiltersEqual(input_.get(), other.input_.get());
913 }
914 
TurbulencePaintFilter(TurbulenceType turbulence_type,SkScalar base_frequency_x,SkScalar base_frequency_y,int num_octaves,SkScalar seed,const SkISize * tile_size,const CropRect * crop_rect)915 TurbulencePaintFilter::TurbulencePaintFilter(TurbulenceType turbulence_type,
916                                              SkScalar base_frequency_x,
917                                              SkScalar base_frequency_y,
918                                              int num_octaves,
919                                              SkScalar seed,
920                                              const SkISize* tile_size,
921                                              const CropRect* crop_rect)
922     : PaintFilter(kType, crop_rect, kHasNoDiscardableImages),
923       turbulence_type_(turbulence_type),
924       base_frequency_x_(base_frequency_x),
925       base_frequency_y_(base_frequency_y),
926       num_octaves_(num_octaves),
927       seed_(seed),
928       tile_size_(tile_size ? *tile_size : SkISize::MakeEmpty()) {
929   sk_sp<SkShader> shader;
930   switch (turbulence_type_) {
931     case TurbulenceType::kTurbulence:
932       shader = SkPerlinNoiseShader::MakeTurbulence(
933           base_frequency_x_, base_frequency_y_, num_octaves_, seed_,
934           &tile_size_);
935       break;
936     case TurbulenceType::kFractalNoise:
937       shader = SkPerlinNoiseShader::MakeFractalNoise(
938           base_frequency_x_, base_frequency_y_, num_octaves_, seed_,
939           &tile_size_);
940       break;
941   }
942 
943   SkPaint paint;
944   paint.setShader(std::move(shader));
945   cached_sk_filter_ = SkPaintImageFilter::Make(paint, crop_rect);
946 }
947 
948 TurbulencePaintFilter::~TurbulencePaintFilter() = default;
949 
SerializedSize() const950 size_t TurbulencePaintFilter::SerializedSize() const {
951   return BaseSerializedSize() + sizeof(turbulence_type_) +
952          sizeof(base_frequency_x_) + sizeof(base_frequency_y_) +
953          sizeof(num_octaves_) + sizeof(seed_) + sizeof(tile_size_);
954 }
955 
SnapshotWithImagesInternal(ImageProvider * image_provider) const956 sk_sp<PaintFilter> TurbulencePaintFilter::SnapshotWithImagesInternal(
957     ImageProvider* image_provider) const {
958   return sk_make_sp<TurbulencePaintFilter>(turbulence_type_, base_frequency_x_,
959                                            base_frequency_y_, num_octaves_,
960                                            seed_, &tile_size_, crop_rect());
961 }
962 
operator ==(const TurbulencePaintFilter & other) const963 bool TurbulencePaintFilter::operator==(
964     const TurbulencePaintFilter& other) const {
965   return turbulence_type_ == other.turbulence_type_ &&
966          PaintOp::AreEqualEvenIfNaN(base_frequency_x_,
967                                     other.base_frequency_x_) &&
968          PaintOp::AreEqualEvenIfNaN(base_frequency_y_,
969                                     other.base_frequency_y_) &&
970          num_octaves_ == other.num_octaves_ &&
971          PaintOp::AreEqualEvenIfNaN(seed_, other.seed_) &&
972          tile_size_ == other.tile_size_;
973 }
974 
PaintFlagsPaintFilter(PaintFlags flags,const CropRect * crop_rect)975 PaintFlagsPaintFilter::PaintFlagsPaintFilter(PaintFlags flags,
976                                              const CropRect* crop_rect)
977     : PaintFlagsPaintFilter(std::move(flags), nullptr, crop_rect) {}
978 
PaintFlagsPaintFilter(PaintFlags flags,ImageProvider * image_provider,const CropRect * crop_rect)979 PaintFlagsPaintFilter::PaintFlagsPaintFilter(PaintFlags flags,
980                                              ImageProvider* image_provider,
981                                              const CropRect* crop_rect)
982     : PaintFilter(kType, crop_rect, flags.HasDiscardableImages()),
983       flags_(std::move(flags)) {
984   if (image_provider) {
985     raster_flags_.emplace(&flags_, image_provider, SkMatrix::I(), 0, 255u);
986   }
987   cached_sk_filter_ = SkPaintImageFilter::Make(
988       raster_flags_ ? raster_flags_->flags()->ToSkPaint() : flags_.ToSkPaint(),
989       crop_rect);
990 }
991 
992 PaintFlagsPaintFilter::~PaintFlagsPaintFilter() = default;
993 
SerializedSize() const994 size_t PaintFlagsPaintFilter::SerializedSize() const {
995   base::CheckedNumeric<size_t> total_size = BaseSerializedSize();
996   total_size += flags_.GetSerializedSize();
997   return total_size.ValueOrDefault(0u);
998 }
999 
SnapshotWithImagesInternal(ImageProvider * image_provider) const1000 sk_sp<PaintFilter> PaintFlagsPaintFilter::SnapshotWithImagesInternal(
1001     ImageProvider* image_provider) const {
1002   return sk_sp<PaintFilter>(
1003       new PaintFlagsPaintFilter(flags_, image_provider, crop_rect()));
1004 }
1005 
operator ==(const PaintFlagsPaintFilter & other) const1006 bool PaintFlagsPaintFilter::operator==(
1007     const PaintFlagsPaintFilter& other) const {
1008   return flags_ == other.flags_;
1009 }
1010 
MatrixPaintFilter(const SkMatrix & matrix,SkFilterQuality filter_quality,sk_sp<PaintFilter> input)1011 MatrixPaintFilter::MatrixPaintFilter(const SkMatrix& matrix,
1012                                      SkFilterQuality filter_quality,
1013                                      sk_sp<PaintFilter> input)
1014     : PaintFilter(Type::kMatrix, nullptr, HasDiscardableImages(input)),
1015       matrix_(matrix),
1016       filter_quality_(filter_quality),
1017       input_(std::move(input)) {
1018   cached_sk_filter_ = SkImageFilter::MakeMatrixFilter(
1019       matrix_, filter_quality_, GetSkFilter(input_.get()));
1020 }
1021 
1022 MatrixPaintFilter::~MatrixPaintFilter() = default;
1023 
SerializedSize() const1024 size_t MatrixPaintFilter::SerializedSize() const {
1025   base::CheckedNumeric<size_t> total_size =
1026       BaseSerializedSize() + sizeof(matrix_) + sizeof(filter_quality_);
1027   total_size += GetFilterSize(input_.get());
1028   return total_size.ValueOrDefault(0u);
1029 }
1030 
SnapshotWithImagesInternal(ImageProvider * image_provider) const1031 sk_sp<PaintFilter> MatrixPaintFilter::SnapshotWithImagesInternal(
1032     ImageProvider* image_provider) const {
1033   return sk_make_sp<MatrixPaintFilter>(matrix_, filter_quality_,
1034                                        Snapshot(input_, image_provider));
1035 }
1036 
operator ==(const MatrixPaintFilter & other) const1037 bool MatrixPaintFilter::operator==(const MatrixPaintFilter& other) const {
1038   return PaintOp::AreSkMatricesEqual(matrix_, other.matrix_) &&
1039          filter_quality_ == other.filter_quality_ &&
1040          AreFiltersEqual(input_.get(), other.input_.get());
1041 }
1042 
LightingDistantPaintFilter(LightingType lighting_type,const SkPoint3 & direction,SkColor light_color,SkScalar surface_scale,SkScalar kconstant,SkScalar shininess,sk_sp<PaintFilter> input,const CropRect * crop_rect)1043 LightingDistantPaintFilter::LightingDistantPaintFilter(
1044     LightingType lighting_type,
1045     const SkPoint3& direction,
1046     SkColor light_color,
1047     SkScalar surface_scale,
1048     SkScalar kconstant,
1049     SkScalar shininess,
1050     sk_sp<PaintFilter> input,
1051     const CropRect* crop_rect)
1052     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
1053       lighting_type_(lighting_type),
1054       direction_(direction),
1055       light_color_(light_color),
1056       surface_scale_(surface_scale),
1057       kconstant_(kconstant),
1058       shininess_(shininess),
1059       input_(std::move(input)) {
1060   switch (lighting_type_) {
1061     case LightingType::kDiffuse:
1062       cached_sk_filter_ = SkLightingImageFilter::MakeDistantLitDiffuse(
1063           direction_, light_color_, surface_scale_, kconstant_,
1064           GetSkFilter(input_.get()), crop_rect);
1065       break;
1066     case LightingType::kSpecular:
1067       cached_sk_filter_ = SkLightingImageFilter::MakeDistantLitSpecular(
1068           direction_, light_color_, surface_scale_, kconstant_, shininess_,
1069           GetSkFilter(input_.get()), crop_rect);
1070       break;
1071   }
1072 }
1073 
1074 LightingDistantPaintFilter::~LightingDistantPaintFilter() = default;
1075 
SerializedSize() const1076 size_t LightingDistantPaintFilter::SerializedSize() const {
1077   base::CheckedNumeric<size_t> total_size =
1078       BaseSerializedSize() + sizeof(lighting_type_) + sizeof(direction_) +
1079       sizeof(light_color_) + sizeof(surface_scale_) + sizeof(kconstant_) +
1080       sizeof(shininess_);
1081   total_size += GetFilterSize(input_.get());
1082   return total_size.ValueOrDefault(0u);
1083 }
1084 
SnapshotWithImagesInternal(ImageProvider * image_provider) const1085 sk_sp<PaintFilter> LightingDistantPaintFilter::SnapshotWithImagesInternal(
1086     ImageProvider* image_provider) const {
1087   return sk_make_sp<LightingDistantPaintFilter>(
1088       lighting_type_, direction_, light_color_, surface_scale_, kconstant_,
1089       shininess_, Snapshot(input_, image_provider), crop_rect());
1090 }
1091 
operator ==(const LightingDistantPaintFilter & other) const1092 bool LightingDistantPaintFilter::operator==(
1093     const LightingDistantPaintFilter& other) const {
1094   return lighting_type_ == other.lighting_type_ &&
1095          PaintOp::AreSkPoint3sEqual(direction_, other.direction_) &&
1096          light_color_ == other.light_color_ &&
1097          PaintOp::AreEqualEvenIfNaN(surface_scale_, other.surface_scale_) &&
1098          PaintOp::AreEqualEvenIfNaN(kconstant_, other.kconstant_) &&
1099          PaintOp::AreEqualEvenIfNaN(shininess_, other.shininess_) &&
1100          AreFiltersEqual(input_.get(), other.input_.get());
1101 }
1102 
LightingPointPaintFilter(LightingType lighting_type,const SkPoint3 & location,SkColor light_color,SkScalar surface_scale,SkScalar kconstant,SkScalar shininess,sk_sp<PaintFilter> input,const CropRect * crop_rect)1103 LightingPointPaintFilter::LightingPointPaintFilter(LightingType lighting_type,
1104                                                    const SkPoint3& location,
1105                                                    SkColor light_color,
1106                                                    SkScalar surface_scale,
1107                                                    SkScalar kconstant,
1108                                                    SkScalar shininess,
1109                                                    sk_sp<PaintFilter> input,
1110                                                    const CropRect* crop_rect)
1111     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
1112       lighting_type_(lighting_type),
1113       location_(location),
1114       light_color_(light_color),
1115       surface_scale_(surface_scale),
1116       kconstant_(kconstant),
1117       shininess_(shininess),
1118       input_(std::move(input)) {
1119   switch (lighting_type_) {
1120     case LightingType::kDiffuse:
1121       cached_sk_filter_ = SkLightingImageFilter::MakePointLitDiffuse(
1122           location_, light_color_, surface_scale_, kconstant_,
1123           GetSkFilter(input_.get()), crop_rect);
1124       break;
1125     case LightingType::kSpecular:
1126       cached_sk_filter_ = SkLightingImageFilter::MakePointLitSpecular(
1127           location_, light_color_, surface_scale_, kconstant_, shininess_,
1128           GetSkFilter(input_.get()), crop_rect);
1129       break;
1130   }
1131 }
1132 
1133 LightingPointPaintFilter::~LightingPointPaintFilter() = default;
1134 
SerializedSize() const1135 size_t LightingPointPaintFilter::SerializedSize() const {
1136   base::CheckedNumeric<size_t> total_size =
1137       BaseSerializedSize() + sizeof(lighting_type_) + sizeof(location_) +
1138       sizeof(light_color_) + sizeof(surface_scale_) + sizeof(kconstant_) +
1139       sizeof(shininess_);
1140   total_size += GetFilterSize(input_.get());
1141   return total_size.ValueOrDefault(0u);
1142 }
1143 
SnapshotWithImagesInternal(ImageProvider * image_provider) const1144 sk_sp<PaintFilter> LightingPointPaintFilter::SnapshotWithImagesInternal(
1145     ImageProvider* image_provider) const {
1146   return sk_make_sp<LightingPointPaintFilter>(
1147       lighting_type_, location_, light_color_, surface_scale_, kconstant_,
1148       shininess_, Snapshot(input_, image_provider), crop_rect());
1149 }
1150 
operator ==(const LightingPointPaintFilter & other) const1151 bool LightingPointPaintFilter::operator==(
1152     const LightingPointPaintFilter& other) const {
1153   return lighting_type_ == other.lighting_type_ &&
1154          PaintOp::AreSkPoint3sEqual(location_, other.location_) &&
1155          light_color_ == other.light_color_ &&
1156          PaintOp::AreEqualEvenIfNaN(surface_scale_, other.surface_scale_) &&
1157          PaintOp::AreEqualEvenIfNaN(kconstant_, other.kconstant_) &&
1158          PaintOp::AreEqualEvenIfNaN(shininess_, other.shininess_) &&
1159          AreFiltersEqual(input_.get(), other.input_.get());
1160 }
1161 
LightingSpotPaintFilter(LightingType lighting_type,const SkPoint3 & location,const SkPoint3 & target,SkScalar specular_exponent,SkScalar cutoff_angle,SkColor light_color,SkScalar surface_scale,SkScalar kconstant,SkScalar shininess,sk_sp<PaintFilter> input,const CropRect * crop_rect)1162 LightingSpotPaintFilter::LightingSpotPaintFilter(LightingType lighting_type,
1163                                                  const SkPoint3& location,
1164                                                  const SkPoint3& target,
1165                                                  SkScalar specular_exponent,
1166                                                  SkScalar cutoff_angle,
1167                                                  SkColor light_color,
1168                                                  SkScalar surface_scale,
1169                                                  SkScalar kconstant,
1170                                                  SkScalar shininess,
1171                                                  sk_sp<PaintFilter> input,
1172                                                  const CropRect* crop_rect)
1173     : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
1174       lighting_type_(lighting_type),
1175       location_(location),
1176       target_(target),
1177       specular_exponent_(specular_exponent),
1178       cutoff_angle_(cutoff_angle),
1179       light_color_(light_color),
1180       surface_scale_(surface_scale),
1181       kconstant_(kconstant),
1182       shininess_(shininess),
1183       input_(std::move(input)) {
1184   switch (lighting_type_) {
1185     case LightingType::kDiffuse:
1186       cached_sk_filter_ = SkLightingImageFilter::MakeSpotLitDiffuse(
1187           location_, target_, specular_exponent_, cutoff_angle_, light_color_,
1188           surface_scale_, kconstant_, GetSkFilter(input_.get()), crop_rect);
1189       break;
1190     case LightingType::kSpecular:
1191       cached_sk_filter_ = SkLightingImageFilter::MakeSpotLitSpecular(
1192           location_, target_, specular_exponent_, cutoff_angle_, light_color_,
1193           surface_scale_, kconstant_, shininess_, GetSkFilter(input_.get()),
1194           crop_rect);
1195       break;
1196   }
1197 }
1198 
1199 LightingSpotPaintFilter::~LightingSpotPaintFilter() = default;
1200 
SerializedSize() const1201 size_t LightingSpotPaintFilter::SerializedSize() const {
1202   base::CheckedNumeric<size_t> total_size =
1203       BaseSerializedSize() + sizeof(lighting_type_) + sizeof(location_) +
1204       sizeof(target_) + sizeof(specular_exponent_) + sizeof(cutoff_angle_) +
1205       sizeof(light_color_) + sizeof(surface_scale_) + sizeof(kconstant_) +
1206       sizeof(shininess_);
1207   total_size += GetFilterSize(input_.get());
1208   return total_size.ValueOrDefault(0u);
1209 }
1210 
SnapshotWithImagesInternal(ImageProvider * image_provider) const1211 sk_sp<PaintFilter> LightingSpotPaintFilter::SnapshotWithImagesInternal(
1212     ImageProvider* image_provider) const {
1213   return sk_make_sp<LightingSpotPaintFilter>(
1214       lighting_type_, location_, target_, specular_exponent_, cutoff_angle_,
1215       light_color_, surface_scale_, kconstant_, shininess_,
1216       Snapshot(input_, image_provider), crop_rect());
1217 }
1218 
operator ==(const LightingSpotPaintFilter & other) const1219 bool LightingSpotPaintFilter::operator==(
1220     const LightingSpotPaintFilter& other) const {
1221   return lighting_type_ == other.lighting_type_ &&
1222          PaintOp::AreSkPoint3sEqual(location_, other.location_) &&
1223          PaintOp::AreSkPoint3sEqual(target_, other.target_) &&
1224          PaintOp::AreEqualEvenIfNaN(specular_exponent_,
1225                                     other.specular_exponent_) &&
1226          PaintOp::AreEqualEvenIfNaN(cutoff_angle_, other.cutoff_angle_) &&
1227          light_color_ == other.light_color_ &&
1228          PaintOp::AreEqualEvenIfNaN(surface_scale_, other.surface_scale_) &&
1229          PaintOp::AreEqualEvenIfNaN(kconstant_, other.kconstant_) &&
1230          PaintOp::AreEqualEvenIfNaN(shininess_, other.shininess_) &&
1231          AreFiltersEqual(input_.get(), other.input_.get());
1232 }
1233 
1234 }  // namespace cc
1235