Chromium Code Reviews| 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 23 matching lines...) Expand all Loading... | |
| 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 // we only need the local coords if we're actually going to generate effect code |
| 76 bool requiresLocalCoordAttrib = optState.numTotalStages() > 0 && | 62 bool requiresLocalCoordAttrib = optState.numTotalStages() > 0 && |
| 77 optState.hasLocalCoordAttribute(); | 63 optState.hasLocalCoordAttribute(); |
| 78 | 64 |
| 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 | |
| 85 int numStages = optState.numTotalStages(); | 65 int numStages = optState.numTotalStages(); |
| 86 | 66 |
| 87 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); | 67 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. | 68 // Make room for everything up to and including the array of offsets to effe ct keys. |
| 89 desc->fKey.reset(); | 69 desc->fKey.reset(); |
| 90 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_ t) * numStages); | 70 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_ t) * numStages); |
| 91 | 71 |
| 92 int offsetAndSizeIndex = 0; | 72 int offsetAndSizeIndex = 0; |
| 93 bool effectKeySuccess = true; | 73 bool effectKeySuccess = true; |
| 94 | 74 |
| 95 KeyHeader* header = desc->header(); | 75 KeyHeader* header = desc->header(); |
| 96 // make sure any padding in the header is zeroed. | 76 // make sure any padding in the header is zeroed. |
| 97 memset(desc->header(), 0, kHeaderSize); | 77 memset(desc->header(), 0, kHeaderSize); |
| 98 | 78 |
| 99 // We can only have one effect which touches the vertex shader | 79 // We can only have one effect which touches the vertex shader |
| 100 if (optState.hasGeometryProcessor()) { | 80 if (optState.hasGeometryProcessor()) { |
| 101 uint16_t* offsetAndSize = | 81 uint16_t* offsetAndSize = |
| 102 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffse tsAndLengthOffset + | 82 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffse tsAndLengthOffset + |
| 103 offsetAndSizeIndex * 2 * sizeof(uint 16_t)); | 83 offsetAndSizeIndex * 2 * sizeof(uint 16_t)); |
| 104 | 84 |
| 105 GrEffectKeyBuilder b(&desc->fKey); | 85 GrEffectKeyBuilder b(&desc->fKey); |
| 106 uint16_t effectKeySize; | 86 uint16_t effectKeySize; |
| 107 uint32_t effectOffset = desc->fKey.count(); | 87 uint32_t effectOffset = desc->fKey.count(); |
| 108 effectKeySuccess |= GetEffectKeyAndUpdateStats( | 88 effectKeySuccess |= GetEffectKey(*optState.getGeometryProcessor(), g pu->glCaps(), |
| 109 *optState.getGeometryProcessor(), gpu->glCap s(), | 89 requiresLocalCoordAttrib, &b, &effe ctKeySize); |
| 110 requiresLocalCoordAttrib, &b, | |
| 111 &effectKeySize, &readsDst, | |
| 112 &readFragPosition, &requiresVertexShader); | |
| 113 effectKeySuccess |= (effectOffset <= SK_MaxU16); | 90 effectKeySuccess |= (effectOffset <= SK_MaxU16); |
| 114 | 91 |
| 115 offsetAndSize[0] = SkToU16(effectOffset); | 92 offsetAndSize[0] = SkToU16(effectOffset); |
| 116 offsetAndSize[1] = effectKeySize; | 93 offsetAndSize[1] = effectKeySize; |
| 117 ++offsetAndSizeIndex; | 94 ++offsetAndSizeIndex; |
| 118 *geometryProcessor = optState.getGeometryProcessor(); | 95 *geometryProcessor = optState.getGeometryProcessor(); |
| 119 SkASSERT(requiresVertexShader); | |
| 120 header->fHasGeometryProcessor = true; | 96 header->fHasGeometryProcessor = true; |
| 121 } | 97 } |
| 122 | 98 |
| 123 for (int s = 0; s < optState.numColorStages(); ++s) { | 99 for (int s = 0; s < optState.numColorStages(); ++s) { |
| 124 uint16_t* offsetAndSize = | 100 uint16_t* offsetAndSize = |
| 125 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn dLengthOffset + | 101 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn dLengthOffset + |
| 126 offsetAndSizeIndex * 2 * sizeof(uint16_t )); | 102 offsetAndSizeIndex * 2 * sizeof(uint16_t )); |
| 127 | 103 |
| 128 bool effectRequiresVertexShader = false; | |
| 129 GrEffectKeyBuilder b(&desc->fKey); | 104 GrEffectKeyBuilder b(&desc->fKey); |
| 130 uint16_t effectKeySize; | 105 uint16_t effectKeySize; |
| 131 uint32_t effectOffset = desc->fKey.count(); | 106 uint32_t effectOffset = desc->fKey.count(); |
| 132 effectKeySuccess |= GetEffectKeyAndUpdateStats( | 107 effectKeySuccess |= GetEffectKey(optState.getColorStage(s), gpu->glCaps( ), |
| 133 optState.getColorStage(s), gpu->glCaps(), | 108 requiresLocalCoordAttrib, &b, &effectKe ySize); |
| 134 requiresLocalCoordAttrib, &b, | |
| 135 &effectKeySize, &readsDst, | |
| 136 &readFragPosition, &effectRequiresVertexShader); | |
| 137 effectKeySuccess |= (effectOffset <= SK_MaxU16); | 109 effectKeySuccess |= (effectOffset <= SK_MaxU16); |
| 138 | 110 |
| 139 offsetAndSize[0] = SkToU16(effectOffset); | 111 offsetAndSize[0] = SkToU16(effectOffset); |
| 140 offsetAndSize[1] = effectKeySize; | 112 offsetAndSize[1] = effectKeySize; |
| 141 ++offsetAndSizeIndex; | 113 ++offsetAndSizeIndex; |
| 142 SkASSERT(!effectRequiresVertexShader); | |
| 143 } | 114 } |
| 144 | 115 |
| 145 for (int s = 0; s < optState.numCoverageStages(); ++s) { | 116 for (int s = 0; s < optState.numCoverageStages(); ++s) { |
| 146 uint16_t* offsetAndSize = | 117 uint16_t* offsetAndSize = |
| 147 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn dLengthOffset + | 118 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn dLengthOffset + |
| 148 offsetAndSizeIndex * 2 * sizeof(uint16_t )); | 119 offsetAndSizeIndex * 2 * sizeof(uint16_t )); |
| 149 | 120 |
| 150 bool effectRequiresVertexShader = false; | |
| 151 GrEffectKeyBuilder b(&desc->fKey); | 121 GrEffectKeyBuilder b(&desc->fKey); |
| 152 uint16_t effectKeySize; | 122 uint16_t effectKeySize; |
| 153 uint32_t effectOffset = desc->fKey.count(); | 123 uint32_t effectOffset = desc->fKey.count(); |
| 154 effectKeySuccess |= GetEffectKeyAndUpdateStats( | 124 effectKeySuccess |= GetEffectKey(optState.getCoverageStage(s), gpu->glCa ps(), |
| 155 optState.getCoverageStage(s), gpu->glCaps(), | 125 requiresLocalCoordAttrib, &b, &effectKe ySize); |
| 156 requiresLocalCoordAttrib, &b, | |
| 157 &effectKeySize, &readsDst, | |
| 158 &readFragPosition, &effectRequiresVertexShader); | |
| 159 effectKeySuccess |= (effectOffset <= SK_MaxU16); | 126 effectKeySuccess |= (effectOffset <= SK_MaxU16); |
| 160 | 127 |
| 161 offsetAndSize[0] = SkToU16(effectOffset); | 128 offsetAndSize[0] = SkToU16(effectOffset); |
| 162 offsetAndSize[1] = effectKeySize; | 129 offsetAndSize[1] = effectKeySize; |
| 163 ++offsetAndSizeIndex; | 130 ++offsetAndSizeIndex; |
| 164 SkASSERT(!effectRequiresVertexShader); | |
| 165 } | 131 } |
| 166 | 132 |
| 167 if (!effectKeySuccess) { | 133 if (!effectKeySuccess) { |
| 168 desc->fKey.reset(); | 134 desc->fKey.reset(); |
| 169 return false; | 135 return false; |
| 170 } | 136 } |
| 171 | 137 |
| 172 // Because header is a pointer into the dynamic array, we can't push any new data into the key | 138 // Because header is a pointer into the dynamic array, we can't push any new data into the key |
| 173 // below here. | 139 // below here. |
| 174 | 140 |
| 175 header->fRequiresVertexShader = requiresVertexShader || requiresLocalCoordAt trib; | 141 // We will only use vertex shader if we have a geometry processor and we sho uld not have a |
|
bsalomon
2014/09/16 21:54:20
use->require ?
egdaniel
2014/09/17 15:00:14
Done.
| |
| 142 // geometry processor if we are doing path rendering. | |
| 143 // TODO: Once we have a default GeometryProcessor on all programs not using path rendering, | |
| 144 // we can remove the !GrGpu::IsPathRenderingDrawType(drawType) in setting he ader | |
| 145 SkASSERT(!GrGpu::IsPathRenderingDrawType(drawType) || !optState.requiresVert exShader()); | |
|
bsalomon
2014/09/16 21:54:20
can requriesLocalCoordAttrib be part of optState.r
egdaniel
2014/09/17 15:00:14
Moved the checking of requires local coord attrib
| |
| 146 header->fRequiresVertexShader = optState.requiresVertexShader() || | |
| 147 requiresLocalCoordAttrib || | |
| 148 !GrGpu::IsPathRenderingDrawType(drawType); | |
| 176 header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; | 149 header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; |
| 177 | 150 |
| 178 // Currently the experimental GS will only work with triangle prims (and it doesn't do anything | 151 // 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). | 152 // other than pass through values from the VS to the FS anyway). |
| 180 #if GR_GL_EXPERIMENTAL_GS | 153 #if GR_GL_EXPERIMENTAL_GS |
| 181 #if 0 | 154 #if 0 |
| 182 header->fExperimentalGS = gpu->caps().geometryShaderSupport(); | 155 header->fExperimentalGS = gpu->caps().geometryShaderSupport(); |
| 183 #else | 156 #else |
| 184 header->fExperimentalGS = false; | 157 header->fExperimentalGS = false; |
| 185 #endif | 158 #endif |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 199 | 172 |
| 200 if (covIsSolidWhite || !inputCoverageIsUsed) { | 173 if (covIsSolidWhite || !inputCoverageIsUsed) { |
| 201 header->fCoverageInput = kAllOnes_ColorInput; | 174 header->fCoverageInput = kAllOnes_ColorInput; |
| 202 } else if (defaultToUniformInputs && !requiresCoverageAttrib) { | 175 } else if (defaultToUniformInputs && !requiresCoverageAttrib) { |
| 203 header->fCoverageInput = kUniform_ColorInput; | 176 header->fCoverageInput = kUniform_ColorInput; |
| 204 } else { | 177 } else { |
| 205 header->fCoverageInput = kAttribute_ColorInput; | 178 header->fCoverageInput = kAttribute_ColorInput; |
| 206 header->fRequiresVertexShader = true; | 179 header->fRequiresVertexShader = true; |
| 207 } | 180 } |
| 208 | 181 |
| 209 if (readsDst) { | 182 if (optState.readsDst()) { |
| 210 SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); | 183 SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); |
| 211 const GrTexture* dstCopyTexture = NULL; | 184 const GrTexture* dstCopyTexture = NULL; |
| 212 if (dstCopy) { | 185 if (dstCopy) { |
| 213 dstCopyTexture = dstCopy->texture(); | 186 dstCopyTexture = dstCopy->texture(); |
| 214 } | 187 } |
| 215 header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTe xture, | 188 header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTe xture, |
| 216 gpu->glCaps()); | 189 gpu->glCaps()); |
| 217 SkASSERT(0 != header->fDstReadKey); | 190 SkASSERT(0 != header->fDstReadKey); |
| 218 } else { | 191 } else { |
| 219 header->fDstReadKey = 0; | 192 header->fDstReadKey = 0; |
| 220 } | 193 } |
| 221 | 194 |
| 222 if (readFragPosition) { | 195 if (optState.readsFragPosition()) { |
| 223 header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition( | 196 header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition( |
| 224 optState.getRenderTarget(), gpu->glCaps()); | 197 optState.getRenderTarget(), gpu->glCaps()); |
| 225 } else { | 198 } else { |
| 226 header->fFragPosKey = 0; | 199 header->fFragPosKey = 0; |
| 227 } | 200 } |
| 228 | 201 |
| 229 // Record attribute indices | 202 // Record attribute indices |
| 230 header->fPositionAttributeIndex = optState.positionAttributeIndex(); | 203 header->fPositionAttributeIndex = optState.positionAttributeIndex(); |
| 231 header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex(); | 204 header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex(); |
| 232 | 205 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 separateCoverageFromColor = true; | 243 separateCoverageFromColor = true; |
| 271 } else if (kSA_GrBlendCoeff == dstCoeff) { | 244 } else if (kSA_GrBlendCoeff == dstCoeff) { |
| 272 // 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. |
| 273 header->fCoverageOutput = kSecondaryCoverageISA_CoverageOutput; | 246 header->fCoverageOutput = kSecondaryCoverageISA_CoverageOutput; |
| 274 separateCoverageFromColor = true; | 247 separateCoverageFromColor = true; |
| 275 } else if (kSC_GrBlendCoeff == dstCoeff) { | 248 } else if (kSC_GrBlendCoeff == dstCoeff) { |
| 276 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. | 249 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. |
| 277 header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput; | 250 header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput; |
| 278 separateCoverageFromColor = true; | 251 separateCoverageFromColor = true; |
| 279 } | 252 } |
| 280 } else if (readsDst && | 253 } else if (optState.readsDst() && |
| 281 kOne_GrBlendCoeff == srcCoeff && | 254 kOne_GrBlendCoeff == srcCoeff && |
| 282 kZero_GrBlendCoeff == dstCoeff) { | 255 kZero_GrBlendCoeff == dstCoeff) { |
| 283 header->fCoverageOutput = kCombineWithDst_CoverageOutput; | 256 header->fCoverageOutput = kCombineWithDst_CoverageOutput; |
| 284 separateCoverageFromColor = true; | 257 separateCoverageFromColor = true; |
| 285 } | 258 } |
| 286 } | 259 } |
| 287 | 260 |
| 288 for (int s = 0; s < optState.numColorStages(); ++s) { | 261 for (int s = 0; s < optState.numColorStages(); ++s) { |
| 289 colorStages->push_back(&optState.getColorStage(s)); | 262 colorStages->push_back(&optState.getColorStage(s)); |
| 290 } | 263 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 314 *checksum = 0; | 287 *checksum = 0; |
| 315 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k eyLength); | 288 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k eyLength); |
| 316 } | 289 } |
| 317 | 290 |
| 318 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { | 291 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { |
| 319 size_t keyLength = other.keyLength(); | 292 size_t keyLength = other.keyLength(); |
| 320 fKey.reset(keyLength); | 293 fKey.reset(keyLength); |
| 321 memcpy(fKey.begin(), other.fKey.begin(), keyLength); | 294 memcpy(fKey.begin(), other.fKey.begin(), keyLength); |
| 322 return *this; | 295 return *this; |
| 323 } | 296 } |
| OLD | NEW |