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

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: update 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 is 1 uint32_t for the length, followed another for the checksum, the header, and then
178 // the effect keys. Everything is fixed length except the effect key array. 172 // the effect keys. Everything is fixed length except the effect key array.
179 enum { 173 enum {
180 kLengthOffset = 0, 174 kLengthOffset = 0,
181 kChecksumOffset = kLengthOffset + sizeof(uint32_t), 175 kChecksumOffset = kLengthOffset + sizeof(uint32_t),
182 kHeaderOffset = kChecksumOffset + sizeof(uint32_t), 176 kHeaderOffset = kChecksumOffset + sizeof(uint32_t),
183 kHeaderSize = SkAlign4(sizeof(KeyHeader)), 177 kHeaderSize = SkAlign4(sizeof(KeyHeader)),
184 kEffectKeyOffset = kHeaderOffset + kHeaderSize, 178 kEffectKeyLengthsOffset = kHeaderOffset + kHeaderSize,
185 }; 179 };
186 180
187 template<typename T, size_t OFFSET> T* atOffset() { 181 template<typename T, size_t OFFSET> T* atOffset() {
188 return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFF SET); 182 return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + O FFSET);
189 } 183 }
190 184
191 template<typename T, size_t OFFSET> const T* atOffset() const { 185 template<typename T, size_t OFFSET> const T* atOffset() const {
192 return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET); 186 return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.begin( )) + OFFSET);
193 } 187 }
194 188
195 typedef GrGLEffect::EffectKey EffectKey; 189 typedef GrBackendEffectFactory::EffectKey EffectKey;
196 190
197 uint32_t* checksum() { return this->atOffset<uint32_t, kChecksumOffset>(); }
198 KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); } 191 KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); }
199 EffectKey* effectKeys() { return this->atOffset<EffectKey, kEffectKeyOffset> (); } 192
193 void finalize();
200 194
201 const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHead erOffset>(); } 195 const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHead erOffset>(); }
202 const EffectKey* getEffectKeys() const { return this->atOffset<EffectKey, kE ffectKeyOffset>(); }
203 196
204 static size_t KeyLength(int effectCnt) { 197 /** Used to provide effects' keys to their emitCode() function. */
robertphillips 2014/07/10 12:15:50 // add comment here r.e. the structure of GrGLProg
bsalomon 2014/07/10 17:24:34 Updated the existing comment about the key structu
205 GR_STATIC_ASSERT(!(sizeof(EffectKey) & 0x3)); 198 class EffectKeyProvider {
206 return kEffectKeyOffset + effectCnt * sizeof(EffectKey); 199 public:
207 } 200 enum EffectType {
201 kColor_EffectType,
202 kCoverage_EffectType,
203 };
204
205 EffectKeyProvider(const GrGLProgramDesc* desc, EffectType type) : fDesc( desc) {
robertphillips 2014/07/10 12:15:50 // The coverage effects come after the color effec
bsalomon 2014/07/10 17:24:35 Done.
206 fBaseIndex = kColor_EffectType == type ? 0 : desc->numColorEffects() ;
207 }
208
209 EffectKey get(int index) const {
210 const uint32_t* offsets = reinterpret_cast<const uint32_t*>(fDesc->f Key.begin() +
211 kEffectK eyLengthsOffset);
212 uint32_t offset = offsets[fBaseIndex + index];
213 return *reinterpret_cast<const EffectKey*>(fDesc->fKey.begin() + off set);
214 }
215 private:
216 const GrGLProgramDesc* fDesc;
217 int fBaseIndex;
218 };
208 219
209 enum { 220 enum {
210 kMaxPreallocEffects = 16, 221 kMaxPreallocEffects = 8,
211 kPreAllocSize = kEffectKeyOffset + kMaxPreallocEffects * sizeof(EffectK ey), 222 kIntsPerEffect = 4, // This is an overestimate of the average ef fect key size.
223 kPreAllocSize = kEffectKeyLengthsOffset +
224 kMaxPreallocEffects * sizeof(uint32_t) * kIntsPerEffect,
212 }; 225 };
213 226
214 SkAutoSMalloc<kPreAllocSize> fKey; 227 SkSTArray<kPreAllocSize, uint8_t, true> fKey;
215 bool fInitialized;
216 228
217 // GrGLProgram and GrGLShaderBuilder read the private fields to generate cod e. TODO: Move all 229 // 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). 230 // part of GrGLShaderBuilder that is used by effects so that this header doe sn't need to be
231 // visible to GrGLEffects. Then make public accessors as necessary and remov e friends.
219 friend class GrGLProgram; 232 friend class GrGLProgram;
220 friend class GrGLShaderBuilder; 233 friend class GrGLShaderBuilder;
221 friend class GrGLFullShaderBuilder; 234 friend class GrGLFullShaderBuilder;
222 friend class GrGLFragmentOnlyShaderBuilder; 235 friend class GrGLFragmentOnlyShaderBuilder;
223 }; 236 };
224 237
225 #endif 238 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698