paint_flags.cc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. #include <utility>
  5. #include "cc/paint/paint_flags.h"
  6. #include "base/notreached.h"
  7. #include "cc/paint/paint_filter.h"
  8. #include "cc/paint/paint_op_buffer.h"
  9. #include "cc/paint/paint_op_writer.h"
  10. #include "cc/paint/paint_shader.h"
  11. namespace {
  12. static bool affects_alpha(const SkColorFilter* cf) {
  13. return cf && !cf->isAlphaUnchanged();
  14. }
  15. } // namespace
  16. namespace cc {
  17. PaintFlags::PaintFlags() {
  18. // Match SkPaint defaults.
  19. bitfields_uint_ = 0u;
  20. bitfields_.cap_type_ = SkPaint::kDefault_Cap;
  21. bitfields_.join_type_ = SkPaint::kDefault_Join;
  22. bitfields_.style_ = SkPaint::kFill_Style;
  23. bitfields_.filter_quality_ =
  24. static_cast<int>(PaintFlags::FilterQuality::kNone);
  25. static_assert(sizeof(bitfields_) <= sizeof(bitfields_uint_),
  26. "Too many bitfields");
  27. }
  28. PaintFlags::PaintFlags(const PaintFlags& flags) = default;
  29. PaintFlags::PaintFlags(PaintFlags&& other) = default;
  30. PaintFlags::~PaintFlags() {
  31. // TODO(enne): non-default dtor to investigate http://crbug.com/790915
  32. // Sanity check accessing this object doesn't crash.
  33. blend_mode_ = static_cast<uint32_t>(SkBlendMode::kLastMode);
  34. // Free refcounted objects one by one.
  35. path_effect_.reset();
  36. shader_.reset();
  37. mask_filter_.reset();
  38. color_filter_.reset();
  39. draw_looper_.reset();
  40. image_filter_.reset();
  41. }
  42. PaintFlags& PaintFlags::operator=(const PaintFlags& other) = default;
  43. PaintFlags& PaintFlags::operator=(PaintFlags&& other) = default;
  44. void PaintFlags::setImageFilter(sk_sp<PaintFilter> filter) {
  45. image_filter_ = std::move(filter);
  46. }
  47. bool PaintFlags::ShaderIsOpaque() const {
  48. return shader_->IsOpaque();
  49. }
  50. void PaintFlags::setShader(sk_sp<PaintShader> shader) {
  51. shader_ = std::move(shader);
  52. }
  53. bool PaintFlags::nothingToDraw() const {
  54. // Duplicated from SkPaint to avoid having to construct an SkPaint to
  55. // answer this question.
  56. if (getLooper())
  57. return false;
  58. switch (getBlendMode()) {
  59. case SkBlendMode::kSrcOver:
  60. case SkBlendMode::kSrcATop:
  61. case SkBlendMode::kDstOut:
  62. case SkBlendMode::kDstOver:
  63. case SkBlendMode::kPlus:
  64. if (getAlpha() == 0) {
  65. return !affects_alpha(color_filter_.get()) && !image_filter_;
  66. }
  67. break;
  68. case SkBlendMode::kDst:
  69. return true;
  70. default:
  71. break;
  72. }
  73. return false;
  74. }
  75. bool PaintFlags::getFillPath(const SkPath& src,
  76. SkPath* dst,
  77. const SkRect* cull_rect,
  78. SkScalar res_scale) const {
  79. SkPaint paint = ToSkPaint();
  80. return paint.getFillPath(src, dst, cull_rect, res_scale);
  81. }
  82. bool PaintFlags::IsSimpleOpacity() const {
  83. uint32_t color = getColor();
  84. if (SK_ColorTRANSPARENT != SkColorSetA(color, SK_AlphaTRANSPARENT))
  85. return false;
  86. if (getBlendMode() != SkBlendMode::kSrcOver)
  87. return false;
  88. if (getLooper())
  89. return false;
  90. if (getPathEffect())
  91. return false;
  92. if (HasShader())
  93. return false;
  94. if (getMaskFilter())
  95. return false;
  96. if (getColorFilter())
  97. return false;
  98. if (getImageFilter())
  99. return false;
  100. return true;
  101. }
  102. bool PaintFlags::SupportsFoldingAlpha() const {
  103. if (getBlendMode() != SkBlendMode::kSrcOver)
  104. return false;
  105. if (getColorFilter())
  106. return false;
  107. if (getImageFilter())
  108. return false;
  109. if (getLooper())
  110. return false;
  111. return true;
  112. }
  113. SkPaint PaintFlags::ToSkPaint() const {
  114. SkPaint paint;
  115. paint.setPathEffect(path_effect_);
  116. if (shader_)
  117. paint.setShader(shader_->GetSkShader(getFilterQuality()));
  118. paint.setMaskFilter(mask_filter_);
  119. paint.setColorFilter(color_filter_);
  120. if (image_filter_)
  121. paint.setImageFilter(image_filter_->cached_sk_filter_);
  122. paint.setColor(color_);
  123. paint.setStrokeWidth(width_);
  124. paint.setStrokeMiter(miter_limit_);
  125. paint.setBlendMode(getBlendMode());
  126. paint.setAntiAlias(bitfields_.antialias_);
  127. paint.setDither(bitfields_.dither_);
  128. paint.setStrokeCap(static_cast<SkPaint::Cap>(getStrokeCap()));
  129. paint.setStrokeJoin(static_cast<SkPaint::Join>(getStrokeJoin()));
  130. paint.setStyle(static_cast<SkPaint::Style>(getStyle()));
  131. return paint;
  132. }
  133. SkSamplingOptions PaintFlags::FilterQualityToSkSamplingOptions(
  134. PaintFlags::FilterQuality filter_quality) {
  135. switch (filter_quality) {
  136. case PaintFlags::FilterQuality::kHigh:
  137. return SkSamplingOptions(SkCubicResampler::CatmullRom());
  138. case PaintFlags::FilterQuality::kMedium:
  139. return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNearest);
  140. case PaintFlags::FilterQuality::kLow:
  141. return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
  142. case PaintFlags::FilterQuality::kNone:
  143. return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
  144. default:
  145. NOTREACHED();
  146. }
  147. }
  148. bool PaintFlags::IsValid() const {
  149. return PaintOp::IsValidPaintFlagsSkBlendMode(getBlendMode());
  150. }
  151. bool PaintFlags::operator==(const PaintFlags& other) const {
  152. // Can't just ToSkPaint and operator== here as SkPaint does pointer
  153. // comparisons on all the ref'd skia objects on the SkPaint, which
  154. // is not true after serialization.
  155. if (getColor() != other.getColor())
  156. return false;
  157. if (!PaintOp::AreEqualEvenIfNaN(getStrokeWidth(), other.getStrokeWidth()))
  158. return false;
  159. if (!PaintOp::AreEqualEvenIfNaN(getStrokeMiter(), other.getStrokeMiter()))
  160. return false;
  161. if (getBlendMode() != other.getBlendMode())
  162. return false;
  163. if (getStrokeCap() != other.getStrokeCap())
  164. return false;
  165. if (getStrokeJoin() != other.getStrokeJoin())
  166. return false;
  167. if (getStyle() != other.getStyle())
  168. return false;
  169. if (getFilterQuality() != other.getFilterQuality())
  170. return false;
  171. if (!PaintOp::AreSkFlattenablesEqual(getPathEffect().get(),
  172. other.getPathEffect().get())) {
  173. return false;
  174. }
  175. if (!PaintOp::AreSkFlattenablesEqual(getMaskFilter().get(),
  176. other.getMaskFilter().get())) {
  177. return false;
  178. }
  179. if (!PaintOp::AreSkFlattenablesEqual(getColorFilter().get(),
  180. other.getColorFilter().get())) {
  181. return false;
  182. }
  183. if (!PaintOp::AreSkFlattenablesEqual(getLooper().get(),
  184. other.getLooper().get())) {
  185. return false;
  186. }
  187. if (!getImageFilter() != !other.getImageFilter())
  188. return false;
  189. if (getImageFilter() && *getImageFilter() != *other.getImageFilter())
  190. return false;
  191. if (!getShader() != !other.getShader())
  192. return false;
  193. if (getShader() && *getShader() != *other.getShader())
  194. return false;
  195. return true;
  196. }
  197. bool PaintFlags::HasDiscardableImages() const {
  198. return (shader_ && shader_->has_discardable_images()) ||
  199. (image_filter_ && image_filter_->has_discardable_images());
  200. }
  201. size_t PaintFlags::GetSerializedSize() const {
  202. return sizeof(color_) + sizeof(width_) + sizeof(miter_limit_) +
  203. sizeof(blend_mode_) + sizeof(bitfields_uint_) +
  204. PaintOpWriter::GetFlattenableSize(path_effect_.get()) +
  205. PaintOpWriter::Alignment() +
  206. PaintOpWriter::GetFlattenableSize(mask_filter_.get()) +
  207. PaintOpWriter::Alignment() +
  208. PaintOpWriter::GetFlattenableSize(color_filter_.get()) +
  209. PaintOpWriter::Alignment() +
  210. PaintOpWriter::GetFlattenableSize(draw_looper_.get()) +
  211. PaintFilter::GetFilterSize(image_filter_.get()) +
  212. PaintShader::GetSerializedSize(shader_.get());
  213. }
  214. } // namespace cc