/src/skia/src/gpu/graphite/KeyContext.h
Line | Count | Source (jump to first uncovered line) |
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) |
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 | 0 | , 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 | | |
57 | 0 | Recorder* recorder() const { return fRecorder; } |
58 | | |
59 | 0 | const Caps* caps() const { return fCaps; } |
60 | | |
61 | 0 | const SkM44& local2Dev() const { return fLocal2Dev; } |
62 | 0 | const SkMatrix* localMatrix() const { return fLocalMatrix; } |
63 | | |
64 | 0 | ShaderCodeDictionary* dict() const { return fDictionary; } |
65 | 0 | RuntimeEffectDictionary* rtEffectDict() const { return fRTEffectDict; } |
66 | | |
67 | 0 | const SkColorInfo& dstColorInfo() const { return fDstColorInfo; } |
68 | | |
69 | | // Proxy to the destination texture, if it needs to be read from, or null otherwise. |
70 | 0 | sk_sp<TextureProxy> dstTexture() const { return fDstTexture; } |
71 | | // Offset within dstTexture to the top-left corner of the area that needs to be read. |
72 | 0 | SkIPoint dstOffset() const { return fDstOffset; } |
73 | | |
74 | 0 | const SkPMColor4f& paintColor() const { return fPaintColor; } |
75 | | |
76 | | enum class Scope { |
77 | | kDefault, |
78 | | kRuntimeEffect, |
79 | | }; |
80 | | |
81 | 0 | Scope scope() const { return fScope; } |
82 | 0 | 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: |
106 | | KeyContextWithLocalMatrix(const KeyContext& other, const SkMatrix& childLM) |
107 | 0 | : KeyContext(other) { |
108 | 0 | if (fLocalMatrix) { |
109 | 0 | fStorage = SkMatrix::Concat(childLM, *fLocalMatrix); |
110 | 0 | } else { |
111 | 0 | fStorage = childLM; |
112 | 0 | } |
113 | |
|
114 | 0 | fLocalMatrix = &fStorage; |
115 | 0 | } |
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: |
126 | 0 | 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 | 0 | SkPMColor4f tmp = fPaintColor; |
130 | 0 | tmp.fA = 1.0f; |
131 | 0 | SkColorSpaceXformSteps(fDstColorInfo, info).apply(tmp.vec()); |
132 | 0 | fPaintColor.fR = tmp.fR; |
133 | 0 | fPaintColor.fG = tmp.fG; |
134 | 0 | fPaintColor.fB = tmp.fB; |
135 | 0 | fDstColorInfo = info; |
136 | 0 | } |
137 | | |
138 | | private: |
139 | | KeyContextWithColorInfo(const KeyContextWithColorInfo&) = delete; |
140 | | KeyContextWithColorInfo& operator=(const KeyContextWithColorInfo&) = delete; |
141 | | }; |
142 | | |
143 | | class KeyContextWithScope : public KeyContext { |
144 | | public: |
145 | 0 | KeyContextWithScope(const KeyContext& other, KeyContext::Scope scope) : KeyContext(other) { |
146 | 0 | fScope = scope; |
147 | | // We skip optimized sampling for runtime effects because these might have arbitrary |
148 | | // coordinate sampling. |
149 | 0 | if (fScope == Scope::kRuntimeEffect) { |
150 | 0 | fOptimizeSampling = OptimizeSampling::kNo; |
151 | 0 | } |
152 | 0 | } |
153 | | |
154 | | private: |
155 | | KeyContextWithScope(const KeyContextWithScope&) = delete; |
156 | | KeyContextWithScope& operator=(const KeyContextWithScope&) = delete; |
157 | | }; |
158 | | |
159 | | class KeyContextWithCoordClamp : public KeyContext { |
160 | | public: |
161 | 0 | KeyContextWithCoordClamp(const KeyContext& other) : KeyContext(other) { |
162 | | // Subtlies in clampling implmentation can lead to texture samples at non pixel aligned |
163 | | // coordinates. |
164 | 0 | fOptimizeSampling = OptimizeSampling::kNo; |
165 | 0 | } |
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 |