• 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_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,sk_sp<TextureProxy> dstTexture,SkIPoint dstOffset)33     KeyContext(const Caps* caps,
34                ShaderCodeDictionary* dict,
35                RuntimeEffectDictionary* rtEffectDict,
36                const SkColorInfo& dstColorInfo,
37                sk_sp<TextureProxy> dstTexture,
38                SkIPoint dstOffset)
39             : fDictionary(dict)
40             , fRTEffectDict(rtEffectDict)
41             , fDstColorInfo(dstColorInfo)
42             , fCaps(caps)
43             , fDstTexture(std::move(dstTexture))
44             , fDstOffset(dstOffset) {}
45 
46     // Constructor for the ExtractPaintData code path (i.e., with a Recorder)
47     KeyContext(Recorder*,
48                const SkM44& local2Dev,
49                const SkColorInfo& dstColorInfo,
50                OptimizeSampling optimizeSampling,
51                const SkColor4f& paintColor,
52                sk_sp<TextureProxy> dstTexture,
53                SkIPoint dstOffset);
54 
55     KeyContext(const KeyContext&);
56 
recorder()57     Recorder* recorder() const { return fRecorder; }
58 
caps()59     const Caps* caps() const { return fCaps; }
60 
local2Dev()61     const SkM44& local2Dev() const { return fLocal2Dev; }
localMatrix()62     const SkMatrix* localMatrix() const { return fLocalMatrix; }
63 
dict()64     ShaderCodeDictionary* dict() const { return fDictionary; }
rtEffectDict()65     RuntimeEffectDictionary* rtEffectDict() const { return fRTEffectDict; }
66 
dstColorInfo()67     const SkColorInfo& dstColorInfo() const { return fDstColorInfo; }
68 
69     // Proxy to the destination texture, if it needs to be read from, or null otherwise.
dstTexture()70     sk_sp<TextureProxy> dstTexture() const { return fDstTexture; }
71     // Offset within dstTexture to the top-left corner of the area that needs to be read.
dstOffset()72     SkIPoint dstOffset() const { return fDstOffset; }
73 
paintColor()74     const SkPMColor4f& paintColor() const { return fPaintColor; }
75 
76     enum class Scope {
77         kDefault,
78         kRuntimeEffect,
79     };
80 
scope()81     Scope scope() const { return fScope; }
optimizeSampling()82     OptimizeSampling optimizeSampling() const { return fOptimizeSampling; }
83 
84 protected:
85     Recorder* fRecorder = nullptr;
86     SkM44 fLocal2Dev;
87     SkMatrix* fLocalMatrix = nullptr;
88     ShaderCodeDictionary* fDictionary;
89     RuntimeEffectDictionary* fRTEffectDict;
90     SkColorInfo fDstColorInfo;
91     // Although stored as premul the paint color is actually comprised of an opaque RGB portion
92     // and a separate alpha portion. The two portions will never be used together but are stored
93     // together to reduce the number of uniforms.
94     SkPMColor4f fPaintColor = SK_PMColor4fBLACK;
95     Scope fScope = Scope::kDefault;
96     OptimizeSampling fOptimizeSampling = OptimizeSampling::kNo;
97 
98 private:
99     const Caps* fCaps = nullptr;
100     sk_sp<TextureProxy> fDstTexture;
101     SkIPoint fDstOffset;
102 };
103 
104 class KeyContextWithLocalMatrix : public KeyContext {
105 public:
KeyContextWithLocalMatrix(const KeyContext & other,const SkMatrix & childLM)106     KeyContextWithLocalMatrix(const KeyContext& other, const SkMatrix& childLM)
107             : KeyContext(other) {
108         if (fLocalMatrix) {
109             fStorage = SkMatrix::Concat(childLM, *fLocalMatrix);
110         } else {
111             fStorage = childLM;
112         }
113 
114         fLocalMatrix = &fStorage;
115     }
116 
117 private:
118     KeyContextWithLocalMatrix(const KeyContextWithLocalMatrix&) = delete;
119     KeyContextWithLocalMatrix& operator=(const KeyContextWithLocalMatrix&) = delete;
120 
121     SkMatrix fStorage;
122 };
123 
124 class KeyContextWithColorInfo : public KeyContext {
125 public:
KeyContextWithColorInfo(const KeyContext & other,const SkColorInfo & info)126     KeyContextWithColorInfo(const KeyContext& other, const SkColorInfo& info) : KeyContext(other) {
127         // We want to keep fPaintColor's alpha value but replace the RGB with values in the new
128         // color space
129         SkPMColor4f tmp = fPaintColor;
130         tmp.fA = 1.0f;
131         SkColorSpaceXformSteps(fDstColorInfo, info).apply(tmp.vec());
132         fPaintColor.fR = tmp.fR;
133         fPaintColor.fG = tmp.fG;
134         fPaintColor.fB = tmp.fB;
135         fDstColorInfo = info;
136     }
137 
138 private:
139     KeyContextWithColorInfo(const KeyContextWithColorInfo&) = delete;
140     KeyContextWithColorInfo& operator=(const KeyContextWithColorInfo&) = delete;
141 };
142 
143 class KeyContextWithScope : public KeyContext {
144 public:
KeyContextWithScope(const KeyContext & other,KeyContext::Scope scope)145     KeyContextWithScope(const KeyContext& other, KeyContext::Scope scope) : KeyContext(other) {
146         fScope = scope;
147         // We skip optimized sampling for runtime effects because these might have arbitrary
148         // coordinate sampling.
149         if (fScope == Scope::kRuntimeEffect) {
150             fOptimizeSampling = OptimizeSampling::kNo;
151         }
152     }
153 
154 private:
155     KeyContextWithScope(const KeyContextWithScope&) = delete;
156     KeyContextWithScope& operator=(const KeyContextWithScope&) = delete;
157 };
158 
159 class KeyContextWithCoordClamp : public KeyContext {
160 public:
KeyContextWithCoordClamp(const KeyContext & other)161     KeyContextWithCoordClamp(const KeyContext& other) : KeyContext(other) {
162         // Subtlies in clampling implmentation can lead to texture samples at non pixel aligned
163         // coordinates.
164         fOptimizeSampling = OptimizeSampling::kNo;
165     }
166 
167 private:
168     KeyContextWithCoordClamp(const KeyContextWithScope&) = delete;
169     KeyContextWithCoordClamp& operator=(const KeyContextWithScope&) = delete;
170 };
171 
172 } // namespace skgpu::graphite
173 
174 #endif // skgpu_graphite_KeyContext_DEFINED
175