[M108 Migration][Loading Performance] Introduce |BeginMainFrame| throttling
[platform/framework/web/chromium-efl.git] / cc / paint / paint_op_reader.cc
1 // Copyright 2017 The Chromium Authors
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_op_reader.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10 #include <memory>
11 #include <type_traits>
12 #include <utility>
13 #include <vector>
14
15 #include "base/bits.h"
16 #include "base/compiler_specific.h"
17 #include "base/debug/dump_without_crashing.h"
18 #include "base/memory/raw_ptr.h"
19 #include "base/metrics/histogram_functions.h"
20 #include "base/notreached.h"
21 #include "base/rand_util.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/types/optional_util.h"
24 #include "cc/paint/image_transfer_cache_entry.h"
25 #include "cc/paint/paint_cache.h"
26 #include "cc/paint/paint_flags.h"
27 #include "cc/paint/paint_image_builder.h"
28 #include "cc/paint/paint_op_buffer.h"
29 #include "cc/paint/paint_shader.h"
30 #include "cc/paint/shader_transfer_cache_entry.h"
31 #include "cc/paint/skottie_transfer_cache_entry.h"
32 #include "cc/paint/skottie_wrapper.h"
33 #include "cc/paint/transfer_cache_deserialize_helper.h"
34 #include "components/crash/core/common/crash_key.h"
35 #include "third_party/skia/include/core/SkColorSpace.h"
36 #include "third_party/skia/include/core/SkPath.h"
37 #include "third_party/skia/include/core/SkRRect.h"
38 #include "third_party/skia/include/core/SkSerialProcs.h"
39 #include "third_party/skia/include/private/chromium/GrSlug.h"
40 #include "third_party/skia/include/private/chromium/SkChromeRemoteGlyphCache.h"
41
42 namespace cc {
43 namespace {
44
45 bool IsValidPaintShaderType(PaintShader::Type type) {
46   return static_cast<uint8_t>(type) <
47          static_cast<uint8_t>(PaintShader::Type::kShaderCount);
48 }
49
50 bool IsValidPaintShaderScalingBehavior(PaintShader::ScalingBehavior behavior) {
51   return behavior == PaintShader::ScalingBehavior::kRasterAtScale ||
52          behavior == PaintShader::ScalingBehavior::kFixedScale;
53 }
54
55 }  // namespace
56
57 // static
58 void PaintOpReader::FixupMatrixPostSerialization(SkMatrix* matrix) {
59   // Can't trust malicious clients to provide the correct derived matrix type.
60   // However, if a matrix thinks that it's identity, then make it so.
61   if (matrix->isIdentity())
62     matrix->setIdentity();
63   else
64     matrix->dirtyMatrixTypeCache();
65 }
66
67 // static
68 bool PaintOpReader::ReadAndValidateOpHeader(const volatile void* input,
69                                             size_t input_size,
70                                             uint8_t* type,
71                                             uint32_t* skip) {
72   if (input_size < 4)
73     return false;
74   uint32_t first_word = reinterpret_cast<const volatile uint32_t*>(input)[0];
75   *type = static_cast<uint8_t>(first_word & 0xFF);
76   *skip = first_word >> 8;
77
78   if (input_size < *skip)
79     return false;
80   if (*skip % PaintOpBuffer::PaintOpAlign != 0)
81     return false;
82   if (*type > static_cast<uint8_t>(PaintOpType::LastPaintOpType))
83     return false;
84   return true;
85 }
86
87 template <typename T>
88 void PaintOpReader::ReadSimple(T* val) {
89   static_assert(std::is_trivially_copyable_v<T>);
90
91   DCHECK_EQ(memory_, base::bits::AlignUp(memory_, PaintOpWriter::Alignment()));
92   // Align everything to 4 bytes, as the writer does.
93   static constexpr size_t size =
94       base::bits::AlignUp(sizeof(T), PaintOpWriter::Alignment());
95
96   if (remaining_bytes_ < size)
97     SetInvalid(DeserializationError::kInsufficientRemainingBytes_ReadSimple);
98
99   if (!valid_)
100     return;
101
102   // Most of the time this is used for primitives, but this function is also
103   // used for SkRect/SkIRect/SkMatrix whose implicit operator= can't use a
104   // volatile.  TOCTOU violations don't matter for these simple types so
105   // use assignment.
106   *val = *reinterpret_cast<const T*>(const_cast<const char*>(memory_));
107
108   memory_ += size;
109   remaining_bytes_ -= size;
110 }
111
112 uint8_t* PaintOpReader::CopyScratchSpace(size_t bytes) {
113   DCHECK(SkIsAlign4(reinterpret_cast<uintptr_t>(memory_)));
114
115   if (options_.scratch_buffer->size() < bytes)
116     options_.scratch_buffer->resize(bytes);
117   memcpy(options_.scratch_buffer->data(), const_cast<const char*>(memory_),
118          bytes);
119   return options_.scratch_buffer->data();
120 }
121
122 template <typename T>
123 void PaintOpReader::ReadFlattenable(
124     sk_sp<T>* val,
125     Factory<T> factory,
126     DeserializationError error_on_factory_failure) {
127   size_t bytes = 0;
128   ReadSize(&bytes);
129   if (remaining_bytes_ < bytes) {
130     SetInvalid(
131         DeserializationError::kInsufficientRemainingBytes_ReadFlattenable);
132     return;
133   }
134
135   if (bytes == 0)
136     return;
137
138   auto* scratch = CopyScratchSpace(bytes);
139   val->reset(factory(scratch, bytes, nullptr).release());
140   if (!val) {
141     SetInvalid(error_on_factory_failure);
142     return;
143   }
144
145   DidRead(bytes);
146 }
147
148 void PaintOpReader::ReadData(size_t bytes, void* data) {
149   DCHECK_EQ(memory_, base::bits::AlignUp(memory_, PaintOpWriter::Alignment()));
150   if (bytes == 0)
151     return;
152
153   if (remaining_bytes_ < bytes) {
154     SetInvalid(DeserializationError::kInsufficientRemainingBytes_ReadData);
155     return;
156   }
157
158   memcpy(data, const_cast<const char*>(memory_), bytes);
159   DidRead(bytes);
160 }
161
162 void PaintOpReader::ReadSize(size_t* size) {
163   AlignMemory(8);
164   if (!valid_)
165     return;
166   uint64_t size64 = 0;
167   ReadSimple(&size64);
168   *size = size64;
169 }
170
171 void PaintOpReader::Read(SkScalar* data) {
172   ReadSimple(data);
173 }
174
175     void
176     PaintOpReader::Read(uint8_t* data) {
177   ReadSimple(data);
178 }
179
180 void PaintOpReader::Read(uint32_t* data) {
181   ReadSimple(data);
182 }
183
184 void PaintOpReader::Read(uint64_t* data) {
185   ReadSimple(data);
186 }
187
188 void PaintOpReader::Read(int32_t* data) {
189   ReadSimple(data);
190 }
191
192 void PaintOpReader::Read(SkRect* rect) {
193   ReadSimple(rect);
194 }
195
196 void PaintOpReader::Read(SkIRect* rect) {
197   ReadSimple(rect);
198 }
199
200 void PaintOpReader::Read(SkRRect* rect) {
201   ReadSimple(rect);
202 }
203
204 void PaintOpReader::Read(SkColor4f* color) {
205   ReadSimple(color);
206 }
207
208 void PaintOpReader::Read(SkPath* path) {
209   uint32_t path_id;
210   ReadSimple(&path_id);
211   if (!valid_)
212     return;
213
214   uint32_t entry_state_int = 0u;
215   ReadSimple(&entry_state_int);
216   if (entry_state_int > static_cast<uint32_t>(PaintCacheEntryState::kLast)) {
217     valid_ = false;
218     return;
219   }
220
221   auto entry_state = static_cast<PaintCacheEntryState>(entry_state_int);
222   switch (entry_state) {
223     case PaintCacheEntryState::kEmpty:
224       return;
225     case PaintCacheEntryState::kCached:
226       if (!options_.paint_cache->GetPath(path_id, path))
227         SetInvalid(DeserializationError::kMissingPaintCachePathEntry);
228       return;
229     case PaintCacheEntryState::kInlined:
230     case PaintCacheEntryState::kInlinedDoNotCache: {
231       size_t path_bytes = 0u;
232       ReadSize(&path_bytes);
233       if (path_bytes > remaining_bytes_)
234         SetInvalid(
235             DeserializationError::kInsufficientRemainingBytes_Read_SkPath);
236       if (path_bytes == 0u)
237         SetInvalid(DeserializationError::kZeroSkPathBytes);
238       if (!valid_)
239         return;
240
241       auto* scratch = CopyScratchSpace(path_bytes);
242       size_t bytes_read = path->readFromMemory(scratch, path_bytes);
243       if (bytes_read == 0u) {
244         SetInvalid(DeserializationError::kSkPathReadFromMemoryFailure);
245         return;
246       }
247       if (entry_state == PaintCacheEntryState::kInlined) {
248         options_.paint_cache->PutPath(path_id, *path);
249       } else {
250         // If we know that this path will only be drawn once, which is
251         // implied by kInlinedDoNotCache, we signal to skia that it should not
252         // do any caching either.
253         path->setIsVolatile(true);
254       }
255       DidRead(path_bytes);
256       return;
257     }
258   }
259 }
260
261 void PaintOpReader::Read(PaintFlags* flags) {
262   ReadSimple(&flags->color_);
263   Read(&flags->width_);
264   Read(&flags->miter_limit_);
265
266   Read(&flags->blend_mode_);
267
268   ReadSimple(&flags->bitfields_uint_);
269
270   ReadFlattenable(&flags->path_effect_, SkPathEffect::Deserialize,
271                   DeserializationError::kSkPathEffectUnflattenFailure);
272   ReadFlattenable(&flags->mask_filter_, SkMaskFilter::Deserialize,
273                   DeserializationError::kSkMaskFilterUnflattenFailure);
274   ReadFlattenable(&flags->color_filter_, SkColorFilter::Deserialize,
275                   DeserializationError::kSkColorFilterUnflattenFailure);
276
277   if (enable_security_constraints_) {
278     size_t bytes = 0;
279     ReadSize(&bytes);
280     if (bytes != 0u) {
281       SetInvalid(DeserializationError::kDrawLooperForbidden);
282       return;
283     }
284   } else {
285     ReadFlattenable(&flags->draw_looper_, SkDrawLooper::Deserialize,
286                     DeserializationError::kSkDrawLooperUnflattenFailure);
287   }
288
289   Read(&flags->image_filter_);
290   Read(&flags->shader_);
291 }
292
293 void PaintOpReader::Read(PaintImage* image) {
294   uint8_t serialized_type_int = 0u;
295   Read(&serialized_type_int);
296   if (serialized_type_int >
297       static_cast<uint8_t>(PaintOp::SerializedImageType::kLastType)) {
298     SetInvalid(DeserializationError::kInvalidSerializedImageType);
299     return;
300   }
301
302   auto serialized_type =
303       static_cast<PaintOp::SerializedImageType>(serialized_type_int);
304   if (serialized_type == PaintOp::SerializedImageType::kNoImage)
305     return;
306
307   if (enable_security_constraints_) {
308     switch (serialized_type) {
309       case PaintOp::SerializedImageType::kNoImage:
310         NOTREACHED();
311         return;
312       case PaintOp::SerializedImageType::kImageData: {
313         SkColorType color_type;
314         Read(&color_type);
315         uint32_t width;
316         Read(&width);
317         uint32_t height;
318         Read(&height);
319         size_t pixel_size;
320         ReadSize(&pixel_size);
321         if (!valid_)
322           return;
323
324         SkImageInfo image_info =
325             SkImageInfo::Make(width, height, color_type, kPremul_SkAlphaType);
326         if (pixel_size < image_info.computeMinByteSize()) {
327           SetInvalid(DeserializationError::kInsufficientPixelData);
328           return;
329         }
330         const volatile void* pixel_data = ExtractReadableMemory(pixel_size);
331         if (!valid_)
332           return;
333
334         SkPixmap pixmap(image_info, const_cast<const void*>(pixel_data),
335                         image_info.minRowBytes());
336
337         *image = PaintImageBuilder::WithDefault()
338                      .set_id(PaintImage::GetNextId())
339                      .set_texture_image(SkImage::MakeRasterCopy(pixmap),
340                                         PaintImage::kNonLazyStableId)
341                      .TakePaintImage();
342       }
343         return;
344       case PaintOp::SerializedImageType::kTransferCacheEntry:
345       case PaintOp::SerializedImageType::kMailbox:
346         SetInvalid(DeserializationError::kForbiddenSerializedImageType);
347         return;
348     }
349
350     NOTREACHED();
351     return;
352   }
353
354   if (serialized_type == PaintOp::SerializedImageType::kMailbox) {
355     if (!options_.shared_image_provider) {
356       SetInvalid(DeserializationError::kMissingSharedImageProvider);
357       return;
358     }
359
360     gpu::Mailbox mailbox;
361     Read(&mailbox);
362     if (mailbox.IsZero()) {
363       SetInvalid(DeserializationError::kZeroMailbox);
364       return;
365     }
366
367     SharedImageProvider::Error error;
368     sk_sp<SkImage> sk_image =
369         options_.shared_image_provider->OpenSharedImageForRead(mailbox, error);
370     if (error != SharedImageProvider::Error::kNoError) {
371       switch (error) {
372         case SharedImageProvider::Error::kNoAccess:
373           SetInvalid(DeserializationError::kSharedImageProviderNoAccess);
374           break;
375         case SharedImageProvider::Error::kSkImageCreationFailed:
376           SetInvalid(
377               DeserializationError::kSharedImageProviderSkImageCreationFailed);
378           break;
379         case SharedImageProvider::Error::kUnknownMailbox:
380           SetInvalid(DeserializationError::kSharedImageProviderUnknownMailbox);
381           break;
382         default:
383           NOTREACHED();
384           break;
385       }
386       SetInvalid(DeserializationError::kSharedImageOpenFailure);
387       return;
388     }
389     DCHECK(sk_image);
390
391     *image = PaintImageBuilder::WithDefault()
392                  .set_id(PaintImage::GetNextId())
393                  .set_texture_image(std::move(sk_image),
394                                     PaintImage::kNonLazyStableId)
395                  .TakePaintImage();
396     return;
397   }
398
399   if (serialized_type != PaintOp::SerializedImageType::kTransferCacheEntry) {
400     SetInvalid(DeserializationError::kUnexpectedSerializedImageType);
401     return;
402   }
403
404   uint32_t transfer_cache_entry_id;
405   ReadSimple(&transfer_cache_entry_id);
406   if (!valid_)
407     return;
408
409   bool needs_mips;
410   ReadSimple(&needs_mips);
411   if (!valid_)
412     return;
413
414   // If we encountered a decode failure, we may write an invalid id for the
415   // image. In these cases, just return, leaving the image as nullptr.
416   if (transfer_cache_entry_id == kInvalidImageTransferCacheEntryId)
417     return;
418
419   // The transfer cache entry for an image may not exist if the upload fails.
420   if (auto* entry =
421           options_.transfer_cache->GetEntryAs<ServiceImageTransferCacheEntry>(
422               transfer_cache_entry_id)) {
423     if (needs_mips)
424       entry->EnsureMips();
425     *image =
426         PaintImageBuilder::WithDefault()
427             .set_id(PaintImage::GetNextId())
428             .set_texture_image(entry->image(), PaintImage::kNonLazyStableId)
429             .TakePaintImage();
430   }
431 }
432
433 void PaintOpReader::Read(sk_sp<SkData>* data) {
434   size_t bytes = 0;
435   ReadSize(&bytes);
436   if (remaining_bytes_ < bytes)
437     SetInvalid(DeserializationError::kInsufficientRemainingBytes_Read_SkData);
438   if (!valid_)
439     return;
440
441   // Separate out empty vs not valid cases.
442   if (bytes == 0) {
443     bool has_data = false;
444     Read(&has_data);
445     if (has_data)
446       *data = SkData::MakeEmpty();
447     return;
448   }
449
450   // This is safe to cast away the volatile as it is just a memcpy internally.
451   *data = SkData::MakeWithCopy(const_cast<const char*>(memory_), bytes);
452   DidRead(bytes);
453 }
454
455 void PaintOpReader::Read(sk_sp<SkColorSpace>* color_space) {
456   size_t size = 0;
457   ReadSize(&size);
458   if (remaining_bytes_ < size)
459     valid_ = false;
460   if (!valid_ || size == 0)
461     return;
462
463   auto* scratch = CopyScratchSpace(size);
464   *color_space = SkColorSpace::Deserialize(scratch, size);
465   // If this had non-zero bytes, it should be a valid color space.
466   if (!color_space)
467     SetInvalid(DeserializationError::kSkColorSpaceDeserializeFailure);
468
469   DidRead(size);
470 }
471
472 void PaintOpReader::Read(sk_sp<GrSlug>* slug) {
473   AssertAlignment(PaintOpWriter::Alignment());
474
475   size_t data_bytes = 0u;
476   ReadSize(&data_bytes);
477   if (data_bytes == 0) {
478     *slug = nullptr;
479     return;
480   }
481
482   if (remaining_bytes_ < data_bytes) {
483     SetInvalid(DeserializationError::kInsufficientRemainingBytes_Read_GrSlug);
484     return;
485   }
486
487   *slug = GrSlug::Deserialize(const_cast<const char*>(memory_), data_bytes,
488                               options_.strike_client);
489   DidRead(data_bytes);
490
491   if (!*slug) {
492     SetInvalid(DeserializationError::kGrSlugDeserializeFailure);
493     return;
494   }
495 }
496
497 void PaintOpReader::Read(sk_sp<PaintShader>* shader) {
498   bool has_shader = false;
499   ReadSimple(&has_shader);
500   if (!has_shader) {
501     *shader = nullptr;
502     return;
503   }
504   PaintShader::Type shader_type;
505   ReadSimple(&shader_type);
506   // Avoid creating a shader if something is invalid.
507   if (!valid_ || !IsValidPaintShaderType(shader_type)) {
508     SetInvalid(DeserializationError::kInvalidPaintShaderType);
509     return;
510   }
511
512   *shader = sk_sp<PaintShader>(new PaintShader(shader_type));
513   PaintShader& ref = **shader;
514   ReadSimple(&ref.flags_);
515   ReadSimple(&ref.end_radius_);
516   ReadSimple(&ref.start_radius_);
517   Read(&ref.tx_);
518   Read(&ref.ty_);
519   ReadSimple(&ref.fallback_color_);
520   ReadSimple(&ref.scaling_behavior_);
521   if (!IsValidPaintShaderScalingBehavior(ref.scaling_behavior_))
522     SetInvalid(DeserializationError::kInvalidPaintShaderScalingBehavior);
523   bool has_local_matrix = false;
524   ReadSimple(&has_local_matrix);
525   if (has_local_matrix) {
526     ref.local_matrix_.emplace();
527     Read(&*ref.local_matrix_);
528   }
529   ReadSimple(&ref.center_);
530   ReadSimple(&ref.tile_);
531   ReadSimple(&ref.start_point_);
532   ReadSimple(&ref.end_point_);
533   ReadSimple(&ref.start_degrees_);
534   ReadSimple(&ref.end_degrees_);
535   Read(&ref.image_);
536   bool has_record = false;
537   ReadSimple(&has_record);
538   uint32_t shader_id = PaintShader::kInvalidRecordShaderId;
539   size_t shader_size = 0;
540   if (has_record) {
541     if (shader_type != PaintShader::Type::kPaintRecord) {
542       SetInvalid(DeserializationError::kUnexpectedPaintShaderType);
543       return;
544     }
545     Read(&shader_id);
546     if (shader_id == PaintShader::kInvalidRecordShaderId) {
547       SetInvalid(DeserializationError::kInvalidRecordShaderId);
548       return;
549     }
550
551     // Track dependent transfer cache entries to make cached shader size
552     // more realistic.
553     size_t pre_size = options_.transfer_cache->GetTotalEntrySizes();
554     size_t record_size = Read(&ref.record_);
555     size_t post_size = options_.transfer_cache->GetTotalEntrySizes();
556     shader_size = post_size - pre_size + record_size;
557
558     ref.id_ = shader_id;
559   }
560   decltype(ref.colors_)::size_type colors_size = 0;
561   ReadSize(&colors_size);
562
563   // If there are too many colors, abort.
564   if (colors_size > remaining_bytes_) {
565     SetInvalid(DeserializationError::
566                    kInsufficientRemainingBytes_Read_PaintShader_ColorSize);
567     return;
568   }
569   size_t colors_bytes =
570       colors_size * (colors_size > 0 ? sizeof(ref.colors_[0]) : 0u);
571   if (colors_bytes > remaining_bytes_) {
572     SetInvalid(DeserializationError::
573                    kInsufficientRemainingBytes_Read_PaintShader_ColorBytes);
574     return;
575   }
576   ref.colors_.resize(colors_size);
577   ReadData(colors_bytes, ref.colors_.data());
578
579   decltype(ref.positions_)::size_type positions_size = 0;
580   ReadSize(&positions_size);
581   // Positions are optional. If they exist, they have the same count as colors.
582   if (positions_size > 0 && positions_size != colors_size) {
583     SetInvalid(DeserializationError::kInvalidPaintShaderPositionsSize);
584     return;
585   }
586   size_t positions_bytes = positions_size * sizeof(SkScalar);
587   if (positions_bytes > remaining_bytes_) {
588     SetInvalid(DeserializationError::
589                    kInsufficientRemainingBytes_Read_PaintShader_Positions);
590     return;
591   }
592   ref.positions_.resize(positions_size);
593   ReadData(positions_size * sizeof(SkScalar), ref.positions_.data());
594
595   // We don't write the cached shader, so don't attempt to read it either.
596
597   if (!(*shader)->IsValid()) {
598     SetInvalid(DeserializationError::kInvalidPaintShader);
599     return;
600   }
601
602   // All shader types but records are done.
603   if (shader_type != PaintShader::Type::kPaintRecord) {
604     (*shader)->ResolveSkObjects();
605     return;
606   }
607
608   // Record shaders have shader ids.  Attempt to use cached versions of
609   // these so that Skia can cache based on SkPictureShader::fUniqueId.
610   // These shaders are always serialized (and assumed to not be large
611   // records).  Handling this edge case in this roundabout way prevents
612   // transfer cache entries from needing to depend on other transfer cache
613   // entries.
614   auto* entry =
615       options_.transfer_cache->GetEntryAs<ServiceShaderTransferCacheEntry>(
616           shader_id);
617   // Only consider entries that use the same scale.  This limits the service
618   // side transfer cache to only having one entry per shader but this will hit
619   // the common case of enabling Skia reuse.
620   if (entry && entry->shader()->tile_ == ref.tile_) {
621     DCHECK(!ref.sk_cached_picture_);
622     ref.sk_cached_picture_ = entry->shader()->sk_cached_picture_;
623   } else {
624     ref.ResolveSkObjects();
625     DCHECK(ref.sk_cached_picture_);
626     options_.transfer_cache->CreateLocalEntry(
627         shader_id, std::make_unique<ServiceShaderTransferCacheEntry>(
628                        *shader, shader_size));
629   }
630 }
631
632 void PaintOpReader::Read(SkMatrix* matrix) {
633   ReadSimple(matrix);
634   FixupMatrixPostSerialization(matrix);
635 }
636
637 void PaintOpReader::Read(SkM44* matrix) {
638   ReadSimple(matrix);
639 }
640
641 void PaintOpReader::Read(SkSamplingOptions* sampling) {
642   bool useCubic;
643   Read(&useCubic);
644   if (useCubic) {
645     SkCubicResampler cubic;
646     Read(&cubic.B);
647     Read(&cubic.C);
648     *sampling = SkSamplingOptions(cubic);
649   } else {
650     SkFilterMode filter;
651     SkMipmapMode mipmap;
652     Read(&filter);
653     Read(&mipmap);
654     *sampling = SkSamplingOptions(filter, mipmap);
655   }
656 }
657
658 void PaintOpReader::Read(SkYUVColorSpace* yuv_color_space) {
659   uint32_t raw_yuv_color_space = kIdentity_SkYUVColorSpace;
660   ReadSimple(&raw_yuv_color_space);
661
662   if (raw_yuv_color_space > kLastEnum_SkYUVColorSpace) {
663     SetInvalid(DeserializationError::kInvalidSkYUVColorSpace);
664     return;
665   }
666
667   *yuv_color_space = static_cast<SkYUVColorSpace>(raw_yuv_color_space);
668 }
669
670 void PaintOpReader::Read(SkYUVAInfo::PlaneConfig* plane_config) {
671   uint32_t raw_plane_config =
672       static_cast<uint32_t>(SkYUVAInfo::PlaneConfig::kUnknown);
673   ReadSimple(&raw_plane_config);
674
675   if (raw_plane_config >
676       static_cast<uint32_t>(SkYUVAInfo::PlaneConfig::kLast)) {
677     SetInvalid(DeserializationError::kInvalidPlaneConfig);
678     return;
679   }
680
681   *plane_config = static_cast<SkYUVAInfo::PlaneConfig>(raw_plane_config);
682 }
683
684 void PaintOpReader::Read(SkYUVAInfo::Subsampling* subsampling) {
685   uint32_t raw_subsampling =
686       static_cast<uint32_t>(SkYUVAInfo::Subsampling::kUnknown);
687   ReadSimple(&raw_subsampling);
688
689   if (raw_subsampling > static_cast<uint32_t>(SkYUVAInfo::Subsampling::kLast)) {
690     SetInvalid(DeserializationError::kInvalidSubsampling);
691     return;
692   }
693
694   *subsampling = static_cast<SkYUVAInfo::Subsampling>(raw_subsampling);
695 }
696
697 void PaintOpReader::Read(gpu::Mailbox* mailbox) {
698   ReadData(sizeof(gpu::Mailbox::Name), (*mailbox).name);
699 }
700
701 void PaintOpReader::Read(scoped_refptr<SkottieWrapper>* skottie) {
702   if (!options_.is_privileged) {
703     valid_ = false;
704     return;
705   }
706
707   uint32_t transfer_cache_entry_id;
708   ReadSimple(&transfer_cache_entry_id);
709   if (!valid_)
710     return;
711   auto* entry =
712       options_.transfer_cache->GetEntryAs<ServiceSkottieTransferCacheEntry>(
713           transfer_cache_entry_id);
714   if (entry) {
715     *skottie = entry->skottie();
716   } else {
717     valid_ = false;
718   }
719
720   size_t bytes_to_skip = 0u;
721   ReadSize(&bytes_to_skip);
722   if (!valid_)
723     return;
724   if (bytes_to_skip > remaining_bytes_) {
725     valid_ = false;
726     return;
727   }
728   DidRead(bytes_to_skip);
729 }
730
731 void PaintOpReader::AlignMemory(size_t alignment) {
732   size_t padding = base::bits::AlignUp(memory_, alignment) - memory_;
733   if (padding > remaining_bytes_)
734     SetInvalid(DeserializationError::kInsufficientRemainingBytes_AlignMemory);
735
736   memory_ += padding;
737   remaining_bytes_ -= padding;
738 }
739
740 // Don't inline this function so that crash reports can show the caller.
741 NOINLINE void PaintOpReader::SetInvalid(DeserializationError error) {
742   static crash_reporter::CrashKeyString<4> deserialization_error_crash_key(
743       "PaintOpReader deserialization error");
744   base::UmaHistogramEnumeration("GPU.PaintOpReader.DeserializationError",
745                                 error);
746   if (valid_ && options_.crash_dump_on_failure && base::RandInt(1, 10) == 1) {
747     crash_reporter::ScopedCrashKeyString crash_key_scope(
748         &deserialization_error_crash_key,
749         base::NumberToString(static_cast<int>(error)));
750     base::debug::DumpWithoutCrashing();
751   }
752   valid_ = false;
753 }
754
755 const volatile void* PaintOpReader::ExtractReadableMemory(size_t bytes) {
756   if (remaining_bytes_ < bytes)
757     SetInvalid(DeserializationError::
758                    kInsufficientRemainingBytes_ExtractReadableMemory);
759   if (!valid_)
760     return nullptr;
761   if (bytes == 0)
762     return nullptr;
763
764   const volatile void* extracted_memory = memory_;
765   DidRead(bytes);
766   return extracted_memory;
767 }
768
769 void PaintOpReader::Read(sk_sp<PaintFilter>* filter) {
770   PaintFilter::Type type;
771   ReadEnum(&type);
772   if (!valid_)
773     return;
774
775   if (type == PaintFilter::Type::kNullFilter) {
776     *filter = nullptr;
777     return;
778   }
779
780   uint32_t has_crop_rect = 0;
781   absl::optional<PaintFilter::CropRect> crop_rect;
782   ReadSimple(&has_crop_rect);
783   if (has_crop_rect) {
784     SkRect rect = SkRect::MakeEmpty();
785     ReadSimple(&rect);
786     crop_rect.emplace(rect);
787   }
788
789   AssertAlignment(PaintOpWriter::Alignment());
790   switch (type) {
791     case PaintFilter::Type::kNullFilter:
792       NOTREACHED();
793       break;
794     case PaintFilter::Type::kColorFilter:
795       ReadColorFilterPaintFilter(filter, crop_rect);
796       break;
797     case PaintFilter::Type::kBlur:
798       ReadBlurPaintFilter(filter, crop_rect);
799       break;
800     case PaintFilter::Type::kDropShadow:
801       ReadDropShadowPaintFilter(filter, crop_rect);
802       break;
803     case PaintFilter::Type::kMagnifier:
804       ReadMagnifierPaintFilter(filter, crop_rect);
805       break;
806     case PaintFilter::Type::kCompose:
807       ReadComposePaintFilter(filter, crop_rect);
808       break;
809     case PaintFilter::Type::kAlphaThreshold:
810       ReadAlphaThresholdPaintFilter(filter, crop_rect);
811       break;
812     case PaintFilter::Type::kXfermode:
813       ReadXfermodePaintFilter(filter, crop_rect);
814       break;
815     case PaintFilter::Type::kArithmetic:
816       ReadArithmeticPaintFilter(filter, crop_rect);
817       break;
818     case PaintFilter::Type::kMatrixConvolution:
819       ReadMatrixConvolutionPaintFilter(filter, crop_rect);
820       break;
821     case PaintFilter::Type::kDisplacementMapEffect:
822       ReadDisplacementMapEffectPaintFilter(filter, crop_rect);
823       break;
824     case PaintFilter::Type::kImage:
825       ReadImagePaintFilter(filter, crop_rect);
826       break;
827     case PaintFilter::Type::kPaintRecord:
828       ReadRecordPaintFilter(filter, crop_rect);
829       break;
830     case PaintFilter::Type::kMerge:
831       ReadMergePaintFilter(filter, crop_rect);
832       break;
833     case PaintFilter::Type::kMorphology:
834       ReadMorphologyPaintFilter(filter, crop_rect);
835       break;
836     case PaintFilter::Type::kOffset:
837       ReadOffsetPaintFilter(filter, crop_rect);
838       break;
839     case PaintFilter::Type::kTile:
840       ReadTilePaintFilter(filter, crop_rect);
841       break;
842     case PaintFilter::Type::kTurbulence:
843       ReadTurbulencePaintFilter(filter, crop_rect);
844       break;
845     case PaintFilter::Type::kShader:
846       ReadShaderPaintFilter(filter, crop_rect);
847       break;
848     case PaintFilter::Type::kMatrix:
849       ReadMatrixPaintFilter(filter, crop_rect);
850       break;
851     case PaintFilter::Type::kLightingDistant:
852       ReadLightingDistantPaintFilter(filter, crop_rect);
853       break;
854     case PaintFilter::Type::kLightingPoint:
855       ReadLightingPointPaintFilter(filter, crop_rect);
856       break;
857     case PaintFilter::Type::kLightingSpot:
858       ReadLightingSpotPaintFilter(filter, crop_rect);
859       break;
860     case PaintFilter::Type::kStretch:
861       ReadStretchPaintFilter(filter, crop_rect);
862       break;
863   }
864 }
865
866 void PaintOpReader::ReadColorFilterPaintFilter(
867     sk_sp<PaintFilter>* filter,
868     const absl::optional<PaintFilter::CropRect>& crop_rect) {
869   sk_sp<SkColorFilter> color_filter;
870   sk_sp<PaintFilter> input;
871
872   ReadFlattenable(&color_filter, SkColorFilter::Deserialize,
873                   DeserializationError::kSkColorFilterUnflattenFailure);
874   Read(&input);
875   if (!color_filter)
876     SetInvalid(DeserializationError::kZeroSkColorFilterBytes);
877   if (!valid_)
878     return;
879   filter->reset(new ColorFilterPaintFilter(std::move(color_filter),
880                                            std::move(input),
881                                            base::OptionalToPtr(crop_rect)));
882 }
883
884 void PaintOpReader::ReadBlurPaintFilter(
885     sk_sp<PaintFilter>* filter,
886     const absl::optional<PaintFilter::CropRect>& crop_rect) {
887   SkScalar sigma_x = 0.f;
888   SkScalar sigma_y = 0.f;
889   SkTileMode tile_mode;
890   sk_sp<PaintFilter> input;
891
892   Read(&sigma_x);
893   Read(&sigma_y);
894   Read(&tile_mode);
895   Read(&input);
896   if (!valid_)
897     return;
898   filter->reset(new BlurPaintFilter(sigma_x, sigma_y, tile_mode,
899                                     std::move(input),
900                                     base::OptionalToPtr(crop_rect)));
901 }
902
903 void PaintOpReader::ReadDropShadowPaintFilter(
904     sk_sp<PaintFilter>* filter,
905     const absl::optional<PaintFilter::CropRect>& crop_rect) {
906   SkScalar dx = 0.f;
907   SkScalar dy = 0.f;
908   SkScalar sigma_x = 0.f;
909   SkScalar sigma_y = 0.f;
910   SkColor color = SK_ColorBLACK;
911   DropShadowPaintFilter::ShadowMode shadow_mode;
912   sk_sp<PaintFilter> input;
913
914   Read(&dx);
915   Read(&dy);
916   Read(&sigma_x);
917   Read(&sigma_y);
918   Read(&color);
919   ReadEnum(&shadow_mode);
920   Read(&input);
921   if (!valid_)
922     return;
923   // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
924   filter->reset(new DropShadowPaintFilter(
925       dx, dy, sigma_x, sigma_y, SkColor4f::FromColor(color), shadow_mode,
926       std::move(input), base::OptionalToPtr(crop_rect)));
927 }
928
929 void PaintOpReader::ReadMagnifierPaintFilter(
930     sk_sp<PaintFilter>* filter,
931     const absl::optional<PaintFilter::CropRect>& crop_rect) {
932   SkRect src_rect = SkRect::MakeEmpty();
933   SkScalar inset = 0.f;
934   sk_sp<PaintFilter> input;
935
936   Read(&src_rect);
937   Read(&inset);
938   Read(&input);
939   if (!valid_)
940     return;
941   filter->reset(new MagnifierPaintFilter(src_rect, inset, std::move(input),
942                                          base::OptionalToPtr(crop_rect)));
943 }
944
945 void PaintOpReader::ReadComposePaintFilter(
946     sk_sp<PaintFilter>* filter,
947     const absl::optional<PaintFilter::CropRect>& crop_rect) {
948   sk_sp<PaintFilter> outer;
949   sk_sp<PaintFilter> inner;
950
951   Read(&outer);
952   Read(&inner);
953   if (!valid_)
954     return;
955   filter->reset(new ComposePaintFilter(std::move(outer), std::move(inner)));
956 }
957
958 void PaintOpReader::ReadAlphaThresholdPaintFilter(
959     sk_sp<PaintFilter>* filter,
960     const absl::optional<PaintFilter::CropRect>& crop_rect) {
961   SkRegion region;
962   SkScalar inner_min = 0.f;
963   SkScalar outer_max = 0.f;
964   sk_sp<PaintFilter> input;
965
966   Read(&region);
967   ReadSimple(&inner_min);
968   ReadSimple(&outer_max);
969   Read(&input);
970   if (!valid_)
971     return;
972   filter->reset(new AlphaThresholdPaintFilter(region, inner_min, outer_max,
973                                               std::move(input),
974                                               base::OptionalToPtr(crop_rect)));
975 }
976
977 void PaintOpReader::ReadXfermodePaintFilter(
978     sk_sp<PaintFilter>* filter,
979     const absl::optional<PaintFilter::CropRect>& crop_rect) {
980   SkBlendMode blend_mode;
981   sk_sp<PaintFilter> background;
982   sk_sp<PaintFilter> foreground;
983
984   Read(&blend_mode);
985   Read(&background);
986   Read(&foreground);
987   if (!valid_)
988     return;
989
990   filter->reset(new XfermodePaintFilter(blend_mode, std::move(background),
991                                         std::move(foreground),
992                                         base::OptionalToPtr(crop_rect)));
993 }
994
995 void PaintOpReader::ReadArithmeticPaintFilter(
996     sk_sp<PaintFilter>* filter,
997     const absl::optional<PaintFilter::CropRect>& crop_rect) {
998   float k1 = 0.f;
999   float k2 = 0.f;
1000   float k3 = 0.f;
1001   float k4 = 0.f;
1002   bool enforce_pm_color = false;
1003   sk_sp<PaintFilter> background;
1004   sk_sp<PaintFilter> foreground;
1005   Read(&k1);
1006   Read(&k2);
1007   Read(&k3);
1008   Read(&k4);
1009   Read(&enforce_pm_color);
1010   Read(&background);
1011   Read(&foreground);
1012   if (!valid_)
1013     return;
1014   filter->reset(new ArithmeticPaintFilter(
1015       k1, k2, k3, k4, enforce_pm_color, std::move(background),
1016       std::move(foreground), base::OptionalToPtr(crop_rect)));
1017 }
1018
1019 void PaintOpReader::ReadMatrixConvolutionPaintFilter(
1020     sk_sp<PaintFilter>* filter,
1021     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1022   SkISize kernel_size = SkISize::MakeEmpty();
1023   SkScalar gain = 0.f;
1024   SkScalar bias = 0.f;
1025   SkIPoint kernel_offset = SkIPoint::Make(0, 0);
1026   SkTileMode tile_mode;
1027   bool convolve_alpha = false;
1028   sk_sp<PaintFilter> input;
1029
1030   ReadSimple(&kernel_size);
1031   if (!valid_)
1032     return;
1033   auto size =
1034       static_cast<size_t>(sk_64_mul(kernel_size.width(), kernel_size.height()));
1035   if (size > remaining_bytes_) {
1036     SetInvalid(
1037         DeserializationError::
1038             kInsufficientRemainingBytes_ReadMatrixConvolutionPaintFilter);
1039     return;
1040   }
1041   std::vector<SkScalar> kernel(size);
1042   for (size_t i = 0; i < size; ++i)
1043     Read(&kernel[i]);
1044   Read(&gain);
1045   Read(&bias);
1046   ReadSimple(&kernel_offset);
1047   Read(&tile_mode);
1048   Read(&convolve_alpha);
1049   Read(&input);
1050   if (!valid_)
1051     return;
1052   filter->reset(new MatrixConvolutionPaintFilter(
1053       kernel_size, kernel.data(), gain, bias, kernel_offset, tile_mode,
1054       convolve_alpha, std::move(input), base::OptionalToPtr(crop_rect)));
1055 }
1056
1057 void PaintOpReader::ReadDisplacementMapEffectPaintFilter(
1058     sk_sp<PaintFilter>* filter,
1059     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1060   SkColorChannel channel_x;
1061   SkColorChannel channel_y;
1062   SkScalar scale = 0.f;
1063   sk_sp<PaintFilter> displacement;
1064   sk_sp<PaintFilter> color;
1065
1066   ReadEnum<SkColorChannel, SkColorChannel::kA>(&channel_x);
1067   ReadEnum<SkColorChannel, SkColorChannel::kA>(&channel_y);
1068   Read(&scale);
1069   Read(&displacement);
1070   Read(&color);
1071
1072   if (!valid_)
1073     return;
1074   filter->reset(new DisplacementMapEffectPaintFilter(
1075       channel_x, channel_y, scale, std::move(displacement), std::move(color),
1076       base::OptionalToPtr(crop_rect)));
1077 }
1078
1079 void PaintOpReader::ReadImagePaintFilter(
1080     sk_sp<PaintFilter>* filter,
1081     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1082   PaintImage image;
1083   Read(&image);
1084   if (!image) {
1085     SetInvalid(DeserializationError::kReadImageFailure);
1086     return;
1087   }
1088
1089   SkRect src_rect;
1090   Read(&src_rect);
1091   SkRect dst_rect;
1092   Read(&dst_rect);
1093   PaintFlags::FilterQuality quality;
1094   Read(&quality);
1095
1096   if (!valid_)
1097     return;
1098   filter->reset(
1099       new ImagePaintFilter(std::move(image), src_rect, dst_rect, quality));
1100 }
1101
1102 void PaintOpReader::ReadRecordPaintFilter(
1103     sk_sp<PaintFilter>* filter,
1104     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1105   bool has_filter = false;
1106   ReadSimple(&has_filter);
1107   if (!has_filter) {
1108     *filter = nullptr;
1109     return;
1110   }
1111
1112   SkRect record_bounds = SkRect::MakeEmpty();
1113   gfx::SizeF raster_scale = {0.f, 0.f};
1114   PaintShader::ScalingBehavior scaling_behavior =
1115       PaintShader::ScalingBehavior::kRasterAtScale;
1116   sk_sp<PaintRecord> record;
1117
1118   ReadSimple(&record_bounds);
1119   ReadSimple(&raster_scale);
1120   if (raster_scale.width() <= 0.f || raster_scale.height() <= 0.f) {
1121     SetInvalid(DeserializationError::kInvalidRasterScale);
1122     return;
1123   }
1124
1125   ReadSimple(&scaling_behavior);
1126   if (!IsValidPaintShaderScalingBehavior(scaling_behavior)) {
1127     SetInvalid(DeserializationError::kInvalidPaintShaderScalingBehavior);
1128     return;
1129   }
1130
1131   // RecordPaintFilter also requires kRasterAtScale to have {1.f, 1.f} as the
1132   // raster_scale, since that is intended for kFixedScale
1133   if (scaling_behavior == PaintShader::ScalingBehavior::kRasterAtScale &&
1134       (raster_scale.width() != 1.f || raster_scale.height() != 1.f)) {
1135     SetInvalid(DeserializationError::kInvalidRasterScale);
1136     return;
1137   }
1138
1139   Read(&record);
1140   if (!valid_)
1141     return;
1142   filter->reset(new RecordPaintFilter(std::move(record), record_bounds,
1143                                       raster_scale, scaling_behavior));
1144 }
1145
1146 void PaintOpReader::ReadMergePaintFilter(
1147     sk_sp<PaintFilter>* filter,
1148     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1149   size_t input_count = 0;
1150   ReadSize(&input_count);
1151
1152   // The minimum size for a serialized filter is 4 bytes (a zero uint32_t to
1153   // indicate a null filter). Make sure the |input_count| doesn't exceed the
1154   // maximum number of filters possible for the remaining data.
1155   const size_t max_filters = remaining_bytes_ / 4u;
1156   if (input_count > max_filters)
1157     SetInvalid(DeserializationError::kPaintFilterHasTooManyInputs);
1158   if (!valid_)
1159     return;
1160   std::vector<sk_sp<PaintFilter>> inputs(input_count);
1161   for (auto& input : inputs)
1162     Read(&input);
1163   if (!valid_)
1164     return;
1165   filter->reset(new MergePaintFilter(inputs.data(),
1166                                      static_cast<int>(input_count),
1167                                      base::OptionalToPtr(crop_rect)));
1168 }
1169
1170 void PaintOpReader::ReadMorphologyPaintFilter(
1171     sk_sp<PaintFilter>* filter,
1172     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1173   MorphologyPaintFilter::MorphType morph_type;
1174   float radius_x = 0;
1175   float radius_y = 0;
1176   sk_sp<PaintFilter> input;
1177   ReadEnum(&morph_type);
1178   Read(&radius_x);
1179   Read(&radius_y);
1180   Read(&input);
1181   if (!valid_)
1182     return;
1183   filter->reset(new MorphologyPaintFilter(morph_type, radius_x, radius_y,
1184                                           std::move(input),
1185                                           base::OptionalToPtr(crop_rect)));
1186 }
1187
1188 void PaintOpReader::ReadOffsetPaintFilter(
1189     sk_sp<PaintFilter>* filter,
1190     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1191   SkScalar dx = 0.f;
1192   SkScalar dy = 0.f;
1193   sk_sp<PaintFilter> input;
1194
1195   Read(&dx);
1196   Read(&dy);
1197   Read(&input);
1198   if (!valid_)
1199     return;
1200   filter->reset(new OffsetPaintFilter(dx, dy, std::move(input),
1201                                       base::OptionalToPtr(crop_rect)));
1202 }
1203
1204 void PaintOpReader::ReadTilePaintFilter(
1205     sk_sp<PaintFilter>* filter,
1206     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1207   SkRect src = SkRect::MakeEmpty();
1208   SkRect dst = SkRect::MakeEmpty();
1209   sk_sp<PaintFilter> input;
1210
1211   Read(&src);
1212   Read(&dst);
1213   Read(&input);
1214   if (!valid_)
1215     return;
1216   filter->reset(new TilePaintFilter(src, dst, std::move(input)));
1217 }
1218
1219 void PaintOpReader::ReadTurbulencePaintFilter(
1220     sk_sp<PaintFilter>* filter,
1221     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1222   TurbulencePaintFilter::TurbulenceType turbulence_type;
1223   SkScalar base_frequency_x = 0.f;
1224   SkScalar base_frequency_y = 0.f;
1225   int num_octaves = 0;
1226   SkScalar seed = 0.f;
1227   SkISize tile_size = SkISize::MakeEmpty();
1228
1229   ReadEnum(&turbulence_type);
1230   Read(&base_frequency_x);
1231   Read(&base_frequency_y);
1232   Read(&num_octaves);
1233   Read(&seed);
1234   ReadSimple(&tile_size);
1235   if (!valid_)
1236     return;
1237   filter->reset(new TurbulencePaintFilter(
1238       turbulence_type, base_frequency_x, base_frequency_y, num_octaves, seed,
1239       &tile_size, base::OptionalToPtr(crop_rect)));
1240 }
1241
1242 void PaintOpReader::ReadShaderPaintFilter(
1243     sk_sp<PaintFilter>* filter,
1244     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1245   using Dither = SkImageFilters::Dither;
1246
1247   sk_sp<PaintShader> shader;
1248   uint8_t alpha = 255;
1249   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kNone;
1250   Dither dither = Dither::kNo;
1251
1252   Read(&shader);
1253   Read(&alpha);
1254   Read(&quality);
1255   ReadEnum<Dither, Dither::kYes>(&dither);
1256
1257   if (!shader || !valid_)
1258     return;
1259
1260   filter->reset(new ShaderPaintFilter(std::move(shader), alpha, quality, dither,
1261                                       base::OptionalToPtr(crop_rect)));
1262 }
1263
1264 void PaintOpReader::ReadMatrixPaintFilter(
1265     sk_sp<PaintFilter>* filter,
1266     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1267   SkMatrix matrix = SkMatrix::I();
1268   PaintFlags::FilterQuality filter_quality = PaintFlags::FilterQuality::kNone;
1269   sk_sp<PaintFilter> input;
1270
1271   Read(&matrix);
1272   Read(&filter_quality);
1273   Read(&input);
1274   if (!valid_)
1275     return;
1276   filter->reset(
1277       new MatrixPaintFilter(matrix, filter_quality, std::move(input)));
1278 }
1279
1280 void PaintOpReader::ReadLightingDistantPaintFilter(
1281     sk_sp<PaintFilter>* filter,
1282     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1283   PaintFilter::LightingType lighting_type;
1284   SkPoint3 direction = SkPoint3::Make(0.f, 0.f, 0.f);
1285   SkColor light_color = SK_ColorBLACK;
1286   SkScalar surface_scale = 0.f;
1287   SkScalar kconstant = 0.f;
1288   SkScalar shininess = 0.f;
1289   sk_sp<PaintFilter> input;
1290
1291   ReadEnum(&lighting_type);
1292   ReadSimple(&direction);
1293   Read(&light_color);
1294   Read(&surface_scale);
1295   Read(&kconstant);
1296   Read(&shininess);
1297   Read(&input);
1298   if (!valid_)
1299     return;
1300   // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
1301   filter->reset(new LightingDistantPaintFilter(
1302       lighting_type, direction, SkColor4f::FromColor(light_color),
1303       surface_scale, kconstant, shininess, std::move(input),
1304       base::OptionalToPtr(crop_rect)));
1305 }
1306
1307 void PaintOpReader::ReadLightingPointPaintFilter(
1308     sk_sp<PaintFilter>* filter,
1309     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1310   PaintFilter::LightingType lighting_type;
1311   SkPoint3 location = SkPoint3::Make(0.f, 0.f, 0.f);
1312   SkColor light_color = SK_ColorBLACK;
1313   SkScalar surface_scale = 0.f;
1314   SkScalar kconstant = 0.f;
1315   SkScalar shininess = 0.f;
1316   sk_sp<PaintFilter> input;
1317
1318   ReadEnum(&lighting_type);
1319   ReadSimple(&location);
1320   Read(&light_color);
1321   Read(&surface_scale);
1322   Read(&kconstant);
1323   Read(&shininess);
1324   Read(&input);
1325   if (!valid_)
1326     return;
1327   // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
1328   filter->reset(new LightingPointPaintFilter(
1329       lighting_type, location, SkColor4f::FromColor(light_color), surface_scale,
1330       kconstant, shininess, std::move(input), base::OptionalToPtr(crop_rect)));
1331 }
1332
1333 void PaintOpReader::ReadLightingSpotPaintFilter(
1334     sk_sp<PaintFilter>* filter,
1335     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1336   PaintFilter::LightingType lighting_type;
1337   SkPoint3 location = SkPoint3::Make(0.f, 0.f, 0.f);
1338   SkPoint3 target = SkPoint3::Make(0.f, 0.f, 0.f);
1339   SkScalar specular_exponent = 0.f;
1340   SkScalar cutoff_angle = 0.f;
1341   SkColor light_color = SK_ColorBLACK;
1342   SkScalar surface_scale = 0.f;
1343   SkScalar kconstant = 0.f;
1344   SkScalar shininess = 0.f;
1345   sk_sp<PaintFilter> input;
1346
1347   ReadEnum(&lighting_type);
1348   ReadSimple(&location);
1349   ReadSimple(&target);
1350   Read(&specular_exponent);
1351   Read(&cutoff_angle);
1352   Read(&light_color);
1353   Read(&surface_scale);
1354   Read(&kconstant);
1355   Read(&shininess);
1356   Read(&input);
1357
1358   if (!valid_)
1359     return;
1360   // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
1361   filter->reset(new LightingSpotPaintFilter(
1362       lighting_type, location, target, specular_exponent, cutoff_angle,
1363       SkColor4f::FromColor(light_color), surface_scale, kconstant, shininess,
1364       std::move(input), base::OptionalToPtr(crop_rect)));
1365 }
1366
1367 void PaintOpReader::ReadStretchPaintFilter(
1368     sk_sp<PaintFilter>* filter,
1369     const absl::optional<PaintFilter::CropRect>& crop_rect) {
1370   SkScalar stretch_x = 0.f;
1371   SkScalar stretch_y = 0.f;
1372   SkScalar width = 0.f;
1373   SkScalar height = 0.f;
1374   sk_sp<PaintFilter> input;
1375
1376   Read(&stretch_x);
1377   Read(&stretch_y);
1378   Read(&width);
1379   Read(&height);
1380   Read(&input);
1381
1382   if (!valid_)
1383     return;
1384   filter->reset(new StretchPaintFilter(stretch_x, stretch_y, width, height,
1385                                        std::move(input),
1386                                        base::OptionalToPtr(crop_rect)));
1387 }
1388
1389 size_t PaintOpReader::Read(sk_sp<PaintRecord>* record) {
1390   size_t size_bytes = 0;
1391   ReadSize(&size_bytes);
1392   AlignMemory(PaintOpBuffer::PaintOpAlign);
1393   if (enable_security_constraints_) {
1394     // Validate that the record was not serialized if security constraints are
1395     // enabled.
1396     if (size_bytes != 0) {
1397       SetInvalid(DeserializationError::kPaintRecordForbidden);
1398       return 0;
1399     }
1400     *record = sk_make_sp<PaintOpBuffer>();
1401     return 0;
1402   }
1403
1404   if (size_bytes > remaining_bytes_)
1405     SetInvalid(
1406         DeserializationError::kInsufficientRemainingBytes_Read_PaintRecord);
1407   if (!valid_)
1408     return 0;
1409
1410   *record = PaintOpBuffer::MakeFromMemory(memory_, size_bytes, options_);
1411   if (!*record) {
1412     SetInvalid(DeserializationError::kPaintOpBufferMakeFromMemoryFailure);
1413     return 0;
1414   }
1415   DidRead(size_bytes);
1416   return size_bytes;
1417 }
1418
1419 void PaintOpReader::Read(SkRegion* region) {
1420   size_t region_bytes = 0;
1421   ReadSize(&region_bytes);
1422   if (region_bytes == 0)
1423     SetInvalid(DeserializationError::kZeroRegionBytes);
1424   if (region_bytes > remaining_bytes_)
1425     SetInvalid(DeserializationError::kInsufficientRemainingBytes_Read_SkRegion);
1426   if (!valid_)
1427     return;
1428   std::unique_ptr<char[]> data(new char[region_bytes]);
1429   ReadData(region_bytes, data.get());
1430   if (!valid_)
1431     return;
1432   size_t result = region->readFromMemory(data.get(), region_bytes);
1433   if (!result)
1434     SetInvalid(DeserializationError::kSkRegionReadFromMemoryFailure);
1435 }
1436
1437 inline void PaintOpReader::DidRead(size_t bytes_read) {
1438   // All data are aligned with PaintOpWriter::Alignment() at least.
1439   size_t aligned_bytes =
1440       base::bits::AlignUp(bytes_read, PaintOpWriter::Alignment());
1441   memory_ += aligned_bytes;
1442   DCHECK_LE(aligned_bytes, remaining_bytes_);
1443   remaining_bytes_ -= aligned_bytes;
1444 }
1445
1446 }  // namespace cc