Index: src/gpu/GrDefaultGeoProcFactory.cpp |
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp |
index 0df519dd8f7450e662ec63af903a94fb28e1bfc8..f6abde5e64c11558f6396988e5c5dfccebeefeb4 100644 |
--- a/src/gpu/GrDefaultGeoProcFactory.cpp |
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp |
@@ -68,20 +68,82 @@ public: |
const GrAttribute* inLocalCoords() const { return fInLocalCoords; } |
const GrAttribute* inCoverage() const { return fInCoverage; } |
+ struct BatchTracker { |
bsalomon
2014/12/05 14:43:03
can this be private?
|
+ Output fOutputColor; |
+ Output fOutputCoverage; |
+ GrColor fColor; |
+ GrColor fCoverage; |
+ }; |
+ |
+ 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->fOutputColor = GetColorOutputType(init, SkToBool(fInColor)); |
+ |
+ bool hasVertexCoverage = init.fOutputCoverage && fInCoverage && !init.fRemoveCoverageAttr; |
+ bool covIsSolidWhite = !hasVertexCoverage && 0xffffffff == init.fCoverage; |
+ if (covIsSolidWhite || !init.fOutputCoverage) { |
+ local->fOutputCoverage = kAllOnes_Output; |
+ } else if (!hasVertexCoverage) { |
+ local->fOutputCoverage = kUniform_Output; |
+ local->fCoverage = init.fCoverage; |
+ } else { |
+ SkASSERT(fInCoverage); |
+ local->fOutputCoverage = kAttribute_Output; |
+ } |
+ } |
+ |
+ virtual bool canBatch(const GrBatchTracker& l, const GrBatchTracker& r) const SK_OVERRIDE { |
+ const BatchTracker& left = l.cast<BatchTracker>(); |
+ const BatchTracker& right = r.cast<BatchTracker>(); |
+ bool sameColors = ((left.fOutputColor == kAttribute_Output && |
bsalomon
2014/12/05 14:43:03
I think this might be a little easier to read with
|
+ right.fOutputColor == kAttribute_Output) || |
+ (left.fOutputColor != kAttribute_Output && |
+ right.fOutputColor != kAttribute_Output && |
+ left.fColor == right.fColor)); |
+ if (!sameColors) { |
+ return false; |
+ } |
+ |
+ bool sameCoverage = ((left.fOutputCoverage == kAttribute_Output && |
+ right.fOutputCoverage == kAttribute_Output) || |
+ (left.fOutputCoverage != kAttribute_Output && |
+ right.fOutputCoverage != kAttribute_Output && |
+ left.fCoverage == right.fCoverage)); |
+ if (!sameCoverage) { |
+ return false; |
+ } |
+ return true; |
+ } |
+ |
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()) { |
+ if (kUniform_Output == local.fOutputColor) { |
+ const char* fragColor; |
+ fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
+ kVec4f_GrSLType, |
+ "Color", |
+ &fragColor); |
+ fs->codeAppendf("%s = %s;", args.fOutputColor, fragColor); |
+ } else if (kAttribute_Output == local.fOutputColor) { |
+ SkASSERT(gp.inColor()); |
args.fPB->addPassThroughAttribute(gp.inColor(), args.fOutputColor); |
+ } else { |
+ fs->codeAppendf("%s = vec4(1);", args.fOutputColor); |
} |
// Setup local coords if needed |
@@ -96,27 +158,52 @@ 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_Output == local.fOutputCoverage) { |
+ const char* fragCoverage; |
+ fCoverageUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
+ kFloat_GrSLType, |
+ "Coverage", |
+ &fragCoverage); |
+ fs->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, fragCoverage); |
+ } else if (kAttribute_Output == local.fOutputCoverage) { |
+ 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.fOutputColor | local.fOutputCoverage << 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>(); |
+ if (kUniform_Output == local.fOutputColor) { |
+ GrGLfloat c[4]; |
+ GrColorToRGBAFloat(local.fColor, c); |
+ pdman.set4fv(fColorUniform, 1, c); |
+ } |
+ if (kUniform_Output == local.fOutputCoverage) { |
+ pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(local.fCoverage)); |
+ } |
+ } |
private: |
+ UniformHandle fColorUniform; |
+ UniformHandle fCoverageUniform; |
+ |
typedef GrGLGeometryProcessor INHERITED; |
}; |
@@ -156,6 +243,7 @@ private: |
kFloat_GrVertexAttribType)); |
this->setHasVertexCoverage(); |
} |
+ fNewStyle = true; |
bsalomon
2014/12/05 14:43:03
?
|
} |
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { |