GrGLProgramDesc.cpp revision 8d47ddc19a40d1984bf1f384d711d36ab59fd1c0
1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "GrGLProgramDesc.h" 9#include "GrBackendEffectFactory.h" 10#include "GrDrawEffect.h" 11#include "GrEffect.h" 12#include "GrGLShaderBuilder.h" 13#include "GrGpuGL.h" 14 15void GrGLProgramDesc::Build(const GrDrawState& drawState, 16 bool isPoints, 17 GrDrawState::BlendOptFlags blendOpts, 18 GrBlendCoeff srcCoeff, 19 GrBlendCoeff dstCoeff, 20 const GrGpuGL* gpu, 21 const GrDeviceCoordTexture* dstCopy, 22 GrGLProgramDesc* desc) { 23 24 // This should already have been caught 25 GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); 26 27 bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag); 28 29 bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag | 30 GrDrawState::kEmitCoverage_BlendOptFlag)); 31 32 // The descriptor is used as a cache key. Thus when a field of the 33 // descriptor will not affect program generation (because of the attribute 34 // bindings in use or other descriptor field settings) it should be set 35 // to a canonical value to avoid duplicate programs with different keys. 36 37 38 desc->fEmitsPointSize = isPoints; 39 40 bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute(); 41 bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAttribute(); 42 // we only need the local coords if we're actually going to generate effect code 43 bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) && 44 drawState.hasLocalCoordAttribute(); 45 46 // fColorInput/fCoverageInput records how colors are specified for the program so we strip the 47 // bits from the bindings to avoid false negatives when searching for an existing program in the 48 // cache. 49 50 desc->fColorFilterXfermode = skipColor ? SkXfermode::kDst_Mode : drawState.getColorFilterMode(); 51 52 53 bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag); 54 bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) || 55 (!requiresColorAttrib && 0xffffffff == drawState.getColor()); 56 if (colorIsTransBlack) { 57 desc->fColorInput = kTransBlack_ColorInput; 58 } else if (colorIsSolidWhite) { 59 desc->fColorInput = kSolidWhite_ColorInput; 60 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresColorAttrib) { 61 desc->fColorInput = kUniform_ColorInput; 62 } else { 63 desc->fColorInput = kAttribute_ColorInput; 64 } 65 66 bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverage(); 67 68 if (skipCoverage) { 69 desc->fCoverageInput = kTransBlack_ColorInput; 70 } else if (covIsSolidWhite) { 71 desc->fCoverageInput = kSolidWhite_ColorInput; 72 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresCoverageAttrib) { 73 desc->fCoverageInput = kUniform_ColorInput; 74 } else { 75 desc->fCoverageInput = kAttribute_ColorInput; 76 } 77 78 bool readsDst = false; 79 int lastEnabledStage = -1; 80 81 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 82 83 bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCoverage; 84 if (!skip && drawState.isStageEnabled(s)) { 85 lastEnabledStage = s; 86 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); 87 const GrBackendEffectFactory& factory = effect->getFactory(); 88 GrDrawEffect drawEffect(drawState.getStage(s), requiresLocalCoordAttrib); 89 desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps()); 90 if (effect->willReadDstColor()) { 91 readsDst = true; 92 } 93 } else { 94 desc->fEffectKeys[s] = 0; 95 } 96 } 97 98 if (readsDst) { 99 GrAssert(NULL != dstCopy || gpu->caps()->dstReadInShaderSupport()); 100 const GrTexture* dstCopyTexture = NULL; 101 if (NULL != dstCopy) { 102 dstCopyTexture = dstCopy->texture(); 103 } 104 desc->fDstRead = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps()); 105 GrAssert(0 != desc->fDstRead); 106 } else { 107 desc->fDstRead = 0; 108 } 109 110 desc->fCoverageOutput = kModulate_CoverageOutput; 111 112 // Currently the experimental GS will only work with triangle prims (and it doesn't do anything 113 // other than pass through values from the VS to the FS anyway). 114#if GR_GL_EXPERIMENTAL_GS 115#if 0 116 desc->fExperimentalGS = gpu->caps().geometryShaderSupport(); 117#else 118 desc->fExperimentalGS = false; 119#endif 120#endif 121 122 // We leave this set to kNumStages until we discover that the coverage/color distinction is 123 // material to the generated program. We do this to avoid distinct keys that generate equivalent 124 // programs. 125 desc->fFirstCoverageStage = GrDrawState::kNumStages; 126 // This tracks the actual first coverage stage. 127 int firstCoverageStage = GrDrawState::kNumStages; 128 desc->fDiscardIfZeroCoverage = false; // Enabled below if stenciling and there is coverage. 129 bool hasCoverage = false; 130 // If we're rendering coverage-as-color then it's as though there are no coverage stages. 131 if (!drawState.isCoverageDrawing()) { 132 // We can have coverage either through a stage or coverage vertex attributes. 133 if (drawState.getFirstCoverageStage() <= lastEnabledStage) { 134 firstCoverageStage = drawState.getFirstCoverageStage(); 135 hasCoverage = true; 136 } else { 137 hasCoverage = requiresCoverageAttrib; 138 } 139 } 140 141 if (hasCoverage) { 142 // color filter is applied between color/coverage computation 143 if (SkXfermode::kDst_Mode != desc->fColorFilterXfermode) { 144 desc->fFirstCoverageStage = firstCoverageStage; 145 } 146 147 // If we're stenciling then we want to discard samples that have zero coverage 148 if (drawState.getStencil().doesWrite()) { 149 desc->fDiscardIfZeroCoverage = true; 150 desc->fFirstCoverageStage = firstCoverageStage; 151 } 152 153 if (gpu->caps()->dualSourceBlendingSupport() && 154 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | 155 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { 156 if (kZero_GrBlendCoeff == dstCoeff) { 157 // write the coverage value to second color 158 desc->fCoverageOutput = kSecondaryCoverage_CoverageOutput; 159 desc->fFirstCoverageStage = firstCoverageStage; 160 } else if (kSA_GrBlendCoeff == dstCoeff) { 161 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. 162 desc->fCoverageOutput = kSecondaryCoverageISA_CoverageOutput; 163 desc->fFirstCoverageStage = firstCoverageStage; 164 } else if (kSC_GrBlendCoeff == dstCoeff) { 165 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. 166 desc->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput; 167 desc->fFirstCoverageStage = firstCoverageStage; 168 } 169 } else if (readsDst && 170 kOne_GrBlendCoeff == drawState.getSrcBlendCoeff() && 171 kZero_GrBlendCoeff == drawState.getDstBlendCoeff()) { 172 desc->fCoverageOutput = kCombineWithDst_CoverageOutput; 173 desc->fFirstCoverageStage = firstCoverageStage; 174 } 175 } 176 177 desc->fPositionAttributeIndex = drawState.positionAttributeIndex(); 178 desc->fLocalCoordAttributeIndex = drawState.localCoordAttributeIndex(); 179 180 // For constant color and coverage we need an attribute with an index beyond those already set 181 int availableAttributeIndex = drawState.getVertexAttribCount(); 182 if (requiresColorAttrib) { 183 desc->fColorAttributeIndex = drawState.colorVertexAttributeIndex(); 184 } else if (GrGLProgramDesc::kAttribute_ColorInput == desc->fColorInput) { 185 GrAssert(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); 186 desc->fColorAttributeIndex = availableAttributeIndex; 187 availableAttributeIndex++; 188 } else { 189 desc->fColorAttributeIndex = -1; 190 } 191 192 if (requiresCoverageAttrib) { 193 desc->fCoverageAttributeIndex = drawState.coverageVertexAttributeIndex(); 194 } else if (GrGLProgramDesc::kAttribute_ColorInput == desc->fCoverageInput) { 195 GrAssert(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); 196 desc->fCoverageAttributeIndex = availableAttributeIndex; 197 } else { 198 desc->fCoverageAttributeIndex = -1; 199 } 200} 201