Index: src/gpu/GrDefaultGeoProcFactory.cpp |
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp |
index 4f89080624314ee0f7e33910d180d026dda7b124..05a1b66dbbf67b5aa4c1722890b367e55cfdb346 100644 |
--- a/src/gpu/GrDefaultGeoProcFactory.cpp |
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp |
@@ -33,21 +33,51 @@ public: |
const GrAttribute* inLocalCoords() const { return fInLocalCoords; } |
const GrAttribute* inCoverage() const { return fInCoverage; } |
+ void initBatchTracker(GrBatchTracker* bt, const InitBT& init) const SK_OVERRIDE { |
+ BatchTracker* local = bt->cast<BatchTracker>(); |
+ |
+ // We will ignore this color unless we have uniform color |
+ local->fColor = init.fColor; |
+ local->fInputColorType = GetColorInputType(init, SkToBool(fInColor)); |
+ |
+ bool hasVertexCoverage = init.fOutputCoverage && fInCoverage && !init.fRemoveCoverageAttr; |
+ bool covIsSolidWhite = !hasVertexCoverage && 0xffffffff == init.fCoverage; |
+ if (covIsSolidWhite || !init.fOutputCoverage) { |
+ local->fInputCoverageType = kAllOnes_GPInput; |
+ } else if (!hasVertexCoverage) { |
+ local->fInputCoverageType = kUniform_GPInput; |
+ local->fCoverage = init.fCoverage; |
+ } else { |
+ SkASSERT(fInCoverage); |
+ local->fInputCoverageType = kAttribute_GPInput; |
+ } |
+ } |
+ |
+ bool onCanBatch(const GrBatchTracker& l, const GrBatchTracker& r) const SK_OVERRIDE { |
+ const BatchTracker& left = l.cast<BatchTracker>(); |
+ const BatchTracker& right = r.cast<BatchTracker>(); |
+ return CanCombineOutput(left.fInputColorType, left.fColor, |
+ right.fInputColorType, right.fColor) && |
+ CanCombineOutput(left.fInputCoverageType, left.fCoverage, |
+ right.fInputCoverageType, right.fCoverage); |
+ } |
+ |
class GLProcessor : public GrGLGeometryProcessor { |
public: |
- GLProcessor(const GrGeometryProcessor&, |
- const GrBatchTracker&) {} |
+ GLProcessor(const GrGeometryProcessor&, const GrBatchTracker&) {} |
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>(); |
- GrGLVertexBuilder* vs = args.fPB->getVertexShaderBuilder(); |
+ GrGLGPBuilder* pb = args.fPB; |
+ GrGLVertexBuilder* vs = pb->getVertexShaderBuilder(); |
+ GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); |
+ const BatchTracker& local = args.fBT.cast<BatchTracker>(); |
vs->codeAppendf("%s = %s;", vs->positionCoords(), gp.inPosition()->fName); |
// Setup pass through color |
- if (gp.inColor()) { |
- args.fPB->addPassThroughAttribute(gp.inColor(), args.fOutputColor); |
- } |
+ this->setupColor(pb, local.fInputColorType, args.fOutputColor, gp.inColor(), |
+ &fColorUniform); |
// Setup local coords if needed |
if (gp.inLocalCoords()) { |
@@ -61,27 +91,50 @@ public: |
gp.inPosition()->fName); |
// Setup coverage as pass through |
- GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); |
- fs->codeAppendf("float alpha = 1.0;"); |
- if (gp.inCoverage()) { |
+ if (kUniform_GPInput == local.fInputCoverageType) { |
+ const char* fragCoverage; |
+ fCoverageUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
+ kFloat_GrSLType, |
+ kDefault_GrSLPrecision, |
+ "Coverage", |
+ &fragCoverage); |
+ fs->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, fragCoverage); |
+ } else if (kAttribute_GPInput == local.fInputCoverageType) { |
+ SkASSERT(gp.inCoverage()); |
+ fs->codeAppendf("float alpha = 1.0;"); |
args.fPB->addPassThroughAttribute(gp.inCoverage(), "alpha"); |
+ fs->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
+ } else { |
+ fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage); |
} |
- fs->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
} |
static inline void GenKey(const GrGeometryProcessor& gp, |
- const GrBatchTracker&, |
+ const GrBatchTracker& bt, |
const GrGLCaps&, |
GrProcessorKeyBuilder* b) { |
const DefaultGeoProc& def = gp.cast<DefaultGeoProc>(); |
b->add32(def.fFlags); |
+ |
+ const BatchTracker& local = bt.cast<BatchTracker>(); |
+ b->add32(local.fInputColorType | local.fInputCoverageType << 16); |
} |
- virtual void setData(const GrGLProgramDataManager&, |
- const GrGeometryProcessor&, |
- const GrBatchTracker&) SK_OVERRIDE {} |
+ virtual void setData(const GrGLProgramDataManager& pdman, |
+ const GrGeometryProcessor& gp, |
+ const GrBatchTracker& bt) SK_OVERRIDE { |
+ const BatchTracker& local = bt.cast<BatchTracker>(); |
+ this->setUniformColorIfRequired(pdman, local.fInputColorType, local.fColor, |
+ fColorUniform); |
+ if (kUniform_GPInput == local.fInputCoverageType) { |
+ pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(local.fCoverage)); |
+ } |
+ } |
private: |
+ UniformHandle fColorUniform; |
+ UniformHandle fCoverageUniform; |
+ |
typedef GrGLGeometryProcessor INHERITED; |
}; |
@@ -138,6 +191,13 @@ private: |
} |
} |
+ struct BatchTracker { |
+ GPInput fInputColorType; |
+ GPInput fInputCoverageType; |
+ GrColor fColor; |
+ GrColor fCoverage; |
+ }; |
+ |
const GrAttribute* fInPosition; |
const GrAttribute* fInColor; |
const GrAttribute* fInLocalCoords; |