Index: src/gpu/gl/GrGLProgramDesc.cpp |
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp |
index 4056c77808750f97620e30f2e1ab0119a6edfa71..b49cff97af739ed22d0b804475914c232d54757a 100644 |
--- a/src/gpu/gl/GrGLProgramDesc.cpp |
+++ b/src/gpu/gl/GrGLProgramDesc.cpp |
@@ -10,6 +10,7 @@ |
#include "GrBackendEffectFactory.h" |
#include "GrEffect.h" |
#include "GrGpuGL.h" |
+#include "GrOptDrawState.h" |
#include "SkChecksum.h" |
@@ -48,9 +49,8 @@ bool GrGLProgramDesc::GetEffectKeyAndUpdateStats(const GrEffectStage& stage, |
return true; |
} |
-bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
+bool GrGLProgramDesc::Build(const GrOptDrawState& optState, |
GrGpu::DrawType drawType, |
- GrDrawState::BlendOptFlags blendOpts, |
GrBlendCoeff srcCoeff, |
GrBlendCoeff dstCoeff, |
const GrGpuGL* gpu, |
@@ -62,47 +62,19 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
colorStages->reset(); |
coverageStages->reset(); |
- // This should already have been caught |
- SkASSERT(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); |
- |
- bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag); |
- |
- bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag | |
- GrDrawState::kEmitCoverage_BlendOptFlag)); |
- |
- int firstEffectiveColorStage = 0; |
- bool inputColorIsUsed = true; |
- |
- if (!skipColor) { |
- firstEffectiveColorStage = drawState.numColorStages(); |
- while (firstEffectiveColorStage > 0 && inputColorIsUsed) { |
- --firstEffectiveColorStage; |
- const GrEffect* effect = drawState.getColorStage(firstEffectiveColorStage).getEffect(); |
- inputColorIsUsed = effect->willUseInputColor(); |
- } |
- } |
- |
- int firstEffectiveCoverageStage = 0; |
- bool inputCoverageIsUsed = true; |
- if (!skipCoverage) { |
- firstEffectiveCoverageStage = drawState.numCoverageStages(); |
- while (firstEffectiveCoverageStage > 0 && inputCoverageIsUsed) { |
- --firstEffectiveCoverageStage; |
- const GrEffect* effect = drawState.getCoverageStage(firstEffectiveCoverageStage).getEffect(); |
- inputCoverageIsUsed = effect->willUseInputColor(); |
- } |
- } |
+ bool inputColorIsUsed = optState.inputColorIsUsed(); |
+ bool inputCoverageIsUsed = optState.inputColorIsUsed(); |
// The descriptor is used as a cache key. Thus when a field of the |
// descriptor will not affect program generation (because of the attribute |
// bindings in use or other descriptor field settings) it should be set |
// to a canonical value to avoid duplicate programs with different keys. |
- bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute(); |
- bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAttribute(); |
+ bool requiresColorAttrib = optState.hasColorVertexAttribute(); |
+ bool requiresCoverageAttrib = optState.hasCoverageVertexAttribute(); |
// we only need the local coords if we're actually going to generate effect code |
- bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) && |
- drawState.hasLocalCoordAttribute(); |
+ bool requiresLocalCoordAttrib = optState.numTotalStages() > 0 && |
+ optState.hasLocalCoordAttribute(); |
bool readsDst = false; |
bool readFragPosition = false; |
@@ -110,16 +82,8 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
// Provide option for shader programs without vertex shader only when drawing paths. |
bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType); |
- int numStages = 0; |
- if (drawState.hasGeometryProcessor()) { |
- numStages++; |
- } |
- if (!skipColor) { |
- numStages += drawState.numColorStages() - firstEffectiveColorStage; |
- } |
- if (!skipCoverage) { |
- numStages += drawState.numCoverageStages() - firstEffectiveCoverageStage; |
- } |
+ int numStages = optState.numTotalStages(); |
+ |
GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); |
// Make room for everything up to and including the array of offsets to effect keys. |
desc->fKey.reset(); |
@@ -133,7 +97,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
memset(desc->header(), 0, kHeaderSize); |
// We can only have one effect which touches the vertex shader |
- if (drawState.hasGeometryProcessor()) { |
+ if (optState.hasGeometryProcessor()) { |
uint16_t* offsetAndSize = |
reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + |
offsetAndSizeIndex * 2 * sizeof(uint16_t)); |
@@ -142,7 +106,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
uint16_t effectKeySize; |
uint32_t effectOffset = desc->fKey.count(); |
effectKeySuccess |= GetEffectKeyAndUpdateStats( |
- *drawState.getGeometryProcessor(), gpu->glCaps(), |
+ *optState.getGeometryProcessor(), gpu->glCaps(), |
requiresLocalCoordAttrib, &b, |
&effectKeySize, &readsDst, |
&readFragPosition, &requiresVertexShader); |
@@ -151,57 +115,55 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
offsetAndSize[0] = SkToU16(effectOffset); |
offsetAndSize[1] = effectKeySize; |
++offsetAndSizeIndex; |
- *geometryProcessor = drawState.getGeometryProcessor(); |
+ *geometryProcessor = optState.getGeometryProcessor(); |
SkASSERT(requiresVertexShader); |
header->fHasGeometryProcessor = true; |
} |
- if (!skipColor) { |
- for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) { |
- uint16_t* offsetAndSize = |
- reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + |
- offsetAndSizeIndex * 2 * sizeof(uint16_t)); |
- |
- bool effectRequiresVertexShader = false; |
- GrEffectKeyBuilder b(&desc->fKey); |
- uint16_t effectKeySize; |
- uint32_t effectOffset = desc->fKey.count(); |
- effectKeySuccess |= GetEffectKeyAndUpdateStats( |
- drawState.getColorStage(s), gpu->glCaps(), |
- requiresLocalCoordAttrib, &b, |
- &effectKeySize, &readsDst, |
- &readFragPosition, &effectRequiresVertexShader); |
- effectKeySuccess |= (effectOffset <= SK_MaxU16); |
- |
- offsetAndSize[0] = SkToU16(effectOffset); |
- offsetAndSize[1] = effectKeySize; |
- ++offsetAndSizeIndex; |
- SkASSERT(!effectRequiresVertexShader); |
- } |
+ for (int s = 0; s < optState.numColorStages(); ++s) { |
+ uint16_t* offsetAndSize = |
+ reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + |
+ offsetAndSizeIndex * 2 * sizeof(uint16_t)); |
+ |
+ bool effectRequiresVertexShader = false; |
+ GrEffectKeyBuilder b(&desc->fKey); |
+ uint16_t effectKeySize; |
+ uint32_t effectOffset = desc->fKey.count(); |
+ effectKeySuccess |= GetEffectKeyAndUpdateStats( |
+ optState.getColorStage(s), gpu->glCaps(), |
+ requiresLocalCoordAttrib, &b, |
+ &effectKeySize, &readsDst, |
+ &readFragPosition, &effectRequiresVertexShader); |
+ effectKeySuccess |= (effectOffset <= SK_MaxU16); |
+ |
+ offsetAndSize[0] = SkToU16(effectOffset); |
+ offsetAndSize[1] = effectKeySize; |
+ ++offsetAndSizeIndex; |
+ SkASSERT(!effectRequiresVertexShader); |
} |
- if (!skipCoverage) { |
- for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) { |
- uint16_t* offsetAndSize = |
- reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + |
- offsetAndSizeIndex * 2 * sizeof(uint16_t)); |
- |
- bool effectRequiresVertexShader = false; |
- GrEffectKeyBuilder b(&desc->fKey); |
- uint16_t effectKeySize; |
- uint32_t effectOffset = desc->fKey.count(); |
- effectKeySuccess |= GetEffectKeyAndUpdateStats( |
- drawState.getCoverageStage(s), gpu->glCaps(), |
- requiresLocalCoordAttrib, &b, |
- &effectKeySize, &readsDst, |
- &readFragPosition, &effectRequiresVertexShader); |
- effectKeySuccess |= (effectOffset <= SK_MaxU16); |
- offsetAndSize[0] = SkToU16(effectOffset); |
- offsetAndSize[1] = effectKeySize; |
- ++offsetAndSizeIndex; |
- SkASSERT(!effectRequiresVertexShader); |
- } |
+ for (int s = 0; s < optState.numCoverageStages(); ++s) { |
+ uint16_t* offsetAndSize = |
+ reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + |
+ offsetAndSizeIndex * 2 * sizeof(uint16_t)); |
+ |
+ bool effectRequiresVertexShader = false; |
+ GrEffectKeyBuilder b(&desc->fKey); |
+ uint16_t effectKeySize; |
+ uint32_t effectOffset = desc->fKey.count(); |
+ effectKeySuccess |= GetEffectKeyAndUpdateStats( |
+ optState.getCoverageStage(s), gpu->glCaps(), |
+ requiresLocalCoordAttrib, &b, |
+ &effectKeySize, &readsDst, |
+ &readFragPosition, &effectRequiresVertexShader); |
+ effectKeySuccess |= (effectOffset <= SK_MaxU16); |
+ |
+ offsetAndSize[0] = SkToU16(effectOffset); |
+ offsetAndSize[1] = effectKeySize; |
+ ++offsetAndSizeIndex; |
+ SkASSERT(!effectRequiresVertexShader); |
} |
+ |
if (!effectKeySuccess) { |
desc->fKey.reset(); |
return false; |
@@ -224,20 +186,20 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
#endif |
bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->pathRenderingSupport(); |
- if (!inputColorIsUsed && !skipColor) { |
+ if (!inputColorIsUsed) { |
header->fColorInput = kAllOnes_ColorInput; |
- } else if (defaultToUniformInputs && !requiresColorAttrib && inputColorIsUsed) { |
+ } else if (defaultToUniformInputs && !requiresColorAttrib) { |
header->fColorInput = kUniform_ColorInput; |
} else { |
header->fColorInput = kAttribute_ColorInput; |
header->fRequiresVertexShader = true; |
} |
- bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor(); |
+ bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == optState.getCoverageColor(); |
- if ((covIsSolidWhite || !inputCoverageIsUsed) && !skipCoverage) { |
+ if (covIsSolidWhite || !inputCoverageIsUsed) { |
header->fCoverageInput = kAllOnes_ColorInput; |
- } else if (defaultToUniformInputs && !requiresCoverageAttrib && inputCoverageIsUsed) { |
+ } else if (defaultToUniformInputs && !requiresCoverageAttrib) { |
header->fCoverageInput = kUniform_ColorInput; |
} else { |
header->fCoverageInput = kAttribute_ColorInput; |
@@ -259,19 +221,19 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
if (readFragPosition) { |
header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition( |
- drawState.getRenderTarget(), gpu->glCaps()); |
+ optState.getRenderTarget(), gpu->glCaps()); |
} else { |
header->fFragPosKey = 0; |
} |
// Record attribute indices |
- header->fPositionAttributeIndex = drawState.positionAttributeIndex(); |
- header->fLocalCoordAttributeIndex = drawState.localCoordAttributeIndex(); |
+ header->fPositionAttributeIndex = optState.positionAttributeIndex(); |
+ header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex(); |
// For constant color and coverage we need an attribute with an index beyond those already set |
- int availableAttributeIndex = drawState.getVertexAttribCount(); |
+ int availableAttributeIndex = optState.getVertexAttribCount(); |
if (requiresColorAttrib) { |
- header->fColorAttributeIndex = drawState.colorVertexAttributeIndex(); |
+ header->fColorAttributeIndex = optState.colorVertexAttributeIndex(); |
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) { |
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); |
header->fColorAttributeIndex = availableAttributeIndex; |
@@ -281,7 +243,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
} |
if (requiresCoverageAttrib) { |
- header->fCoverageAttributeIndex = drawState.coverageVertexAttributeIndex(); |
+ header->fCoverageAttributeIndex = optState.coverageVertexAttributeIndex(); |
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) { |
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); |
header->fCoverageAttributeIndex = availableAttributeIndex; |
@@ -295,15 +257,13 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
header->fCoverageOutput = kModulate_CoverageOutput; |
// If we do have coverage determine whether it matters. |
- bool separateCoverageFromColor = drawState.hasGeometryProcessor(); |
- if (!drawState.isCoverageDrawing() && !skipCoverage && |
- (drawState.numCoverageStages() > 0 || |
- drawState.hasGeometryProcessor() || |
+ bool separateCoverageFromColor = optState.hasGeometryProcessor(); |
+ if (!optState.isCoverageDrawing() && |
+ (optState.numCoverageStages() > 0 || |
+ optState.hasGeometryProcessor() || |
requiresCoverageAttrib)) { |
- if (gpu->caps()->dualSourceBlendingSupport() && |
- !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | |
- GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { |
+ if (gpu->caps()->dualSourceBlendingSupport()) { |
if (kZero_GrBlendCoeff == dstCoeff) { |
// write the coverage value to second color |
header->fCoverageOutput = kSecondaryCoverage_CoverageOutput; |
@@ -325,22 +285,19 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
} |
} |
- if (!skipColor) { |
- for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) { |
- colorStages->push_back(&drawState.getColorStage(s)); |
- } |
+ for (int s = 0; s < optState.numColorStages(); ++s) { |
+ colorStages->push_back(&optState.getColorStage(s)); |
} |
- if (!skipCoverage) { |
- SkTArray<const GrEffectStage*, true>* array; |
- if (separateCoverageFromColor) { |
- array = coverageStages; |
- } else { |
- array = colorStages; |
- } |
- for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) { |
- array->push_back(&drawState.getCoverageStage(s)); |
- } |
+ SkTArray<const GrEffectStage*, true>* array; |
+ if (separateCoverageFromColor) { |
+ array = coverageStages; |
+ } else { |
+ array = colorStages; |
+ } |
+ for (int s = 0; s < optState.numCoverageStages(); ++s) { |
+ array->push_back(&optState.getCoverageStage(s)); |
} |
+ |
header->fColorEffectCnt = colorStages->count(); |
header->fCoverageEffectCnt = coverageStages->count(); |