1/*
2 * Copyright 2019 Google Inc.
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
8#ifndef SkSGRenderEffect_DEFINED
9#define SkSGRenderEffect_DEFINED
10
11#include "modules/sksg/include/SkSGEffectNode.h"
12
13#include "include/core/SkBlendMode.h"
14#include "include/core/SkColor.h"
15#include "include/effects/SkImageFilters.h"
16
17#include <memory>
18#include <vector>
19
20// TODO: merge EffectNode.h with this header
21
22class SkImageFilter;
23class SkMaskFilter;
24class SkShader;
25
26namespace sksg {
27
28/**
29 * Shader base class.
30 */
31class Shader : public Node {
32public:
33 ~Shader() override;
34
35 const sk_sp<SkShader>& getShader() const {
36 SkASSERT(!this->hasInval());
37 return fShader;
38 }
39
40protected:
41 Shader();
42
43 SkRect onRevalidate(InvalidationController*, const SkMatrix&) final;
44
45 virtual sk_sp<SkShader> onRevalidateShader() = 0;
46
47private:
48 sk_sp<SkShader> fShader;
49
50 using INHERITED = Node;
51};
52
53/**
54 * Attaches a shader to the render DAG.
55 */
56class ShaderEffect final : public EffectNode {
57public:
58 ~ShaderEffect() override;
59
60 static sk_sp<ShaderEffect> Make(sk_sp<RenderNode> child, sk_sp<Shader> shader = 0);
61
62 void setShader(sk_sp<Shader>);
63
64protected:
65 void onRender(SkCanvas*, const RenderContext*) const override;
66
67 SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
68
69private:
70 ShaderEffect(sk_sp<RenderNode> child, sk_sp<Shader> shader);
71
72 sk_sp<Shader> fShader;
73
74 using INHERITED = EffectNode;
75};
76
77/**
78 * Attaches a mask shader to the render DAG.
79 */
80class MaskShaderEffect final : public EffectNode {
81public:
82 static sk_sp<MaskShaderEffect> Make(sk_sp<RenderNode>, sk_sp<SkShader> = nullptr);
83
84 SG_ATTRIBUTE(Shader, sk_sp<SkShader>, fShader)
85
86protected:
87 void onRender(SkCanvas*, const RenderContext*) const override;
88
89private:
90 MaskShaderEffect(sk_sp<RenderNode>, sk_sp<SkShader>);
91
92 sk_sp<SkShader> fShader;
93
94 using INHERITED = EffectNode;
95};
96
97/**
98 * ImageFilter base class.
99 */
100class ImageFilter : public Node {
101public:
102 ~ImageFilter() override;
103
104 const sk_sp<SkImageFilter>& getFilter() const {
105 SkASSERT(!this->hasInval());
106 return fFilter;
107 }
108
109protected:
110 explicit ImageFilter(sk_sp<ImageFilter> input = 0);
111
112 using InputsT = std::vector<sk_sp<ImageFilter>>;
113 explicit ImageFilter(std::unique_ptr<InputsT> inputs);
114
115 SkRect onRevalidate(InvalidationController*, const SkMatrix&) final;
116
117 virtual sk_sp<SkImageFilter> onRevalidateFilter() = 0;
118
119 sk_sp<SkImageFilter> refInput(size_t) const;
120
121private:
122 const std::unique_ptr<InputsT> fInputs;
123
124 sk_sp<SkImageFilter> fFilter;
125
126 using INHERITED = Node;
127};
128
129/**
130 * Attaches an ImageFilter (chain) to the render DAG.
131 */
132class ImageFilterEffect final : public EffectNode {
133public:
134 ~ImageFilterEffect() override;
135
136 static sk_sp<RenderNode> Make(sk_sp<RenderNode> child, sk_sp<ImageFilter> filter);
137
138protected:
139 void onRender(SkCanvas*, const RenderContext*) const override;
140 const RenderNode* onNodeAt(const SkPoint&) const override;
141
142 SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
143
144private:
145 ImageFilterEffect(sk_sp<RenderNode> child, sk_sp<ImageFilter> filter);
146
147 sk_sp<ImageFilter> fImageFilter;
148
149 using INHERITED = EffectNode;
150};
151
152/**
153 * SkDropShadowImageFilter node.
154 */
155class DropShadowImageFilter final : public ImageFilter {
156public:
157 ~DropShadowImageFilter() override;
158
159 static sk_sp<DropShadowImageFilter> Make(sk_sp<ImageFilter> input = nullptr);
160
161 enum class Mode { kShadowAndForeground, kShadowOnly };
162
163 SG_ATTRIBUTE(Offset, SkVector, fOffset)
164 SG_ATTRIBUTE(Sigma , SkVector, fSigma )
165 SG_ATTRIBUTE(Color , SkColor , fColor )
166 SG_ATTRIBUTE(Mode , Mode , fMode )
167
168protected:
169 sk_sp<SkImageFilter> onRevalidateFilter() override;
170
171private:
172 explicit DropShadowImageFilter(sk_sp<ImageFilter> input);
173
174 SkVector fOffset = { 0, 0 },
175 fSigma = { 0, 0 };
176 SkColor fColor = SK_ColorBLACK;
177 Mode fMode = Mode::kShadowAndForeground;
178
179 using INHERITED = ImageFilter;
180};
181
182/**
183 * SkBlurImageFilter node.
184 */
185class BlurImageFilter final : public ImageFilter {
186public:
187 ~BlurImageFilter() override;
188
189 static sk_sp<BlurImageFilter> Make(sk_sp<ImageFilter> input = nullptr);
190
191 SG_ATTRIBUTE(Sigma , SkVector , fSigma )
192 SG_ATTRIBUTE(TileMode, SkTileMode, fTileMode)
193
194protected:
195 sk_sp<SkImageFilter> onRevalidateFilter() override;
196
197private:
198 explicit BlurImageFilter(sk_sp<ImageFilter> input);
199
200 SkVector fSigma = { 0, 0 };
201 SkTileMode fTileMode = SkTileMode::kClamp;
202
203 using INHERITED = ImageFilter;
204};
205
206/**
207 * Applies a SkBlendMode to descendant render nodes.
208 */
209class BlendModeEffect final : public EffectNode {
210public:
211 ~BlendModeEffect() override;
212
213 static sk_sp<BlendModeEffect> Make(sk_sp<RenderNode> child,
214 SkBlendMode = SkBlendMode::kSrcOver);
215
216 SG_ATTRIBUTE(Mode, SkBlendMode, fMode)
217
218protected:
219 void onRender(SkCanvas*, const RenderContext*) const override;
220 const RenderNode* onNodeAt(const SkPoint&) const override;
221
222private:
223 BlendModeEffect(sk_sp<RenderNode>, SkBlendMode);
224
225 SkBlendMode fMode;
226
227 using INHERITED = EffectNode;
228};
229
230} // namespace sksg
231
232#endif // SkSGRenderEffect_DEFINED
233