Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 "GrGpuGL.h" | |
| 13 | |
| 14 void GrGLProgramDesc::Build(const GrDrawState& drawState, | |
| 15 bool isPoints, | |
| 16 GrDrawState::BlendOptFlags blendOpts, | |
| 17 GrBlendCoeff srcCoeff, | |
| 18 GrBlendCoeff dstCoeff, | |
| 19 const GrGpuGL* gpu, | |
| 20 GrGLProgramDesc* desc) { | |
| 21 | |
| 22 // This should already have been caught | |
| 23 GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); | |
| 24 | |
| 25 bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendO ptFlag); | |
| 26 | |
| 27 bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOpt Flag | | |
| 28 GrDrawState::kEmitCoverage_BlendOptFl ag)); | |
| 29 | |
| 30 // The descriptor is used as a cache key. Thus when a field of the | |
| 31 // descriptor will not affect program generation (because of the attribute | |
| 32 // bindings in use or other descriptor field settings) it should be set | |
| 33 // to a canonical value to avoid duplicate programs with different keys. | |
| 34 | |
| 35 // Must initialize all fields or cache will have false negatives! | |
| 36 desc->fAttribBindings = drawState.getAttribBindings(); | |
| 37 | |
| 38 desc->fEmitsPointSize = isPoints; | |
| 39 | |
| 40 bool requiresAttributeColors = | |
| 41 !skipColor && SkToBool(desc->fAttribBindings & GrDrawState::kColor_Attri bBindingsBit); | |
| 42 bool requiresAttributeCoverage = | |
| 43 !skipCoverage && SkToBool(desc->fAttribBindings & GrDrawState::kCoverage _AttribBindingsBit); | |
| 44 | |
|
robertphillips
2013/03/27 18:44:52
So -> so
bsalomon
2013/03/27 19:50:31
Done.
| |
| 45 // fColorInput/fCoverageInput records how colors are specified for the progr am So we strip the | |
| 46 // bits from the bindings to avoid false negatives when searching for an exi sting program in the | |
| 47 // cache. | |
| 48 desc->fAttribBindings &= | |
| 49 ~(GrDrawState::kColor_AttribBindingsBit | GrDrawState::kCoverage_AttribB indingsBit); | |
| 50 | |
| 51 desc->fColorFilterXfermode = skipColor ? | |
|
robertphillips
2013/03/27 18:44:52
spaces
bsalomon
2013/03/27 19:50:31
Done.
| |
| 52 SkXfermode::kDst_Mode : | |
| 53 drawState.getColorFilterMode(); | |
| 54 | |
| 55 // no reason to do edge aa or look at per-vertex coverage if coverage is ign ored | |
| 56 if (skipCoverage) { | |
| 57 desc->fAttribBindings &= ~(GrDrawState::kCoverage_AttribBindingsBit); | |
| 58 } | |
| 59 | |
| 60 bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_B lendOptFlag); | |
| 61 bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFla g) || | |
| 62 (!requiresAttributeColors && 0xffffffff == drawStat e.getColor()); | |
| 63 if (colorIsTransBlack) { | |
| 64 desc->fColorInput = kTransBlack_ColorInput; | |
| 65 } else if (colorIsSolidWhite) { | |
| 66 desc->fColorInput = kSolidWhite_ColorInput; | |
| 67 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) { | |
| 68 desc->fColorInput = kUniform_ColorInput; | |
| 69 } else { | |
| 70 desc->fColorInput = kAttribute_ColorInput; | |
| 71 } | |
| 72 | |
| 73 bool covIsSolidWhite = !requiresAttributeCoverage && 0xffffffff == drawState .getCoverage(); | |
| 74 | |
| 75 if (skipCoverage) { | |
| 76 desc->fCoverageInput = kTransBlack_ColorInput; | |
| 77 } else if (covIsSolidWhite) { | |
| 78 desc->fCoverageInput = kSolidWhite_ColorInput; | |
| 79 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) { | |
| 80 desc->fCoverageInput = kUniform_ColorInput; | |
| 81 } else { | |
| 82 desc->fCoverageInput = kAttribute_ColorInput; | |
| 83 } | |
| 84 | |
| 85 int lastEnabledStage = -1; | |
| 86 | |
| 87 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | |
| 88 | |
| 89 bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCove rage; | |
| 90 if (!skip && drawState.isStageEnabled(s)) { | |
| 91 lastEnabledStage = s; | |
| 92 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); | |
| 93 const GrBackendEffectFactory& factory = effect->getFactory(); | |
| 94 bool explicitLocalCoords = (drawState.getAttribBindings() & | |
| 95 GrDrawState::kLocalCoords_AttribBindings Bit); | |
| 96 GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords); | |
| 97 desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps() ); | |
| 98 } else { | |
| 99 desc->fEffectKeys[s] = 0; | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 desc->fDualSrcOutput = kNone_DualSrcOutput; | |
| 104 | |
| 105 // Currently the experimental GS will only work with triangle prims (and it doesn't do anything | |
| 106 // other than pass through values from the VS to the FS anyway). | |
| 107 #if GR_GL_EXPERIMENTAL_GS | |
| 108 #if 0 | |
| 109 desc->fExperimentalGS = gpu->caps().geometryShaderSupport(); | |
| 110 #else | |
| 111 desc->fExperimentalGS = false; | |
| 112 #endif | |
| 113 #endif | |
| 114 | |
| 115 // We leave this set to kNumStages until we discover that the coverage/color distinction is | |
| 116 // material to the generated program. We do this to avoid distinct keys that generate equivalent | |
| 117 // programs. | |
| 118 desc->fFirstCoverageStage = GrDrawState::kNumStages; | |
| 119 // This tracks the actual first coverage stage. | |
| 120 int firstCoverageStage = GrDrawState::kNumStages; | |
| 121 desc->fDiscardIfZeroCoverage = false; // Enabled below if stenciling and the re is coverage. | |
| 122 bool hasCoverage = false; | |
|
robertphillips
2013/03/27 18:44:52
its -> it's
bsalomon
2013/03/27 19:50:31
Done.
| |
| 123 // If we're rendering coverage-as-color then its as though there are no cove rage stages. | |
| 124 if (!drawState.isCoverageDrawing()) { | |
| 125 // We can have coverage either through a stage or coverage vertex attrib utes. | |
| 126 if (drawState.getFirstCoverageStage() <= lastEnabledStage) { | |
| 127 firstCoverageStage = drawState.getFirstCoverageStage(); | |
| 128 hasCoverage = true; | |
| 129 } else { | |
| 130 hasCoverage = requiresAttributeCoverage; | |
| 131 } | |
| 132 } | |
| 133 | |
| 134 if (hasCoverage) { | |
| 135 // color filter is applied between color/coverage computation | |
| 136 if (SkXfermode::kDst_Mode != desc->fColorFilterXfermode) { | |
| 137 desc->fFirstCoverageStage = firstCoverageStage; | |
| 138 } | |
| 139 | |
| 140 // If we're stenciling then we want to discard samples that have zero co verage | |
| 141 if (drawState.getStencil().doesWrite()) { | |
| 142 desc->fDiscardIfZeroCoverage = true; | |
| 143 desc->fFirstCoverageStage = firstCoverageStage; | |
| 144 } | |
| 145 | |
| 146 if (gpu->caps()->dualSourceBlendingSupport() && | |
| 147 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | | |
| 148 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { | |
| 149 if (kZero_GrBlendCoeff == dstCoeff) { | |
| 150 // write the coverage value to second color | |
| 151 desc->fDualSrcOutput = kCoverage_DualSrcOutput; | |
| 152 desc->fFirstCoverageStage = firstCoverageStage; | |
| 153 } else if (kSA_GrBlendCoeff == dstCoeff) { | |
| 154 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. | |
| 155 desc->fDualSrcOutput = kCoverageISA_DualSrcOutput; | |
| 156 desc->fFirstCoverageStage = firstCoverageStage; | |
| 157 } else if (kSC_GrBlendCoeff == dstCoeff) { | |
| 158 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. | |
| 159 desc->fDualSrcOutput = kCoverageISC_DualSrcOutput; | |
| 160 desc->fFirstCoverageStage = firstCoverageStage; | |
| 161 } | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 desc->fPositionAttributeIndex = drawState.getAttribIndex(GrDrawState::kPosit ion_AttribIndex); | |
| 166 if (requiresAttributeColors) { | |
| 167 desc->fColorAttributeIndex = drawState.getAttribIndex(GrDrawState::kColo r_AttribIndex); | |
| 168 } else { | |
| 169 desc->fColorAttributeIndex = GrDrawState::kColorOverrideAttribIndexValue ; | |
| 170 } | |
| 171 if (requiresAttributeCoverage) { | |
| 172 desc->fCoverageAttributeIndex = drawState.getAttribIndex(GrDrawState::kC overage_AttribIndex); | |
| 173 } else { | |
| 174 desc->fCoverageAttributeIndex = GrDrawState::kCoverageOverrideAttribInde xValue; | |
| 175 } | |
| 176 if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { | |
| 177 desc->fLocalCoordsAttributeIndex = drawState.getAttribIndex(GrDrawState: :kLocalCoords_AttribIndex); | |
| 178 } | |
|
robertphillips
2013/03/27 18:44:52
do we not have a kLocalCoordsOverrideAttribIndexVa
bsalomon
2013/03/27 19:50:31
No. The override values are there because we somet
| |
| 179 | |
| 180 #if GR_DEBUG | |
| 181 // Verify valid vertex attribute state. These assertions should probably be done somewhere | |
| 182 // higher up the callstack | |
| 183 const GrVertexAttrib* vertexAttribs = drawState.getVertexAttribs(); | |
| 184 GrAssert(desc->fPositionAttributeIndex < GrDrawState::kVertexAttribCnt); | |
| 185 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fPositionAttributeIndex] .fType).fCount == 2); | |
| 186 if (requiresAttributeColors) { | |
| 187 GrAssert(desc->fColorAttributeIndex < GrDrawState::kVertexAttribCnt); | |
| 188 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fColorAttributeIndex ].fType).fCount == 4); | |
| 189 } | |
| 190 if (requiresAttributeCoverage) { | |
| 191 GrAssert(desc->fCoverageAttributeIndex < GrDrawState::kVertexAttribCnt); | |
| 192 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fCoverageAttributeIn dex].fType).fCount == 4); | |
| 193 } | |
| 194 if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { | |
| 195 GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCn t); | |
| 196 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fLocalCoordsAttribut eIndex].fType).fCount == 2); | |
| 197 } | |
| 198 #endif | |
| 199 } | |
| OLD | NEW |