Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(641)

Side by Side Diff: src/gpu/gl/GrGLProgramDesc.h

Issue 356513003: Step towards variable length effect keys. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweak comment Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
14 #include "GrGpu.h" 13 #include "GrGpu.h"
15 14
16 class GrGpuGL; 15 class GrGpuGL;
17 16
18 #ifdef SK_DEBUG 17 #ifdef SK_DEBUG
19 // Optionally compile the experimental GS code. Set to SK_DEBUG so that debug build bots will 18 // Optionally compile the experimental GS code. Set to SK_DEBUG so that debug build bots will
20 // execute the code. 19 // execute the code.
21 #define GR_GL_EXPERIMENTAL_GS 1 20 #define GR_GL_EXPERIMENTAL_GS 1
22 #else 21 #else
23 #define GR_GL_EXPERIMENTAL_GS 0 22 #define GR_GL_EXPERIMENTAL_GS 0
24 #endif 23 #endif
25 24
26 25
27 /** This class describes a program to generate. It also serves as a program cach e key. Very little 26 /** This class describes a program to generate. It also serves as a program cach e key. Very little
28 of this is GL-specific. There is the generation of GrGLEffect::EffectKeys an d the dst-read part 27 of this is GL-specific. There is the generation of GrGLEffect::EffectKeys an d the dst-read part
29 of the key set by GrGLShaderBuilder. If the interfaces that set those portio ns were abstracted 28 of the key set by GrGLShaderBuilder. If the interfaces that set those portio ns were abstracted
30 to be API-neutral then so could this class. */ 29 to be API-neutral then so could this class. */
31 class GrGLProgramDesc { 30 class GrGLProgramDesc {
32 public: 31 public:
33 GrGLProgramDesc() : fInitialized(false) {} 32 GrGLProgramDesc() {}
34 GrGLProgramDesc(const GrGLProgramDesc& desc) { *this = desc; } 33 GrGLProgramDesc(const GrGLProgramDesc& desc) { *this = desc; }
35 34
36 // Returns this as a uint32_t array to be used as a key in the program cache . 35 // Returns this as a uint32_t array to be used as a key in the program cache .
37 const uint32_t* asKey() const { 36 const uint32_t* asKey() const {
38 SkASSERT(fInitialized); 37 return reinterpret_cast<const uint32_t*>(fKey.begin());
39 return reinterpret_cast<const uint32_t*>(fKey.get());
40 } 38 }
41 39
42 // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. W hen comparing two 40 // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. W hen comparing two
43 // keys the size of either key can be used with memcmp() since the lengths t hemselves begin the 41 // keys the size of either key can be used with memcmp() since the lengths t hemselves begin the
44 // keys and thus the memcmp will exit early if the keys are of different len gths. 42 // keys and thus the memcmp will exit early if the keys are of different len gths.
45 uint32_t keyLength() const { return *this->atOffset<uint32_t, kLengthOffset> (); } 43 uint32_t keyLength() const { return *this->atOffset<uint32_t, kLengthOffset> (); }
46 44
47 // Gets the a checksum of the key. Can be used as a hash value for a fast lo okup in a cache. 45 // Gets the a checksum of the key. Can be used as a hash value for a fast lo okup in a cache.
48 uint32_t getChecksum() const { return *this->atOffset<uint32_t, kChecksumOff set>(); } 46 uint32_t getChecksum() const { return *this->atOffset<uint32_t, kChecksumOff set>(); }
49 47
50 // For unit testing. 48 // For unit testing.
51 void setRandom(SkRandom*, 49 bool setRandom(SkRandom*,
52 const GrGpuGL* gpu, 50 const GrGpuGL* gpu,
53 const GrRenderTarget* dummyDstRenderTarget, 51 const GrRenderTarget* dummyDstRenderTarget,
54 const GrTexture* dummyDstCopyTexture, 52 const GrTexture* dummyDstCopyTexture,
55 const GrEffectStage* stages[], 53 const GrEffectStage* stages[],
56 int numColorStages, 54 int numColorStages,
57 int numCoverageStages, 55 int numCoverageStages,
58 int currAttribIndex); 56 int currAttribIndex);
59 57
60 /** 58 /**
61 * Builds a program descriptor from a GrDrawState. Whether the primitive typ e is points, the 59 * Builds a program descriptor from a GrDrawState. Whether the primitive typ e is points, the
62 * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs. It also 60 * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs. It also
63 * outputs the color and coverage stages referenced by the generated descrip tor. This may 61 * outputs the color and coverage stages referenced by the generated descrip tor. This may
64 * not contain all stages from the draw state and coverage stages from the d rawState may 62 * not contain all stages from the draw state and coverage stages from the d rawState may
65 * be treated as color stages in the output. 63 * be treated as color stages in the output.
66 */ 64 */
67 static void Build(const GrDrawState&, 65 static bool Build(const GrDrawState&,
68 GrGpu::DrawType drawType, 66 GrGpu::DrawType drawType,
69 GrDrawState::BlendOptFlags, 67 GrDrawState::BlendOptFlags,
70 GrBlendCoeff srcCoeff, 68 GrBlendCoeff srcCoeff,
71 GrBlendCoeff dstCoeff, 69 GrBlendCoeff dstCoeff,
72 const GrGpuGL* gpu, 70 const GrGpuGL* gpu,
73 const GrDeviceCoordTexture* dstCopy, 71 const GrDeviceCoordTexture* dstCopy,
74 SkTArray<const GrEffectStage*, true>* outColorStages, 72 SkTArray<const GrEffectStage*, true>* outColorStages,
75 SkTArray<const GrEffectStage*, true>* outCoverageStages, 73 SkTArray<const GrEffectStage*, true>* outCoverageStages,
76 GrGLProgramDesc* outDesc); 74 GrGLProgramDesc* outDesc);
77 75
78 int numColorEffects() const { 76 int numColorEffects() const {
79 SkASSERT(fInitialized);
80 return this->getHeader().fColorEffectCnt; 77 return this->getHeader().fColorEffectCnt;
81 } 78 }
82 79
83 int numCoverageEffects() const { 80 int numCoverageEffects() const {
84 SkASSERT(fInitialized);
85 return this->getHeader().fCoverageEffectCnt; 81 return this->getHeader().fCoverageEffectCnt;
86 } 82 }
87 83
88 int numTotalEffects() const { return this->numColorEffects() + this->numCove rageEffects(); } 84 int numTotalEffects() const { return this->numColorEffects() + this->numCove rageEffects(); }
89 85
90 GrGLProgramDesc& operator= (const GrGLProgramDesc& other); 86 GrGLProgramDesc& operator= (const GrGLProgramDesc& other);
91 87
92 bool operator== (const GrGLProgramDesc& other) const { 88 bool operator== (const GrGLProgramDesc& other) const {
93 SkASSERT(fInitialized && other.fInitialized);
94 // The length is masked as a hint to the compiler that the address will be 4 byte aligned. 89 // The length is masked as a hint to the compiler that the address will be 4 byte aligned.
95 return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x 3); 90 return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x 3);
96 } 91 }
97 92
98 bool operator!= (const GrGLProgramDesc& other) const { 93 bool operator!= (const GrGLProgramDesc& other) const {
99 return !(*this == other); 94 return !(*this == other);
100 } 95 }
101 96
102 static bool Less(const GrGLProgramDesc& a, const GrGLProgramDesc& b) { 97 static bool Less(const GrGLProgramDesc& a, const GrGLProgramDesc& b) {
103 return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0; 98 return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 case kSecondaryCoverage_CoverageOutput: // fallthru 133 case kSecondaryCoverage_CoverageOutput: // fallthru
139 case kSecondaryCoverageISA_CoverageOutput: 134 case kSecondaryCoverageISA_CoverageOutput:
140 case kSecondaryCoverageISC_CoverageOutput: 135 case kSecondaryCoverageISC_CoverageOutput:
141 return true; 136 return true;
142 default: 137 default:
143 return false; 138 return false;
144 } 139 }
145 } 140 }
146 141
147 struct KeyHeader { 142 struct KeyHeader {
148 GrGLShaderBuilder::DstReadKey fDstReadKey; // set by GrGLShaderBuil der if there 143 uint8_t fDstReadKey; // set by GrGLShaderBuil der if there
149 // are effects that must read the dst. 144 // are effects that must read the dst.
150 // Otherwise, 0. 145 // Otherwise, 0.
151 GrGLShaderBuilder::FragPosKey fFragPosKey; // set by GrGLShaderBuil der if there are 146 uint8_t fFragPosKey; // set by GrGLShaderBuil der if there are
152 // effects that read the fragment position. 147 // effects that read the fragment position.
153 // Otherwise, 0. 148 // Otherwise, 0.
154
155 ColorInput fColorInput : 8; 149 ColorInput fColorInput : 8;
156 ColorInput fCoverageInput : 8; 150 ColorInput fCoverageInput : 8;
157 CoverageOutput fCoverageOutput : 8; 151 CoverageOutput fCoverageOutput : 8;
158 152
159 SkBool8 fHasVertexCode; 153 SkBool8 fHasVertexCode;
160 SkBool8 fEmitsPointSize; 154 SkBool8 fEmitsPointSize;
161 155
162 // To enable experimental geometry shader code (not for use in 156 // To enable experimental geometry shader code (not for use in
163 // production) 157 // production)
164 #if GR_GL_EXPERIMENTAL_GS 158 #if GR_GL_EXPERIMENTAL_GS
165 SkBool8 fExperimentalGS; 159 SkBool8 fExperimentalGS;
166 #endif 160 #endif
167 161
168 int8_t fPositionAttributeIndex; 162 int8_t fPositionAttributeIndex;
169 int8_t fLocalCoordAttributeIndex; 163 int8_t fLocalCoordAttributeIndex;
170 int8_t fColorAttributeIndex; 164 int8_t fColorAttributeIndex;
171 int8_t fCoverageAttributeIndex; 165 int8_t fCoverageAttributeIndex;
172 166
173 int8_t fColorEffectCnt; 167 int8_t fColorEffectCnt;
174 int8_t fCoverageEffectCnt; 168 int8_t fCoverageEffectCnt;
175 }; 169 };
176 170
177 // The key is 1 uint32_t for the length, followed another for the checksum, the header, and then 171 // The key, stored in fKey, is composed of five parts:
178 // the effect keys. Everything is fixed length except the effect key array. 172 // 1. uint32_t for total key length.
173 // 2. uint32_t for a checksum.
174 // 3. Header struct defined above.
175 // 4. uint32_t offsets to beginning of every effects' key (see 5).
176 // 5. per-effect keys. Each effect's key is a variable length array of uint3 2_t.
179 enum { 177 enum {
180 kLengthOffset = 0, 178 kLengthOffset = 0,
181 kChecksumOffset = kLengthOffset + sizeof(uint32_t), 179 kChecksumOffset = kLengthOffset + sizeof(uint32_t),
182 kHeaderOffset = kChecksumOffset + sizeof(uint32_t), 180 kHeaderOffset = kChecksumOffset + sizeof(uint32_t),
183 kHeaderSize = SkAlign4(sizeof(KeyHeader)), 181 kHeaderSize = SkAlign4(sizeof(KeyHeader)),
184 kEffectKeyOffset = kHeaderOffset + kHeaderSize, 182 kEffectKeyLengthsOffset = kHeaderOffset + kHeaderSize,
185 }; 183 };
186 184
187 template<typename T, size_t OFFSET> T* atOffset() { 185 template<typename T, size_t OFFSET> T* atOffset() {
188 return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFF SET); 186 return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + O FFSET);
189 } 187 }
190 188
191 template<typename T, size_t OFFSET> const T* atOffset() const { 189 template<typename T, size_t OFFSET> const T* atOffset() const {
192 return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET); 190 return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.begin( )) + OFFSET);
193 } 191 }
194 192
195 typedef GrGLEffect::EffectKey EffectKey; 193 typedef GrBackendEffectFactory::EffectKey EffectKey;
196 194
197 uint32_t* checksum() { return this->atOffset<uint32_t, kChecksumOffset>(); }
198 KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); } 195 KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); }
199 EffectKey* effectKeys() { return this->atOffset<EffectKey, kEffectKeyOffset> (); } 196
197 void finalize();
200 198
201 const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHead erOffset>(); } 199 const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHead erOffset>(); }
202 const EffectKey* getEffectKeys() const { return this->atOffset<EffectKey, kE ffectKeyOffset>(); }
203 200
204 static size_t KeyLength(int effectCnt) { 201 /** Used to provide effects' keys to their emitCode() function. */
205 GR_STATIC_ASSERT(!(sizeof(EffectKey) & 0x3)); 202 class EffectKeyProvider {
206 return kEffectKeyOffset + effectCnt * sizeof(EffectKey); 203 public:
207 } 204 enum EffectType {
205 kColor_EffectType,
206 kCoverage_EffectType,
207 };
208
209 EffectKeyProvider(const GrGLProgramDesc* desc, EffectType type) : fDesc( desc) {
210 // Coverage effect key offsets begin immediately after those of the color effects.
211 fBaseIndex = kColor_EffectType == type ? 0 : desc->numColorEffects() ;
212 }
213
214 EffectKey get(int index) const {
215 const uint32_t* offsets = reinterpret_cast<const uint32_t*>(fDesc->f Key.begin() +
216 kEffectK eyLengthsOffset);
217 uint32_t offset = offsets[fBaseIndex + index];
218 return *reinterpret_cast<const EffectKey*>(fDesc->fKey.begin() + off set);
219 }
220 private:
221 const GrGLProgramDesc* fDesc;
222 int fBaseIndex;
223 };
208 224
209 enum { 225 enum {
210 kMaxPreallocEffects = 16, 226 kMaxPreallocEffects = 8,
211 kPreAllocSize = kEffectKeyOffset + kMaxPreallocEffects * sizeof(EffectK ey), 227 kIntsPerEffect = 4, // This is an overestimate of the average ef fect key size.
228 kPreAllocSize = kEffectKeyLengthsOffset +
229 kMaxPreallocEffects * sizeof(uint32_t) * kIntsPerEffect,
212 }; 230 };
213 231
214 SkAutoSMalloc<kPreAllocSize> fKey; 232 SkSTArray<kPreAllocSize, uint8_t, true> fKey;
215 bool fInitialized;
216 233
217 // GrGLProgram and GrGLShaderBuilder read the private fields to generate cod e. TODO: Move all 234 // GrGLProgram and GrGLShaderBuilder read the private fields to generate cod e. TODO: Split out
218 // code generation to GrGLShaderBuilder (and maybe add getters rather than f riending). 235 // part of GrGLShaderBuilder that is used by effects so that this header doe sn't need to be
236 // visible to GrGLEffects. Then make public accessors as necessary and remov e friends.
219 friend class GrGLProgram; 237 friend class GrGLProgram;
220 friend class GrGLShaderBuilder; 238 friend class GrGLShaderBuilder;
221 friend class GrGLFullShaderBuilder; 239 friend class GrGLFullShaderBuilder;
222 friend class GrGLFragmentOnlyShaderBuilder; 240 friend class GrGLFragmentOnlyShaderBuilder;
223 }; 241 };
224 242
225 #endif 243 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698