1 /*
2 * Copyright 2022 Google LLC
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 skgpu_graphite_Precompile_DEFINED
9 #define skgpu_graphite_Precompile_DEFINED
10
11 #include "include/core/SkBlendMode.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/core/SkSpan.h"
14
15 #include <functional>
16 #include <optional>
17 #include <vector>
18
19 class SkRuntimeEffect;
20
21 namespace skgpu::graphite {
22
23 class KeyContext;
24 class PrecompileBasePriv;
25 class UniquePaintParamsID;
26
27 class PrecompileBase : public SkRefCnt {
28 public:
29 enum class Type {
30 kBlender,
31 kColorFilter,
32 kImageFilter,
33 kMaskFilter,
34 kShader,
35 // TODO: add others: kDrawable, kPathEffect (?!)
36 };
37
PrecompileBase(Type type)38 PrecompileBase(Type type) : fType(type) {}
39
type()40 Type type() const { return fType; }
41
42 // TODO: Maybe convert these two to be parameters passed into PrecompileBase from all the
43 // derived classes and then make them non-virtual.
numIntrinsicCombinations()44 virtual int numIntrinsicCombinations() const { return 1; }
numChildCombinations()45 virtual int numChildCombinations() const { return 1; }
46
numCombinations()47 int numCombinations() const {
48 return this->numIntrinsicCombinations() * this->numChildCombinations();
49 }
50
51 // Provides access to functions that aren't part of the public API.
52 PrecompileBasePriv priv();
53 const PrecompileBasePriv priv() const; // NOLINT(readability-const-return-type)
54
55 protected:
56 // In general, derived classes should use AddToKey to select the desired child option from
57 // a vector and then have it added to the key with its reduced/nested child option.
58 template<typename T>
59 static void AddToKey(const KeyContext&,
60 PaintParamsKeyBuilder*,
61 const std::vector<sk_sp<T>>& options,
62 int desiredOption);
63
64 private:
65 friend class PaintOptions;
66 friend class PrecompileBasePriv;
67
isALocalMatrixShader()68 virtual bool isALocalMatrixShader() const { return false; }
69
70 virtual void addToKey(const KeyContext&,
71 int desiredCombination,
72 PaintParamsKeyBuilder*) const = 0;
73
74 Type fType;
75 };
76
77 //--------------------------------------------------------------------------------------------------
78 template<typename T>
AddToKey(const KeyContext & keyContext,PaintParamsKeyBuilder * builder,const std::vector<sk_sp<T>> & options,int desiredOption)79 void PrecompileBase::AddToKey(const KeyContext& keyContext,
80 PaintParamsKeyBuilder* builder,
81 const std::vector<sk_sp<T>>& options,
82 int desiredOption) {
83 for (const sk_sp<T>& option : options) {
84 if (desiredOption < option->numCombinations()) {
85 option->priv().addToKey(keyContext, desiredOption, builder);
86 break;
87 }
88
89 desiredOption -= option->numCombinations();
90 }
91 }
92
93 //--------------------------------------------------------------------------------------------------
94 class PrecompileColorFilter;
95
96 class PrecompileShader : public PrecompileBase {
97 public:
PrecompileShader()98 PrecompileShader() : PrecompileBase(Type::kShader) {}
99
100 sk_sp<PrecompileShader> makeWithLocalMatrix();
101
102 sk_sp<PrecompileShader> makeWithColorFilter(sk_sp<PrecompileColorFilter>);
103 };
104
105 class PrecompileMaskFilter : public PrecompileBase {
106 public:
PrecompileMaskFilter()107 PrecompileMaskFilter() : PrecompileBase(Type::kMaskFilter) {}
108 };
109
110 class PrecompileColorFilter : public PrecompileBase {
111 public:
PrecompileColorFilter()112 PrecompileColorFilter() : PrecompileBase(Type::kColorFilter) {}
113 };
114
115 class PrecompileImageFilter : public PrecompileBase {
116 public:
PrecompileImageFilter()117 PrecompileImageFilter() : PrecompileBase(Type::kImageFilter) {}
118 };
119
120 class PrecompileBlender : public PrecompileBase {
121 public:
PrecompileBlender()122 PrecompileBlender() : PrecompileBase(Type::kBlender) {}
123
asBlendMode()124 virtual std::optional<SkBlendMode> asBlendMode() const { return {}; }
125
126 static sk_sp<PrecompileBlender> Mode(SkBlendMode);
127 };
128
129 //--------------------------------------------------------------------------------------------------
130 class PaintOptionsPriv;
131
132 class PaintOptions {
133 public:
setShaders(SkSpan<const sk_sp<PrecompileShader>> shaders)134 void setShaders(SkSpan<const sk_sp<PrecompileShader>> shaders) {
135 fShaderOptions.assign(shaders.begin(), shaders.end());
136 }
137
setMaskFilters(SkSpan<const sk_sp<PrecompileMaskFilter>> maskFilters)138 void setMaskFilters(SkSpan<const sk_sp<PrecompileMaskFilter>> maskFilters) {
139 fMaskFilterOptions.assign(maskFilters.begin(), maskFilters.end());
140 }
141
setColorFilters(SkSpan<const sk_sp<PrecompileColorFilter>> colorFilters)142 void setColorFilters(SkSpan<const sk_sp<PrecompileColorFilter>> colorFilters) {
143 fColorFilterOptions.assign(colorFilters.begin(), colorFilters.end());
144 }
145
setImageFilters(SkSpan<const sk_sp<PrecompileImageFilter>> imageFilters)146 void setImageFilters(SkSpan<const sk_sp<PrecompileImageFilter>> imageFilters) {
147 fImageFilterOptions.assign(imageFilters.begin(), imageFilters.end());
148 }
149
setBlendModes(SkSpan<SkBlendMode> blendModes)150 void setBlendModes(SkSpan<SkBlendMode> blendModes) {
151 fBlenderOptions.reserve(blendModes.size());
152 for (SkBlendMode bm : blendModes) {
153 fBlenderOptions.emplace_back(PrecompileBlender::Mode(bm));
154 }
155 }
setBlenders(SkSpan<const sk_sp<PrecompileBlender>> blenders)156 void setBlenders(SkSpan<const sk_sp<PrecompileBlender>> blenders) {
157 fBlenderOptions.assign(blenders.begin(), blenders.end());
158 }
159
160 // Provides access to functions that aren't part of the public API.
161 PaintOptionsPriv priv();
162 const PaintOptionsPriv priv() const; // NOLINT(readability-const-return-type)
163
164 private:
165 friend class PaintOptionsPriv;
166
167 int numShaderCombinations() const;
168 int numMaskFilterCombinations() const;
169 int numColorFilterCombinations() const;
170 // TODO: need to decompose imagefilters into component draws
171 int numBlendModeCombinations() const;
172
173 int numCombinations() const;
174 // 'desiredCombination' must be less than the result of the numCombinations call
175 void createKey(const KeyContext&, int desiredCombination,
176 PaintParamsKeyBuilder*, bool addPrimitiveBlender) const;
177 void buildCombinations(
178 const KeyContext&,
179 bool addPrimitiveBlender,
180 const std::function<void(UniquePaintParamsID)>& processCombination) const;
181
182 std::vector<sk_sp<PrecompileShader>> fShaderOptions;
183 std::vector<sk_sp<PrecompileMaskFilter>> fMaskFilterOptions;
184 std::vector<sk_sp<PrecompileColorFilter>> fColorFilterOptions;
185 std::vector<sk_sp<PrecompileImageFilter>> fImageFilterOptions;
186 std::vector<sk_sp<PrecompileBlender>> fBlenderOptions;
187 };
188
189 } // namespace skgpu::graphite
190
191 #endif // skgpu_graphite_Precompile_DEFINED
192