• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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