| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrGLProgram.h" | 8 #include "GrGLProgram.h" |
| 9 | 9 |
| 10 #include "GrAllocator.h" | 10 #include "GrAllocator.h" |
| 11 #include "GrEffect.h" | 11 #include "GrEffect.h" |
| 12 #include "GrDrawEffect.h" | 12 #include "GrDrawEffect.h" |
| 13 #include "GrGLEffect.h" | 13 #include "GrGLEffect.h" |
| 14 #include "GrGpuGL.h" | 14 #include "GrGpuGL.h" |
| 15 #include "GrGLShaderVar.h" | 15 #include "GrGLShaderVar.h" |
| 16 #include "GrBackendEffectFactory.h" | |
| 17 #include "SkTrace.h" | 16 #include "SkTrace.h" |
| 18 #include "SkXfermode.h" | 17 #include "SkXfermode.h" |
| 19 | 18 |
| 20 #include "SkRTConf.h" | 19 #include "SkRTConf.h" |
| 21 | 20 |
| 22 SK_DEFINE_INST_COUNT(GrGLProgram) | 21 SK_DEFINE_INST_COUNT(GrGLProgram) |
| 23 | 22 |
| 24 #define GL_CALL(X) GR_GL_CALL(fContext.interface(), X) | 23 #define GL_CALL(X) GR_GL_CALL(fContext.interface(), X) |
| 25 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContext.interface(), R, X) | 24 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContext.interface(), R, X) |
| 26 | 25 |
| 27 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, | 26 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, |
| 28 "Print the source code for all shaders generated."); | 27 "Print the source code for all shaders generated."); |
| 29 | 28 |
| 30 #define COL_ATTR_NAME "aColor" | 29 #define COL_ATTR_NAME "aColor" |
| 31 #define COV_ATTR_NAME "aCoverage" | 30 #define COV_ATTR_NAME "aCoverage" |
| 32 #define EDGE_ATTR_NAME "aEdge" | 31 #define EDGE_ATTR_NAME "aEdge" |
| 33 | 32 |
| 34 namespace { | 33 namespace { |
| 35 inline const char* declared_color_output_name() { return "fsColorOut"; } | 34 inline const char* declared_color_output_name() { return "fsColorOut"; } |
| 36 inline const char* dual_source_output_name() { return "dualSourceOut"; } | 35 inline const char* dual_source_output_name() { return "dualSourceOut"; } |
| 37 } | 36 } |
| 38 | 37 |
| 39 void GrGLProgramDesc::Build(const GrDrawState& drawState, | |
| 40 bool isPoints, | |
| 41 GrDrawState::BlendOptFlags blendOpts, | |
| 42 GrBlendCoeff srcCoeff, | |
| 43 GrBlendCoeff dstCoeff, | |
| 44 const GrGpuGL* gpu, | |
| 45 GrGLProgramDesc* desc) { | |
| 46 | |
| 47 // This should already have been caught | |
| 48 GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); | |
| 49 | |
| 50 bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendO
ptFlag); | |
| 51 | |
| 52 bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOpt
Flag | | |
| 53 GrDrawState::kEmitCoverage_BlendOptFl
ag)); | |
| 54 | |
| 55 // The descriptor is used as a cache key. Thus when a field of the | |
| 56 // descriptor will not affect program generation (because of the attribute | |
| 57 // bindings in use or other descriptor field settings) it should be set | |
| 58 // to a canonical value to avoid duplicate programs with different keys. | |
| 59 | |
| 60 // Must initialize all fields or cache will have false negatives! | |
| 61 desc->fAttribBindings = drawState.getAttribBindings(); | |
| 62 | |
| 63 desc->fEmitsPointSize = isPoints; | |
| 64 | |
| 65 bool requiresAttributeColors = | |
| 66 !skipColor && SkToBool(desc->fAttribBindings & GrDrawState::kColor_Attri
bBindingsBit); | |
| 67 bool requiresAttributeCoverage = | |
| 68 !skipCoverage && SkToBool(desc->fAttribBindings & GrDrawState::kCoverage
_AttribBindingsBit); | |
| 69 | |
| 70 // fColorInput/fCoverageInput records how colors are specified for the progr
am So we strip the | |
| 71 // bits from the bindings to avoid false negatives when searching for an exi
sting program in the | |
| 72 // cache. | |
| 73 desc->fAttribBindings &= | |
| 74 ~(GrDrawState::kColor_AttribBindingsBit | GrDrawState::kCoverage_AttribB
indingsBit); | |
| 75 | |
| 76 desc->fColorFilterXfermode = skipColor ? | |
| 77 SkXfermode::kDst_Mode : | |
| 78 drawState.getColorFilterMode(); | |
| 79 | |
| 80 // no reason to do edge aa or look at per-vertex coverage if coverage is ign
ored | |
| 81 if (skipCoverage) { | |
| 82 desc->fAttribBindings &= ~(GrDrawState::kCoverage_AttribBindingsBit); | |
| 83 } | |
| 84 | |
| 85 bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_B
lendOptFlag); | |
| 86 bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFla
g) || | |
| 87 (!requiresAttributeColors && 0xffffffff == drawStat
e.getColor()); | |
| 88 if (colorIsTransBlack) { | |
| 89 desc->fColorInput = kTransBlack_ColorInput; | |
| 90 } else if (colorIsSolidWhite) { | |
| 91 desc->fColorInput = kSolidWhite_ColorInput; | |
| 92 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) { | |
| 93 desc->fColorInput = kUniform_ColorInput; | |
| 94 } else { | |
| 95 desc->fColorInput = kAttribute_ColorInput; | |
| 96 } | |
| 97 | |
| 98 bool covIsSolidWhite = !requiresAttributeCoverage && 0xffffffff == drawState
.getCoverage(); | |
| 99 | |
| 100 if (skipCoverage) { | |
| 101 desc->fCoverageInput = kTransBlack_ColorInput; | |
| 102 } else if (covIsSolidWhite) { | |
| 103 desc->fCoverageInput = kSolidWhite_ColorInput; | |
| 104 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) { | |
| 105 desc->fCoverageInput = kUniform_ColorInput; | |
| 106 } else { | |
| 107 desc->fCoverageInput = kAttribute_ColorInput; | |
| 108 } | |
| 109 | |
| 110 int lastEnabledStage = -1; | |
| 111 | |
| 112 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | |
| 113 | |
| 114 bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCove
rage; | |
| 115 if (!skip && drawState.isStageEnabled(s)) { | |
| 116 lastEnabledStage = s; | |
| 117 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); | |
| 118 const GrBackendEffectFactory& factory = effect->getFactory(); | |
| 119 bool explicitLocalCoords = (drawState.getAttribBindings() & | |
| 120 GrDrawState::kLocalCoords_AttribBindings
Bit); | |
| 121 GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords); | |
| 122 desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps()
); | |
| 123 } else { | |
| 124 desc->fEffectKeys[s] = 0; | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 desc->fDualSrcOutput = kNone_DualSrcOutput; | |
| 129 | |
| 130 // Currently the experimental GS will only work with triangle prims (and it
doesn't do anything | |
| 131 // other than pass through values from the VS to the FS anyway). | |
| 132 #if GR_GL_EXPERIMENTAL_GS | |
| 133 #if 0 | |
| 134 desc->fExperimentalGS = gpu->caps().geometryShaderSupport(); | |
| 135 #else | |
| 136 desc->fExperimentalGS = false; | |
| 137 #endif | |
| 138 #endif | |
| 139 | |
| 140 // We leave this set to kNumStages until we discover that the coverage/color
distinction is | |
| 141 // material to the generated program. We do this to avoid distinct keys that
generate equivalent | |
| 142 // programs. | |
| 143 desc->fFirstCoverageStage = GrDrawState::kNumStages; | |
| 144 // This tracks the actual first coverage stage. | |
| 145 int firstCoverageStage = GrDrawState::kNumStages; | |
| 146 desc->fDiscardIfZeroCoverage = false; // Enabled below if stenciling and the
re is coverage. | |
| 147 bool hasCoverage = false; | |
| 148 // If we're rendering coverage-as-color then its as though there are no cove
rage stages. | |
| 149 if (!drawState.isCoverageDrawing()) { | |
| 150 // We can have coverage either through a stage or coverage vertex attrib
utes. | |
| 151 if (drawState.getFirstCoverageStage() <= lastEnabledStage) { | |
| 152 firstCoverageStage = drawState.getFirstCoverageStage(); | |
| 153 hasCoverage = true; | |
| 154 } else { | |
| 155 hasCoverage = requiresAttributeCoverage; | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 if (hasCoverage) { | |
| 160 // color filter is applied between color/coverage computation | |
| 161 if (SkXfermode::kDst_Mode != desc->fColorFilterXfermode) { | |
| 162 desc->fFirstCoverageStage = firstCoverageStage; | |
| 163 } | |
| 164 | |
| 165 // If we're stenciling then we want to discard samples that have zero co
verage | |
| 166 if (drawState.getStencil().doesWrite()) { | |
| 167 desc->fDiscardIfZeroCoverage = true; | |
| 168 desc->fFirstCoverageStage = firstCoverageStage; | |
| 169 } | |
| 170 | |
| 171 if (gpu->caps()->dualSourceBlendingSupport() && | |
| 172 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | | |
| 173 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { | |
| 174 if (kZero_GrBlendCoeff == dstCoeff) { | |
| 175 // write the coverage value to second color | |
| 176 desc->fDualSrcOutput = kCoverage_DualSrcOutput; | |
| 177 desc->fFirstCoverageStage = firstCoverageStage; | |
| 178 } else if (kSA_GrBlendCoeff == dstCoeff) { | |
| 179 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. | |
| 180 desc->fDualSrcOutput = kCoverageISA_DualSrcOutput; | |
| 181 desc->fFirstCoverageStage = firstCoverageStage; | |
| 182 } else if (kSC_GrBlendCoeff == dstCoeff) { | |
| 183 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. | |
| 184 desc->fDualSrcOutput = kCoverageISC_DualSrcOutput; | |
| 185 desc->fFirstCoverageStage = firstCoverageStage; | |
| 186 } | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 desc->fPositionAttributeIndex = drawState.getAttribIndex(GrDrawState::kPosit
ion_AttribIndex); | |
| 191 if (requiresAttributeColors) { | |
| 192 desc->fColorAttributeIndex = drawState.getAttribIndex(GrDrawState::kColo
r_AttribIndex); | |
| 193 } else { | |
| 194 desc->fColorAttributeIndex = GrDrawState::kColorOverrideAttribIndexValue
; | |
| 195 } | |
| 196 if (requiresAttributeCoverage) { | |
| 197 desc->fCoverageAttributeIndex = drawState.getAttribIndex(GrDrawState::kC
overage_AttribIndex); | |
| 198 } else { | |
| 199 desc->fCoverageAttributeIndex = GrDrawState::kCoverageOverrideAttribInde
xValue; | |
| 200 } | |
| 201 if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { | |
| 202 desc->fLocalCoordsAttributeIndex = drawState.getAttribIndex(GrDrawState:
:kLocalCoords_AttribIndex); | |
| 203 } | |
| 204 | |
| 205 #if GR_DEBUG | |
| 206 // Verify valid vertex attribute state. These assertions should probably be
done somewhere | |
| 207 // higher up the callstack | |
| 208 const GrVertexAttrib* vertexAttribs = drawState.getVertexAttribs(); | |
| 209 GrAssert(desc->fPositionAttributeIndex < GrDrawState::kVertexAttribCnt); | |
| 210 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fPositionAttributeIndex]
.fType).fCount == 2); | |
| 211 if (requiresAttributeColors) { | |
| 212 GrAssert(desc->fColorAttributeIndex < GrDrawState::kVertexAttribCnt); | |
| 213 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fColorAttributeIndex
].fType).fCount == 4); | |
| 214 } | |
| 215 if (requiresAttributeCoverage) { | |
| 216 GrAssert(desc->fCoverageAttributeIndex < GrDrawState::kVertexAttribCnt); | |
| 217 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fCoverageAttributeIn
dex].fType).fCount == 4); | |
| 218 } | |
| 219 if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { | |
| 220 GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCn
t); | |
| 221 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fLocalCoordsAttribut
eIndex].fType).fCount == 2); | |
| 222 } | |
| 223 #endif | |
| 224 } | |
| 225 | |
| 226 GrGLProgram* GrGLProgram::Create(const GrGLContext& gl, | 38 GrGLProgram* GrGLProgram::Create(const GrGLContext& gl, |
| 227 const GrGLProgramDesc& desc, | 39 const GrGLProgramDesc& desc, |
| 228 const GrEffectStage* stages[]) { | 40 const GrEffectStage* stages[]) { |
| 229 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages)); | 41 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages)); |
| 230 if (!program->succeeded()) { | 42 if (!program->succeeded()) { |
| 231 delete program; | 43 delete program; |
| 232 program = NULL; | 44 program = NULL; |
| 233 } | 45 } |
| 234 return program; | 46 return program; |
| 235 } | 47 } |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 SkScalarToFloat(m[SkMatrix::kMTransX]), | 916 SkScalarToFloat(m[SkMatrix::kMTransX]), |
| 1105 SkScalarToFloat(m[SkMatrix::kMTransY]), | 917 SkScalarToFloat(m[SkMatrix::kMTransY]), |
| 1106 SkScalarToFloat(m[SkMatrix::kMPersp2]) | 918 SkScalarToFloat(m[SkMatrix::kMPersp2]) |
| 1107 }; | 919 }; |
| 1108 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); | 920 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); |
| 1109 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 921 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
| 1110 fMatrixState.fRenderTargetSize = size; | 922 fMatrixState.fRenderTargetSize = size; |
| 1111 fMatrixState.fRenderTargetOrigin = rt->origin(); | 923 fMatrixState.fRenderTargetOrigin = rt->origin(); |
| 1112 } | 924 } |
| 1113 } | 925 } |
| OLD | NEW |