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