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

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

Issue 15252004: Make GrGLProgramDesc's key variable length by compacting the effect key array (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: fixes Created 7 years, 7 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 | Annotate | Revision Log
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" 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
robertphillips 2013/05/21 19:22:37 hache -> cache
bsalomon 2013/05/22 14:11:25 Done. (actually hash)
42 // Gets the a checksum of the key. Can be used as a hache value for a fast l ookup 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);
robertphillips 2013/05/21 19:22:37 Is the ~0x3 necessary here?
bsalomon 2013/05/22 14:11:25 No... but I was hoping the compiler would see that
86 return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x 3);
87 }
88
89 bool operator!= (const GrGLProgramDesc& other) const {
90 return !(*this == other);
91 }
92
93 static bool Less(const GrGLProgramDesc& a, const GrGLProgramDesc& b) {
94 return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0;
95 }
96
58 private: 97 private:
59 // Specifies where the initial color comes from before the stages are applie d. 98 // Specifies where the initial color comes from before the stages are applie d.
60 enum ColorInput { 99 enum ColorInput {
61 kSolidWhite_ColorInput, 100 kSolidWhite_ColorInput,
62 kTransBlack_ColorInput, 101 kTransBlack_ColorInput,
63 kAttribute_ColorInput, 102 kAttribute_ColorInput,
64 kUniform_ColorInput, 103 kUniform_ColorInput,
65 104
66 kColorInputCnt 105 kColorInputCnt
67 }; 106 };
(...skipping 21 matching lines...) Expand all
89 switch (co) { 128 switch (co) {
90 case kSecondaryCoverage_CoverageOutput: // fallthru 129 case kSecondaryCoverage_CoverageOutput: // fallthru
91 case kSecondaryCoverageISA_CoverageOutput: 130 case kSecondaryCoverageISA_CoverageOutput:
92 case kSecondaryCoverageISC_CoverageOutput: 131 case kSecondaryCoverageISC_CoverageOutput:
93 return true; 132 return true;
94 default: 133 default:
95 return false; 134 return false;
96 } 135 }
97 } 136 }
98 137
99 /** Non-zero if this stage has an effect */ 138 struct KeyHeader {
100 GrGLEffect::EffectKey fEffectKeys[GrDrawState::kNumStages]; 139 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. 140 // are effects that must read the dst.
110 // Otherwise, 0. 141 // Otherwise, 0.
111 GrGLShaderBuilder::FragPosKey fFragPosKey; // set by GrGLShaderBuil der if there are 142 GrGLShaderBuilder::FragPosKey fFragPosKey; // set by GrGLShaderBuil der if there are
112 // effects that read the fragment position. 143 // effects that read the fragment position.
113 // Otherwise, 0. 144 // Otherwise, 0.
114 145
115 // should the FS discard if the coverage is zero (to avoid stencil manipulat ion) 146 // should the FS discard if the coverage is zero (to avoid stencil manip ulation)
116 SkBool8 fDiscardIfZeroCoverage; 147 SkBool8 fDiscardIfZeroCoverage;
117 148
118 uint8_t fColorInput; // casts to enum ColorIn put 149 uint8_t fColorInput; // casts to enum Col orInput
119 uint8_t fCoverageInput; // casts to enum ColorIn put 150 uint8_t fCoverageInput; // casts to enum Col orInput
120 uint8_t fCoverageOutput; // casts to enum Coverag eOutput 151 uint8_t fCoverageOutput; // casts to enum Cov erageOutput
121 152
122 int8_t fFirstCoverageStage; 153 SkBool8 fEmitsPointSize;
123 SkBool8 fEmitsPointSize; 154 uint8_t fColorFilterXfermode; // casts to enum SkX fermode::Mode
124 uint8_t fColorFilterXfermode; // casts to enum SkXferm ode::Mode
125 155
126 int8_t fPositionAttributeIndex; 156 // To enable experimental geometry shader code (not for use in
127 int8_t fLocalCoordAttributeIndex; 157 // production)
128 int8_t fColorAttributeIndex; 158 #if GR_GL_EXPERIMENTAL_GS
129 int8_t fCoverageAttributeIndex; 159 SkBool8 fExperimentalGS;
160 #endif
161
162 int8_t fPositionAttributeIndex;
163 int8_t fLocalCoordAttributeIndex;
164 int8_t fColorAttributeIndex;
165 int8_t fCoverageAttributeIndex;
166
167 int8_t fColorEffectCnt;
168 int8_t fCoverageEffectCnt;
169 };
170
171 // The key is 1 uint32_t for the length, followed another for the checksum, the header, and then
172 // the effect keys. Everything is fixed length except the effect key array.
173 enum {
174 kLengthOffset = 0,
175 kChecksumOffset = kLengthOffset + sizeof(uint32_t),
176 kHeaderOffset = kChecksumOffset + sizeof(uint32_t),
177 kHeaderSize = SkAlign4(sizeof(KeyHeader)),
178 kEffectKeyOffset = kHeaderOffset + kHeaderSize,
179 };
180
181 template<typename T, size_t OFFSET> T* atOffset() {
182 return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFF SET);
183 }
184
185 template<typename T, size_t OFFSET> const T* atOffset() const {
186 return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET);
187 }
188
189 typedef GrGLEffect::EffectKey EffectKey;
190
191 uint32_t* checksum() { return this->atOffset<uint32_t, kChecksumOffset>(); }
192 KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); }
193 EffectKey* effectKeys() { return this->atOffset<EffectKey, kEffectKeyOffset> (); }
194
195 const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHead erOffset>(); }
196 const EffectKey* getEffectKeys() const { return this->atOffset<EffectKey, kE ffectKeyOffset>(); }
197
198 static size_t KeyLength(int effectCnt) {
199 GR_STATIC_ASSERT(!(sizeof(EffectKey) & 0x3));
200 return kEffectKeyOffset + effectCnt * sizeof(EffectKey);
201 }
202
203 enum {
204 kMaxPreallocEffects = 16,
205 kPreAllocSize = kEffectKeyOffset + kMaxPreallocEffects * sizeof(EffectK ey),
206 };
207
208 SkAutoSMalloc<kPreAllocSize> fKey;
209 bool fInitialized;
130 210
131 // GrGLProgram and GrGLShaderBuilder read the private fields to generate cod e. TODO: Move all 211 // 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). 212 // code generation to GrGLShaderBuilder (and maybe add getters rather than f riending).
133 friend class GrGLProgram; 213 friend class GrGLProgram;
134 friend class GrGLShaderBuilder; 214 friend class GrGLShaderBuilder;
135 }; 215 };
136 216
137 #endif 217 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698