Chromium Code Reviews| Index: src/gpu/GrDefaultGeoProcFactory.cpp |
| diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp |
| index 7756f6a1fc15a69b4173a357fd333d31dc9b065f..3e4ee7eb13c454cb0fdc1aefe60dcd6423a58ae4 100644 |
| --- a/src/gpu/GrDefaultGeoProcFactory.cpp |
| +++ b/src/gpu/GrDefaultGeoProcFactory.cpp |
| @@ -32,20 +32,67 @@ 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->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>(); |
| + if (left.fOutputColor != right.fOutputColor) { |
| + return false; |
| + } |
| + |
| + if (kAttribute_Output != left.fOutputColor && left.fColor != right.fColor) { |
|
bsalomon
2014/12/10 18:36:20
need these comparisons for coverage too? also seem
|
| + 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, |
| + kDefault_GrSLPrecision, |
| + "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 |
| @@ -60,27 +107,53 @@ 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, |
| + kDefault_GrSLPrecision, |
| + "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) { |
|
bsalomon
2014/12/10 18:36:20
I wonder whether we should be skipping uni uploads
|
| + 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; |
| }; |
| @@ -121,6 +194,7 @@ private: |
| kFloat_GrVertexAttribType)); |
| this->setHasVertexCoverage(); |
| } |
| + fNewStyle = true; |
| } |
| virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { |
| @@ -137,6 +211,13 @@ private: |
| } |
| } |
| + struct BatchTracker { |
| + Output fOutputColor; |
|
bsalomon
2014/12/10 18:36:20
The names of these vars and enum don't seem right
|
| + Output fOutputCoverage; |
| + GrColor fColor; |
| + GrColor fCoverage; |
| + }; |
| + |
| const GrAttribute* fInPosition; |
| const GrAttribute* fInColor; |
| const GrAttribute* fInLocalCoords; |