Initial change to create GeometryProcessor
BUG=skia:
R=bsalomon@google.com, robertphillips@google.com, egdaniel@google.com, jvanverth@google.com
Author: joshualitt@chromium.org
Review URL: https://codereview.chromium.org/509153002
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 534e3c3..7b5dbb4 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -23,17 +23,19 @@
GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
const GrGLProgramDesc& desc,
+ const GrEffectStage* geometryProcessor,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[]) {
SkAutoTDelete<GrGLProgramBuilder> builder;
if (!desc.getHeader().fRequiresVertexShader &&
gpu->glCaps().pathRenderingSupport() &&
gpu->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunction_TexturingMode) {
+ SkASSERT(NULL == geometryProcessor);
builder.reset(SkNEW_ARGS(GrGLFragmentOnlyProgramBuilder, (gpu, desc)));
} else {
builder.reset(SkNEW_ARGS(GrGLFullProgramBuilder, (gpu, desc)));
}
- if (builder->genProgram(colorStages, coverageStages)) {
+ if (builder->genProgram(geometryProcessor, colorStages, coverageStages)) {
SkASSERT(0 != builder->getProgramID());
return SkNEW_ARGS(GrGLProgram, (gpu, desc, *builder));
}
@@ -47,6 +49,7 @@
, fCoverage(GrColor_ILLEGAL)
, fDstCopyTexUnit(-1)
, fBuiltinUniformHandles(builder.getBuiltinUniformHandles())
+ , fGeometryProcessor(SkSafeRef(builder.getGeometryProcessor()))
, fColorEffects(SkRef(builder.getColorEffects()))
, fCoverageEffects(SkRef(builder.getCoverageEffects()))
, fProgramID(builder.getProgramID())
@@ -97,6 +100,9 @@
fProgramDataManager.setSampler(fBuiltinUniformHandles.fDstCopySamplerUni, texUnitIdx);
fDstCopyTexUnit = texUnitIdx++;
}
+ if (NULL != fGeometryProcessor.get()) {
+ fGeometryProcessor->initSamplers(fProgramDataManager, &texUnitIdx);
+ }
fColorEffects->initSamplers(fProgramDataManager, &texUnitIdx);
fCoverageEffects->initSamplers(fProgramDataManager, &texUnitIdx);
}
@@ -105,6 +111,7 @@
void GrGLProgram::setData(GrGpu::DrawType drawType,
GrDrawState::BlendOptFlags blendOpts,
+ const GrEffectStage* geometryProcessor,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[],
const GrDeviceCoordTexture* dstCopy,
@@ -149,6 +156,10 @@
SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
}
+ if (NULL != fGeometryProcessor.get()) {
+ SkASSERT(NULL != geometryProcessor);
+ fGeometryProcessor->setData(fGpu, drawType,fProgramDataManager, geometryProcessor);
+ }
fColorEffects->setData(fGpu, drawType,fProgramDataManager, colorStages);
fCoverageEffects->setData(fGpu, drawType,fProgramDataManager, coverageStages);
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 5b9deb9..0f89e07 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -41,6 +41,7 @@
static GrGLProgram* Create(GrGpuGL* gpu,
const GrGLProgramDesc& desc,
+ const GrEffectStage* geometryProcessor,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[]);
@@ -158,6 +159,7 @@
*/
void setData(GrGpu::DrawType,
GrDrawState::BlendOptFlags,
+ const GrEffectStage* geometryProcessor,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[],
const GrDeviceCoordTexture* dstCopy, // can be NULL
@@ -191,6 +193,7 @@
int fDstCopyTexUnit;
BuiltinUniformHandles fBuiltinUniformHandles;
+ SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor;
SkAutoTUnref<GrGLProgramEffects> fColorEffects;
SkAutoTUnref<GrGLProgramEffects> fCoverageEffects;
GrGLuint fProgramID;
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index 545ed21..8d0ea3d 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -53,6 +53,7 @@
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 @@
int firstEffectiveColorStage = 0;
bool inputColorIsUsed = true;
+
if (!skipColor) {
firstEffectiveColorStage = drawState.numColorStages();
while (firstEffectiveColorStage > 0 && inputColorIsUsed) {
@@ -107,6 +109,9 @@
bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType);
int numStages = 0;
+ if (drawState.hasGeometryProcessor()) {
+ numStages++;
+ }
if (!skipColor) {
numStages += drawState.numColorStages() - firstEffectiveColorStage;
}
@@ -120,9 +125,14 @@
int offsetAndSizeIndex = 0;
bool effectKeySuccess = true;
- if (!skipColor) {
- for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
- uint16_t* offsetAndSize =
+
+ 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));
@@ -130,7 +140,7 @@
uint16_t effectKeySize;
uint32_t effectOffset = desc->fKey.count();
effectKeySuccess |= GetEffectKeyAndUpdateStats(
- drawState.getColorStage(s), gpu->glCaps(),
+ *drawState.getGeometryProcessor(), gpu->glCaps(),
requiresLocalCoordAttrib, &b,
&effectKeySize, &readsDst,
&readFragPosition, &requiresVertexShader);
@@ -139,6 +149,32 @@
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();
+ 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);
}
}
if (!skipCoverage) {
@@ -147,6 +183,7 @@
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 @@
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 @@
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 @@
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 @@
separateCoverageFromColor = true;
}
}
+
if (!skipColor) {
for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
colorStages->push_back(&drawState.getColorStage(s));
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index aefcb50..b1f54b7 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -48,6 +48,7 @@
const GrGpuGL* gpu,
const GrRenderTarget* dummyDstRenderTarget,
const GrTexture* dummyDstCopyTexture,
+ const GrEffectStage* geometryProcessor,
const GrEffectStage* stages[],
int numColorStages,
int numCoverageStages,
@@ -67,10 +68,15 @@
GrBlendCoeff dstCoeff,
const GrGpuGL* gpu,
const GrDeviceCoordTexture* dstCopy,
+ const GrEffectStage** outGeometryProcessor,
SkTArray<const GrEffectStage*, true>* outColorStages,
SkTArray<const GrEffectStage*, true>* outCoverageStages,
GrGLProgramDesc* outDesc);
+ bool hasGeometryProcessor() const {
+ return SkToBool(this->getHeader().fHasGeometryProcessor);
+ }
+
int numColorEffects() const {
return this->getHeader().fColorEffectCnt;
}
@@ -161,6 +167,7 @@
int8_t fColorAttributeIndex;
int8_t fCoverageAttributeIndex;
+ SkBool8 fHasGeometryProcessor;
int8_t fColorEffectCnt;
int8_t fCoverageEffectCnt;
};
@@ -213,13 +220,24 @@
class EffectKeyProvider {
public:
enum EffectType {
+ kGeometryProcessor_EffectType,
kColor_EffectType,
kCoverage_EffectType,
};
EffectKeyProvider(const GrGLProgramDesc* desc, EffectType type) : fDesc(desc) {
- // Coverage effect key offsets begin immediately after those of the color effects.
- fBaseIndex = kColor_EffectType == type ? 0 : desc->numColorEffects();
+ switch (type) {
+ case kGeometryProcessor_EffectType:
+ // there can be only one
+ fBaseIndex = 0;
+ break;
+ case kColor_EffectType:
+ fBaseIndex = desc->hasGeometryProcessor() ? 1 : 0;
+ break;
+ case kCoverage_EffectType:
+ fBaseIndex = desc->numColorEffects() + (desc->hasGeometryProcessor() ? 1 : 0);
+ break;
+ }
}
GrEffectKey get(int index) const {
diff --git a/src/gpu/gl/GrGLProgramEffects.cpp b/src/gpu/gl/GrGLProgramEffects.cpp
index 8d97b42..45edca8 100644
--- a/src/gpu/gl/GrGLProgramEffects.cpp
+++ b/src/gpu/gl/GrGLProgramEffects.cpp
@@ -387,6 +387,24 @@
}
}
+void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
+ GrGpu::DrawType drawType,
+ const GrGLProgramDataManager& programDataManager,
+ const GrEffectStage* effectStage) {
+ SkASSERT(1 == fTransforms.count());
+ SkASSERT(1 == fSamplers.count());
+ SkASSERT(1 == fGLEffects.count());
+ GrDrawEffect drawEffect(*effectStage, fHasExplicitLocalCoords);
+ fGLEffects[0]->setData(programDataManager, drawEffect);
+ if (GrGpu::IsPathRenderingDrawType(drawType)) {
+ this->setPathTransformData(gpu, programDataManager, drawEffect, 0);
+ } else {
+ this->setTransformData(gpu, programDataManager, drawEffect, 0);
+ }
+
+ this->bindTextures(gpu, drawEffect.effect(), 0);
+}
+
void GrGLVertexProgramEffects::setTransformData(GrGpuGL* gpu,
const GrGLProgramDataManager& pdman,
const GrDrawEffect& drawEffect,
diff --git a/src/gpu/gl/GrGLProgramEffects.h b/src/gpu/gl/GrGLProgramEffects.h
index 0eaff53..daaebd6 100644
--- a/src/gpu/gl/GrGLProgramEffects.h
+++ b/src/gpu/gl/GrGLProgramEffects.h
@@ -57,6 +57,11 @@
const GrGLProgramDataManager&,
const GrEffectStage* effectStages[]) = 0;
+ virtual void setData(GrGpuGL*,
+ GrGpu::DrawType,
+ const GrGLProgramDataManager&,
+ const GrEffectStage* effectStages) { SkFAIL("DO NOT USE"); }
+
void addEffect(GrGLEffect* effect) { fGLEffects.push_back(effect); }
/**
@@ -140,7 +145,6 @@
SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
private:
- friend class GrGLFragmentO;
typedef SkRefCnt INHERITED;
};
@@ -172,6 +176,11 @@
const GrGLProgramDataManager&,
const GrEffectStage* effectStages[]) SK_OVERRIDE;
+ virtual void setData(GrGpuGL*,
+ GrGpu::DrawType,
+ const GrGLProgramDataManager&,
+ const GrEffectStage* effectStages) SK_OVERRIDE;
+
private:
friend class GrGLFullProgramBuilder;
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 1f748bb..004ce25 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -179,6 +179,7 @@
void abandon();
GrGLProgram* getProgram(const GrGLProgramDesc& desc,
+ const GrEffectStage* geometryProcessor,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[]);
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 8cdceb8..67c0cd3 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -90,6 +90,7 @@
}
GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc,
+ const GrEffectStage* geometryProcessor,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[]) {
#ifdef PROGRAM_CACHE_STATS
@@ -126,7 +127,8 @@
#ifdef PROGRAM_CACHE_STATS
++fCacheMisses;
#endif
- GrGLProgram* program = GrGLProgram::Create(fGpu, desc, colorStages, coverageStages);
+ GrGLProgram* program = GrGLProgram::Create(fGpu, desc, geometryProcessor,
+ colorStages, coverageStages);
if (NULL == program) {
return NULL;
}
@@ -222,6 +224,7 @@
return false;
}
+ const GrEffectStage* geometryProcessor = NULL;
SkSTArray<8, const GrEffectStage*, true> colorStages;
SkSTArray<8, const GrEffectStage*, true> coverageStages;
GrGLProgramDesc desc;
@@ -232,6 +235,7 @@
dstCoeff,
this,
dstCopy,
+ &geometryProcessor,
&colorStages,
&coverageStages,
&desc)) {
@@ -240,6 +244,7 @@
}
fCurrentProgram.reset(fProgramCache->getProgram(desc,
+ geometryProcessor,
colorStages.begin(),
coverageStages.begin()));
if (NULL == fCurrentProgram.get()) {
@@ -260,6 +265,7 @@
fCurrentProgram->setData(type,
blendOpts,
+ geometryProcessor,
colorStages.begin(),
coverageStages.begin(),
dstCopy,
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index 7664bab..ab64e28 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -31,7 +31,8 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
-bool GrGLProgramBuilder::genProgram(const GrEffectStage* colorStages[],
+bool GrGLProgramBuilder::genProgram(const GrEffectStage* geometryProcessor,
+ const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[]) {
const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
@@ -79,6 +80,8 @@
colorKeyProvider,
&inputColor));
+ this->emitGeometryProcessor(geometryProcessor, &inputCoverage);
+
GrGLProgramDesc::EffectKeyProvider coverageKeyProvider(
&this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType);
fCoverageEffects.reset(this->createAndEmitEffects(coverageStages,
@@ -334,10 +337,23 @@
, fVS(this) {
}
-void GrGLFullProgramBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
+void GrGLFullProgramBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color,
+ GrGLSLExpr4* coverage) {
fVS.emitCodeBeforeEffects(color, coverage);
}
+void GrGLFullProgramBuilder::emitGeometryProcessor(const GrEffectStage* geometryProcessor,
+ GrGLSLExpr4* coverage) {
+ if (NULL != geometryProcessor) {
+ GrGLProgramDesc::EffectKeyProvider geometryProcessorKeyProvider(
+ &this->desc(), GrGLProgramDesc::EffectKeyProvider::kGeometryProcessor_EffectType);
+ fGeometryProcessor.reset(this->createAndEmitEffect(
+ geometryProcessor,
+ geometryProcessorKeyProvider,
+ coverage));
+ }
+}
+
void GrGLFullProgramBuilder::emitCodeAfterEffects() {
fVS.emitCodeAfterEffects();
}
@@ -388,6 +404,56 @@
return programEffectsBuilder.finish();
}
+void GrGLFullProgramBuilder::createAndEmitEffect(GrGLProgramEffectsBuilder* programEffectsBuilder,
+ const GrEffectStage* effectStages,
+ const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+ GrGLSLExpr4* fsInOutColor) {
+ GrGLSLExpr4 inColor = *fsInOutColor;
+ GrGLSLExpr4 outColor;
+
+ SkASSERT(NULL != effectStages && NULL != effectStages->getEffect());
+ const GrEffectStage& stage = *effectStages;
+
+ // Using scope to force ASR destructor to be triggered
+ {
+ CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
+
+ if (inColor.isZeros()) {
+ SkString inColorName;
+
+ // Effects have no way to communicate zeros, they treat an empty string as ones.
+ this->nameVariable(&inColorName, '\0', "input");
+ fFS.codeAppendf("vec4 %s = %s;", inColorName.c_str(), inColor.c_str());
+ inColor = inColorName;
+ }
+
+ // create var to hold stage result
+ SkString outColorName;
+ this->nameVariable(&outColorName, '\0', "output");
+ fFS.codeAppendf("vec4 %s;", outColorName.c_str());
+ outColor = outColorName;
+
+
+ programEffectsBuilder->emitEffect(stage,
+ keyProvider.get(0),
+ outColor.c_str(),
+ inColor.isOnes() ? NULL : inColor.c_str(),
+ fCodeStage.stageIndex());
+ }
+
+ *fsInOutColor = outColor;
+}
+
+GrGLProgramEffects* GrGLFullProgramBuilder::createAndEmitEffect(
+ const GrEffectStage* geometryProcessor,
+ const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+ GrGLSLExpr4* inOutFSColor) {
+
+ GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, 1);
+ this->createAndEmitEffect(&programEffectsBuilder, geometryProcessor, keyProvider, inOutFSColor);
+ return programEffectsBuilder.finish();
+}
+
bool GrGLFullProgramBuilder::compileAndAttachShaders(GrGLuint programId,
SkTDArray<GrGLuint>* shaderIds) const {
return INHERITED::compileAndAttachShaders(programId, shaderIds)
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 00193ef..deb3708 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -84,11 +84,14 @@
* to be used.
* @return true if generation was successful.
*/
- bool genProgram(const GrEffectStage* inColorStages[],
+
+ bool genProgram(const GrEffectStage* inGeometryProcessor,
+ const GrEffectStage* inColorStages[],
const GrEffectStage* inCoverageStages[]);
- // Below are the results of the shader generation.
-
+ GrGLProgramEffects* getGeometryProcessor() const {
+ SkASSERT(fProgramID); return fGeometryProcessor.get();
+ }
GrGLProgramEffects* getColorEffects() const { SkASSERT(fProgramID); return fColorEffects.get(); }
GrGLProgramEffects* getCoverageEffects() const { SkASSERT(fProgramID); return fCoverageEffects.get(); }
const BuiltinUniformHandles& getBuiltinUniformHandles() const {
@@ -165,6 +168,7 @@
void appendDecls(const VarArray&, SkString*) const;
void appendUniformDecls(ShaderVisibility, SkString*) const;
+ SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor;
SkAutoTUnref<GrGLProgramEffects> fColorEffects;
SkAutoTUnref<GrGLProgramEffects> fCoverageEffects;
BuiltinUniformHandles fUniformHandles;
@@ -173,7 +177,7 @@
GrGLuint fProgramID;
GrGLFragmentShaderBuilder fFS;
SeparableVaryingInfoArray fSeparableVaryingInfos;
-private:
+
class CodeStage : SkNoncopyable {
public:
CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
@@ -224,6 +228,7 @@
int fCurrentIndex;
const GrEffectStage* fEffectStage;
} fCodeStage;
+private:
/**
* The base class will emit the fragment code that precedes the per-effect code and then call
@@ -232,7 +237,14 @@
*
* The subclass can modify the initial color or coverage
*/
- virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) = 0;
+ virtual void emitCodeBeforeEffects(GrGLSLExpr4* color,
+ GrGLSLExpr4* coverage) = 0;
+
+ /*
+ * Full shader builder needs to emit code after the color stages and before the coverage stages
+ */
+ virtual void emitGeometryProcessor(const GrEffectStage* geometryProcessor,
+ GrGLSLExpr4* coverage) = 0;
/**
* Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
@@ -297,13 +309,30 @@
GrGLVertexShaderBuilder* getVertexShaderBuilder() { return &fVS; }
private:
- virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) SK_OVERRIDE;
+ virtual void emitCodeBeforeEffects(GrGLSLExpr4* color,
+ GrGLSLExpr4* coverage) SK_OVERRIDE;
+
+ virtual void emitGeometryProcessor(const GrEffectStage* geometryProcessor,
+ GrGLSLExpr4* coverage) SK_OVERRIDE;
virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
int effectCnt,
const GrGLProgramDesc::EffectKeyProvider&,
GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
+ /*
+ * These functions are temporary and will eventually operate not on effects but on
+ * geometry processors
+ */
+ void createAndEmitEffect(GrGLProgramEffectsBuilder*,
+ const GrEffectStage* effectStage,
+ const GrGLProgramDesc::EffectKeyProvider&,
+ GrGLSLExpr4* inOutFSColor);
+
+ GrGLProgramEffects* createAndEmitEffect(const GrEffectStage* geometryProcessor,
+ const GrGLProgramDesc::EffectKeyProvider&,
+ GrGLSLExpr4* inOutFSColor);
+
virtual void emitCodeAfterEffects() SK_OVERRIDE;
virtual bool compileAndAttachShaders(GrGLuint programId,
@@ -326,7 +355,13 @@
int addTexCoordSets(int count);
private:
- virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) SK_OVERRIDE {}
+ virtual void emitCodeBeforeEffects(GrGLSLExpr4* color,
+ GrGLSLExpr4* coverage) SK_OVERRIDE {}
+
+ virtual void emitGeometryProcessor(const GrEffectStage* geometryProcessor,
+ GrGLSLExpr4* coverage) SK_OVERRIDE {
+ SkASSERT(NULL == geometryProcessor);
+ }
virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
int effectCnt,