| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CC_PAINT_SCOPED_RASTER_FLAGS_H_ |
| #define CC_PAINT_SCOPED_RASTER_FLAGS_H_ |
| |
| #include <optional> |
| |
| #include "base/memory/stack_allocated.h" |
| #include "cc/paint/decode_stashing_image_provider.h" |
| #include "cc/paint/paint_export.h" |
| #include "cc/paint/paint_flags.h" |
| |
| namespace cc { |
| |
| // A helper class to modify the flags for raster. This includes alpha folding |
| // from SaveLayers and decoding images. |
| class CC_PAINT_EXPORT ScopedRasterFlags { |
| STACK_ALLOCATED(); |
| |
| public: |
| // |flags| and |image_provider| must outlive this class. |
| template <class F> |
| requires(std::is_same_v<F, float>) |
| ScopedRasterFlags(const PaintFlags* flags, |
| ImageProvider* image_provider, |
| const SkMatrix& ctm, |
| int max_texture_size, |
| F alpha) |
| : original_flags_(flags) { |
| if (image_provider) { |
| decode_stashing_image_provider_.emplace(image_provider); |
| |
| // We skip the op if any images fail to decode. |
| DecodeImageShader(ctm); |
| if (decode_failed_) |
| return; |
| DecodeRecordShader(ctm, max_texture_size); |
| if (decode_failed_) |
| return; |
| DecodeFilter(); |
| if (decode_failed_) |
| return; |
| } |
| |
| if (alpha != 1.0f) { |
| DCHECK(flags->SupportsFoldingAlpha()); |
| MutableFlags()->setAlphaf(flags->getAlphaf() * alpha); |
| } |
| |
| AdjustStrokeIfNeeded(ctm); |
| } |
| ScopedRasterFlags(const ScopedRasterFlags&) = delete; |
| ~ScopedRasterFlags(); |
| |
| ScopedRasterFlags& operator=(const ScopedRasterFlags&) = delete; |
| |
| // The usage of these flags should not extend beyond the lifetime of this |
| // object. |
| const PaintFlags* flags() const { |
| if (decode_failed_) |
| return nullptr; |
| |
| return modified_flags_ ? &*modified_flags_ : original_flags_; |
| } |
| |
| private: |
| void DecodeImageShader(const SkMatrix& ctm); |
| void DecodeRecordShader(const SkMatrix& ctm, int max_texture_size); |
| void DecodeFilter(); |
| |
| void AdjustStrokeIfNeeded(const SkMatrix& ctm); |
| |
| PaintFlags* MutableFlags() { |
| if (!modified_flags_) |
| modified_flags_.emplace(*original_flags_); |
| return &*modified_flags_; |
| } |
| |
| const PaintFlags* original_flags_ = nullptr; |
| std::optional<PaintFlags> modified_flags_; |
| std::optional<DecodeStashingImageProvider> decode_stashing_image_provider_; |
| bool decode_failed_ = false; |
| }; |
| |
| } // namespace cc |
| |
| #endif // CC_PAINT_SCOPED_RASTER_FLAGS_H_ |