Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkColorFilterImageFilter.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
11#include "include/core/SkRect.h"
18#include "src/core/SkRectPriv.h"
21
22#include <optional>
23#include <utility>
24
25namespace {
26
27class SkColorFilterImageFilter final : public SkImageFilter_Base {
28public:
29 SkColorFilterImageFilter(sk_sp<SkColorFilter> cf, sk_sp<SkImageFilter> input)
30 : SkImageFilter_Base(&input, 1)
31 , fColorFilter(std::move(cf)) {}
32
33 SkRect computeFastBounds(const SkRect& bounds) const override;
34
35protected:
36 void flatten(SkWriteBuffer&) const override;
37
38private:
39 friend void ::SkRegisterColorFilterImageFilterFlattenable();
40 SK_FLATTENABLE_HOOKS(SkColorFilterImageFilter)
41
42 skif::FilterResult onFilterImage(const skif::Context&) const override;
43
45 const skif::Mapping& mapping,
46 const skif::LayerSpace<SkIRect>& desiredOutput,
47 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const override;
48
49 std::optional<skif::LayerSpace<SkIRect>> onGetOutputLayerBounds(
50 const skif::Mapping& mapping,
51 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const override;
52
53 MatrixCapability onGetCTMCapability() const override { return MatrixCapability::kComplex; }
54
55 bool onAffectsTransparentBlack() const override {
56 return as_CFB(fColorFilter)->affectsTransparentBlack();
57 }
58
59 bool onIsColorFilterNode(SkColorFilter** filter) const override {
60 SkASSERT(1 == this->countInputs());
61 if (filter) {
62 *filter = SkRef(fColorFilter.get());
63 }
64 return true;
65 }
66
67 sk_sp<SkColorFilter> fColorFilter;
68};
69
70} // end namespace
71
74 const CropRect& cropRect) {
75 if (cf) {
76 SkColorFilter* inputCF;
77 // This is an optimization, as it collapses the hierarchy by just combining the two
78 // colorfilters into a single one, which the new imagefilter will wrap.
79 // NOTE: FilterResults are capable of composing non-adjacent CF nodes together. We could
80 // remove this optimization at construction time, but may as well do the work just once.
81 if (input && input->isColorFilterNode(&inputCF)) {
82 cf = cf->makeComposed(sk_sp<SkColorFilter>(inputCF));
83 input = sk_ref_sp(input->getInput(0));
84 }
85 }
86
87 sk_sp<SkImageFilter> filter = std::move(input);
88 if (cf) {
89 filter = sk_sp<SkImageFilter>(
90 new SkColorFilterImageFilter(std::move(cf), std::move(filter)));
91 }
92 if (cropRect) {
93 filter = SkImageFilters::Crop(*cropRect, std::move(filter));
94 }
95 return filter;
96}
97
99 SK_REGISTER_FLATTENABLE(SkColorFilterImageFilter);
100 // TODO (michaelludwig) - Remove after grace period for SKPs to stop using old name
101 SkFlattenable::Register("SkColorFilterImageFilterImpl", SkColorFilterImageFilter::CreateProc);
102}
103
104sk_sp<SkFlattenable> SkColorFilterImageFilter::CreateProc(SkReadBuffer& buffer) {
106 sk_sp<SkColorFilter> cf(buffer.readColorFilter());
107 return SkImageFilters::ColorFilter(std::move(cf), common.getInput(0), common.cropRect());
108}
109
110void SkColorFilterImageFilter::flatten(SkWriteBuffer& buffer) const {
111 this->SkImageFilter_Base::flatten(buffer);
112 buffer.writeFlattenable(fColorFilter.get());
113}
114
115///////////////////////////////////////////////////////////////////////////////////////////////////
116
117skif::FilterResult SkColorFilterImageFilter::onFilterImage(const skif::Context& ctx) const {
118 return this->getChildOutput(0, ctx).applyColorFilter(ctx, fColorFilter);
119}
120
121skif::LayerSpace<SkIRect> SkColorFilterImageFilter::onGetInputLayerBounds(
122 const skif::Mapping& mapping,
123 const skif::LayerSpace<SkIRect>& desiredOutput,
124 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const {
125 return this->getChildInputLayerBounds(0, mapping, desiredOutput, contentBounds);
126}
127
128std::optional<skif::LayerSpace<SkIRect>> SkColorFilterImageFilter::onGetOutputLayerBounds(
129 const skif::Mapping& mapping,
130 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const {
131 // For bounds calculations, we only need to consider the current node's transparency
132 // effect, since any child's transparency-affecting behavior should be accounted for in
133 // the child's bounds call.
134 if (as_CFB(fColorFilter)->affectsTransparentBlack()) {
136 } else {
137 return this->getChildOutputLayerBounds(0, mapping, contentBounds);
138 }
139}
140
141SkRect SkColorFilterImageFilter::computeFastBounds(const SkRect& bounds) const {
142 // See comment in onGetOutputLayerBounds().
143 if (as_CFB(fColorFilter)->affectsTransparentBlack()) {
145 } else if (this->getInput(0)) {
146 return this->getInput(0)->computeFastBounds(bounds);
147 } else {
148 return bounds;
149 }
150}
#define SkASSERT(cond)
Definition SkAssert.h:116
static SkColorFilterBase * as_CFB(SkColorFilter *filter)
void SkRegisterColorFilterImageFilterFlattenable()
#define SK_FLATTENABLE_HOOKS(type)
#define SK_REGISTER_FLATTENABLE(type)
#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount)
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
static T * SkRef(T *obj)
Definition SkRefCnt.h:132
bool affectsTransparentBlack() const
static void Register(const char name[], Factory)
virtual bool onIsColorFilterNode(SkColorFilter **) const
virtual skif::LayerSpace< SkIRect > onGetInputLayerBounds(const skif::Mapping &mapping, const skif::LayerSpace< SkIRect > &desiredOutput, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const =0
virtual bool onAffectsTransparentBlack() const
void flatten(SkWriteBuffer &) const override
virtual std::optional< skif::LayerSpace< SkIRect > > onGetOutputLayerBounds(const skif::Mapping &mapping, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const =0
virtual skif::FilterResult onFilterImage(const skif::Context &context) const =0
virtual MatrixCapability onGetCTMCapability() const
virtual SkRect computeFastBounds(const SkRect &bounds) const
int countInputs() const
static sk_sp< SkImageFilter > ColorFilter(sk_sp< SkColorFilter > cf, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Crop(const SkRect &rect, SkTileMode tileMode, sk_sp< SkImageFilter > input)
static SkRect MakeLargeS32()
Definition SkRectPriv.h:33
FilterResult applyColorFilter(const Context &ctx, sk_sp< SkColorFilter > colorFilter) const
static const uint8_t buffer[]
Optional< SkRect > bounds
Definition SkRecords.h:189
Definition ref_ptr.h:256