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