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 #ifndef CC_PAINT_PAINT_FLAGS_H_ 6 #define CC_PAINT_PAINT_FLAGS_H_ 7 8 #include "base/compiler_specific.h" 9 #include "cc/paint/paint_export.h" 10 #include "cc/paint/paint_shader.h" 11 #include "third_party/skia/include/core/SkCanvas.h" 12 #include "third_party/skia/include/core/SkColorFilter.h" 13 #include "third_party/skia/include/core/SkDrawLooper.h" 14 #include "third_party/skia/include/core/SkImageFilter.h" 15 #include "third_party/skia/include/core/SkMaskFilter.h" 16 #include "third_party/skia/include/core/SkPaint.h" 17 #include "third_party/skia/include/core/SkPathEffect.h" 18 #include "third_party/skia/include/core/SkShader.h" 19 20 namespace cc { 21 class PaintFilter; 22 23 class CC_PAINT_EXPORT PaintFlags { 24 public: 25 PaintFlags(); 26 PaintFlags(const PaintFlags& flags); 27 PaintFlags(PaintFlags&& other); 28 ~PaintFlags(); 29 30 PaintFlags& operator=(const PaintFlags& other); 31 PaintFlags& operator=(PaintFlags&& other); 32 33 enum Style { 34 kFill_Style = SkPaint::kFill_Style, 35 kStroke_Style = SkPaint::kStroke_Style, 36 }; 37 bool nothingToDraw() const; getStyle()38 ALWAYS_INLINE Style getStyle() const { 39 return static_cast<Style>(bitfields_.style_); 40 } setStyle(Style style)41 ALWAYS_INLINE void setStyle(Style style) { bitfields_.style_ = style; } getColor()42 ALWAYS_INLINE SkColor getColor() const { return color_; } setColor(SkColor color)43 ALWAYS_INLINE void setColor(SkColor color) { color_ = color; } getAlpha()44 ALWAYS_INLINE uint8_t getAlpha() const { return SkColorGetA(color_); } setAlpha(uint8_t a)45 ALWAYS_INLINE void setAlpha(uint8_t a) { 46 color_ = SkColorSetARGB(a, SkColorGetR(color_), SkColorGetG(color_), 47 SkColorGetB(color_)); 48 } setBlendMode(SkBlendMode mode)49 ALWAYS_INLINE void setBlendMode(SkBlendMode mode) { 50 blend_mode_ = static_cast<uint32_t>(mode); 51 } getBlendMode()52 ALWAYS_INLINE SkBlendMode getBlendMode() const { 53 return static_cast<SkBlendMode>(blend_mode_); 54 } isAntiAlias()55 ALWAYS_INLINE bool isAntiAlias() const { return bitfields_.antialias_; } setAntiAlias(bool aa)56 ALWAYS_INLINE void setAntiAlias(bool aa) { bitfields_.antialias_ = aa; } isDither()57 ALWAYS_INLINE bool isDither() const { return bitfields_.dither_; } setDither(bool dither)58 ALWAYS_INLINE void setDither(bool dither) { bitfields_.dither_ = dither; } setFilterQuality(SkFilterQuality quality)59 ALWAYS_INLINE void setFilterQuality(SkFilterQuality quality) { 60 bitfields_.filter_quality_ = quality; 61 } getFilterQuality()62 ALWAYS_INLINE SkFilterQuality getFilterQuality() const { 63 return static_cast<SkFilterQuality>(bitfields_.filter_quality_); 64 } useDarkModeForImage()65 ALWAYS_INLINE bool useDarkModeForImage() const { 66 return bitfields_.use_dark_mode_for_image_; 67 } setUseDarkModeForImage(bool use_dark_mode_for_image)68 ALWAYS_INLINE void setUseDarkModeForImage(bool use_dark_mode_for_image) { 69 bitfields_.use_dark_mode_for_image_ = use_dark_mode_for_image; 70 } getStrokeWidth()71 ALWAYS_INLINE SkScalar getStrokeWidth() const { return width_; } setStrokeWidth(SkScalar width)72 ALWAYS_INLINE void setStrokeWidth(SkScalar width) { width_ = width; } getStrokeMiter()73 ALWAYS_INLINE SkScalar getStrokeMiter() const { return miter_limit_; } setStrokeMiter(SkScalar miter)74 ALWAYS_INLINE void setStrokeMiter(SkScalar miter) { miter_limit_ = miter; } 75 enum Cap { 76 kButt_Cap = SkPaint::kButt_Cap, //!< begin/end contours with no extension 77 kRound_Cap = SkPaint::kRound_Cap, //!< begin/end contours with a 78 //! semi-circle extension 79 kSquare_Cap = SkPaint::kSquare_Cap, //!< begin/end contours with a half 80 //! square extension 81 kLast_Cap = kSquare_Cap, 82 kDefault_Cap = kButt_Cap 83 }; getStrokeCap()84 ALWAYS_INLINE Cap getStrokeCap() const { 85 return static_cast<Cap>(bitfields_.cap_type_); 86 } setStrokeCap(Cap cap)87 ALWAYS_INLINE void setStrokeCap(Cap cap) { bitfields_.cap_type_ = cap; } 88 enum Join { 89 kMiter_Join = SkPaint::kMiter_Join, 90 kRound_Join = SkPaint::kRound_Join, 91 kBevel_Join = SkPaint::kBevel_Join, 92 kLast_Join = kBevel_Join, 93 kDefault_Join = kMiter_Join 94 }; getStrokeJoin()95 ALWAYS_INLINE Join getStrokeJoin() const { 96 return static_cast<Join>(bitfields_.join_type_); 97 } setStrokeJoin(Join join)98 ALWAYS_INLINE void setStrokeJoin(Join join) { bitfields_.join_type_ = join; } 99 getColorFilter()100 ALWAYS_INLINE const sk_sp<SkColorFilter>& getColorFilter() const { 101 return color_filter_; 102 } setColorFilter(sk_sp<SkColorFilter> filter)103 ALWAYS_INLINE void setColorFilter(sk_sp<SkColorFilter> filter) { 104 color_filter_ = std::move(filter); 105 } getMaskFilter()106 ALWAYS_INLINE const sk_sp<SkMaskFilter>& getMaskFilter() const { 107 return mask_filter_; 108 } setMaskFilter(sk_sp<SkMaskFilter> mask)109 ALWAYS_INLINE void setMaskFilter(sk_sp<SkMaskFilter> mask) { 110 mask_filter_ = std::move(mask); 111 } 112 getShader()113 ALWAYS_INLINE const PaintShader* getShader() const { return shader_.get(); } 114 115 // Returns true if the shader has been set on the flags. HasShader()116 ALWAYS_INLINE bool HasShader() const { return !!shader_; } 117 118 // Returns whether the shader is opaque. Note that it is only valid to call 119 // this function if HasShader() returns true. ShaderIsOpaque()120 ALWAYS_INLINE bool ShaderIsOpaque() const { return shader_->IsOpaque(); } 121 setShader(sk_sp<PaintShader> shader)122 ALWAYS_INLINE void setShader(sk_sp<PaintShader> shader) { 123 shader_ = std::move(shader); 124 } 125 getPathEffect()126 ALWAYS_INLINE const sk_sp<SkPathEffect>& getPathEffect() const { 127 return path_effect_; 128 } setPathEffect(sk_sp<SkPathEffect> effect)129 ALWAYS_INLINE void setPathEffect(sk_sp<SkPathEffect> effect) { 130 path_effect_ = std::move(effect); 131 } 132 bool getFillPath(const SkPath& src, 133 SkPath* dst, 134 const SkRect* cull_rect = nullptr, 135 SkScalar res_scale = 1) const; 136 getImageFilter()137 ALWAYS_INLINE const sk_sp<PaintFilter>& getImageFilter() const { 138 return image_filter_; 139 } 140 void setImageFilter(sk_sp<PaintFilter> filter); 141 getLooper()142 ALWAYS_INLINE const sk_sp<SkDrawLooper>& getLooper() const { 143 return draw_looper_; 144 } setLooper(sk_sp<SkDrawLooper> looper)145 ALWAYS_INLINE void setLooper(sk_sp<SkDrawLooper> looper) { 146 draw_looper_ = std::move(looper); 147 } 148 149 // Returns true if this just represents an opacity blend when used as 150 // saveLayer flags, thus the saveLayer can be converted to a saveLayerAlpha. 151 bool IsSimpleOpacity() const; 152 153 // Returns true if this (of a drawOp) allows the sequence 154 // saveLayerAlpha/drawOp/restore to be folded into a single drawOp by baking 155 // the alpha in the saveLayerAlpha into the flags of the drawOp. 156 bool SupportsFoldingAlpha() const; 157 158 // SkPaint does not support loopers, so callers of SkToPaint need 159 // to check for loopers manually (see getLooper()). 160 SkPaint ToSkPaint() const; 161 162 template <typename Proc> DrawToSk(SkCanvas * canvas,Proc proc)163 void DrawToSk(SkCanvas* canvas, Proc proc) const { 164 SkPaint paint = ToSkPaint(); 165 if (const sk_sp<SkDrawLooper>& looper = getLooper()) 166 looper->apply(canvas, paint, proc); 167 else 168 proc(canvas, paint); 169 } 170 171 bool IsValid() const; 172 bool operator==(const PaintFlags& other) const; 173 bool operator!=(const PaintFlags& other) const { return !(*this == other); } 174 175 bool HasDiscardableImages() const; 176 177 size_t GetSerializedSize() const; 178 179 private: 180 friend class PaintOpReader; 181 friend class PaintOpWriter; 182 183 sk_sp<SkPathEffect> path_effect_; 184 sk_sp<PaintShader> shader_; 185 sk_sp<SkMaskFilter> mask_filter_; 186 sk_sp<SkColorFilter> color_filter_; 187 sk_sp<SkDrawLooper> draw_looper_; 188 sk_sp<PaintFilter> image_filter_; 189 190 // Match(ish) SkPaint defaults. SkPaintDefaults is not public, so this 191 // just uses these values and ignores any SkUserConfig overrides. 192 SkColor color_ = SK_ColorBLACK; 193 float width_ = 0.f; 194 float miter_limit_ = 4.f; 195 uint32_t blend_mode_ = static_cast<uint32_t>(SkBlendMode::kSrcOver); 196 197 struct PaintFlagsBitfields { 198 uint32_t antialias_ : 1; 199 uint32_t dither_ : 1; 200 uint32_t cap_type_ : 2; 201 uint32_t join_type_ : 2; 202 uint32_t style_ : 2; 203 uint32_t filter_quality_ : 2; 204 // Specifies whether the compositor should use a dark mode filter when 205 // rasterizing image on the draw op with this PaintFlags. 206 uint32_t use_dark_mode_for_image_ : 1; 207 }; 208 209 union { 210 PaintFlagsBitfields bitfields_; 211 uint32_t bitfields_uint_; 212 }; 213 }; 214 215 } // namespace cc 216 217 #endif // CC_PAINT_PAINT_FLAGS_H_ 218