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 #include "gl/builders/GrGLProgramBuilder.h" | 8 #include "gl/builders/GrGLProgramBuilder.h" |
9 #include "GrGLProgramDesc.h" | 9 #include "GrGLProgramDesc.h" |
10 #include "GrBackendEffectFactory.h" | 10 #include "GrBackendEffectFactory.h" |
11 #include "GrDrawEffect.h" | 11 #include "GrDrawEffect.h" |
12 #include "GrEffect.h" | 12 #include "GrEffect.h" |
13 #include "GrGpuGL.h" | 13 #include "GrGpuGL.h" |
14 #include "GrOptDrawState.h" | |
14 | 15 |
15 #include "SkChecksum.h" | 16 #include "SkChecksum.h" |
16 | 17 |
17 bool GrGLProgramDesc::GetEffectKeyAndUpdateStats(const GrEffectStage& stage, | 18 bool GrGLProgramDesc::GetEffectKeyAndUpdateStats(const GrEffectStage& stage, |
18 const GrGLCaps& caps, | 19 const GrGLCaps& caps, |
19 bool useExplicitLocalCoords, | 20 bool useExplicitLocalCoords, |
20 GrEffectKeyBuilder* b, | 21 GrEffectKeyBuilder* b, |
21 uint16_t* effectKeySize, | 22 uint16_t* effectKeySize, |
22 bool* setTrueIfReadsDst, | 23 bool* setTrueIfReadsDst, |
23 bool* setTrueIfReadsPos, | 24 bool* setTrueIfReadsPos, |
(...skipping 15 matching lines...) Expand all Loading... | |
39 *effectKeySize = 0; // suppresses a warning. | 40 *effectKeySize = 0; // suppresses a warning. |
40 return false; | 41 return false; |
41 } | 42 } |
42 *effectKeySize = SkToU16(size); | 43 *effectKeySize = SkToU16(size); |
43 if (!GrGLProgramEffects::GenEffectMetaKey(drawEffect, caps, b)) { | 44 if (!GrGLProgramEffects::GenEffectMetaKey(drawEffect, caps, b)) { |
44 return false; | 45 return false; |
45 } | 46 } |
46 return true; | 47 return true; |
47 } | 48 } |
48 | 49 |
49 bool GrGLProgramDesc::Build(const GrDrawState& drawState, | 50 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, |
50 GrGpu::DrawType drawType, | 51 GrGpu::DrawType drawType, |
51 GrDrawState::BlendOptFlags blendOpts, | |
52 GrBlendCoeff srcCoeff, | 52 GrBlendCoeff srcCoeff, |
53 GrBlendCoeff dstCoeff, | 53 GrBlendCoeff dstCoeff, |
54 const GrGpuGL* gpu, | 54 const GrGpuGL* gpu, |
55 const GrDeviceCoordTexture* dstCopy, | 55 const GrDeviceCoordTexture* dstCopy, |
56 const GrEffectStage** geometryProcessor, | 56 const GrEffectStage** geometryProcessor, |
57 SkTArray<const GrEffectStage*, true>* colorStages, | 57 SkTArray<const GrEffectStage*, true>* colorStages, |
58 SkTArray<const GrEffectStage*, true>* coverageStages , | 58 SkTArray<const GrEffectStage*, true>* coverageStages , |
59 GrGLProgramDesc* desc) { | 59 GrGLProgramDesc* desc) { |
60 colorStages->reset(); | 60 colorStages->reset(); |
61 coverageStages->reset(); | 61 coverageStages->reset(); |
62 | 62 |
63 // This should already have been caught | 63 bool inputColorIsUsed = optState.inputColorIsUsed(); |
64 SkASSERT(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); | 64 bool inputCoverageIsUsed = optState.inputColorIsUsed(); |
65 | |
66 bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendO ptFlag); | |
bsalomon
2014/09/15 14:04:34
love seeing this code go away.
egdaniel
2014/09/15 17:51:35
more code going away soon!
| |
67 | |
68 bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOpt Flag | | |
69 GrDrawState::kEmitCoverage_BlendOptFl ag)); | |
70 | |
71 int firstEffectiveColorStage = 0; | |
72 bool inputColorIsUsed = true; | |
73 | |
74 if (!skipColor) { | |
75 firstEffectiveColorStage = drawState.numColorStages(); | |
76 while (firstEffectiveColorStage > 0 && inputColorIsUsed) { | |
77 --firstEffectiveColorStage; | |
78 const GrEffect* effect = drawState.getColorStage(firstEffectiveColor Stage).getEffect(); | |
79 inputColorIsUsed = effect->willUseInputColor(); | |
80 } | |
81 } | |
82 | |
83 int firstEffectiveCoverageStage = 0; | |
84 bool inputCoverageIsUsed = true; | |
85 if (!skipCoverage) { | |
86 firstEffectiveCoverageStage = drawState.numCoverageStages(); | |
87 while (firstEffectiveCoverageStage > 0 && inputCoverageIsUsed) { | |
88 --firstEffectiveCoverageStage; | |
89 const GrEffect* effect = drawState.getCoverageStage(firstEffectiveCo verageStage).getEffect(); | |
90 inputCoverageIsUsed = effect->willUseInputColor(); | |
91 } | |
92 } | |
93 | 65 |
94 // The descriptor is used as a cache key. Thus when a field of the | 66 // The descriptor is used as a cache key. Thus when a field of the |
95 // descriptor will not affect program generation (because of the attribute | 67 // descriptor will not affect program generation (because of the attribute |
96 // bindings in use or other descriptor field settings) it should be set | 68 // bindings in use or other descriptor field settings) it should be set |
97 // to a canonical value to avoid duplicate programs with different keys. | 69 // to a canonical value to avoid duplicate programs with different keys. |
98 | 70 |
99 bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute() ; | 71 bool requiresColorAttrib = optState.hasColorVertexAttribute(); |
100 bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAt tribute(); | 72 bool requiresCoverageAttrib = optState.hasCoverageVertexAttribute(); |
101 // we only need the local coords if we're actually going to generate effect code | 73 // we only need the local coords if we're actually going to generate effect code |
102 bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) && | 74 bool requiresLocalCoordAttrib = optState.numTotalStages() > 0 && |
103 drawState.hasLocalCoordAttribute(); | 75 optState.hasLocalCoordAttribute(); |
104 | 76 |
105 bool readsDst = false; | 77 bool readsDst = false; |
106 bool readFragPosition = false; | 78 bool readFragPosition = false; |
107 | 79 |
108 // Provide option for shader programs without vertex shader only when drawin g paths. | 80 // Provide option for shader programs without vertex shader only when drawin g paths. |
109 bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType); | 81 bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType); |
110 | 82 |
111 int numStages = 0; | 83 int numStages = optState.numTotalStages(); |
112 if (drawState.hasGeometryProcessor()) { | 84 |
113 numStages++; | |
114 } | |
115 if (!skipColor) { | |
116 numStages += drawState.numColorStages() - firstEffectiveColorStage; | |
117 } | |
118 if (!skipCoverage) { | |
119 numStages += drawState.numCoverageStages() - firstEffectiveCoverageStage ; | |
120 } | |
121 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); | 85 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); |
122 // Make room for everything up to and including the array of offsets to effe ct keys. | 86 // Make room for everything up to and including the array of offsets to effe ct keys. |
123 desc->fKey.reset(); | 87 desc->fKey.reset(); |
124 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_ t) * numStages); | 88 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_ t) * numStages); |
125 | 89 |
126 int offsetAndSizeIndex = 0; | 90 int offsetAndSizeIndex = 0; |
127 bool effectKeySuccess = true; | 91 bool effectKeySuccess = true; |
128 | 92 |
129 KeyHeader* header = desc->header(); | 93 KeyHeader* header = desc->header(); |
130 // make sure any padding in the header is zeroed. | 94 // make sure any padding in the header is zeroed. |
131 memset(desc->header(), 0, kHeaderSize); | 95 memset(desc->header(), 0, kHeaderSize); |
132 | 96 |
133 // We can only have one effect which touches the vertex shader | 97 // We can only have one effect which touches the vertex shader |
134 if (drawState.hasGeometryProcessor()) { | 98 if (optState.hasGeometryProcessor()) { |
135 uint16_t* offsetAndSize = | 99 uint16_t* offsetAndSize = |
136 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffse tsAndLengthOffset + | 100 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffse tsAndLengthOffset + |
137 offsetAndSizeIndex * 2 * sizeof(uint 16_t)); | 101 offsetAndSizeIndex * 2 * sizeof(uint 16_t)); |
138 | 102 |
139 GrEffectKeyBuilder b(&desc->fKey); | 103 GrEffectKeyBuilder b(&desc->fKey); |
140 uint16_t effectKeySize; | 104 uint16_t effectKeySize; |
141 uint32_t effectOffset = desc->fKey.count(); | 105 uint32_t effectOffset = desc->fKey.count(); |
142 effectKeySuccess |= GetEffectKeyAndUpdateStats( | 106 effectKeySuccess |= GetEffectKeyAndUpdateStats( |
143 *drawState.getGeometryProcessor(), gpu->glCa ps(), | 107 *optState.getGeometryProcessor(), gpu->glCap s(), |
144 requiresLocalCoordAttrib, &b, | 108 requiresLocalCoordAttrib, &b, |
145 &effectKeySize, &readsDst, | 109 &effectKeySize, &readsDst, |
146 &readFragPosition, &requiresVertexShader); | 110 &readFragPosition, &requiresVertexShader); |
147 effectKeySuccess |= (effectOffset <= SK_MaxU16); | 111 effectKeySuccess |= (effectOffset <= SK_MaxU16); |
148 | 112 |
149 offsetAndSize[0] = SkToU16(effectOffset); | 113 offsetAndSize[0] = SkToU16(effectOffset); |
150 offsetAndSize[1] = effectKeySize; | 114 offsetAndSize[1] = effectKeySize; |
151 ++offsetAndSizeIndex; | 115 ++offsetAndSizeIndex; |
152 *geometryProcessor = drawState.getGeometryProcessor(); | 116 *geometryProcessor = optState.getGeometryProcessor(); |
153 SkASSERT(requiresVertexShader); | 117 SkASSERT(requiresVertexShader); |
154 header->fHasGeometryProcessor = true; | 118 header->fHasGeometryProcessor = true; |
155 } | 119 } |
156 | 120 |
157 if (!skipColor) { | 121 for (int s = 0; s < optState.numColorStages(); ++s) { |
158 for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); + +s) { | 122 uint16_t* offsetAndSize = |
159 uint16_t* offsetAndSize = | 123 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn dLengthOffset + |
160 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffse tsAndLengthOffset + | 124 offsetAndSizeIndex * 2 * sizeof(uint16_t )); |
161 offsetAndSizeIndex * 2 * sizeof(uint 16_t)); | |
162 | 125 |
163 bool effectRequiresVertexShader = false; | 126 bool effectRequiresVertexShader = false; |
164 GrEffectKeyBuilder b(&desc->fKey); | 127 GrEffectKeyBuilder b(&desc->fKey); |
165 uint16_t effectKeySize; | 128 uint16_t effectKeySize; |
166 uint32_t effectOffset = desc->fKey.count(); | 129 uint32_t effectOffset = desc->fKey.count(); |
167 effectKeySuccess |= GetEffectKeyAndUpdateStats( | 130 effectKeySuccess |= GetEffectKeyAndUpdateStats( |
168 drawState.getColorStage(s), gpu->glCaps(), | 131 optState.getColorStage(s), gpu->glCaps(), |
169 requiresLocalCoordAttrib, &b, | 132 requiresLocalCoordAttrib, &b, |
170 &effectKeySize, &readsDst, | 133 &effectKeySize, &readsDst, |
171 &readFragPosition, &effectRequiresVertexShad er); | 134 &readFragPosition, &effectRequiresVertexShader); |
172 effectKeySuccess |= (effectOffset <= SK_MaxU16); | 135 effectKeySuccess |= (effectOffset <= SK_MaxU16); |
173 | 136 |
174 offsetAndSize[0] = SkToU16(effectOffset); | 137 offsetAndSize[0] = SkToU16(effectOffset); |
175 offsetAndSize[1] = effectKeySize; | 138 offsetAndSize[1] = effectKeySize; |
176 ++offsetAndSizeIndex; | 139 ++offsetAndSizeIndex; |
177 SkASSERT(!effectRequiresVertexShader); | 140 SkASSERT(!effectRequiresVertexShader); |
178 } | |
179 } | 141 } |
180 if (!skipCoverage) { | |
181 for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStage s(); ++s) { | |
182 uint16_t* offsetAndSize = | |
183 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffse tsAndLengthOffset + | |
184 offsetAndSizeIndex * 2 * sizeof(uint 16_t)); | |
185 | 142 |
186 bool effectRequiresVertexShader = false; | 143 for (int s = 0; s < optState.numCoverageStages(); ++s) { |
187 GrEffectKeyBuilder b(&desc->fKey); | 144 uint16_t* offsetAndSize = |
188 uint16_t effectKeySize; | 145 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn dLengthOffset + |
189 uint32_t effectOffset = desc->fKey.count(); | 146 offsetAndSizeIndex * 2 * sizeof(uint16_t )); |
190 effectKeySuccess |= GetEffectKeyAndUpdateStats( | |
191 drawState.getCoverageStage(s), gpu->glCaps() , | |
192 requiresLocalCoordAttrib, &b, | |
193 &effectKeySize, &readsDst, | |
194 &readFragPosition, &effectRequiresVertexShad er); | |
195 effectKeySuccess |= (effectOffset <= SK_MaxU16); | |
196 | 147 |
197 offsetAndSize[0] = SkToU16(effectOffset); | 148 bool effectRequiresVertexShader = false; |
198 offsetAndSize[1] = effectKeySize; | 149 GrEffectKeyBuilder b(&desc->fKey); |
199 ++offsetAndSizeIndex; | 150 uint16_t effectKeySize; |
200 SkASSERT(!effectRequiresVertexShader); | 151 uint32_t effectOffset = desc->fKey.count(); |
201 } | 152 effectKeySuccess |= GetEffectKeyAndUpdateStats( |
153 optState.getCoverageStage(s), gpu->glCaps(), | |
154 requiresLocalCoordAttrib, &b, | |
155 &effectKeySize, &readsDst, | |
156 &readFragPosition, &effectRequiresVertexShader); | |
157 effectKeySuccess |= (effectOffset <= SK_MaxU16); | |
158 | |
159 offsetAndSize[0] = SkToU16(effectOffset); | |
160 offsetAndSize[1] = effectKeySize; | |
161 ++offsetAndSizeIndex; | |
162 SkASSERT(!effectRequiresVertexShader); | |
202 } | 163 } |
164 | |
203 if (!effectKeySuccess) { | 165 if (!effectKeySuccess) { |
204 desc->fKey.reset(); | 166 desc->fKey.reset(); |
205 return false; | 167 return false; |
206 } | 168 } |
207 | 169 |
208 // Because header is a pointer into the dynamic array, we can't push any new data into the key | 170 // Because header is a pointer into the dynamic array, we can't push any new data into the key |
209 // below here. | 171 // below here. |
210 | 172 |
211 header->fRequiresVertexShader = requiresVertexShader || requiresLocalCoordAt trib; | 173 header->fRequiresVertexShader = requiresVertexShader || requiresLocalCoordAt trib; |
212 header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; | 174 header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; |
213 | 175 |
214 // Currently the experimental GS will only work with triangle prims (and it doesn't do anything | 176 // Currently the experimental GS will only work with triangle prims (and it doesn't do anything |
215 // other than pass through values from the VS to the FS anyway). | 177 // other than pass through values from the VS to the FS anyway). |
216 #if GR_GL_EXPERIMENTAL_GS | 178 #if GR_GL_EXPERIMENTAL_GS |
217 #if 0 | 179 #if 0 |
218 header->fExperimentalGS = gpu->caps().geometryShaderSupport(); | 180 header->fExperimentalGS = gpu->caps().geometryShaderSupport(); |
219 #else | 181 #else |
220 header->fExperimentalGS = false; | 182 header->fExperimentalGS = false; |
221 #endif | 183 #endif |
222 #endif | 184 #endif |
223 bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->p athRenderingSupport(); | 185 bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->p athRenderingSupport(); |
224 | 186 |
225 if (!inputColorIsUsed && !skipColor) { | 187 if (!inputColorIsUsed) { |
226 header->fColorInput = kAllOnes_ColorInput; | 188 header->fColorInput = kAllOnes_ColorInput; |
227 } else if (defaultToUniformInputs && !requiresColorAttrib && inputColorIsUse d) { | 189 } else if (defaultToUniformInputs && !requiresColorAttrib) { |
228 header->fColorInput = kUniform_ColorInput; | 190 header->fColorInput = kUniform_ColorInput; |
229 } else { | 191 } else { |
230 header->fColorInput = kAttribute_ColorInput; | 192 header->fColorInput = kAttribute_ColorInput; |
231 header->fRequiresVertexShader = true; | 193 header->fRequiresVertexShader = true; |
232 } | 194 } |
233 | 195 |
234 bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.ge tCoverageColor(); | 196 bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == optState.get CoverageColor(); |
235 | 197 |
236 if ((covIsSolidWhite || !inputCoverageIsUsed) && !skipCoverage) { | 198 if (covIsSolidWhite || !inputCoverageIsUsed) { |
237 header->fCoverageInput = kAllOnes_ColorInput; | 199 header->fCoverageInput = kAllOnes_ColorInput; |
238 } else if (defaultToUniformInputs && !requiresCoverageAttrib && inputCoverag eIsUsed) { | 200 } else if (defaultToUniformInputs && !requiresCoverageAttrib) { |
239 header->fCoverageInput = kUniform_ColorInput; | 201 header->fCoverageInput = kUniform_ColorInput; |
240 } else { | 202 } else { |
241 header->fCoverageInput = kAttribute_ColorInput; | 203 header->fCoverageInput = kAttribute_ColorInput; |
242 header->fRequiresVertexShader = true; | 204 header->fRequiresVertexShader = true; |
243 } | 205 } |
244 | 206 |
245 if (readsDst) { | 207 if (readsDst) { |
246 SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); | 208 SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); |
247 const GrTexture* dstCopyTexture = NULL; | 209 const GrTexture* dstCopyTexture = NULL; |
248 if (dstCopy) { | 210 if (dstCopy) { |
249 dstCopyTexture = dstCopy->texture(); | 211 dstCopyTexture = dstCopy->texture(); |
250 } | 212 } |
251 header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTe xture, | 213 header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTe xture, |
252 gpu->glCaps()); | 214 gpu->glCaps()); |
253 SkASSERT(0 != header->fDstReadKey); | 215 SkASSERT(0 != header->fDstReadKey); |
254 } else { | 216 } else { |
255 header->fDstReadKey = 0; | 217 header->fDstReadKey = 0; |
256 } | 218 } |
257 | 219 |
258 if (readFragPosition) { | 220 if (readFragPosition) { |
259 header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition( | 221 header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition( |
260 drawState.getRenderTarget(), gpu->glCaps()); | 222 optState.getRenderTarget(), gpu->glCaps()); |
261 } else { | 223 } else { |
262 header->fFragPosKey = 0; | 224 header->fFragPosKey = 0; |
263 } | 225 } |
264 | 226 |
265 // Record attribute indices | 227 // Record attribute indices |
266 header->fPositionAttributeIndex = drawState.positionAttributeIndex(); | 228 header->fPositionAttributeIndex = optState.positionAttributeIndex(); |
267 header->fLocalCoordAttributeIndex = drawState.localCoordAttributeIndex(); | 229 header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex(); |
268 | 230 |
269 // For constant color and coverage we need an attribute with an index beyond those already set | 231 // For constant color and coverage we need an attribute with an index beyond those already set |
270 int availableAttributeIndex = drawState.getVertexAttribCount(); | 232 int availableAttributeIndex = optState.getVertexAttribCount(); |
271 if (requiresColorAttrib) { | 233 if (requiresColorAttrib) { |
272 header->fColorAttributeIndex = drawState.colorVertexAttributeIndex(); | 234 header->fColorAttributeIndex = optState.colorVertexAttributeIndex(); |
273 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) { | 235 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) { |
274 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); | 236 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); |
275 header->fColorAttributeIndex = availableAttributeIndex; | 237 header->fColorAttributeIndex = availableAttributeIndex; |
276 availableAttributeIndex++; | 238 availableAttributeIndex++; |
277 } else { | 239 } else { |
278 header->fColorAttributeIndex = -1; | 240 header->fColorAttributeIndex = -1; |
279 } | 241 } |
280 | 242 |
281 if (requiresCoverageAttrib) { | 243 if (requiresCoverageAttrib) { |
282 header->fCoverageAttributeIndex = drawState.coverageVertexAttributeIndex (); | 244 header->fCoverageAttributeIndex = optState.coverageVertexAttributeIndex( ); |
283 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) { | 245 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) { |
284 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); | 246 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); |
285 header->fCoverageAttributeIndex = availableAttributeIndex; | 247 header->fCoverageAttributeIndex = availableAttributeIndex; |
286 } else { | 248 } else { |
287 header->fCoverageAttributeIndex = -1; | 249 header->fCoverageAttributeIndex = -1; |
288 } | 250 } |
289 | 251 |
290 // Here we deal with whether/how we handle color and coverage separately. | 252 // Here we deal with whether/how we handle color and coverage separately. |
291 | 253 |
292 // Set this default and then possibly change our mind if there is coverage. | 254 // Set this default and then possibly change our mind if there is coverage. |
293 header->fCoverageOutput = kModulate_CoverageOutput; | 255 header->fCoverageOutput = kModulate_CoverageOutput; |
294 | 256 |
295 // If we do have coverage determine whether it matters. | 257 // If we do have coverage determine whether it matters. |
296 bool separateCoverageFromColor = drawState.hasGeometryProcessor(); | 258 bool separateCoverageFromColor = optState.hasGeometryProcessor(); |
297 if (!drawState.isCoverageDrawing() && !skipCoverage && | 259 if (!optState.isCoverageDrawing() && |
298 (drawState.numCoverageStages() > 0 || | 260 (optState.numCoverageStages() > 0 || |
299 drawState.hasGeometryProcessor() || | 261 optState.hasGeometryProcessor() || |
300 requiresCoverageAttrib)) { | 262 requiresCoverageAttrib)) { |
301 | 263 |
302 if (gpu->caps()->dualSourceBlendingSupport() && | 264 if (gpu->caps()->dualSourceBlendingSupport()) { |
303 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | | |
304 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { | |
305 if (kZero_GrBlendCoeff == dstCoeff) { | 265 if (kZero_GrBlendCoeff == dstCoeff) { |
306 // write the coverage value to second color | 266 // write the coverage value to second color |
307 header->fCoverageOutput = kSecondaryCoverage_CoverageOutput; | 267 header->fCoverageOutput = kSecondaryCoverage_CoverageOutput; |
308 separateCoverageFromColor = true; | 268 separateCoverageFromColor = true; |
309 } else if (kSA_GrBlendCoeff == dstCoeff) { | 269 } else if (kSA_GrBlendCoeff == dstCoeff) { |
310 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. | 270 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. |
311 header->fCoverageOutput = kSecondaryCoverageISA_CoverageOutput; | 271 header->fCoverageOutput = kSecondaryCoverageISA_CoverageOutput; |
312 separateCoverageFromColor = true; | 272 separateCoverageFromColor = true; |
313 } else if (kSC_GrBlendCoeff == dstCoeff) { | 273 } else if (kSC_GrBlendCoeff == dstCoeff) { |
314 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. | 274 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. |
315 header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput; | 275 header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput; |
316 separateCoverageFromColor = true; | 276 separateCoverageFromColor = true; |
317 } | 277 } |
318 } else if (readsDst && | 278 } else if (readsDst && |
319 kOne_GrBlendCoeff == srcCoeff && | 279 kOne_GrBlendCoeff == srcCoeff && |
320 kZero_GrBlendCoeff == dstCoeff) { | 280 kZero_GrBlendCoeff == dstCoeff) { |
321 header->fCoverageOutput = kCombineWithDst_CoverageOutput; | 281 header->fCoverageOutput = kCombineWithDst_CoverageOutput; |
322 separateCoverageFromColor = true; | 282 separateCoverageFromColor = true; |
323 } | 283 } |
324 } | 284 } |
325 | 285 |
326 if (!skipColor) { | 286 for (int s = 0; s < optState.numColorStages(); ++s) { |
327 for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); + +s) { | 287 colorStages->push_back(&optState.getColorStage(s)); |
328 colorStages->push_back(&drawState.getColorStage(s)); | |
329 } | |
330 } | 288 } |
331 if (!skipCoverage) { | 289 SkTArray<const GrEffectStage*, true>* array; |
332 SkTArray<const GrEffectStage*, true>* array; | 290 if (separateCoverageFromColor) { |
333 if (separateCoverageFromColor) { | 291 array = coverageStages; |
334 array = coverageStages; | 292 } else { |
335 } else { | 293 array = colorStages; |
336 array = colorStages; | |
337 } | |
338 for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStage s(); ++s) { | |
339 array->push_back(&drawState.getCoverageStage(s)); | |
340 } | |
341 } | 294 } |
295 for (int s = 0; s < optState.numCoverageStages(); ++s) { | |
296 array->push_back(&optState.getCoverageStage(s)); | |
297 } | |
298 | |
342 header->fColorEffectCnt = colorStages->count(); | 299 header->fColorEffectCnt = colorStages->count(); |
343 header->fCoverageEffectCnt = coverageStages->count(); | 300 header->fCoverageEffectCnt = coverageStages->count(); |
344 | 301 |
345 desc->finalize(); | 302 desc->finalize(); |
346 return true; | 303 return true; |
347 } | 304 } |
348 | 305 |
349 void GrGLProgramDesc::finalize() { | 306 void GrGLProgramDesc::finalize() { |
350 int keyLength = fKey.count(); | 307 int keyLength = fKey.count(); |
351 SkASSERT(0 == (keyLength % 4)); | 308 SkASSERT(0 == (keyLength % 4)); |
352 *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength); | 309 *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength); |
353 | 310 |
354 uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>(); | 311 uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>(); |
355 *checksum = 0; | 312 *checksum = 0; |
356 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k eyLength); | 313 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k eyLength); |
357 } | 314 } |
358 | 315 |
359 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { | 316 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { |
360 size_t keyLength = other.keyLength(); | 317 size_t keyLength = other.keyLength(); |
361 fKey.reset(keyLength); | 318 fKey.reset(keyLength); |
362 memcpy(fKey.begin(), other.fKey.begin(), keyLength); | 319 memcpy(fKey.begin(), other.fKey.begin(), keyLength); |
363 return *this; | 320 return *this; |
364 } | 321 } |
OLD | NEW |