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