Index: src/gpu/gl/GrGLProgramDesc.cpp |
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp |
index 545ed2114c7d5ea01512cae139f7f0537bb9e15b..8d0ea3d6b370f7df36ce9a6a90cf4eb21a2df00b 100644 |
--- a/src/gpu/gl/GrGLProgramDesc.cpp |
+++ b/src/gpu/gl/GrGLProgramDesc.cpp |
@@ -53,6 +53,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
GrBlendCoeff dstCoeff, |
const GrGpuGL* gpu, |
const GrDeviceCoordTexture* dstCopy, |
+ const GrEffectStage** geometryProcessor, |
SkTArray<const GrEffectStage*, true>* colorStages, |
SkTArray<const GrEffectStage*, true>* coverageStages, |
GrGLProgramDesc* desc) { |
@@ -69,6 +70,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
int firstEffectiveColorStage = 0; |
bool inputColorIsUsed = true; |
+ |
if (!skipColor) { |
firstEffectiveColorStage = drawState.numColorStages(); |
while (firstEffectiveColorStage > 0 && inputColorIsUsed) { |
@@ -107,6 +109,9 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType); |
int numStages = 0; |
+ if (drawState.hasGeometryProcessor()) { |
+ numStages++; |
+ } |
if (!skipColor) { |
numStages += drawState.numColorStages() - firstEffectiveColorStage; |
} |
@@ -120,12 +125,42 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
int offsetAndSizeIndex = 0; |
bool effectKeySuccess = true; |
+ |
+ KeyHeader* header = desc->header(); |
+ // make sure any padding in the header is zeroed. |
+ memset(desc->header(), 0, kHeaderSize); |
+ |
+ // We can only have one effect which touches the vertex shader |
+ if (drawState.hasGeometryProcessor()) { |
+ uint16_t* offsetAndSize = |
+ reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + |
+ offsetAndSizeIndex * 2 * sizeof(uint16_t)); |
+ |
+ GrEffectKeyBuilder b(&desc->fKey); |
+ uint16_t effectKeySize; |
+ uint32_t effectOffset = desc->fKey.count(); |
+ effectKeySuccess |= GetEffectKeyAndUpdateStats( |
+ *drawState.getGeometryProcessor(), gpu->glCaps(), |
+ requiresLocalCoordAttrib, &b, |
+ &effectKeySize, &readsDst, |
+ &readFragPosition, &requiresVertexShader); |
+ effectKeySuccess |= (effectOffset <= SK_MaxU16); |
+ |
+ offsetAndSize[0] = SkToU16(effectOffset); |
+ offsetAndSize[1] = effectKeySize; |
+ ++offsetAndSizeIndex; |
+ *geometryProcessor = drawState.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(); |
@@ -133,12 +168,13 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
drawState.getColorStage(s), gpu->glCaps(), |
requiresLocalCoordAttrib, &b, |
&effectKeySize, &readsDst, |
- &readFragPosition, &requiresVertexShader); |
+ &readFragPosition, &effectRequiresVertexShader); |
effectKeySuccess |= (effectOffset <= SK_MaxU16); |
offsetAndSize[0] = SkToU16(effectOffset); |
offsetAndSize[1] = effectKeySize; |
++offsetAndSizeIndex; |
+ SkASSERT(!effectRequiresVertexShader); |
} |
} |
if (!skipCoverage) { |
@@ -147,6 +183,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
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(); |
@@ -154,12 +191,13 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
drawState.getCoverageStage(s), gpu->glCaps(), |
requiresLocalCoordAttrib, &b, |
&effectKeySize, &readsDst, |
- &readFragPosition, &requiresVertexShader); |
+ &readFragPosition, &effectRequiresVertexShader); |
effectKeySuccess |= (effectOffset <= SK_MaxU16); |
offsetAndSize[0] = SkToU16(effectOffset); |
offsetAndSize[1] = effectKeySize; |
++offsetAndSizeIndex; |
+ SkASSERT(!effectRequiresVertexShader); |
} |
} |
if (!effectKeySuccess) { |
@@ -167,10 +205,6 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
return false; |
} |
- KeyHeader* header = desc->header(); |
- // make sure any padding in the header is zeroed. |
- memset(desc->header(), 0, kHeaderSize); |
- |
// Because header is a pointer into the dynamic array, we can't push any new data into the key |
// below here. |
@@ -259,9 +293,11 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
header->fCoverageOutput = kModulate_CoverageOutput; |
// If we do have coverage determine whether it matters. |
- bool separateCoverageFromColor = false; |
+ bool separateCoverageFromColor = drawState.hasGeometryProcessor(); |
if (!drawState.isCoverageDrawing() && !skipCoverage && |
- (drawState.numCoverageStages() > 0 || requiresCoverageAttrib)) { |
+ (drawState.numCoverageStages() > 0 || |
+ drawState.hasGeometryProcessor() || |
+ requiresCoverageAttrib)) { |
if (gpu->caps()->dualSourceBlendingSupport() && |
!(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | |
@@ -286,6 +322,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState, |
separateCoverageFromColor = true; |
} |
} |
+ |
if (!skipColor) { |
for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) { |
colorStages->push_back(&drawState.getColorStage(s)); |