OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrGLProgramDesc_DEFINED | 8 #ifndef GrGLProgramDesc_DEFINED |
9 #define GrGLProgramDesc_DEFINED | 9 #define GrGLProgramDesc_DEFINED |
10 | 10 |
11 #include "GrGLEffect.h" | 11 #include "GrGLEffect.h" |
12 #include "GrDrawState.h" | 12 #include "GrDrawState.h" |
13 #include "GrGLShaderBuilder.h" | 13 #include "GrGLShaderBuilder.h" |
14 | 14 |
15 class GrGpuGL; | 15 class GrGpuGL; |
16 | 16 |
17 // optionally compile the experimental GS code. Set to GR_DEBUG so that debug bu
ild bots will | 17 // optionally compile the experimental GS code. Set to GR_DEBUG so that debug bu
ild bots will |
18 // execute the code. | 18 // execute the code. |
19 #define GR_GL_EXPERIMENTAL_GS GR_DEBUG | 19 #define GR_GL_EXPERIMENTAL_GS GR_DEBUG |
20 | 20 |
21 | 21 |
22 /** This class describes a program to generate. It also serves as a program cach
e key. Very little | 22 /** This class describes a program to generate. It also serves as a program cach
e key. Very little |
23 of this is GL-specific. There is the generation of GrGLEffect::EffectKeys an
d the dst-read part | 23 of this is GL-specific. There is the generation of GrGLEffect::EffectKeys an
d the dst-read part |
24 of the key set by GrGLShaderBuilder. If the interfaces that set those portio
ns were abstracted | 24 of the key set by GrGLShaderBuilder. If the interfaces that set those portio
ns were abstracted |
25 to be API-neutral then so could this class. */ | 25 to be API-neutral then so could this class. */ |
26 class GrGLProgramDesc { | 26 class GrGLProgramDesc { |
27 public: | 27 public: |
28 GrGLProgramDesc() { | 28 GrGLProgramDesc() : fInitialized(false) {} |
29 // since we use this as part of a key we can't have any uninitialized pa
dding | 29 GrGLProgramDesc(const GrGLProgramDesc& desc) { *this = desc; } |
30 memset(this, 0, sizeof(GrGLProgramDesc)); | 30 |
| 31 // Returns this as a uint32_t array to be used as a key in the program cache
. |
| 32 const uint32_t* asKey() const { |
| 33 GrAssert(fInitialized); |
| 34 return reinterpret_cast<const uint32_t*>(fKey.get()); |
31 } | 35 } |
32 | 36 |
33 // Returns this as a uint32_t array to be used as a key in the program cache | 37 // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. W
hen comparing two |
34 const uint32_t* asKey() const { | 38 // keys the size of either key can be used with memcmp() since the lengths t
hemselves begin the |
35 return reinterpret_cast<const uint32_t*>(this); | 39 // keys and thus the memcmp will exit early if the keys are of different len
gths. |
36 } | 40 uint32_t keyLength() const { return *this->atOffset<uint32_t, kLengthOffset>
(); } |
| 41 |
| 42 // Gets the a checksum of the key. Can be used as a hash value for a fast lo
okup in a cache. |
| 43 uint32_t getChecksum() const { return *this->atOffset<uint32_t, kChecksumOff
set>(); } |
37 | 44 |
38 // For unit testing. | 45 // For unit testing. |
39 void setRandom(SkMWCRandom*, | 46 void setRandom(SkMWCRandom*, |
40 const GrGpuGL* gpu, | 47 const GrGpuGL* gpu, |
41 const GrTexture* dummyDstTexture, | 48 const GrRenderTarget* dummyDstRenderTarget, |
42 const GrEffectStage* stages[GrDrawState::kNumStages], | 49 const GrTexture* dummyDstCopyTexture, |
| 50 const GrEffectStage* stages[], |
| 51 int numColorStages, |
| 52 int numCoverageStages, |
43 int currAttribIndex); | 53 int currAttribIndex); |
44 | 54 |
45 /** | 55 /** |
46 * Builds a program descriptor from a GrDrawState. Whether the primitive typ
e is points, the | 56 * Builds a program descriptor from a GrDrawState. Whether the primitive typ
e is points, the |
47 * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also
inputs. | 57 * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also
inputs. It also |
| 58 * writes a tightly packed array of GrEffectStage* from the drawState. |
48 */ | 59 */ |
49 static void Build(const GrDrawState&, | 60 static void Build(const GrDrawState&, |
50 bool isPoints, | 61 bool isPoints, |
51 GrDrawState::BlendOptFlags, | 62 GrDrawState::BlendOptFlags, |
52 GrBlendCoeff srcCoeff, | 63 GrBlendCoeff srcCoeff, |
53 GrBlendCoeff dstCoeff, | 64 GrBlendCoeff dstCoeff, |
54 const GrGpuGL* gpu, | 65 const GrGpuGL* gpu, |
55 const GrDeviceCoordTexture* dstCopy, | 66 const GrDeviceCoordTexture* dstCopy, |
| 67 const GrEffectStage* outStages[GrDrawState::kNumStages], |
56 GrGLProgramDesc* outDesc); | 68 GrGLProgramDesc* outDesc); |
57 | 69 |
| 70 int numColorEffects() const { |
| 71 GrAssert(fInitialized); |
| 72 return this->getHeader().fColorEffectCnt; |
| 73 } |
| 74 |
| 75 int numCoverageEffects() const { |
| 76 GrAssert(fInitialized); |
| 77 return this->getHeader().fCoverageEffectCnt; |
| 78 } |
| 79 |
| 80 int numTotalEffects() const { return this->numColorEffects() + this->numCove
rageEffects(); } |
| 81 |
| 82 GrGLProgramDesc& operator= (const GrGLProgramDesc& other); |
| 83 |
| 84 bool operator== (const GrGLProgramDesc& other) const { |
| 85 GrAssert(fInitialized && other.fInitialized); |
| 86 // The length is masked as a hint to the compiler that the address will
be 4 byte aligned. |
| 87 return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x
3); |
| 88 } |
| 89 |
| 90 bool operator!= (const GrGLProgramDesc& other) const { |
| 91 return !(*this == other); |
| 92 } |
| 93 |
| 94 static bool Less(const GrGLProgramDesc& a, const GrGLProgramDesc& b) { |
| 95 return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0; |
| 96 } |
| 97 |
58 private: | 98 private: |
59 // Specifies where the initial color comes from before the stages are applie
d. | 99 // Specifies where the initial color comes from before the stages are applie
d. |
60 enum ColorInput { | 100 enum ColorInput { |
61 kSolidWhite_ColorInput, | 101 kSolidWhite_ColorInput, |
62 kTransBlack_ColorInput, | 102 kTransBlack_ColorInput, |
63 kAttribute_ColorInput, | 103 kAttribute_ColorInput, |
64 kUniform_ColorInput, | 104 kUniform_ColorInput, |
65 | 105 |
66 kColorInputCnt | 106 kColorInputCnt |
67 }; | 107 }; |
(...skipping 21 matching lines...) Expand all Loading... |
89 switch (co) { | 129 switch (co) { |
90 case kSecondaryCoverage_CoverageOutput: // fallthru | 130 case kSecondaryCoverage_CoverageOutput: // fallthru |
91 case kSecondaryCoverageISA_CoverageOutput: | 131 case kSecondaryCoverageISA_CoverageOutput: |
92 case kSecondaryCoverageISC_CoverageOutput: | 132 case kSecondaryCoverageISC_CoverageOutput: |
93 return true; | 133 return true; |
94 default: | 134 default: |
95 return false; | 135 return false; |
96 } | 136 } |
97 } | 137 } |
98 | 138 |
99 /** Non-zero if this stage has an effect */ | 139 struct KeyHeader { |
100 GrGLEffect::EffectKey fEffectKeys[GrDrawState::kNumStages]; | 140 GrGLShaderBuilder::DstReadKey fDstReadKey; // set by GrGLShaderBuil
der if there |
101 | |
102 // To enable experimental geometry shader code (not for use in | |
103 // production) | |
104 #if GR_GL_EXPERIMENTAL_GS | |
105 bool fExperimentalGS; | |
106 #endif | |
107 | |
108 GrGLShaderBuilder::DstReadKey fDstReadKey; // set by GrGLShaderBuil
der if there | |
109 // are effects that must
read the dst. | 141 // are effects that must
read the dst. |
110 // Otherwise, 0. | 142 // Otherwise, 0. |
111 GrGLShaderBuilder::FragPosKey fFragPosKey; // set by GrGLShaderBuil
der if there are | 143 GrGLShaderBuilder::FragPosKey fFragPosKey; // set by GrGLShaderBuil
der if there are |
112 // effects that read the
fragment position. | 144 // effects that read the
fragment position. |
113 // Otherwise, 0. | 145 // Otherwise, 0. |
114 | 146 |
115 // should the FS discard if the coverage is zero (to avoid stencil manipulat
ion) | 147 // should the FS discard if the coverage is zero (to avoid stencil manip
ulation) |
116 SkBool8 fDiscardIfZeroCoverage; | 148 SkBool8 fDiscardIfZeroCoverage; |
117 | 149 |
118 uint8_t fColorInput; // casts to enum ColorIn
put | 150 uint8_t fColorInput; // casts to enum Col
orInput |
119 uint8_t fCoverageInput; // casts to enum ColorIn
put | 151 uint8_t fCoverageInput; // casts to enum Col
orInput |
120 uint8_t fCoverageOutput; // casts to enum Coverag
eOutput | 152 uint8_t fCoverageOutput; // casts to enum Cov
erageOutput |
121 | 153 |
122 int8_t fFirstCoverageStage; | 154 SkBool8 fEmitsPointSize; |
123 SkBool8 fEmitsPointSize; | 155 uint8_t fColorFilterXfermode; // casts to enum SkX
fermode::Mode |
124 uint8_t fColorFilterXfermode; // casts to enum SkXferm
ode::Mode | |
125 | 156 |
126 int8_t fPositionAttributeIndex; | 157 // To enable experimental geometry shader code (not for use in |
127 int8_t fLocalCoordAttributeIndex; | 158 // production) |
128 int8_t fColorAttributeIndex; | 159 #if GR_GL_EXPERIMENTAL_GS |
129 int8_t fCoverageAttributeIndex; | 160 SkBool8 fExperimentalGS; |
| 161 #endif |
| 162 |
| 163 int8_t fPositionAttributeIndex; |
| 164 int8_t fLocalCoordAttributeIndex; |
| 165 int8_t fColorAttributeIndex; |
| 166 int8_t fCoverageAttributeIndex; |
| 167 |
| 168 int8_t fColorEffectCnt; |
| 169 int8_t fCoverageEffectCnt; |
| 170 }; |
| 171 |
| 172 // The key is 1 uint32_t for the length, followed another for the checksum,
the header, and then |
| 173 // the effect keys. Everything is fixed length except the effect key array. |
| 174 enum { |
| 175 kLengthOffset = 0, |
| 176 kChecksumOffset = kLengthOffset + sizeof(uint32_t), |
| 177 kHeaderOffset = kChecksumOffset + sizeof(uint32_t), |
| 178 kHeaderSize = SkAlign4(sizeof(KeyHeader)), |
| 179 kEffectKeyOffset = kHeaderOffset + kHeaderSize, |
| 180 }; |
| 181 |
| 182 template<typename T, size_t OFFSET> T* atOffset() { |
| 183 return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFF
SET); |
| 184 } |
| 185 |
| 186 template<typename T, size_t OFFSET> const T* atOffset() const { |
| 187 return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.get())
+ OFFSET); |
| 188 } |
| 189 |
| 190 typedef GrGLEffect::EffectKey EffectKey; |
| 191 |
| 192 uint32_t* checksum() { return this->atOffset<uint32_t, kChecksumOffset>(); } |
| 193 KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); } |
| 194 EffectKey* effectKeys() { return this->atOffset<EffectKey, kEffectKeyOffset>
(); } |
| 195 |
| 196 const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHead
erOffset>(); } |
| 197 const EffectKey* getEffectKeys() const { return this->atOffset<EffectKey, kE
ffectKeyOffset>(); } |
| 198 |
| 199 static size_t KeyLength(int effectCnt) { |
| 200 GR_STATIC_ASSERT(!(sizeof(EffectKey) & 0x3)); |
| 201 return kEffectKeyOffset + effectCnt * sizeof(EffectKey); |
| 202 } |
| 203 |
| 204 enum { |
| 205 kMaxPreallocEffects = 16, |
| 206 kPreAllocSize = kEffectKeyOffset + kMaxPreallocEffects * sizeof(EffectK
ey), |
| 207 }; |
| 208 |
| 209 SkAutoSMalloc<kPreAllocSize> fKey; |
| 210 bool fInitialized; |
130 | 211 |
131 // GrGLProgram and GrGLShaderBuilder read the private fields to generate cod
e. TODO: Move all | 212 // GrGLProgram and GrGLShaderBuilder read the private fields to generate cod
e. TODO: Move all |
132 // code generation to GrGLShaderBuilder (and maybe add getters rather than f
riending). | 213 // code generation to GrGLShaderBuilder (and maybe add getters rather than f
riending). |
133 friend class GrGLProgram; | 214 friend class GrGLProgram; |
134 friend class GrGLShaderBuilder; | 215 friend class GrGLShaderBuilder; |
135 }; | 216 }; |
136 | 217 |
137 #endif | 218 #endif |
OLD | NEW |