xref: /aosp_15_r20/external/skia/src/gpu/graphite/KeyContext.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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_KeyContext_DEFINED
9 #define skgpu_graphite_KeyContext_DEFINED
10 
11 #include "include/core/SkImageInfo.h"
12 #include "include/core/SkM44.h"
13 #include "include/core/SkMatrix.h"
14 #include "include/private/SkColorData.h"
15 #include "src/core/SkColorSpaceXformSteps.h"
16 #include "src/gpu/graphite/TextureProxy.h"
17 
18 namespace skgpu::graphite {
19 
20 class Caps;
21 enum class DstReadRequirement;
22 class Recorder;
23 class RuntimeEffectDictionary;
24 class ShaderCodeDictionary;
25 
26 // The key context must always be able to provide a valid ShaderCodeDictionary and
27 // SkRuntimeEffectDictionary. Depending on the calling context it can also supply a
28 // backend-specific resource providing object (e.g., a Recorder).
29 class KeyContext {
30 public:
31     enum class OptimizeSampling : bool { kNo = false, kYes = true };
32     // Constructor for the pre-compile code path (i.e., no Recorder)
KeyContext(const Caps * caps,ShaderCodeDictionary * dict,RuntimeEffectDictionary * rtEffectDict,const SkColorInfo & dstColorInfo)33     KeyContext(const Caps* caps,
34                ShaderCodeDictionary* dict,
35                RuntimeEffectDictionary* rtEffectDict,
36                const SkColorInfo& dstColorInfo)
37             : fDictionary(dict)
38             , fRTEffectDict(rtEffectDict)
39             , fDstColorInfo(dstColorInfo)
40             , fCaps(caps) {}
41 
42     // Constructor for the ExtractPaintData code path (i.e., with a Recorder)
43     KeyContext(Recorder*,
44                const SkM44& local2Dev,
45                const SkColorInfo& dstColorInfo,
46                OptimizeSampling optimizeSampling,
47                const SkColor4f& paintColor);
48 
49     KeyContext(const KeyContext&);
50 
recorder()51     Recorder* recorder() const { return fRecorder; }
52 
caps()53     const Caps* caps() const { return fCaps; }
54 
local2Dev()55     const SkM44& local2Dev() const { return fLocal2Dev; }
localMatrix()56     const SkMatrix* localMatrix() const { return fLocalMatrix; }
57 
dict()58     ShaderCodeDictionary* dict() const { return fDictionary; }
rtEffectDict()59     RuntimeEffectDictionary* rtEffectDict() const { return fRTEffectDict; }
60 
dstColorInfo()61     const SkColorInfo& dstColorInfo() const { return fDstColorInfo; }
62 
paintColor()63     const SkPMColor4f& paintColor() const { return fPaintColor; }
64 
65     enum class Scope {
66         kDefault,
67         kRuntimeEffect,
68     };
69 
scope()70     Scope scope() const { return fScope; }
optimizeSampling()71     OptimizeSampling optimizeSampling() const { return fOptimizeSampling; }
72 
73 protected:
74     Recorder* fRecorder = nullptr;
75     SkM44 fLocal2Dev;
76     SkMatrix* fLocalMatrix = nullptr;
77     ShaderCodeDictionary* fDictionary;
78     RuntimeEffectDictionary* fRTEffectDict;
79     SkColorInfo fDstColorInfo;
80     // Although stored as premul the paint color is actually comprised of an opaque RGB portion
81     // and a separate alpha portion. The two portions will never be used together but are stored
82     // together to reduce the number of uniforms.
83     SkPMColor4f fPaintColor = SK_PMColor4fBLACK;
84     Scope fScope = Scope::kDefault;
85     OptimizeSampling fOptimizeSampling = OptimizeSampling::kNo;
86 
87 private:
88     const Caps* fCaps = nullptr;
89 };
90 
91 class KeyContextWithLocalMatrix : public KeyContext {
92 public:
KeyContextWithLocalMatrix(const KeyContext & other,const SkMatrix & childLM)93     KeyContextWithLocalMatrix(const KeyContext& other, const SkMatrix& childLM)
94             : KeyContext(other) {
95         if (fLocalMatrix) {
96             fStorage = SkMatrix::Concat(childLM, *fLocalMatrix);
97         } else {
98             fStorage = childLM;
99         }
100 
101         fLocalMatrix = &fStorage;
102     }
103 
104 private:
105     KeyContextWithLocalMatrix(const KeyContextWithLocalMatrix&) = delete;
106     KeyContextWithLocalMatrix& operator=(const KeyContextWithLocalMatrix&) = delete;
107 
108     SkMatrix fStorage;
109 };
110 
111 class KeyContextWithColorInfo : public KeyContext {
112 public:
KeyContextWithColorInfo(const KeyContext & other,const SkColorInfo & info)113     KeyContextWithColorInfo(const KeyContext& other, const SkColorInfo& info) : KeyContext(other) {
114         // We want to keep fPaintColor's alpha value but replace the RGB with values in the new
115         // color space
116         SkPMColor4f tmp = fPaintColor;
117         tmp.fA = 1.0f;
118         SkColorSpaceXformSteps(fDstColorInfo, info).apply(tmp.vec());
119         fPaintColor.fR = tmp.fR;
120         fPaintColor.fG = tmp.fG;
121         fPaintColor.fB = tmp.fB;
122         fDstColorInfo = info;
123     }
124 
125 private:
126     KeyContextWithColorInfo(const KeyContextWithColorInfo&) = delete;
127     KeyContextWithColorInfo& operator=(const KeyContextWithColorInfo&) = delete;
128 };
129 
130 class KeyContextWithScope : public KeyContext {
131 public:
KeyContextWithScope(const KeyContext & other,KeyContext::Scope scope)132     KeyContextWithScope(const KeyContext& other, KeyContext::Scope scope) : KeyContext(other) {
133         fScope = scope;
134         // We skip optimized sampling for runtime effects because these might have arbitrary
135         // coordinate sampling.
136         if (fScope == Scope::kRuntimeEffect) {
137             fOptimizeSampling = OptimizeSampling::kNo;
138         }
139     }
140 
141 private:
142     KeyContextWithScope(const KeyContextWithScope&) = delete;
143     KeyContextWithScope& operator=(const KeyContextWithScope&) = delete;
144 };
145 
146 class KeyContextWithCoordClamp : public KeyContext {
147 public:
KeyContextWithCoordClamp(const KeyContext & other)148     KeyContextWithCoordClamp(const KeyContext& other) : KeyContext(other) {
149         // Subtlies in clampling implmentation can lead to texture samples at non pixel aligned
150         // coordinates.
151         fOptimizeSampling = OptimizeSampling::kNo;
152     }
153 
154 private:
155     KeyContextWithCoordClamp(const KeyContextWithScope&) = delete;
156     KeyContextWithCoordClamp& operator=(const KeyContextWithScope&) = delete;
157 };
158 
159 } // namespace skgpu::graphite
160 
161 #endif // skgpu_graphite_KeyContext_DEFINED
162