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