123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <utility>
- #include "cc/paint/paint_flags.h"
- #include "base/notreached.h"
- #include "cc/paint/paint_filter.h"
- #include "cc/paint/paint_op_buffer.h"
- #include "cc/paint/paint_op_writer.h"
- #include "cc/paint/paint_shader.h"
- namespace {
- static bool affects_alpha(const SkColorFilter* cf) {
- return cf && !cf->isAlphaUnchanged();
- }
- } // namespace
- namespace cc {
- PaintFlags::PaintFlags() {
- // Match SkPaint defaults.
- bitfields_uint_ = 0u;
- bitfields_.cap_type_ = SkPaint::kDefault_Cap;
- bitfields_.join_type_ = SkPaint::kDefault_Join;
- bitfields_.style_ = SkPaint::kFill_Style;
- bitfields_.filter_quality_ =
- static_cast<int>(PaintFlags::FilterQuality::kNone);
- static_assert(sizeof(bitfields_) <= sizeof(bitfields_uint_),
- "Too many bitfields");
- }
- PaintFlags::PaintFlags(const PaintFlags& flags) = default;
- PaintFlags::PaintFlags(PaintFlags&& other) = default;
- PaintFlags::~PaintFlags() {
- // TODO(enne): non-default dtor to investigate http://crbug.com/790915
- // Sanity check accessing this object doesn't crash.
- blend_mode_ = static_cast<uint32_t>(SkBlendMode::kLastMode);
- // Free refcounted objects one by one.
- path_effect_.reset();
- shader_.reset();
- mask_filter_.reset();
- color_filter_.reset();
- draw_looper_.reset();
- image_filter_.reset();
- }
- PaintFlags& PaintFlags::operator=(const PaintFlags& other) = default;
- PaintFlags& PaintFlags::operator=(PaintFlags&& other) = default;
- void PaintFlags::setImageFilter(sk_sp<PaintFilter> filter) {
- image_filter_ = std::move(filter);
- }
- bool PaintFlags::ShaderIsOpaque() const {
- return shader_->IsOpaque();
- }
- void PaintFlags::setShader(sk_sp<PaintShader> shader) {
- shader_ = std::move(shader);
- }
- bool PaintFlags::nothingToDraw() const {
- // Duplicated from SkPaint to avoid having to construct an SkPaint to
- // answer this question.
- if (getLooper())
- return false;
- switch (getBlendMode()) {
- case SkBlendMode::kSrcOver:
- case SkBlendMode::kSrcATop:
- case SkBlendMode::kDstOut:
- case SkBlendMode::kDstOver:
- case SkBlendMode::kPlus:
- if (getAlpha() == 0) {
- return !affects_alpha(color_filter_.get()) && !image_filter_;
- }
- break;
- case SkBlendMode::kDst:
- return true;
- default:
- break;
- }
- return false;
- }
- bool PaintFlags::getFillPath(const SkPath& src,
- SkPath* dst,
- const SkRect* cull_rect,
- SkScalar res_scale) const {
- SkPaint paint = ToSkPaint();
- return paint.getFillPath(src, dst, cull_rect, res_scale);
- }
- bool PaintFlags::IsSimpleOpacity() const {
- uint32_t color = getColor();
- if (SK_ColorTRANSPARENT != SkColorSetA(color, SK_AlphaTRANSPARENT))
- return false;
- if (getBlendMode() != SkBlendMode::kSrcOver)
- return false;
- if (getLooper())
- return false;
- if (getPathEffect())
- return false;
- if (HasShader())
- return false;
- if (getMaskFilter())
- return false;
- if (getColorFilter())
- return false;
- if (getImageFilter())
- return false;
- return true;
- }
- bool PaintFlags::SupportsFoldingAlpha() const {
- if (getBlendMode() != SkBlendMode::kSrcOver)
- return false;
- if (getColorFilter())
- return false;
- if (getImageFilter())
- return false;
- if (getLooper())
- return false;
- return true;
- }
- SkPaint PaintFlags::ToSkPaint() const {
- SkPaint paint;
- paint.setPathEffect(path_effect_);
- if (shader_)
- paint.setShader(shader_->GetSkShader(getFilterQuality()));
- paint.setMaskFilter(mask_filter_);
- paint.setColorFilter(color_filter_);
- if (image_filter_)
- paint.setImageFilter(image_filter_->cached_sk_filter_);
- paint.setColor(color_);
- paint.setStrokeWidth(width_);
- paint.setStrokeMiter(miter_limit_);
- paint.setBlendMode(getBlendMode());
- paint.setAntiAlias(bitfields_.antialias_);
- paint.setDither(bitfields_.dither_);
- paint.setStrokeCap(static_cast<SkPaint::Cap>(getStrokeCap()));
- paint.setStrokeJoin(static_cast<SkPaint::Join>(getStrokeJoin()));
- paint.setStyle(static_cast<SkPaint::Style>(getStyle()));
- return paint;
- }
- SkSamplingOptions PaintFlags::FilterQualityToSkSamplingOptions(
- PaintFlags::FilterQuality filter_quality) {
- switch (filter_quality) {
- case PaintFlags::FilterQuality::kHigh:
- return SkSamplingOptions(SkCubicResampler::CatmullRom());
- case PaintFlags::FilterQuality::kMedium:
- return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNearest);
- case PaintFlags::FilterQuality::kLow:
- return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
- case PaintFlags::FilterQuality::kNone:
- return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
- default:
- NOTREACHED();
- }
- }
- bool PaintFlags::IsValid() const {
- return PaintOp::IsValidPaintFlagsSkBlendMode(getBlendMode());
- }
- bool PaintFlags::operator==(const PaintFlags& other) const {
- // Can't just ToSkPaint and operator== here as SkPaint does pointer
- // comparisons on all the ref'd skia objects on the SkPaint, which
- // is not true after serialization.
- if (getColor() != other.getColor())
- return false;
- if (!PaintOp::AreEqualEvenIfNaN(getStrokeWidth(), other.getStrokeWidth()))
- return false;
- if (!PaintOp::AreEqualEvenIfNaN(getStrokeMiter(), other.getStrokeMiter()))
- return false;
- if (getBlendMode() != other.getBlendMode())
- return false;
- if (getStrokeCap() != other.getStrokeCap())
- return false;
- if (getStrokeJoin() != other.getStrokeJoin())
- return false;
- if (getStyle() != other.getStyle())
- return false;
- if (getFilterQuality() != other.getFilterQuality())
- return false;
- if (!PaintOp::AreSkFlattenablesEqual(getPathEffect().get(),
- other.getPathEffect().get())) {
- return false;
- }
- if (!PaintOp::AreSkFlattenablesEqual(getMaskFilter().get(),
- other.getMaskFilter().get())) {
- return false;
- }
- if (!PaintOp::AreSkFlattenablesEqual(getColorFilter().get(),
- other.getColorFilter().get())) {
- return false;
- }
- if (!PaintOp::AreSkFlattenablesEqual(getLooper().get(),
- other.getLooper().get())) {
- return false;
- }
- if (!getImageFilter() != !other.getImageFilter())
- return false;
- if (getImageFilter() && *getImageFilter() != *other.getImageFilter())
- return false;
- if (!getShader() != !other.getShader())
- return false;
- if (getShader() && *getShader() != *other.getShader())
- return false;
- return true;
- }
- bool PaintFlags::HasDiscardableImages() const {
- return (shader_ && shader_->has_discardable_images()) ||
- (image_filter_ && image_filter_->has_discardable_images());
- }
- size_t PaintFlags::GetSerializedSize() const {
- return sizeof(color_) + sizeof(width_) + sizeof(miter_limit_) +
- sizeof(blend_mode_) + sizeof(bitfields_uint_) +
- PaintOpWriter::GetFlattenableSize(path_effect_.get()) +
- PaintOpWriter::Alignment() +
- PaintOpWriter::GetFlattenableSize(mask_filter_.get()) +
- PaintOpWriter::Alignment() +
- PaintOpWriter::GetFlattenableSize(color_filter_.get()) +
- PaintOpWriter::Alignment() +
- PaintOpWriter::GetFlattenableSize(draw_looper_.get()) +
- PaintFilter::GetFilterSize(image_filter_.get()) +
- PaintShader::GetSerializedSize(shader_.get());
- }
- } // namespace cc
|