| 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 #include "GrOptDrawState.h" |
| 14 | 14 |
| 15 #include "SkChecksum.h" | 15 #include "SkChecksum.h" |
| 16 | 16 |
| 17 bool GrGLProgramDesc::GetEffectKeyAndUpdateStats(const GrEffectStage& stage, | 17 bool GrGLProgramDesc::GetEffectKey(const GrEffectStage& stage, const GrGLCaps& c
aps, |
| 18 const GrGLCaps& caps, | 18 bool useExplicitLocalCoords, GrEffectKeyBuild
er* b, |
| 19 bool useExplicitLocalCoords, | 19 uint16_t* effectKeySize) { |
| 20 GrEffectKeyBuilder* b, | |
| 21 uint16_t* effectKeySize, | |
| 22 bool* setTrueIfReadsDst, | |
| 23 bool* setTrueIfReadsPos, | |
| 24 bool* setTrueIfRequiresVertexSh
ader) { | |
| 25 const GrBackendEffectFactory& factory = stage.getEffect()->getFactory(); | 20 const GrBackendEffectFactory& factory = stage.getEffect()->getFactory(); |
| 26 const GrEffect& effect = *stage.getEffect(); | 21 const GrEffect& effect = *stage.getEffect(); |
| 27 if (effect.willReadDstColor()) { | |
| 28 *setTrueIfReadsDst = true; | |
| 29 } | |
| 30 if (effect.willReadFragmentPosition()) { | |
| 31 *setTrueIfReadsPos = true; | |
| 32 } | |
| 33 if (effect.requiresVertexShader()) { | |
| 34 *setTrueIfRequiresVertexShader = true; | |
| 35 } | |
| 36 factory.getGLEffectKey(effect, caps, b); | 22 factory.getGLEffectKey(effect, caps, b); |
| 37 size_t size = b->size(); | 23 size_t size = b->size(); |
| 38 if (size > SK_MaxU16) { | 24 if (size > SK_MaxU16) { |
| 39 *effectKeySize = 0; // suppresses a warning. | 25 *effectKeySize = 0; // suppresses a warning. |
| 40 return false; | 26 return false; |
| 41 } | 27 } |
| 42 *effectKeySize = SkToU16(size); | 28 *effectKeySize = SkToU16(size); |
| 43 if (!GrGLProgramEffects::GenEffectMetaKey(stage, | 29 if (!GrGLProgramEffects::GenEffectMetaKey(stage, |
| 44 useExplicitLocalCoords, | 30 useExplicitLocalCoords, |
| 45 caps, | 31 caps, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 65 bool inputColorIsUsed = optState.inputColorIsUsed(); | 51 bool inputColorIsUsed = optState.inputColorIsUsed(); |
| 66 bool inputCoverageIsUsed = optState.inputColorIsUsed(); | 52 bool inputCoverageIsUsed = optState.inputColorIsUsed(); |
| 67 | 53 |
| 68 // The descriptor is used as a cache key. Thus when a field of the | 54 // The descriptor is used as a cache key. Thus when a field of the |
| 69 // descriptor will not affect program generation (because of the attribute | 55 // descriptor will not affect program generation (because of the attribute |
| 70 // bindings in use or other descriptor field settings) it should be set | 56 // bindings in use or other descriptor field settings) it should be set |
| 71 // to a canonical value to avoid duplicate programs with different keys. | 57 // to a canonical value to avoid duplicate programs with different keys. |
| 72 | 58 |
| 73 bool requiresColorAttrib = optState.hasColorVertexAttribute(); | 59 bool requiresColorAttrib = optState.hasColorVertexAttribute(); |
| 74 bool requiresCoverageAttrib = optState.hasCoverageVertexAttribute(); | 60 bool requiresCoverageAttrib = optState.hasCoverageVertexAttribute(); |
| 75 // we only need the local coords if we're actually going to generate effect
code | 61 bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib(); |
| 76 bool requiresLocalCoordAttrib = optState.numTotalStages() > 0 && | |
| 77 optState.hasLocalCoordAttribute(); | |
| 78 | |
| 79 bool readsDst = false; | |
| 80 bool readFragPosition = false; | |
| 81 | |
| 82 // Provide option for shader programs without vertex shader only when drawin
g paths. | |
| 83 bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType); | |
| 84 | 62 |
| 85 int numStages = optState.numTotalStages(); | 63 int numStages = optState.numTotalStages(); |
| 86 | 64 |
| 87 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); | 65 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); |
| 88 // Make room for everything up to and including the array of offsets to effe
ct keys. | 66 // Make room for everything up to and including the array of offsets to effe
ct keys. |
| 89 desc->fKey.reset(); | 67 desc->fKey.reset(); |
| 90 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_
t) * numStages); | 68 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_
t) * numStages); |
| 91 | 69 |
| 92 int offsetAndSizeIndex = 0; | 70 int offsetAndSizeIndex = 0; |
| 93 bool effectKeySuccess = true; | 71 bool effectKeySuccess = true; |
| 94 | 72 |
| 95 KeyHeader* header = desc->header(); | 73 KeyHeader* header = desc->header(); |
| 96 // make sure any padding in the header is zeroed. | 74 // make sure any padding in the header is zeroed. |
| 97 memset(desc->header(), 0, kHeaderSize); | 75 memset(desc->header(), 0, kHeaderSize); |
| 98 | 76 |
| 99 // We can only have one effect which touches the vertex shader | 77 // We can only have one effect which touches the vertex shader |
| 100 if (optState.hasGeometryProcessor()) { | 78 if (optState.hasGeometryProcessor()) { |
| 101 uint16_t* offsetAndSize = | 79 uint16_t* offsetAndSize = |
| 102 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffse
tsAndLengthOffset + | 80 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffse
tsAndLengthOffset + |
| 103 offsetAndSizeIndex * 2 * sizeof(uint
16_t)); | 81 offsetAndSizeIndex * 2 * sizeof(uint
16_t)); |
| 104 | 82 |
| 105 GrEffectKeyBuilder b(&desc->fKey); | 83 GrEffectKeyBuilder b(&desc->fKey); |
| 106 uint16_t effectKeySize; | 84 uint16_t effectKeySize; |
| 107 uint32_t effectOffset = desc->fKey.count(); | 85 uint32_t effectOffset = desc->fKey.count(); |
| 108 effectKeySuccess |= GetEffectKeyAndUpdateStats( | 86 effectKeySuccess |= GetEffectKey(*optState.getGeometryProcessor(), g
pu->glCaps(), |
| 109 *optState.getGeometryProcessor(), gpu->glCap
s(), | 87 requiresLocalCoordAttrib, &b, &effe
ctKeySize); |
| 110 requiresLocalCoordAttrib, &b, | |
| 111 &effectKeySize, &readsDst, | |
| 112 &readFragPosition, &requiresVertexShader); | |
| 113 effectKeySuccess |= (effectOffset <= SK_MaxU16); | 88 effectKeySuccess |= (effectOffset <= SK_MaxU16); |
| 114 | 89 |
| 115 offsetAndSize[0] = SkToU16(effectOffset); | 90 offsetAndSize[0] = SkToU16(effectOffset); |
| 116 offsetAndSize[1] = effectKeySize; | 91 offsetAndSize[1] = effectKeySize; |
| 117 ++offsetAndSizeIndex; | 92 ++offsetAndSizeIndex; |
| 118 *geometryProcessor = optState.getGeometryProcessor(); | 93 *geometryProcessor = optState.getGeometryProcessor(); |
| 119 SkASSERT(requiresVertexShader); | |
| 120 header->fHasGeometryProcessor = true; | 94 header->fHasGeometryProcessor = true; |
| 121 } | 95 } |
| 122 | 96 |
| 123 for (int s = 0; s < optState.numColorStages(); ++s) { | 97 for (int s = 0; s < optState.numColorStages(); ++s) { |
| 124 uint16_t* offsetAndSize = | 98 uint16_t* offsetAndSize = |
| 125 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn
dLengthOffset + | 99 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn
dLengthOffset + |
| 126 offsetAndSizeIndex * 2 * sizeof(uint16_t
)); | 100 offsetAndSizeIndex * 2 * sizeof(uint16_t
)); |
| 127 | 101 |
| 128 bool effectRequiresVertexShader = false; | |
| 129 GrEffectKeyBuilder b(&desc->fKey); | 102 GrEffectKeyBuilder b(&desc->fKey); |
| 130 uint16_t effectKeySize; | 103 uint16_t effectKeySize; |
| 131 uint32_t effectOffset = desc->fKey.count(); | 104 uint32_t effectOffset = desc->fKey.count(); |
| 132 effectKeySuccess |= GetEffectKeyAndUpdateStats( | 105 effectKeySuccess |= GetEffectKey(optState.getColorStage(s), gpu->glCaps(
), |
| 133 optState.getColorStage(s), gpu->glCaps(), | 106 requiresLocalCoordAttrib, &b, &effectKe
ySize); |
| 134 requiresLocalCoordAttrib, &b, | |
| 135 &effectKeySize, &readsDst, | |
| 136 &readFragPosition, &effectRequiresVertexShader); | |
| 137 effectKeySuccess |= (effectOffset <= SK_MaxU16); | 107 effectKeySuccess |= (effectOffset <= SK_MaxU16); |
| 138 | 108 |
| 139 offsetAndSize[0] = SkToU16(effectOffset); | 109 offsetAndSize[0] = SkToU16(effectOffset); |
| 140 offsetAndSize[1] = effectKeySize; | 110 offsetAndSize[1] = effectKeySize; |
| 141 ++offsetAndSizeIndex; | 111 ++offsetAndSizeIndex; |
| 142 SkASSERT(!effectRequiresVertexShader); | |
| 143 } | 112 } |
| 144 | 113 |
| 145 for (int s = 0; s < optState.numCoverageStages(); ++s) { | 114 for (int s = 0; s < optState.numCoverageStages(); ++s) { |
| 146 uint16_t* offsetAndSize = | 115 uint16_t* offsetAndSize = |
| 147 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn
dLengthOffset + | 116 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn
dLengthOffset + |
| 148 offsetAndSizeIndex * 2 * sizeof(uint16_t
)); | 117 offsetAndSizeIndex * 2 * sizeof(uint16_t
)); |
| 149 | 118 |
| 150 bool effectRequiresVertexShader = false; | |
| 151 GrEffectKeyBuilder b(&desc->fKey); | 119 GrEffectKeyBuilder b(&desc->fKey); |
| 152 uint16_t effectKeySize; | 120 uint16_t effectKeySize; |
| 153 uint32_t effectOffset = desc->fKey.count(); | 121 uint32_t effectOffset = desc->fKey.count(); |
| 154 effectKeySuccess |= GetEffectKeyAndUpdateStats( | 122 effectKeySuccess |= GetEffectKey(optState.getCoverageStage(s), gpu->glCa
ps(), |
| 155 optState.getCoverageStage(s), gpu->glCaps(), | 123 requiresLocalCoordAttrib, &b, &effectKe
ySize); |
| 156 requiresLocalCoordAttrib, &b, | |
| 157 &effectKeySize, &readsDst, | |
| 158 &readFragPosition, &effectRequiresVertexShader); | |
| 159 effectKeySuccess |= (effectOffset <= SK_MaxU16); | 124 effectKeySuccess |= (effectOffset <= SK_MaxU16); |
| 160 | 125 |
| 161 offsetAndSize[0] = SkToU16(effectOffset); | 126 offsetAndSize[0] = SkToU16(effectOffset); |
| 162 offsetAndSize[1] = effectKeySize; | 127 offsetAndSize[1] = effectKeySize; |
| 163 ++offsetAndSizeIndex; | 128 ++offsetAndSizeIndex; |
| 164 SkASSERT(!effectRequiresVertexShader); | |
| 165 } | 129 } |
| 166 | 130 |
| 167 if (!effectKeySuccess) { | 131 if (!effectKeySuccess) { |
| 168 desc->fKey.reset(); | 132 desc->fKey.reset(); |
| 169 return false; | 133 return false; |
| 170 } | 134 } |
| 171 | 135 |
| 172 // Because header is a pointer into the dynamic array, we can't push any new
data into the key | 136 // Because header is a pointer into the dynamic array, we can't push any new
data into the key |
| 173 // below here. | 137 // below here. |
| 174 | 138 |
| 175 header->fRequiresVertexShader = requiresVertexShader || requiresLocalCoordAt
trib; | 139 // We will only require a vertex shader if we have more than just the positi
on VA attrib. |
| 140 // If we have a geom processor we must us a vertex shader and we should not
have a geometry |
| 141 // processor if we are doing path rendering. |
| 142 SkASSERT(!GrGpu::IsPathRenderingDrawType(drawType) || !optState.requiresVert
exShader()); |
| 143 header->fRequiresVertexShader = optState.requiresVertexShader() || |
| 144 !GrGpu::IsPathRenderingDrawType(drawType); |
| 176 header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; | 145 header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; |
| 177 | 146 |
| 178 // Currently the experimental GS will only work with triangle prims (and it
doesn't do anything | 147 // Currently the experimental GS will only work with triangle prims (and it
doesn't do anything |
| 179 // other than pass through values from the VS to the FS anyway). | 148 // other than pass through values from the VS to the FS anyway). |
| 180 #if GR_GL_EXPERIMENTAL_GS | 149 #if GR_GL_EXPERIMENTAL_GS |
| 181 #if 0 | 150 #if 0 |
| 182 header->fExperimentalGS = gpu->caps().geometryShaderSupport(); | 151 header->fExperimentalGS = gpu->caps().geometryShaderSupport(); |
| 183 #else | 152 #else |
| 184 header->fExperimentalGS = false; | 153 header->fExperimentalGS = false; |
| 185 #endif | 154 #endif |
| (...skipping 13 matching lines...) Expand all Loading... |
| 199 | 168 |
| 200 if (covIsSolidWhite || !inputCoverageIsUsed) { | 169 if (covIsSolidWhite || !inputCoverageIsUsed) { |
| 201 header->fCoverageInput = kAllOnes_ColorInput; | 170 header->fCoverageInput = kAllOnes_ColorInput; |
| 202 } else if (defaultToUniformInputs && !requiresCoverageAttrib) { | 171 } else if (defaultToUniformInputs && !requiresCoverageAttrib) { |
| 203 header->fCoverageInput = kUniform_ColorInput; | 172 header->fCoverageInput = kUniform_ColorInput; |
| 204 } else { | 173 } else { |
| 205 header->fCoverageInput = kAttribute_ColorInput; | 174 header->fCoverageInput = kAttribute_ColorInput; |
| 206 header->fRequiresVertexShader = true; | 175 header->fRequiresVertexShader = true; |
| 207 } | 176 } |
| 208 | 177 |
| 209 if (readsDst) { | 178 if (optState.readsDst()) { |
| 210 SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); | 179 SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); |
| 211 const GrTexture* dstCopyTexture = NULL; | 180 const GrTexture* dstCopyTexture = NULL; |
| 212 if (dstCopy) { | 181 if (dstCopy) { |
| 213 dstCopyTexture = dstCopy->texture(); | 182 dstCopyTexture = dstCopy->texture(); |
| 214 } | 183 } |
| 215 header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTe
xture, | 184 header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTe
xture, |
| 216 gpu->glCaps()); | 185 gpu->glCaps()); |
| 217 SkASSERT(0 != header->fDstReadKey); | 186 SkASSERT(0 != header->fDstReadKey); |
| 218 } else { | 187 } else { |
| 219 header->fDstReadKey = 0; | 188 header->fDstReadKey = 0; |
| 220 } | 189 } |
| 221 | 190 |
| 222 if (readFragPosition) { | 191 if (optState.readsFragPosition()) { |
| 223 header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition( | 192 header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition( |
| 224 optState.getRenderTarget(), gpu->glCaps()); | 193 optState.getRenderTarget(), gpu->glCaps()); |
| 225 } else { | 194 } else { |
| 226 header->fFragPosKey = 0; | 195 header->fFragPosKey = 0; |
| 227 } | 196 } |
| 228 | 197 |
| 229 // Record attribute indices | 198 // Record attribute indices |
| 230 header->fPositionAttributeIndex = optState.positionAttributeIndex(); | 199 header->fPositionAttributeIndex = optState.positionAttributeIndex(); |
| 231 header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex(); | 200 header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex(); |
| 232 | 201 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 separateCoverageFromColor = true; | 239 separateCoverageFromColor = true; |
| 271 } else if (kSA_GrBlendCoeff == dstCoeff) { | 240 } else if (kSA_GrBlendCoeff == dstCoeff) { |
| 272 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. | 241 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. |
| 273 header->fCoverageOutput = kSecondaryCoverageISA_CoverageOutput; | 242 header->fCoverageOutput = kSecondaryCoverageISA_CoverageOutput; |
| 274 separateCoverageFromColor = true; | 243 separateCoverageFromColor = true; |
| 275 } else if (kSC_GrBlendCoeff == dstCoeff) { | 244 } else if (kSC_GrBlendCoeff == dstCoeff) { |
| 276 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. | 245 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. |
| 277 header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput; | 246 header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput; |
| 278 separateCoverageFromColor = true; | 247 separateCoverageFromColor = true; |
| 279 } | 248 } |
| 280 } else if (readsDst && | 249 } else if (optState.readsDst() && |
| 281 kOne_GrBlendCoeff == srcCoeff && | 250 kOne_GrBlendCoeff == srcCoeff && |
| 282 kZero_GrBlendCoeff == dstCoeff) { | 251 kZero_GrBlendCoeff == dstCoeff) { |
| 283 header->fCoverageOutput = kCombineWithDst_CoverageOutput; | 252 header->fCoverageOutput = kCombineWithDst_CoverageOutput; |
| 284 separateCoverageFromColor = true; | 253 separateCoverageFromColor = true; |
| 285 } | 254 } |
| 286 } | 255 } |
| 287 | 256 |
| 288 for (int s = 0; s < optState.numColorStages(); ++s) { | 257 for (int s = 0; s < optState.numColorStages(); ++s) { |
| 289 colorStages->push_back(&optState.getColorStage(s)); | 258 colorStages->push_back(&optState.getColorStage(s)); |
| 290 } | 259 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 314 *checksum = 0; | 283 *checksum = 0; |
| 315 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k
eyLength); | 284 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k
eyLength); |
| 316 } | 285 } |
| 317 | 286 |
| 318 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { | 287 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { |
| 319 size_t keyLength = other.keyLength(); | 288 size_t keyLength = other.keyLength(); |
| 320 fKey.reset(keyLength); | 289 fKey.reset(keyLength); |
| 321 memcpy(fKey.begin(), other.fKey.begin(), keyLength); | 290 memcpy(fKey.begin(), other.fKey.begin(), keyLength); |
| 322 return *this; | 291 return *this; |
| 323 } | 292 } |
| OLD | NEW |