| 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 |