From d3a560fa80bfb3e2d2e989f951bb3b1c52316654 Mon Sep 17 00:00:00 2001 From: joshualitt Date: Tue, 19 May 2015 07:15:28 -0700 Subject: Revert of Preliminary attempt to remove batch tracker (patchset #3 id:40001 of https://codereview.chromium.org/1139723004/) Reason for revert: breaking bots Original issue's description: > Preliminary attempt to remove batch tracker > > BUG=skia: > > Committed: https://skia.googlesource.com/skia/+/cbfe91d82500f4ae8c3ff7bd74b3021a4b89fd84 TBR=robertphillips@google.com,joshualitt@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/1132323003 --- src/gpu/GrAAConvexPathRenderer.cpp | 81 ++++++----- src/gpu/GrAADistanceFieldPathRenderer.cpp | 21 ++- src/gpu/GrAAHairLinePathRenderer.cpp | 29 +++- src/gpu/GrAARectRenderer.cpp | 40 ++++-- src/gpu/GrAtlasTextContext.cpp | 30 ++-- src/gpu/GrBatchTarget.h | 6 + src/gpu/GrContext.cpp | 33 +++-- src/gpu/GrDefaultGeoProcFactory.cpp | 123 ++++++++-------- src/gpu/GrDefaultGeoProcFactory.h | 2 - src/gpu/GrDefaultPathRenderer.cpp | 13 +- src/gpu/GrGeometryProcessor.h | 32 ++++- src/gpu/GrOvalRenderer.cpp | 221 ++++++++++++++++++----------- src/gpu/GrPathProcessor.cpp | 19 +-- src/gpu/GrPathProcessor.h | 32 +++++ src/gpu/GrRectBatch.cpp | 28 ++-- src/gpu/GrTessellatingPathRenderer.cpp | 5 +- src/gpu/GrTestBatch.h | 10 ++ src/gpu/effects/GrBezierEffect.cpp | 130 +++++++++++------ src/gpu/effects/GrBezierEffect.h | 33 ++--- src/gpu/effects/GrBitmapTextGeoProc.cpp | 50 ++++--- src/gpu/effects/GrBitmapTextGeoProc.h | 15 +- src/gpu/effects/GrDashingEffect.cpp | 136 +++++++++--------- src/gpu/effects/GrDistanceFieldGeoProc.cpp | 131 ++++++++++------- src/gpu/effects/GrDistanceFieldGeoProc.h | 44 +++--- src/gpu/gl/GrGLPrimitiveProcessor.cpp | 32 +++-- src/gpu/gl/GrGLPrimitiveProcessor.h | 11 +- 26 files changed, 805 insertions(+), 502 deletions(-) (limited to 'src') diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index 1b7efefd07..0d909b1dc6 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -525,9 +525,8 @@ static void create_vertices(const SegmentArray& segments, class QuadEdgeEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(GrColor color, const SkMatrix& localMatrix, - bool usesLocalCoords) { - return SkNEW_ARGS(QuadEdgeEffect, (color, localMatrix, usesLocalCoords)); + static GrGeometryProcessor* Create(GrColor color, const SkMatrix& localMatrix) { + return SkNEW_ARGS(QuadEdgeEffect, (color, localMatrix)); } virtual ~QuadEdgeEffect() {} @@ -537,9 +536,7 @@ public: const Attribute* inPosition() const { return fInPosition; } const Attribute* inQuadEdge() const { return fInQuadEdge; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } const SkMatrix& localMatrix() const { return fLocalMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } class GLProcessor : public GrGLGeometryProcessor { public: @@ -559,10 +556,11 @@ public: args.fPB->addVarying("QuadEdge", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName); + const BatchTracker& local = args.fBT.cast(); + // Setup pass through color - if (!qe.colorIgnored()) { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, + &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, qe.inPosition()->fName); @@ -600,22 +598,22 @@ public: const GrBatchTracker& bt, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { + const BatchTracker& local = bt.cast(); const QuadEdgeEffect& qee = gp.cast(); - uint32_t key = 0; - key |= qee.usesLocalCoords() && qee.localMatrix().hasPerspective() ? 0x1 : 0x0; - key |= qee.colorIgnored() ? 0x2 : 0x0; + uint32_t key = local.fInputColorType << 16; + key |= local.fUsesLocalCoords && qee.localMatrix().hasPerspective() ? 0x1 : 0x0; b->add32(key); } virtual void setData(const GrGLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, const GrBatchTracker& bt) override { - const QuadEdgeEffect& qe = gp.cast(); - if (qe.color() != fColor) { + const BatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(qe.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = qe.color(); + fColor = local.fColor; } } @@ -644,21 +642,31 @@ public: return SkNEW_ARGS(GLProcessor, (*this, bt)); } + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override { + BatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fUsesLocalCoords = init.fUsesLocalCoords; + } + private: - QuadEdgeEffect(GrColor color, const SkMatrix& localMatrix, bool usesLocalCoords) + QuadEdgeEffect(GrColor color, const SkMatrix& localMatrix) : fColor(color) - , fLocalMatrix(localMatrix) - , fUsesLocalCoords(usesLocalCoords) { + , fLocalMatrix(localMatrix) { this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); fInQuadEdge = &this->addVertexAttrib(Attribute("inQuadEdge", kVec4f_GrVertexAttribType)); } + struct BatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; + }; + const Attribute* fInPosition; const Attribute* fInQuadEdge; GrColor fColor; SkMatrix fLocalMatrix; - bool fUsesLocalCoords; GR_DECLARE_GEOMETRY_PROCESSOR_TEST; @@ -674,8 +682,7 @@ GrGeometryProcessor* QuadEdgeEffect::TestCreate(SkRandom* random, // Doesn't work without derivative instructions. return caps.shaderCaps()->shaderDerivativeSupport() ? QuadEdgeEffect::Create(GrRandomColor(random), - GrTest::TestMatrix(random), - random->nextBool()) : NULL; + GrTest::TestMatrix(random)) : NULL; } /////////////////////////////////////////////////////////////////////////////// @@ -725,16 +732,13 @@ static void extract_verts(const GrAAConvexTessellator& tess, } static const GrGeometryProcessor* create_fill_gp(bool tweakAlphaForCoverage, - const SkMatrix& localMatrix, - bool usesLocalCoords, - bool coverageIgnored) { + const SkMatrix& localMatrix) { uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; if (!tweakAlphaForCoverage) { flags |= GrDefaultGeoProcFactory::kCoverage_GPType; } - return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, usesLocalCoords, coverageIgnored, - SkMatrix::I(), localMatrix); + return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, SkMatrix::I(), localMatrix); } class AAConvexPathBatch : public GrBatch { @@ -787,12 +791,18 @@ public: // Setup GrGeometryProcessor SkAutoTUnref gp( - create_fill_gp(canTweakAlphaForCoverage, invert, - this->usesLocalCoords(), - this->coverageIgnored())); + create_fill_gp(canTweakAlphaForCoverage, invert)); batchTarget->initDraw(gp, pipeline); + // TODO remove this when batch is everywhere + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + size_t vertexStride = gp->getVertexStride(); SkASSERT(canTweakAlphaForCoverage ? @@ -860,11 +870,19 @@ public: } // Setup GrGeometryProcessor - SkAutoTUnref quadProcessor( - QuadEdgeEffect::Create(this->color(), invert, this->usesLocalCoords())); + SkAutoTUnref quadProcessor(QuadEdgeEffect::Create(this->color(), + invert)); batchTarget->initDraw(quadProcessor, pipeline); + // TODO remove this when batch is everywhere + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + quadProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init); + // TODO generate all segments for all paths and use one vertex buffer for (int i = 0; i < instanceCount; i++) { Geometry& args = fGeoData[i]; @@ -973,7 +991,6 @@ private: bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } struct BatchTracker { GrColor fColor; diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp index 21fbcb37fb..b6a9797bc3 100755 --- a/src/gpu/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp @@ -197,10 +197,9 @@ public: this->viewMatrix(), atlas->getTexture(), params, - flags, - this->usesLocalCoords())); + flags)); - batchTarget->initDraw(dfProcessor, pipeline); + this->initDraw(batchTarget, dfProcessor, pipeline); FlushInfo flushInfo; @@ -415,7 +414,7 @@ private: &atlasLocation); if (!success) { this->flush(batchTarget, flushInfo); - batchTarget->initDraw(dfProcessor, pipeline); + this->initDraw(batchTarget, dfProcessor, pipeline); SkDEBUGCODE(success =) atlas->addToAtlas(&id, batchTarget, width, height, dfStorage.get(), &atlasLocation); @@ -492,6 +491,20 @@ private: vertexStride); } + void initDraw(GrBatchTarget* batchTarget, + const GrGeometryProcessor* dfProcessor, + const GrPipeline* pipeline) { + batchTarget->initDraw(dfProcessor, pipeline); + + // TODO remove this when batch is everywhere + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + dfProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init); + } + void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) { GrVertices vertices; int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads(); diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index 6dcf063974..dc035fc772 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -774,7 +774,6 @@ private: uint8_t coverage() const { return fBatch.fCoverage; } bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } struct BatchTracker { GrColor fColor; @@ -816,8 +815,6 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel SkAutoTUnref lineGP( GrDefaultGeoProcFactory::Create(gpFlags, this->color(), - this->usesLocalCoords(), - this->coverageIgnored(), *geometryProcessorViewM, *geometryProcessorLocalM, this->coverage())); @@ -828,7 +825,6 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel kHairlineAA_GrProcessorEdgeType, batchTarget->caps(), *geometryProcessorLocalM, - this->usesLocalCoords(), this->coverage())); SkAutoTUnref conicGP( @@ -837,7 +833,6 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel kHairlineAA_GrProcessorEdgeType, batchTarget->caps(), *geometryProcessorLocalM, - this->usesLocalCoords(), this->coverage())); // This is hand inlined for maximum performance. @@ -864,6 +859,14 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel ref_lines_index_buffer(batchTarget->resourceProvider())); batchTarget->initDraw(lineGP, pipeline); + // TODO remove this when batch is everywhere + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + lineGP->initBatchTracker(batchTarget->currentBatchTracker(), init); + const GrVertexBuffer* vertexBuffer; int firstVertex; @@ -926,6 +929,14 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel if (quadCount > 0) { batchTarget->initDraw(quadGP, pipeline); + // TODO remove this when batch is everywhere + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + quadGP->initBatchTracker(batchTarget->currentBatchTracker(), init); + { GrVertices verts; verts.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer, @@ -939,6 +950,14 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel if (conicCount > 0) { batchTarget->initDraw(conicGP, pipeline); + // TODO remove this when batch is everywhere + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + conicGP->initBatchTracker(batchTarget->currentBatchTracker(), init); + { GrVertices verts; verts.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer, diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 6b8abc38fb..a4656a7c3e 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -31,18 +31,14 @@ static void set_inset_fan(SkPoint* pts, size_t stride, } static const GrGeometryProcessor* create_fill_rect_gp(bool tweakAlphaForCoverage, - const SkMatrix& localMatrix, - bool usesLocalCoords, - bool coverageIgnored) { + const SkMatrix& localMatrix) { uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; const GrGeometryProcessor* gp; if (tweakAlphaForCoverage) { - gp = GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, usesLocalCoords, coverageIgnored, - SkMatrix::I(), localMatrix); + gp = GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, SkMatrix::I(), localMatrix); } else { flags |= GrDefaultGeoProcFactory::kCoverage_GPType; - gp = GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, usesLocalCoords, coverageIgnored, - SkMatrix::I(), localMatrix); + gp = GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, SkMatrix::I(), localMatrix); } return gp; } @@ -99,12 +95,20 @@ public: } SkAutoTUnref gp(create_fill_rect_gp(canTweakAlphaForCoverage, - localMatrix, - this->usesLocalCoords(), - this->coverageIgnored())); + localMatrix)); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + size_t vertexStride = gp->getVertexStride(); SkASSERT(canTweakAlphaForCoverage ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : @@ -172,7 +176,6 @@ private: bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } bool colorIgnored() const { return fBatch.fColorIgnored; } const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } bool onCombineIfPossible(GrBatch* t) override { AAFillRectBatch* that = t->cast(); @@ -450,12 +453,20 @@ public: } SkAutoTUnref gp(create_fill_rect_gp(canTweakAlphaForCoverage, - localMatrix, - this->usesLocalCoords(), - this->coverageIgnored())); + localMatrix)); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + size_t vertexStride = gp->getVertexStride(); SkASSERT(canTweakAlphaForCoverage ? @@ -615,7 +626,6 @@ private: bool colorIgnored() const { return fBatch.fColorIgnored; } const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } bool miterStroke() const { return fBatch.fMiterStroke; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } bool onCombineIfPossible(GrBatch* t) override { AAStrokeRectBatch* that = t->cast(); diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index f2307574fb..dfb07ed820 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -1537,8 +1537,7 @@ public: texture, params, fMaskFormat, - localMatrix, - this->usesLocalCoords())); + localMatrix)); } FlushInfo flushInfo; @@ -1548,7 +1547,7 @@ public: get_vertex_stride_df(fMaskFormat, fUseLCDText) : get_vertex_stride(fMaskFormat))); - batchTarget->initDraw(gp, pipeline); + this->initDraw(batchTarget, gp, pipeline); int glyphCount = this->numGlyphs(); int instanceCount = fInstanceCount; @@ -1658,7 +1657,7 @@ public: if (!fFontCache->hasGlyph(glyph) && !strike->addGlyphToAtlas(batchTarget, glyph, scaler)) { this->flush(batchTarget, &flushInfo); - batchTarget->initDraw(gp, pipeline); + this->initDraw(batchTarget, gp, pipeline); brokenRun = glyphIdx > 0; SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(batchTarget, @@ -1850,6 +1849,20 @@ private: } } + void initDraw(GrBatchTarget* batchTarget, + const GrGeometryProcessor* gp, + const GrPipeline* pipeline) { + batchTarget->initDraw(gp, pipeline); + + // TODO remove this when batch is everywhere + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + } + void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) { GrVertices vertices; int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads(); @@ -1979,8 +1992,7 @@ private: texture, params, widthAdjust, - flags, - this->usesLocalCoords()); + flags); } else { flags |= kColorAttr_DistanceFieldEffectFlag; #ifdef SK_GAMMA_APPLY_TO_A8 @@ -1991,15 +2003,13 @@ private: texture, params, correction, - flags, - this->usesLocalCoords()); + flags); #else return GrDistanceFieldA8TextGeoProc::Create(color, viewMatrix, texture, params, - flags, - this->usesLocalCoords()); + flags); #endif } diff --git a/src/gpu/GrBatchTarget.h b/src/gpu/GrBatchTarget.h index 61f12d8169..f317f3046e 100644 --- a/src/gpu/GrBatchTarget.h +++ b/src/gpu/GrBatchTarget.h @@ -104,6 +104,12 @@ public: fInlineUploads.reset(); } + // TODO This goes away when everything uses batch + GrBatchTracker* currentBatchTracker() { + SkASSERT(!fFlushBuffer.empty()); + return &fFlushBuffer.back().fBatchTracker; + } + const GrDrawTargetCaps& caps() const { return *fGpu->caps(); } GrResourceProvider* resourceProvider() const { return fGpu->getContext()->resourceProvider(); } diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 1609efb440..1863b7f962 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -438,13 +438,21 @@ public: SkAutoTUnref gp( GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType, this->color(), - this->usesLocalCoords(), - this->coverageIgnored(), this->viewMatrix(), SkMatrix::I())); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr)); @@ -541,7 +549,6 @@ private: bool colorIgnored() const { return fBatch.fColorIgnored; } const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } bool hairline() const { return fBatch.fHairline; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } bool onCombineIfPossible(GrBatch* t) override { // StrokeRectBatch* that = t->cast(); @@ -704,8 +711,7 @@ static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords, int* colorOffset, int* texOffset, GrColor color, - const SkMatrix& viewMatrix, - bool coverageIgnored) { + const SkMatrix& viewMatrix) { *texOffset = -1; *colorOffset = -1; uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType; @@ -721,8 +727,7 @@ static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords, *colorOffset = sizeof(SkPoint); flags |= GrDefaultGeoProcFactory::kColor_GPType; } - return GrDefaultGeoProcFactory::Create(flags, color, hasLocalCoords, coverageIgnored, - viewMatrix, SkMatrix::I()); + return GrDefaultGeoProcFactory::Create(flags, color, viewMatrix, SkMatrix::I()); } class DrawVerticesBatch : public GrBatch { @@ -780,11 +785,20 @@ public: int colorOffset = -1, texOffset = -1; SkAutoTUnref gp( set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &colorOffset, - &texOffset, this->color(), this->viewMatrix(), - this->coverageIgnored())); + &texOffset, this->color(), this->viewMatrix())); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(SkPoint) + (this->hasLocalCoords() ? sizeof(SkPoint) : 0) @@ -909,7 +923,6 @@ private: bool hasLocalCoords() const { return fBatch.fHasLocalCoords; } int vertexCount() const { return fBatch.fVertexCount; } int indexCount() const { return fBatch.fIndexCount; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } bool onCombineIfPossible(GrBatch* t) override { DrawVerticesBatch* that = t->cast(); diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp index 55b3a1f9ef..6dbf71e0d8 100644 --- a/src/gpu/GrDefaultGeoProcFactory.cpp +++ b/src/gpu/GrDefaultGeoProcFactory.cpp @@ -24,16 +24,12 @@ public: GrColor color, const SkMatrix& viewMatrix, const SkMatrix& localMatrix, - bool usesLocalCoords, - bool coverageIgnored, uint8_t coverage) { return SkNEW_ARGS(DefaultGeoProc, (gpTypeFlags, color, viewMatrix, localMatrix, - coverage, - usesLocalCoords, - coverageIgnored)); + coverage)); } const char* name() const override { return "DefaultGeometryProcessor"; } @@ -43,14 +39,30 @@ public: const Attribute* inLocalCoords() const { return fInLocalCoords; } const Attribute* inCoverage() const { return fInCoverage; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } - bool hasVertexColor() const { return SkToBool(fInColor); } const SkMatrix& viewMatrix() const { return fViewMatrix; } const SkMatrix& localMatrix() const { return fLocalMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } uint8_t coverage() const { return fCoverage; } - bool coverageIgnored() const { return fCoverageIgnored; } - bool hasVertexCoverage() const { return SkToBool(fInCoverage); } + + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override { + BatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, + SkToBool(fInColor)); + + bool hasVertexCoverage = SkToBool(fInCoverage) && !init.fCoverageIgnored; + bool covIsSolidWhite = !hasVertexCoverage && 0xff == this->coverage(); + if (init.fCoverageIgnored) { + local->fInputCoverageType = kIgnored_GrGPInput; + } else if (covIsSolidWhite) { + local->fInputCoverageType = kAllOnes_GrGPInput; + } else if (hasVertexCoverage) { + SkASSERT(fInCoverage); + local->fInputCoverageType = kAttribute_GrGPInput; + } else { + local->fInputCoverageType = kUniform_GrGPInput; + local->fCoverage = this->coverage(); + } + local->fUsesLocalCoords = init.fUsesLocalCoords; + } class GLProcessor : public GrGLGeometryProcessor { public: @@ -62,19 +74,14 @@ public: GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); GrGLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); + const BatchTracker& local = args.fBT.cast(); // emit attributes vsBuilder->emitAttributes(gp); // Setup pass through color - if (!gp.colorIgnored()) { - if (gp.hasVertexColor()) { - pb->addPassThroughAttribute(gp.inColor(), args.fOutputColor); - } else { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } - } - + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, gp.inColor(), + &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, gp.inPosition()->fName, gp.viewMatrix()); @@ -89,22 +96,21 @@ public: } // Setup coverage as pass through - if (!gp.coverageIgnored()) { - if (gp.hasVertexCoverage()) { - fs->codeAppendf("float alpha = 1.0;"); - args.fPB->addPassThroughAttribute(gp.inCoverage(), "alpha"); - fs->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); - } else if (gp.coverage() == 0xff) { - fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage); - } else { - const char* fragCoverage; - fCoverageUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, - kFloat_GrSLType, - kDefault_GrSLPrecision, - "Coverage", - &fragCoverage); - fs->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, fragCoverage); - } + if (kUniform_GrGPInput == 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_GrGPInput == 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 if (kAllOnes_GrGPInput == local.fInputCoverageType) { + fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage); } } @@ -113,13 +119,10 @@ public: const GrGLSLCaps&, GrProcessorKeyBuilder* b) { const DefaultGeoProc& def = gp.cast(); + const BatchTracker& local = bt.cast(); uint32_t key = def.fFlags; - key |= def.colorIgnored() << 8; - key |= def.coverageIgnored() << 9; - key |= def.hasVertexColor() << 10; - key |= def.hasVertexCoverage() << 11; - key |= def.coverage() == 0xff ? 0x1 << 12 : 0; - key |= def.usesLocalCoords() && def.localMatrix().hasPerspective() ? 0x1 << 24 : 0x0; + key |= local.fInputColorType << 8 | local.fInputCoverageType << 16; + key |= local.fUsesLocalCoords && def.localMatrix().hasPerspective() ? 0x1 << 24 : 0x0; key |= ComputePosKey(def.viewMatrix()) << 25; b->add32(key); } @@ -130,16 +133,16 @@ public: const DefaultGeoProc& dgp = gp.cast(); this->setUniformViewMatrix(pdman, dgp.viewMatrix()); - if (dgp.color() != fColor && !dgp.hasVertexColor()) { + const BatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(dgp.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = dgp.color(); + fColor = local.fColor; } - - if (dgp.coverage() != fCoverage && !dgp.hasVertexCoverage()) { - pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(dgp.coverage())); - fCoverage = dgp.coverage(); + if (kUniform_GrGPInput == local.fInputCoverageType && local.fCoverage != fCoverage) { + pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(local.fCoverage)); + fCoverage = local.fCoverage; } } @@ -175,9 +178,7 @@ private: GrColor color, const SkMatrix& viewMatrix, const SkMatrix& localMatrix, - uint8_t coverage, - bool usesLocalCoords, - bool coverageIgnored) + uint8_t coverage) : fInPosition(NULL) , fInColor(NULL) , fInLocalCoords(NULL) @@ -186,9 +187,7 @@ private: , fViewMatrix(viewMatrix) , fLocalMatrix(localMatrix) , fCoverage(coverage) - , fFlags(gpTypeFlags) - , fUsesLocalCoords(usesLocalCoords) - , fCoverageIgnored(coverageIgnored) { + , fFlags(gpTypeFlags) { this->initClassID(); bool hasColor = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kColor_GPType); bool hasLocalCoord = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kLocalCoord_GPType); @@ -199,7 +198,7 @@ private: } if (hasLocalCoord) { fInLocalCoords = &this->addVertexAttrib(Attribute("inLocalCoord", - kVec2f_GrVertexAttribType)); + kVec2f_GrVertexAttribType)); this->setHasLocalCoords(); } if (hasCoverage) { @@ -208,6 +207,14 @@ private: } } + struct BatchTracker { + GrGPInput fInputColorType; + GrGPInput fInputCoverageType; + GrColor fColor; + GrColor fCoverage; + bool fUsesLocalCoords; + }; + const Attribute* fInPosition; const Attribute* fInColor; const Attribute* fInLocalCoords; @@ -217,8 +224,6 @@ private: SkMatrix fLocalMatrix; uint8_t fCoverage; uint32_t fFlags; - bool fUsesLocalCoords; - bool fCoverageIgnored; GR_DECLARE_GEOMETRY_PROCESSOR_TEST; @@ -246,15 +251,11 @@ GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random, GrRandomColor(random), GrTest::TestMatrix(random), GrTest::TestMatrix(random), - random->nextBool(), - random->nextBool(), GrRandomCoverage(random)); } const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(uint32_t gpTypeFlags, GrColor color, - bool usesLocalCoords, - bool coverageIgnored, const SkMatrix& viewMatrix, const SkMatrix& localMatrix, uint8_t coverage) { @@ -262,7 +263,5 @@ const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(uint32_t gpTypeFlags, color, viewMatrix, localMatrix, - usesLocalCoords, - coverageIgnored, coverage); } diff --git a/src/gpu/GrDefaultGeoProcFactory.h b/src/gpu/GrDefaultGeoProcFactory.h index 3722a320ce..aee16fd027 100644 --- a/src/gpu/GrDefaultGeoProcFactory.h +++ b/src/gpu/GrDefaultGeoProcFactory.h @@ -83,8 +83,6 @@ public: // TODO clean this up static const GrGeometryProcessor* Create(uint32_t gpTypeFlags, GrColor, - bool usesLocalCoords, - bool coverageIgnored, const SkMatrix& viewMatrix = SkMatrix::I(), const SkMatrix& localMatrix = SkMatrix::I(), uint8_t coverage = 0xff); diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index 7659847ecc..1be5ce7939 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -254,8 +254,6 @@ public: SkAutoTUnref gp( GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType, this->color(), - this->usesLocalCoords(), - this->coverageIgnored(), this->viewMatrix(), SkMatrix::I(), this->coverage())); @@ -265,6 +263,16 @@ public: batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + int instanceCount = fGeoData.count(); // compute number of vertices @@ -510,7 +518,6 @@ private: bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } bool isHairline() const { return fBatch.fIsHairline; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } struct BatchTracker { GrColor fColor; diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h index 9c55359af5..eee286b20d 100644 --- a/src/gpu/GrGeometryProcessor.h +++ b/src/gpu/GrGeometryProcessor.h @@ -26,9 +26,6 @@ public: bool willUseGeoShader() const { return fWillUseGeoShader; } - // TODO delete when paths are in batch - void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const override {} - // TODO delete this when paths are in batch bool canMakeEqual(const GrBatchTracker& mine, const GrPrimitiveProcessor& that, @@ -46,6 +43,35 @@ public: } protected: + /* + * An optional simple helper function to determine by what means the GrGeometryProcessor should + * use to provide color. If we are given an override color(ie the given overridecolor is NOT + * GrColor_ILLEGAL) then we must always emit that color(currently overrides are only supported + * via uniform, but with deferred Geometry we could use attributes). Otherwise, if our color is + * ignored then we should not emit a color. Lastly, if we don't have vertex colors then we must + * emit a color via uniform + * TODO this function changes quite a bit with deferred geometry. There the GrGeometryProcessor + * can upload a new color via attribute if needed. + */ + static GrGPInput GetColorInputType(GrColor* color, GrColor primitiveColor, + const GrPipelineInfo& init, + bool hasVertexColor) { + if (init.fColorIgnored) { + *color = GrColor_ILLEGAL; + return kIgnored_GrGPInput; + } else if (GrColor_ILLEGAL != init.fOverrideColor) { + *color = init.fOverrideColor; + return kUniform_GrGPInput; + } + + *color = primitiveColor; + if (hasVertexColor) { + return kAttribute_GrGPInput; + } else { + return kUniform_GrGPInput; + } + } + /** * Subclasses call this from their constructor to register vertex attributes. Attributes * will be padded to the nearest 4 bytes for performance reasons. diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 69baebb228..0a7b3f89fc 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -71,17 +71,14 @@ inline bool circle_stays_circle(const SkMatrix& m) { class CircleEdgeEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatrix& localMatrix, - bool usesLocalCoords) { - return SkNEW_ARGS(CircleEdgeEffect, (color, stroke, localMatrix, usesLocalCoords)); + static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatrix& localMatrix) { + return SkNEW_ARGS(CircleEdgeEffect, (color, stroke, localMatrix)); } const Attribute* inPosition() const { return fInPosition; } const Attribute* inCircleEdge() const { return fInCircleEdge; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } const SkMatrix& localMatrix() const { return fLocalMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } virtual ~CircleEdgeEffect() {} const char* name() const override { return "CircleEdge"; } @@ -97,6 +94,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const CircleEdgeEffect& ce = args.fGP.cast(); GrGLGPBuilder* pb = args.fPB; + const BatchTracker& local = args.fBT.cast(); GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); // emit attributes @@ -106,10 +104,9 @@ public: args.fPB->addVarying("CircleEdge", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName); - // setup pass through color - if (!ce.colorIgnored()) { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } + // Setup pass through color + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, + &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, ce.inPosition()->fName); @@ -134,22 +131,22 @@ public: const GrBatchTracker& bt, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { + const BatchTracker& local = bt.cast(); const CircleEdgeEffect& ce = gp.cast(); uint16_t key = ce.isStroked() ? 0x1 : 0x0; - key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x2 : 0x0; - key |= ce.colorIgnored() ? 0x4 : 0x0; - b->add32(key); + key |= local.fUsesLocalCoords && ce.localMatrix().hasPerspective() ? 0x2 : 0x0; + b->add32(key << 16 | local.fInputColorType); } virtual void setData(const GrGLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, const GrBatchTracker& bt) override { - const CircleEdgeEffect& ce = gp.cast(); - if (ce.color() != fColor) { + const BatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(ce.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = ce.color(); + fColor = local.fColor; } } @@ -177,11 +174,16 @@ public: return SkNEW_ARGS(GLProcessor, (*this, bt)); } + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override { + BatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fUsesLocalCoords = init.fUsesLocalCoords; + } + private: - CircleEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix, bool usesLocalCoords) + CircleEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix) : fColor(color) - , fLocalMatrix(localMatrix) - , fUsesLocalCoords(usesLocalCoords) { + , fLocalMatrix(localMatrix) { this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); fInCircleEdge = &this->addVertexAttrib(Attribute("inCircleEdge", @@ -189,12 +191,17 @@ private: fStroke = stroke; } + struct BatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; + }; + GrColor fColor; SkMatrix fLocalMatrix; const Attribute* fInPosition; const Attribute* fInCircleEdge; bool fStroke; - bool fUsesLocalCoords; GR_DECLARE_GEOMETRY_PROCESSOR_TEST; @@ -209,8 +216,7 @@ GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, GrTexture* textures[]) { return CircleEdgeEffect::Create(GrRandomColor(random), random->nextBool(), - GrTest::TestMatrix(random), - random->nextBool()); + GrTest::TestMatrix(random)); } /////////////////////////////////////////////////////////////////////////////// @@ -225,9 +231,8 @@ GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, class EllipseEdgeEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatrix& localMatrix, - bool usesLocalCoords) { - return SkNEW_ARGS(EllipseEdgeEffect, (color, stroke, localMatrix, usesLocalCoords)); + static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatrix& localMatrix) { + return SkNEW_ARGS(EllipseEdgeEffect, (color, stroke, localMatrix)); } virtual ~EllipseEdgeEffect() {} @@ -238,9 +243,7 @@ public: const Attribute* inEllipseOffset() const { return fInEllipseOffset; } const Attribute* inEllipseRadii() const { return fInEllipseRadii; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } const SkMatrix& localMatrix() const { return fLocalMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } inline bool isStroked() const { return fStroke; } @@ -253,6 +256,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const EllipseEdgeEffect& ee = args.fGP.cast(); GrGLGPBuilder* pb = args.fPB; + const BatchTracker& local = args.fBT.cast(); GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); // emit attributes @@ -268,10 +272,9 @@ public: vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), ee.inEllipseRadii()->fName); - // setup pass through color - if (!ee.colorIgnored()) { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } + // Setup pass through color + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, + &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, ee.inPosition()->fName); @@ -311,22 +314,23 @@ public: const GrBatchTracker& bt, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { + const BatchTracker& local = bt.cast(); const EllipseEdgeEffect& ee = gp.cast(); uint16_t key = ee.isStroked() ? 0x1 : 0x0; - key |= ee.usesLocalCoords() && ee.localMatrix().hasPerspective() ? 0x2 : 0x0; - key |= ee.colorIgnored() ? 0x4 : 0x0; - b->add32(key); + key |= local.fUsesLocalCoords && ee.localMatrix().hasPerspective() ? 0x2 : 0x0; + b->add32(key << 16 | local.fInputColorType); } virtual void setData(const GrGLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, const GrBatchTracker& bt) override { - const EllipseEdgeEffect& ee = gp.cast(); - if (ee.color() != fColor) { + + const BatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(ee.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = ee.color(); + fColor = local.fColor; } } @@ -355,12 +359,16 @@ public: return SkNEW_ARGS(GLProcessor, (*this, bt)); } + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override { + BatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fUsesLocalCoords = init.fUsesLocalCoords; + } + private: - EllipseEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix, - bool usesLocalCoords) + EllipseEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix) : fColor(color) - , fLocalMatrix(localMatrix) - , fUsesLocalCoords(usesLocalCoords) { + , fLocalMatrix(localMatrix) { this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); fInEllipseOffset = &this->addVertexAttrib(Attribute("inEllipseOffset", @@ -370,13 +378,18 @@ private: fStroke = stroke; } + struct BatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; + }; + const Attribute* fInPosition; const Attribute* fInEllipseOffset; const Attribute* fInEllipseRadii; GrColor fColor; SkMatrix fLocalMatrix; bool fStroke; - bool fUsesLocalCoords; GR_DECLARE_GEOMETRY_PROCESSOR_TEST; @@ -391,8 +404,7 @@ GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, GrTexture* textures[]) { return EllipseEdgeEffect::Create(GrRandomColor(random), random->nextBool(), - GrTest::TestMatrix(random), - random->nextBool()); + GrTest::TestMatrix(random)); } /////////////////////////////////////////////////////////////////////////////// @@ -410,9 +422,8 @@ class DIEllipseEdgeEffect : public GrGeometryProcessor { public: enum Mode { kStroke = 0, kHairline, kFill }; - static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, Mode mode, - bool usesLocalCoords) { - return SkNEW_ARGS(DIEllipseEdgeEffect, (color, viewMatrix, mode, usesLocalCoords)); + static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, Mode mode) { + return SkNEW_ARGS(DIEllipseEdgeEffect, (color, viewMatrix, mode)); } virtual ~DIEllipseEdgeEffect() {} @@ -423,9 +434,7 @@ public: const Attribute* inEllipseOffsets0() const { return fInEllipseOffsets0; } const Attribute* inEllipseOffsets1() const { return fInEllipseOffsets1; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } const SkMatrix& viewMatrix() const { return fViewMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } inline Mode getMode() const { return fMode; } @@ -438,6 +447,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const DIEllipseEdgeEffect& ee = args.fGP.cast(); GrGLGPBuilder* pb = args.fPB; + const BatchTracker& local = args.fBT.cast(); GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); // emit attributes @@ -453,10 +463,9 @@ public: vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), ee.inEllipseOffsets1()->fName); - // setup pass through color - if (!ee.colorIgnored()) { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } + // Setup pass through color + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, + &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, ee.inPosition()->fName, ee.viewMatrix()); @@ -510,11 +519,11 @@ public: const GrBatchTracker& bt, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { + const BatchTracker& local = bt.cast(); const DIEllipseEdgeEffect& ellipseEffect = gp.cast(); uint16_t key = ellipseEffect.getMode(); - key |= ellipseEffect.colorIgnored() << 9; - key |= ComputePosKey(ellipseEffect.viewMatrix()) << 10; - b->add32(key); + key |= ComputePosKey(ellipseEffect.viewMatrix()) << 9; + b->add32(key << 16 | local.fInputColorType); } virtual void setData(const GrGLProgramDataManager& pdman, @@ -523,11 +532,12 @@ public: const DIEllipseEdgeEffect& dee = gp.cast(); this->setUniformViewMatrix(pdman, dee.viewMatrix()); - if (dee.color() != fColor) { + const BatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(dee.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = dee.color(); + fColor = local.fColor; } } @@ -549,28 +559,37 @@ public: return SkNEW_ARGS(GLProcessor, (*this, bt)); } + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override { + BatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fUsesLocalCoords = init.fUsesLocalCoords; + } + private: - DIEllipseEdgeEffect(GrColor color, const SkMatrix& viewMatrix, Mode mode, - bool usesLocalCoords) + DIEllipseEdgeEffect(GrColor color, const SkMatrix& viewMatrix, Mode mode) : fColor(color) - , fViewMatrix(viewMatrix) - , fUsesLocalCoords(usesLocalCoords) { + , fViewMatrix(viewMatrix) { this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); fInEllipseOffsets0 = &this->addVertexAttrib(Attribute("inEllipseOffsets0", - kVec2f_GrVertexAttribType)); + kVec2f_GrVertexAttribType)); fInEllipseOffsets1 = &this->addVertexAttrib(Attribute("inEllipseOffsets1", - kVec2f_GrVertexAttribType)); + kVec2f_GrVertexAttribType)); fMode = mode; } + struct BatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; + }; + const Attribute* fInPosition; const Attribute* fInEllipseOffsets0; const Attribute* fInEllipseOffsets1; GrColor fColor; SkMatrix fViewMatrix; Mode fMode; - bool fUsesLocalCoords; GR_DECLARE_GEOMETRY_PROCESSOR_TEST; @@ -585,8 +604,7 @@ GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, GrTexture* textures[]) { return DIEllipseEdgeEffect::Create(GrRandomColor(random), GrTest::TestMatrix(random), - (Mode)(random->nextRangeU(0,2)), - random->nextBool()); + (Mode)(random->nextRangeU(0,2))); } /////////////////////////////////////////////////////////////////////////////// @@ -674,11 +692,20 @@ public: // Setup geometry processor SkAutoTUnref gp(CircleEdgeEffect::Create(this->color(), this->stroke(), - invert, - this->usesLocalCoords())); + invert)); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + int instanceCount = fGeoData.count(); size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(CircleVertex)); @@ -889,11 +916,20 @@ public: // Setup geometry processor SkAutoTUnref gp(EllipseEdgeEffect::Create(this->color(), this->stroke(), - invert, - this->usesLocalCoords())); + invert)); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + int instanceCount = fGeoData.count(); QuadHelper helper; size_t vertexStride = gp->getVertexStride(); @@ -1148,11 +1184,20 @@ public: // Setup geometry processor SkAutoTUnref gp(DIEllipseEdgeEffect::Create(this->color(), this->viewMatrix(), - this->mode(), - this->usesLocalCoords())); + this->mode())); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + int instanceCount = fGeoData.count(); size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(DIEllipseVertex)); @@ -1504,11 +1549,20 @@ public: // Setup geometry processor SkAutoTUnref gp(CircleEdgeEffect::Create(this->color(), this->stroke(), - invert, - this->usesLocalCoords())); + invert)); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + int instanceCount = fGeoData.count(); size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(CircleVertex)); @@ -1677,11 +1731,20 @@ public: // Setup geometry processor SkAutoTUnref gp(EllipseEdgeEffect::Create(this->color(), this->stroke(), - invert, - this->usesLocalCoords())); + invert)); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + int instanceCount = fGeoData.count(); size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(EllipseVertex)); diff --git a/src/gpu/GrPathProcessor.cpp b/src/gpu/GrPathProcessor.cpp index 4660aa080f..5c07a8b156 100644 --- a/src/gpu/GrPathProcessor.cpp +++ b/src/gpu/GrPathProcessor.cpp @@ -57,19 +57,12 @@ bool GrPathProcessor::canMakeEqual(const GrBatchTracker& m, const PathBatchTracker& mine = m.cast(); const PathBatchTracker& theirs = t.cast(); - if (mine.fColor != theirs.fColor) { - return false; - } - - if (mine.fUsesLocalCoords != theirs.fUsesLocalCoords) { - return false; - } - - if (mine.fUsesLocalCoords && !this->localMatrix().cheapEqualTo(other.localMatrix())) { - return false; - } - - return true; + return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, + that, theirs.fUsesLocalCoords) && + CanCombineOutput(mine.fInputColorType, mine.fColor, + theirs.fInputColorType, theirs.fColor) && + CanCombineOutput(mine.fInputCoverageType, 0xff, + theirs.fInputCoverageType, 0xff); } void GrPathProcessor::getGLProcessorKey(const GrBatchTracker& bt, diff --git a/src/gpu/GrPathProcessor.h b/src/gpu/GrPathProcessor.h index 7c1ab2b5df..e34d0cefbe 100644 --- a/src/gpu/GrPathProcessor.h +++ b/src/gpu/GrPathProcessor.h @@ -57,6 +57,38 @@ public: private: GrPathProcessor(GrColor color, const SkMatrix& viewMatrix, const SkMatrix& localMatrix); + /* + * CanCombineOutput will return true if two draws are 'batchable' from a color perspective. + * TODO is this really necessary? + */ + static bool CanCombineOutput(GrGPInput left, GrColor lColor, GrGPInput right, GrColor rColor) { + if (left != right) { + return false; + } + + if (kUniform_GrGPInput == left && lColor != rColor) { + return false; + } + + return true; + } + + static bool CanCombineLocalMatrices(const GrPrimitiveProcessor& l, + bool leftUsesLocalCoords, + const GrPrimitiveProcessor& r, + bool rightUsesLocalCoords) { + if (leftUsesLocalCoords != rightUsesLocalCoords) { + return false; + } + + const GrPathProcessor& left = l.cast(); + const GrPathProcessor& right = r.cast(); + if (leftUsesLocalCoords && !left.localMatrix().cheapEqualTo(right.localMatrix())) { + return false; + } + return true; + } + bool hasExplicitLocalCoords() const override { return false; } GrColor fColor; diff --git a/src/gpu/GrRectBatch.cpp b/src/gpu/GrRectBatch.cpp index bf085bdfdf..100aafc4ca 100644 --- a/src/gpu/GrRectBatch.cpp +++ b/src/gpu/GrRectBatch.cpp @@ -25,19 +25,15 @@ The vertex attrib order is always pos, color, [local coords]. */ static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords, - const SkMatrix* localMatrix, - bool usesLocalCoords, - bool coverageIgnored) { - // TODO remove color when we have ignored color from the XP + GrColor color, + const SkMatrix* localMatrix) { uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType | GrDefaultGeoProcFactory::kColor_GPType; flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0; if (localMatrix) { - return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, usesLocalCoords, - coverageIgnored, SkMatrix::I(), *localMatrix); + return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *localMatrix); } else { - return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, usesLocalCoords, - coverageIgnored, SkMatrix::I(), SkMatrix::I()); + return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMatrix::I()); } } @@ -102,12 +98,21 @@ public: } SkAutoTUnref gp(create_rect_gp(hasExplicitLocalCoords, - &invert, - this->usesLocalCoords(), - this->coverageIgnored())); + this->color(), + &invert)); batchTarget->initDraw(gp, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + int instanceCount = fGeoData.count(); size_t vertexStride = gp->getVertexStride(); SkASSERT(hasExplicitLocalCoords ? @@ -171,7 +176,6 @@ private: const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; } bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; } bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } bool onCombineIfPossible(GrBatch* t) override { RectBatch* that = t->cast(); diff --git a/src/gpu/GrTessellatingPathRenderer.cpp b/src/gpu/GrTessellatingPathRenderer.cpp index a41a88eed6..0fd8afd754 100644 --- a/src/gpu/GrTessellatingPathRenderer.cpp +++ b/src/gpu/GrTessellatingPathRenderer.cpp @@ -1412,10 +1412,9 @@ public: LOG("got %d pts, %d contours\n", maxPts, contourCnt); uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType; SkAutoTUnref gp( - GrDefaultGeoProcFactory::Create(flags, fColor, fPipelineInfo.fUsesLocalCoords, - fPipelineInfo.fCoverageIgnored, fViewMatrix, - SkMatrix::I())); + GrDefaultGeoProcFactory::Create(flags, fColor, fViewMatrix, SkMatrix::I())); batchTarget->initDraw(gp, pipeline); + gp->initBatchTracker(batchTarget->currentBatchTracker(), fPipelineInfo); SkAutoTDeleteArray contours(SkNEW_ARRAY(Vertex *, contourCnt)); diff --git a/src/gpu/GrTestBatch.h b/src/gpu/GrTestBatch.h index aa0c63773e..a165f4ab4e 100644 --- a/src/gpu/GrTestBatch.h +++ b/src/gpu/GrTestBatch.h @@ -50,6 +50,16 @@ public: void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { batchTarget->initDraw(fGeometryProcessor, pipeline); + // TODO this is hacky, but the only way we have to initialize the GP is to use the + // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch + // everywhere we can remove this nastiness + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = fBatch.fUsesLocalCoords; + fGeometryProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init); + this->onGenerateGeometry(batchTarget, pipeline); } diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index 8d1b0dbd7a..a09d6ce414 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -12,6 +12,13 @@ #include "gl/GrGLGeometryProcessor.h" #include "gl/builders/GrGLProgramBuilder.h" +struct ConicBatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + uint8_t fCoverageScale; + bool fUsesLocalCoords; +}; + class GrGLConicEffect : public GrGLGeometryProcessor { public: GrGLConicEffect(const GrGeometryProcessor&, @@ -30,16 +37,16 @@ public: const GrConicEffect& ce = primProc.cast(); this->setUniformViewMatrix(pdman, ce.viewMatrix()); - if (ce.color() != fColor) { + const ConicBatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(ce.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = ce.color(); + fColor = local.fColor; } - - if (ce.coverageScale() != 0xff && ce.coverageScale() != fCoverageScale) { - pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.coverageScale())); - fCoverageScale = ce.coverageScale(); + if (0xff != local.fCoverageScale && fCoverageScale != local.fCoverageScale) { + pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(local.fCoverageScale)); + fCoverageScale = local.fCoverageScale; } } @@ -71,6 +78,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); const GrConicEffect& gp = args.fGP.cast(); + const ConicBatchTracker& local = args.fBT.cast(); // emit attributes vsBuilder->emitAttributes(gp); @@ -80,9 +88,8 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName); // Setup pass through color - if (!gp.colorIgnored()) { - this->setupUniformColor(args.fPB, args.fOutputColor, &fColorUniform); - } + this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL, + &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, gp.inPosition()->fName, gp.viewMatrix()); @@ -148,8 +155,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { SkFAIL("Shouldn't get here"); } - // TODO should we really be doing this? - if (gp.coverageScale() != 0xff) { + if (0xff != local.fCoverageScale) { const char* coverageScale; fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, kFloat_GrSLType, @@ -167,10 +173,11 @@ void GrGLConicEffect::GenKey(const GrGeometryProcessor& gp, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { const GrConicEffect& ce = gp.cast(); + const ConicBatchTracker& local = bt.cast(); uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2; - key |= GrColor_ILLEGAL != ce.color() ? 0x4 : 0x0; - key |= 0xff != ce.coverageScale() ? 0x8 : 0x0; - key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0; + key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x0; + key |= 0xff != local.fCoverageScale ? 0x8 : 0x0; + key |= local.fUsesLocalCoords && ce.localMatrix().hasPerspective() ? 0x10 : 0x0; key |= ComputePosKey(ce.viewMatrix()) << 5; b->add32(key); } @@ -191,18 +198,23 @@ GrGLPrimitiveProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt } GrConicEffect::GrConicEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage, - GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix, - bool usesLocalCoords) + GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix) : fColor(color) , fViewMatrix(viewMatrix) , fLocalMatrix(viewMatrix) - , fUsesLocalCoords(usesLocalCoords) , fCoverageScale(coverage) , fEdgeType(edgeType) { this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); fInConicCoeffs = &this->addVertexAttrib(Attribute("inConicCoeffs", - kVec4f_GrVertexAttribType)); + kVec4f_GrVertexAttribType)); +} + +void GrConicEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const { + ConicBatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fCoverageScale = fCoverageScale; + local->fUsesLocalCoords = init.fUsesLocalCoords; } ////////////////////////////////////////////////////////////////////////////// @@ -219,7 +231,7 @@ GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random, random->nextULessThan(kGrProcessorEdgeTypeCnt)); gp = GrConicEffect::Create(GrRandomColor(random), GrTest::TestMatrix(random), edgeType, caps, - GrTest::TestMatrix(random), random->nextBool()); + GrTest::TestMatrix(random)); } while (NULL == gp); return gp; } @@ -228,6 +240,13 @@ GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random, // Quad ////////////////////////////////////////////////////////////////////////////// +struct QuadBatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + uint8_t fCoverageScale; + bool fUsesLocalCoords; +}; + class GrGLQuadEffect : public GrGLGeometryProcessor { public: GrGLQuadEffect(const GrGeometryProcessor&, @@ -246,16 +265,16 @@ public: const GrQuadEffect& qe = primProc.cast(); this->setUniformViewMatrix(pdman, qe.viewMatrix()); - if (qe.color() != fColor) { + const QuadBatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(qe.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = qe.color(); + fColor = local.fColor; } - - if (qe.coverageScale() != 0xff && qe.coverageScale() != fCoverageScale) { - pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.coverageScale())); - fCoverageScale = qe.coverageScale(); + if (0xff != local.fCoverageScale && local.fCoverageScale != fCoverageScale) { + pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(local.fCoverageScale)); + fCoverageScale = local.fCoverageScale; } } @@ -287,6 +306,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); const GrQuadEffect& gp = args.fGP.cast(); + const QuadBatchTracker& local = args.fBT.cast(); // emit attributes vsBuilder->emitAttributes(gp); @@ -296,9 +316,8 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName); // Setup pass through color - if (!gp.colorIgnored()) { - this->setupUniformColor(args.fPB, args.fOutputColor, &fColorUniform); - } + this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL, + &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, gp.inPosition()->fName, gp.viewMatrix()); @@ -350,7 +369,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { SkFAIL("Shouldn't get here"); } - if (0xff != gp.coverageScale()) { + if (0xff != local.fCoverageScale) { const char* coverageScale; fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, kFloat_GrSLType, @@ -368,10 +387,11 @@ void GrGLQuadEffect::GenKey(const GrGeometryProcessor& gp, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { const GrQuadEffect& ce = gp.cast(); + const QuadBatchTracker& local = bt.cast(); uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2; - key |= ce.color() != GrColor_ILLEGAL ? 0x4 : 0x0; - key |= ce.coverageScale() != 0xff ? 0x8 : 0x0; - key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0; + key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x0; + key |= 0xff != local.fCoverageScale ? 0x8 : 0x0; + key |= local.fUsesLocalCoords && ce.localMatrix().hasPerspective() ? 0x10 : 0x0; key |= ComputePosKey(ce.viewMatrix()) << 5; b->add32(key); } @@ -392,12 +412,10 @@ GrGLPrimitiveProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt, } GrQuadEffect::GrQuadEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage, - GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix, - bool usesLocalCoords) + GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix) : fColor(color) , fViewMatrix(viewMatrix) , fLocalMatrix(localMatrix) - , fUsesLocalCoords(usesLocalCoords) , fCoverageScale(coverage) , fEdgeType(edgeType) { this->initClassID(); @@ -406,6 +424,13 @@ GrQuadEffect::GrQuadEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t co kVec4f_GrVertexAttribType)); } +void GrQuadEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const { + QuadBatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fCoverageScale = fCoverageScale; + local->fUsesLocalCoords = init.fUsesLocalCoords; +} + ////////////////////////////////////////////////////////////////////////////// GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect); @@ -421,8 +446,7 @@ GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random, gp = GrQuadEffect::Create(GrRandomColor(random), GrTest::TestMatrix(random), edgeType, caps, - GrTest::TestMatrix(random), - random->nextBool()); + GrTest::TestMatrix(random)); } while (NULL == gp); return gp; } @@ -431,6 +455,12 @@ GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random, // Cubic ////////////////////////////////////////////////////////////////////////////// +struct CubicBatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; +}; + class GrGLCubicEffect : public GrGLGeometryProcessor { public: GrGLCubicEffect(const GrGeometryProcessor&, @@ -449,11 +479,12 @@ public: const GrCubicEffect& ce = primProc.cast(); this->setUniformViewMatrix(pdman, ce.viewMatrix()); - if (ce.color() != fColor) { + const CubicBatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(ce.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = ce.color(); + fColor = local.fColor; } } @@ -475,6 +506,7 @@ GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor, void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); const GrCubicEffect& gp = args.fGP.cast(); + const CubicBatchTracker& local = args.fBT.cast(); // emit attributes vsBuilder->emitAttributes(gp); @@ -484,9 +516,8 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName); // Setup pass through color - if (!gp.colorIgnored()) { - this->setupUniformColor(args.fPB, args.fOutputColor, &fColorUniform); - } + this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL, + &fColorUniform); // Setup position this->setupPosition(args.fPB, gpArgs, gp.inPosition()->fName, gp.viewMatrix()); @@ -587,8 +618,9 @@ void GrGLCubicEffect::GenKey(const GrGeometryProcessor& gp, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { const GrCubicEffect& ce = gp.cast(); + const CubicBatchTracker& local = bt.cast(); uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2; - key |= ce.color() != GrColor_ILLEGAL ? 0x4 : 0x8; + key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x8; key |= ComputePosKey(ce.viewMatrix()) << 5; b->add32(key); } @@ -619,6 +651,12 @@ GrCubicEffect::GrCubicEffect(GrColor color, const SkMatrix& viewMatrix, kVec4f_GrVertexAttribType)); } +void GrCubicEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const { + CubicBatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fUsesLocalCoords = init.fUsesLocalCoords; +} + ////////////////////////////////////////////////////////////////////////////// GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect); diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h index 7700c58fe6..f1b22fa8a4 100644 --- a/src/gpu/effects/GrBezierEffect.h +++ b/src/gpu/effects/GrBezierEffect.h @@ -63,7 +63,6 @@ public: const GrPrimitiveEdgeType edgeType, const GrDrawTargetCaps& caps, const SkMatrix& localMatrix, - bool usesLocalCoords, uint8_t coverage = 0xff) { switch (edgeType) { case kFillAA_GrProcessorEdgeType: @@ -72,18 +71,18 @@ public: } return SkNEW_ARGS(GrConicEffect, (color, viewMatrix, coverage, kFillAA_GrProcessorEdgeType, - localMatrix, usesLocalCoords)); + localMatrix)); case kHairlineAA_GrProcessorEdgeType: if (!caps.shaderCaps()->shaderDerivativeSupport()) { return NULL; } return SkNEW_ARGS(GrConicEffect, (color, viewMatrix, coverage, kHairlineAA_GrProcessorEdgeType, - localMatrix, usesLocalCoords)); + localMatrix)); case kFillBW_GrProcessorEdgeType: return SkNEW_ARGS(GrConicEffect, (color, viewMatrix, coverage, kFillBW_GrProcessorEdgeType, - localMatrix, usesLocalCoords)); + localMatrix)); default: return NULL; } @@ -99,11 +98,8 @@ public: inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); } inline GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } const SkMatrix& viewMatrix() const { return fViewMatrix; } const SkMatrix& localMatrix() const { return fLocalMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } - uint8_t coverageScale() const { return fCoverageScale; } virtual void getGLProcessorKey(const GrBatchTracker& bt, const GrGLSLCaps& caps, @@ -112,14 +108,15 @@ public: virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, const GrGLSLCaps&) const override; + void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const override; + private: GrConicEffect(GrColor, const SkMatrix& viewMatrix, uint8_t coverage, GrPrimitiveEdgeType, - const SkMatrix& localMatrix, bool usesLocalCoords); + const SkMatrix& localMatrix); GrColor fColor; SkMatrix fViewMatrix; SkMatrix fLocalMatrix; - bool fUsesLocalCoords; uint8_t fCoverageScale; GrPrimitiveEdgeType fEdgeType; const Attribute* fInPosition; @@ -148,7 +145,6 @@ public: const GrPrimitiveEdgeType edgeType, const GrDrawTargetCaps& caps, const SkMatrix& localMatrix, - bool usesLocalCoords, uint8_t coverage = 0xff) { switch (edgeType) { case kFillAA_GrProcessorEdgeType: @@ -157,18 +153,18 @@ public: } return SkNEW_ARGS(GrQuadEffect, (color, viewMatrix, coverage, kFillAA_GrProcessorEdgeType, - localMatrix, usesLocalCoords)); + localMatrix)); case kHairlineAA_GrProcessorEdgeType: if (!caps.shaderCaps()->shaderDerivativeSupport()) { return NULL; } return SkNEW_ARGS(GrQuadEffect, (color, viewMatrix, coverage, kHairlineAA_GrProcessorEdgeType, - localMatrix, usesLocalCoords)); + localMatrix)); case kFillBW_GrProcessorEdgeType: return SkNEW_ARGS(GrQuadEffect, (color, viewMatrix, coverage, kFillBW_GrProcessorEdgeType, - localMatrix, usesLocalCoords)); + localMatrix)); default: return NULL; } @@ -184,11 +180,8 @@ public: inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); } inline GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } const SkMatrix& viewMatrix() const { return fViewMatrix; } const SkMatrix& localMatrix() const { return fLocalMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } - uint8_t coverageScale() const { return fCoverageScale; } virtual void getGLProcessorKey(const GrBatchTracker& bt, const GrGLSLCaps& caps, @@ -197,14 +190,15 @@ public: virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, const GrGLSLCaps&) const override; + void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const override; + private: GrQuadEffect(GrColor, const SkMatrix& viewMatrix, uint8_t coverage, GrPrimitiveEdgeType, - const SkMatrix& localMatrix, bool usesLocalCoords); + const SkMatrix& localMatrix); GrColor fColor; SkMatrix fViewMatrix; SkMatrix fLocalMatrix; - bool fUsesLocalCoords; uint8_t fCoverageScale; GrPrimitiveEdgeType fEdgeType; const Attribute* fInPosition; @@ -264,7 +258,6 @@ public: inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); } inline GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } const SkMatrix& viewMatrix() const { return fViewMatrix; } virtual void getGLProcessorKey(const GrBatchTracker& bt, @@ -274,6 +267,8 @@ public: virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, const GrGLSLCaps&) const override; + void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const override; + private: GrCubicEffect(GrColor, const SkMatrix& viewMatrix, GrPrimitiveEdgeType); diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index ad06792fb5..a7261c0549 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -15,6 +15,12 @@ #include "gl/GrGLGeometryProcessor.h" #include "gl/builders/GrGLProgramBuilder.h" +struct BitmapTextBatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; +}; + class GrGLBitmapTextGeoProc : public GrGLGeometryProcessor { public: GrGLBitmapTextGeoProc(const GrGeometryProcessor&, const GrBatchTracker&) @@ -22,6 +28,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrBitmapTextGeoProc& cte = args.fGP.cast(); + const BitmapTextBatchTracker& local = args.fBT.cast(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); @@ -43,13 +50,8 @@ public: } // Setup pass through color - if (!cte.colorIgnored()) { - if (cte.hasVertexColor()) { - pb->addPassThroughAttribute(cte.inColor(), args.fOutputColor); - } else { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } - } + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, cte.inColor(), + &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, cte.inPosition()->fName); @@ -77,12 +79,12 @@ public: virtual void setData(const GrGLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, const GrBatchTracker& bt) override { - const GrBitmapTextGeoProc& btgp = gp.cast(); - if (btgp.color() != fColor && !btgp.hasVertexColor()) { + const BitmapTextBatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(btgp.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = btgp.color(); + fColor = local.fColor; } } @@ -97,12 +99,16 @@ public: const GrBatchTracker& bt, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { + const BitmapTextBatchTracker& local = bt.cast(); + // We have to put the optional vertex attribute as part of the key. See the comment + // on addVertexAttrib. + // TODO When we have deferred geometry we can fix this const GrBitmapTextGeoProc& gp = proc.cast(); uint32_t key = 0; - key |= gp.usesLocalCoords() && gp.localMatrix().hasPerspective() ? 0x1 : 0x0; - key |= gp.colorIgnored() ? 0x2 : 0x0; - key |= gp.maskFormat() << 3; - b->add32(key); + key |= SkToBool(gp.inColor()) ? 0x1 : 0x0; + key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x2 : 0x0; + key |= gp.maskFormat() == kARGB_GrMaskFormat ? 0x4 : 0x0; + b->add32(local.fInputColorType << 16 | key); } private: @@ -116,18 +122,15 @@ private: GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture, const GrTextureParams& params, GrMaskFormat format, - const SkMatrix& localMatrix, bool usesLocalCoords) + const SkMatrix& localMatrix) : fColor(color) , fLocalMatrix(localMatrix) - , fUsesLocalCoords(usesLocalCoords) , fTextureAccess(texture, params) , fInColor(NULL) , fMaskFormat(format) { this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); - // TODO we could think about removing this attribute if color is ignored, but unfortunately - // we don't do text positioning in batch, so we can't quite do that yet. bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat; if (hasVertexColor) { fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); @@ -149,6 +152,13 @@ GrBitmapTextGeoProc::createGLInstance(const GrBatchTracker& bt, return SkNEW_ARGS(GrGLBitmapTextGeoProc, (*this, bt)); } +void GrBitmapTextGeoProc::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const { + BitmapTextBatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, + SkToBool(fInColor)); + local->fUsesLocalCoords = init.fUsesLocalCoords; +} + /////////////////////////////////////////////////////////////////////////////// GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc); @@ -187,5 +197,5 @@ GrGeometryProcessor* GrBitmapTextGeoProc::TestCreate(SkRandom* random, } return GrBitmapTextGeoProc::Create(GrRandomColor(random), textures[texIdx], params, - format, GrTest::TestMatrix(random), random->nextBool()); + format, GrTest::TestMatrix(random)); } diff --git a/src/gpu/effects/GrBitmapTextGeoProc.h b/src/gpu/effects/GrBitmapTextGeoProc.h index 2bd2726814..837dcb6fe5 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.h +++ b/src/gpu/effects/GrBitmapTextGeoProc.h @@ -22,10 +22,9 @@ class GrInvariantOutput; class GrBitmapTextGeoProc : public GrGeometryProcessor { public: static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& p, - GrMaskFormat format, const SkMatrix& localMatrix, - bool usesLocalCoords) { - return SkNEW_ARGS(GrBitmapTextGeoProc, (color, tex, p, format, localMatrix, - usesLocalCoords)); + GrMaskFormat format, + const SkMatrix& localMatrix) { + return SkNEW_ARGS(GrBitmapTextGeoProc, (color, tex, p, format, localMatrix)); } virtual ~GrBitmapTextGeoProc() {} @@ -37,10 +36,7 @@ public: const Attribute* inTextureCoords() const { return fInTextureCoords; } GrMaskFormat maskFormat() const { return fMaskFormat; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } - bool hasVertexColor() const { return SkToBool(fInColor); } const SkMatrix& localMatrix() const { return fLocalMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } virtual void getGLProcessorKey(const GrBatchTracker& bt, const GrGLSLCaps& caps, @@ -49,13 +45,14 @@ public: virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, const GrGLSLCaps& caps) const override; + void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const override; + private: GrBitmapTextGeoProc(GrColor, GrTexture* texture, const GrTextureParams& params, - GrMaskFormat format, const SkMatrix& localMatrix, bool usesLocalCoords); + GrMaskFormat format, const SkMatrix& localMatrix); GrColor fColor; SkMatrix fLocalMatrix; - bool fUsesLocalCoords; GrTextureAccess fTextureAccess; const Attribute* fInPosition; const Attribute* fInColor; diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 8e942a1dfd..1d873de749 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -241,8 +241,7 @@ static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& m static GrGeometryProcessor* create_dash_gp(GrColor, DashAAMode aaMode, DashCap cap, - const SkMatrix& localMatrix, - bool usesLocalCoords); + const SkMatrix& localMatrix); class DashBatch : public GrBatch { public: @@ -316,20 +315,25 @@ public: bool isRoundCap = SkPaint::kRound_Cap == cap; DashCap capType = isRoundCap ? kRound_DashCap : kNonRound_DashCap; if (this->fullDash()) { - gp.reset(create_dash_gp(this->color(), this->aaMode(), capType, invert, - this->usesLocalCoords())); + gp.reset(create_dash_gp(this->color(), this->aaMode(), capType, invert)); } else { // Set up the vertex data for the line and start/end dashes gp.reset(GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType, this->color(), - this->usesLocalCoords(), - this->coverageIgnored(), SkMatrix::I(), invert)); } batchTarget->initDraw(gp, pipeline); + // TODO remove this when batch is everywhere + GrPipelineInfo init; + init.fColorIgnored = fBatch.fColorIgnored; + init.fOverrideColor = GrColor_ILLEGAL; + init.fCoverageIgnored = fBatch.fCoverageIgnored; + init.fUsesLocalCoords = this->usesLocalCoords(); + gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + // useAA here means Edge AA or MSAA bool useAA = this->aaMode() != kBW_DashAAMode; bool fullDash = this->fullDash(); @@ -657,7 +661,6 @@ private: DashAAMode aaMode() const { return fBatch.fAAMode; } bool fullDash() const { return fBatch.fFullDash; } SkPaint::Cap cap() const { return fBatch.fCap; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } struct BatchTracker { GrColor fColor; @@ -747,6 +750,12 @@ bool GrDashingEffect::DrawDashLine(GrDrawTarget* target, class GLDashingCircleEffect; +struct DashingCircleBatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; +}; + /* * This effect will draw a dotted line (defined as a dashed lined with round caps and no on * interval). The radius of the dots is given by the strokeWidth and the spacing by the DashInfo. @@ -762,8 +771,7 @@ public: static GrGeometryProcessor* Create(GrColor, DashAAMode aaMode, - const SkMatrix& localMatrix, - bool usesLocalCoords); + const SkMatrix& localMatrix); const char* name() const override { return "DashingCircleEffect"; } @@ -777,12 +785,8 @@ public: GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } - const SkMatrix& localMatrix() const { return fLocalMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } - virtual void getGLProcessorKey(const GrBatchTracker&, const GrGLSLCaps&, GrProcessorKeyBuilder* b) const override; @@ -790,13 +794,13 @@ public: virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker&, const GrGLSLCaps&) const override; + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override; + private: - DashingCircleEffect(GrColor, DashAAMode aaMode, const SkMatrix& localMatrix, - bool usesLocalCoords); + DashingCircleEffect(GrColor, DashAAMode aaMode, const SkMatrix& localMatrix); GrColor fColor; SkMatrix fLocalMatrix; - bool fUsesLocalCoords; DashAAMode fAAMode; const Attribute* fInPosition; const Attribute* fInDashParams; @@ -851,6 +855,7 @@ GLDashingCircleEffect::GLDashingCircleEffect(const GrGeometryProcessor&, void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { const DashingCircleEffect& dce = args.fGP.cast(); + const DashingCircleBatchTracker local = args.fBT.cast(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); @@ -868,9 +873,7 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { vsBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams()->fName); // Setup pass through color - if (!dce.colorIgnored()) { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, dce.inPosition()->fName); @@ -901,12 +904,12 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman, const GrPrimitiveProcessor& processor, const GrBatchTracker& bt) { - const DashingCircleEffect& dce = processor.cast(); - if (dce.color() != fColor) { + const DashingCircleBatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(dce.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = dce.color(); + fColor = local.fColor; } } @@ -914,21 +917,20 @@ void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp, const GrBatchTracker& bt, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { + const DashingCircleBatchTracker& local = bt.cast(); const DashingCircleEffect& dce = gp.cast(); uint32_t key = 0; - key |= dce.usesLocalCoords() && dce.localMatrix().hasPerspective() ? 0x1 : 0x0; - key |= dce.colorIgnored() ? 0x2 : 0x0; + key |= local.fUsesLocalCoords && dce.localMatrix().hasPerspective() ? 0x1 : 0x0; key |= dce.aaMode() << 8; - b->add32(key); + b->add32(key << 16 | local.fInputColorType); } ////////////////////////////////////////////////////////////////////////////// GrGeometryProcessor* DashingCircleEffect::Create(GrColor color, DashAAMode aaMode, - const SkMatrix& localMatrix, - bool usesLocalCoords) { - return SkNEW_ARGS(DashingCircleEffect, (color, aaMode, localMatrix, usesLocalCoords)); + const SkMatrix& localMatrix) { + return SkNEW_ARGS(DashingCircleEffect, (color, aaMode, localMatrix)); } void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt, @@ -944,11 +946,9 @@ GrGLPrimitiveProcessor* DashingCircleEffect::createGLInstance(const GrBatchTrack DashingCircleEffect::DashingCircleEffect(GrColor color, DashAAMode aaMode, - const SkMatrix& localMatrix, - bool usesLocalCoords) + const SkMatrix& localMatrix) : fColor(color) , fLocalMatrix(localMatrix) - , fUsesLocalCoords(usesLocalCoords) , fAAMode(aaMode) { this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); @@ -957,6 +957,12 @@ DashingCircleEffect::DashingCircleEffect(GrColor color, kVec2f_GrVertexAttribType)); } +void DashingCircleEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const { + DashingCircleBatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fUsesLocalCoords = init.fUsesLocalCoords; +} + GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect); GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random, @@ -965,14 +971,19 @@ GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random, GrTexture*[]) { DashAAMode aaMode = static_cast(random->nextULessThan(kDashAAModeCount)); return DashingCircleEffect::Create(GrRandomColor(random), - aaMode, GrTest::TestMatrix(random), - random->nextBool()); + aaMode, GrTest::TestMatrix(random)); } ////////////////////////////////////////////////////////////////////////////// class GLDashingLineEffect; +struct DashingLineBatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; +}; + /* * This effect will draw a dashed line. The width of the dash is given by the strokeWidth and the * length and spacing by the DashInfo. Both of the previous two parameters are in device space. @@ -988,8 +999,7 @@ public: static GrGeometryProcessor* Create(GrColor, DashAAMode aaMode, - const SkMatrix& localMatrix, - bool usesLocalCoords); + const SkMatrix& localMatrix); const char* name() const override { return "DashingEffect"; } @@ -1003,12 +1013,8 @@ public: GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } - const SkMatrix& localMatrix() const { return fLocalMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } - virtual void getGLProcessorKey(const GrBatchTracker& bt, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; @@ -1016,13 +1022,13 @@ public: virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, const GrGLSLCaps&) const override; + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override; + private: - DashingLineEffect(GrColor, DashAAMode aaMode, const SkMatrix& localMatrix, - bool usesLocalCoords); + DashingLineEffect(GrColor, DashAAMode aaMode, const SkMatrix& localMatrix); GrColor fColor; SkMatrix fLocalMatrix; - bool fUsesLocalCoords; DashAAMode fAAMode; const Attribute* fInPosition; const Attribute* fInDashParams; @@ -1070,6 +1076,7 @@ GLDashingLineEffect::GLDashingLineEffect(const GrGeometryProcessor&, void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { const DashingLineEffect& de = args.fGP.cast(); + const DashingLineBatchTracker& local = args.fBT.cast(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); @@ -1089,10 +1096,7 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { vsBuilder->codeAppendf("%s = %s;", inRectParams.vsOut(), de.inRectParams()->fName); // Setup pass through color - if (!de.colorIgnored()) { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } - + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, de.inPosition()->fName); @@ -1140,12 +1144,12 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman, const GrPrimitiveProcessor& processor, const GrBatchTracker& bt) { - const DashingLineEffect& de = processor.cast(); - if (de.color() != fColor) { + const DashingLineBatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(de.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = de.color(); + fColor = local.fColor; } } @@ -1153,21 +1157,20 @@ void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp, const GrBatchTracker& bt, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { + const DashingLineBatchTracker& local = bt.cast(); const DashingLineEffect& de = gp.cast(); uint32_t key = 0; - key |= de.usesLocalCoords() && de.localMatrix().hasPerspective() ? 0x1 : 0x0; - key |= de.colorIgnored() ? 0x2 : 0x0; + key |= local.fUsesLocalCoords && de.localMatrix().hasPerspective() ? 0x1 : 0x0; key |= de.aaMode() << 8; - b->add32(key); + b->add32(key << 16 | local.fInputColorType); } ////////////////////////////////////////////////////////////////////////////// GrGeometryProcessor* DashingLineEffect::Create(GrColor color, DashAAMode aaMode, - const SkMatrix& localMatrix, - bool usesLocalCoords) { - return SkNEW_ARGS(DashingLineEffect, (color, aaMode, localMatrix, usesLocalCoords)); + const SkMatrix& localMatrix) { + return SkNEW_ARGS(DashingLineEffect, (color, aaMode, localMatrix)); } void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt, @@ -1183,11 +1186,9 @@ GrGLPrimitiveProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker DashingLineEffect::DashingLineEffect(GrColor color, DashAAMode aaMode, - const SkMatrix& localMatrix, - bool usesLocalCoords) + const SkMatrix& localMatrix) : fColor(color) , fLocalMatrix(localMatrix) - , fUsesLocalCoords(usesLocalCoords) , fAAMode(aaMode) { this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); @@ -1195,6 +1196,12 @@ DashingLineEffect::DashingLineEffect(GrColor color, fInRectParams = &this->addVertexAttrib(Attribute("inRect", kVec4f_GrVertexAttribType)); } +void DashingLineEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const { + DashingLineBatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fUsesLocalCoords = init.fUsesLocalCoords; +} + GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect); GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, @@ -1203,7 +1210,7 @@ GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, GrTexture*[]) { DashAAMode aaMode = static_cast(random->nextULessThan(kDashAAModeCount)); return DashingLineEffect::Create(GrRandomColor(random), - aaMode, GrTest::TestMatrix(random), random->nextBool()); + aaMode, GrTest::TestMatrix(random)); } ////////////////////////////////////////////////////////////////////////////// @@ -1211,13 +1218,12 @@ GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, static GrGeometryProcessor* create_dash_gp(GrColor color, DashAAMode dashAAMode, DashCap cap, - const SkMatrix& localMatrix, - bool usesLocalCoords) { + const SkMatrix& localMatrix) { switch (cap) { case kRound_DashCap: - return DashingCircleEffect::Create(color, dashAAMode, localMatrix, usesLocalCoords); + return DashingCircleEffect::Create(color, dashAAMode, localMatrix); case kNonRound_DashCap: - return DashingLineEffect::Create(color, dashAAMode, localMatrix, usesLocalCoords); + return DashingLineEffect::Create(color, dashAAMode, localMatrix); default: SkFAIL("Unexpected dashed cap."); } diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index 09228e505a..ba42bb44f1 100755 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -21,6 +21,12 @@ // Assuming a radius of a little less than the diagonal of the fragment #define SK_DistanceFieldAAFactor "0.65" +struct DistanceFieldBatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; +}; + class GrGLDistanceFieldA8TextGeoProc : public GrGLGeometryProcessor { public: GrGLDistanceFieldA8TextGeoProc(const GrGeometryProcessor&, @@ -34,6 +40,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrDistanceFieldA8TextGeoProc& dfTexEffect = args.fGP.cast(); + const DistanceFieldBatchTracker& local = args.fBT.cast(); GrGLGPBuilder* pb = args.fPB; GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); SkAssertResult(fsBuilder->enableFeature( @@ -54,13 +61,8 @@ public: #endif // Setup pass through color - if (!dfTexEffect.colorIgnored()) { - if (dfTexEffect.hasVertexColor()) { - pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); - } else { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } - } + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, + dfTexEffect.inColor(), &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix()); @@ -152,11 +154,12 @@ public: const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast(); this->setUniformViewMatrix(pdman, dfa8gp.viewMatrix()); - if (dfa8gp.color() != fColor && !dfa8gp.hasVertexColor()) { + const DistanceFieldBatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(dfa8gp.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = dfa8gp.color(); + fColor = local.fColor; } } @@ -165,9 +168,9 @@ public: const GrGLSLCaps&, GrProcessorKeyBuilder* b) { const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast(); + const DistanceFieldBatchTracker& local = bt.cast(); uint32_t key = dfTexEffect.getFlags(); - key |= dfTexEffect.hasVertexColor() << 16; - key |= dfTexEffect.colorIgnored() << 17; + key |= local.fInputColorType << 16; key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25; b->add32(key); } @@ -192,8 +195,7 @@ GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color, #ifdef SK_GAMMA_APPLY_TO_A8 float distanceAdjust, #endif - uint32_t flags, - bool usesLocalCoords) + uint32_t flags) : fColor(color) , fViewMatrix(viewMatrix) , fTextureAccess(texture, params) @@ -201,8 +203,7 @@ GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color, , fDistanceAdjust(distanceAdjust) #endif , fFlags(flags & kNonLCD_DistanceFieldEffectMask) - , fInColor(NULL) - , fUsesLocalCoords(usesLocalCoords) { + , fInColor(NULL) { SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); @@ -226,6 +227,14 @@ GrDistanceFieldA8TextGeoProc::createGLInstance(const GrBatchTracker& bt, return SkNEW_ARGS(GrGLDistanceFieldA8TextGeoProc, (*this, bt)); } +void GrDistanceFieldA8TextGeoProc::initBatchTracker(GrBatchTracker* bt, + const GrPipelineInfo& init) const { + DistanceFieldBatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, + SkToBool(fInColor)); + local->fUsesLocalCoords = init.fUsesLocalCoords; +} + /////////////////////////////////////////////////////////////////////////////// GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldA8TextGeoProc); @@ -255,12 +264,17 @@ GrGeometryProcessor* GrDistanceFieldA8TextGeoProc::TestCreate(SkRandom* random, random->nextF(), #endif random->nextBool() ? - kSimilarity_DistanceFieldEffectFlag : 0, - random->nextBool()); + kSimilarity_DistanceFieldEffectFlag : 0); } /////////////////////////////////////////////////////////////////////////////// +struct DistanceFieldPathBatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; +}; + class GrGLDistanceFieldPathGeoProc : public GrGLGeometryProcessor { public: GrGLDistanceFieldPathGeoProc(const GrGeometryProcessor&, @@ -270,6 +284,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast(); + const DistanceFieldPathBatchTracker& local = args.fBT.cast(); GrGLGPBuilder* pb = args.fPB; GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); SkAssertResult(fsBuilder->enableFeature( @@ -284,13 +299,9 @@ public: args.fPB->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); // setup pass through color - if (!dfTexEffect.colorIgnored()) { - if (dfTexEffect.hasVertexColor()) { - pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); - } else { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } - } + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, + dfTexEffect.inColor(), &fColorUniform); + vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); // Setup position @@ -373,11 +384,12 @@ public: const GrDistanceFieldPathGeoProc& dfpgp = proc.cast(); this->setUniformViewMatrix(pdman, dfpgp.viewMatrix()); - if (dfpgp.color() != fColor) { + const DistanceFieldPathBatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(dfpgp.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = dfpgp.color(); + fColor = local.fColor; } } @@ -387,9 +399,9 @@ public: GrProcessorKeyBuilder* b) { const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast(); + const DistanceFieldPathBatchTracker& local = bt.cast(); uint32_t key = dfTexEffect.getFlags(); - key |= dfTexEffect.colorIgnored() << 16; - key |= dfTexEffect.hasVertexColor() << 17; + key |= local.fInputColorType << 16; key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25; b->add32(key); } @@ -410,14 +422,12 @@ GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc( const SkMatrix& viewMatrix, GrTexture* texture, const GrTextureParams& params, - uint32_t flags, - bool usesLocalCoords) + uint32_t flags) : fColor(color) , fViewMatrix(viewMatrix) , fTextureAccess(texture, params) , fFlags(flags & kNonLCD_DistanceFieldEffectMask) - , fInColor(NULL) - , fUsesLocalCoords(usesLocalCoords) { + , fInColor(NULL) { SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); @@ -425,7 +435,7 @@ GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc( fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); } fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", - kVec2f_GrVertexAttribType)); + kVec2f_GrVertexAttribType)); this->addTextureAccess(&fTextureAccess); } @@ -440,6 +450,14 @@ GrDistanceFieldPathGeoProc::createGLInstance(const GrBatchTracker& bt, const GrG return SkNEW_ARGS(GrGLDistanceFieldPathGeoProc, (*this, bt)); } +void GrDistanceFieldPathGeoProc::initBatchTracker(GrBatchTracker* bt, + const GrPipelineInfo& init) const { + DistanceFieldPathBatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, + SkToBool(fInColor)); + local->fUsesLocalCoords = init.fUsesLocalCoords; +} + /////////////////////////////////////////////////////////////////////////////// GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldPathGeoProc); @@ -466,13 +484,17 @@ GrGeometryProcessor* GrDistanceFieldPathGeoProc::TestCreate(SkRandom* random, GrTest::TestMatrix(random), textures[texIdx], params, - random->nextBool() ? - kSimilarity_DistanceFieldEffectFlag : 0, - random->nextBool()); + random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0); } /////////////////////////////////////////////////////////////////////////////// +struct DistanceFieldLCDBatchTracker { + GrGPInput fInputColorType; + GrColor fColor; + bool fUsesLocalCoords; +}; + class GrGLDistanceFieldLCDTextGeoProc : public GrGLGeometryProcessor { public: GrGLDistanceFieldLCDTextGeoProc(const GrGeometryProcessor&, const GrBatchTracker&) @@ -483,6 +505,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrDistanceFieldLCDTextGeoProc& dfTexEffect = args.fGP.cast(); + const DistanceFieldLCDBatchTracker& local = args.fBT.cast(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); @@ -491,9 +514,8 @@ public: vsBuilder->emitAttributes(dfTexEffect); // setup pass through color - if (!dfTexEffect.colorIgnored()) { - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); - } + this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, + &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix()); @@ -630,11 +652,12 @@ public: this->setUniformViewMatrix(pdman, dfTexEffect.viewMatrix()); - if (dfTexEffect.color() != fColor) { + const DistanceFieldLCDBatchTracker& local = bt.cast(); + if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { GrGLfloat c[4]; - GrColorToRGBAFloat(dfTexEffect.color(), c); + GrColorToRGBAFloat(local.fColor, c); pdman.set4fv(fColorUniform, 1, c); - fColor = dfTexEffect.color(); + fColor = local.fColor; } } @@ -644,8 +667,9 @@ public: GrProcessorKeyBuilder* b) { const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast(); + const DistanceFieldLCDBatchTracker& local = bt.cast(); uint32_t key = dfTexEffect.getFlags(); - key |= dfTexEffect.colorIgnored() << 16; + key |= local.fInputColorType << 16; key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25; b->add32(key); } @@ -665,18 +689,17 @@ GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc( GrColor color, const SkMatrix& viewMatrix, GrTexture* texture, const GrTextureParams& params, DistanceAdjust distanceAdjust, - uint32_t flags, bool usesLocalCoords) + uint32_t flags) : fColor(color) , fViewMatrix(viewMatrix) , fTextureAccess(texture, params) , fDistanceAdjust(distanceAdjust) - , fFlags(flags & kLCD_DistanceFieldEffectMask) - , fUsesLocalCoords(usesLocalCoords) { + , fFlags(flags & kLCD_DistanceFieldEffectMask){ SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag)); this->initClassID(); fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", - kVec2s_GrVertexAttribType)); + kVec2s_GrVertexAttribType)); this->addTextureAccess(&fTextureAccess); } @@ -692,6 +715,13 @@ GrDistanceFieldLCDTextGeoProc::createGLInstance(const GrBatchTracker& bt, return SkNEW_ARGS(GrGLDistanceFieldLCDTextGeoProc, (*this, bt)); } +void GrDistanceFieldLCDTextGeoProc::initBatchTracker(GrBatchTracker* bt, + const GrPipelineInfo& init) const { + DistanceFieldLCDBatchTracker* local = bt->cast(); + local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); + local->fUsesLocalCoords = init.fUsesLocalCoords; +} + /////////////////////////////////////////////////////////////////////////////// GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextGeoProc); @@ -721,6 +751,5 @@ GrGeometryProcessor* GrDistanceFieldLCDTextGeoProc::TestCreate(SkRandom* random, GrTest::TestMatrix(random), textures[texIdx], params, wa, - flags, - random->nextBool()); + flags); } diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.h b/src/gpu/effects/GrDistanceFieldGeoProc.h index 42c397dd6c..ec661cedb8 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.h +++ b/src/gpu/effects/GrDistanceFieldGeoProc.h @@ -49,16 +49,15 @@ public: #ifdef SK_GAMMA_APPLY_TO_A8 static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex, const GrTextureParams& params, - float lum, uint32_t flags, bool usesLocalCoords) { + float lum, uint32_t flags) { return SkNEW_ARGS(GrDistanceFieldA8TextGeoProc, (color, viewMatrix, tex, params, lum, - flags, usesLocalCoords)); + flags)); } #else static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex, const GrTextureParams& params, - uint32_t flags, bool usesLocalCoords) { - return SkNEW_ARGS(GrDistanceFieldA8TextGeoProc, (color, viewMatrix, tex, params, flags, - usesLocalCoords)); + uint32_t flags) { + return SkNEW_ARGS(GrDistanceFieldA8TextGeoProc, (color, viewMatrix, tex, params, flags)); } #endif @@ -70,10 +69,7 @@ public: const Attribute* inColor() const { return fInColor; } const Attribute* inTextureCoords() const { return fInTextureCoords; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } - bool hasVertexColor() const { return SkToBool(fInColor); } const SkMatrix& viewMatrix() const { return fViewMatrix; } - bool usesLocalCoords() const { return fUsesLocalCoords; } #ifdef SK_GAMMA_APPLY_TO_A8 float getDistanceAdjust() const { return fDistanceAdjust; } #endif @@ -86,13 +82,15 @@ public: virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, const GrGLSLCaps&) const override; + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override; + private: GrDistanceFieldA8TextGeoProc(GrColor, const SkMatrix& viewMatrix, GrTexture* texture, const GrTextureParams& params, #ifdef SK_GAMMA_APPLY_TO_A8 float distanceAdjust, #endif - uint32_t flags, bool usesLocalCoords); + uint32_t flags); GrColor fColor; SkMatrix fViewMatrix; @@ -104,7 +102,6 @@ private: const Attribute* fInPosition; const Attribute* fInColor; const Attribute* fInTextureCoords; - bool fUsesLocalCoords; GR_DECLARE_GEOMETRY_PROCESSOR_TEST; @@ -122,9 +119,8 @@ class GrDistanceFieldPathGeoProc : public GrGeometryProcessor { public: static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex, const GrTextureParams& params, - uint32_t flags, bool usesLocalCoords) { - return SkNEW_ARGS(GrDistanceFieldPathGeoProc, (color, viewMatrix, tex, params, flags, - usesLocalCoords)); + uint32_t flags) { + return SkNEW_ARGS(GrDistanceFieldPathGeoProc, (color, viewMatrix, tex, params, flags)); } virtual ~GrDistanceFieldPathGeoProc() {} @@ -135,11 +131,8 @@ public: const Attribute* inColor() const { return fInColor; } const Attribute* inTextureCoords() const { return fInTextureCoords; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } - bool hasVertexColor() const { return SkToBool(fInColor); } const SkMatrix& viewMatrix() const { return fViewMatrix; } uint32_t getFlags() const { return fFlags; } - bool usesLocalCoords() const { return fUsesLocalCoords; } virtual void getGLProcessorKey(const GrBatchTracker& bt, const GrGLSLCaps& caps, @@ -148,10 +141,11 @@ public: virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, const GrGLSLCaps&) const override; + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override; + private: GrDistanceFieldPathGeoProc(GrColor, const SkMatrix& viewMatrix, GrTexture* texture, - const GrTextureParams& params, uint32_t flags, - bool usesLocalCoords); + const GrTextureParams& params, uint32_t flags); GrColor fColor; SkMatrix fViewMatrix; @@ -160,7 +154,6 @@ private: const Attribute* fInPosition; const Attribute* fInColor; const Attribute* fInTextureCoords; - bool fUsesLocalCoords; GR_DECLARE_GEOMETRY_PROCESSOR_TEST; @@ -192,10 +185,9 @@ public: static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex, const GrTextureParams& params, - DistanceAdjust distanceAdjust, uint32_t flags, - bool usesLocalCoords) { + DistanceAdjust distanceAdjust, uint32_t flags) { return SkNEW_ARGS(GrDistanceFieldLCDTextGeoProc, - (color, viewMatrix, tex, params, distanceAdjust, flags, usesLocalCoords)); + (color, viewMatrix, tex, params, distanceAdjust, flags)); } virtual ~GrDistanceFieldLCDTextGeoProc() {} @@ -206,10 +198,8 @@ public: const Attribute* inTextureCoords() const { return fInTextureCoords; } DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; } GrColor color() const { return fColor; } - bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } const SkMatrix& viewMatrix() const { return fViewMatrix; } uint32_t getFlags() const { return fFlags; } - bool usesLocalCoords() const { return fUsesLocalCoords; } virtual void getGLProcessorKey(const GrBatchTracker& bt, const GrGLSLCaps& caps, @@ -218,11 +208,12 @@ public: virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, const GrGLSLCaps&) const override; + void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override; + private: GrDistanceFieldLCDTextGeoProc(GrColor, const SkMatrix& viewMatrix, GrTexture* texture, const GrTextureParams& params, - DistanceAdjust wa, uint32_t flags, - bool usesLocalCoords); + DistanceAdjust wa, uint32_t flags); GrColor fColor; SkMatrix fViewMatrix; @@ -231,7 +222,6 @@ private: uint32_t fFlags; const Attribute* fInPosition; const Attribute* fInTextureCoords; - bool fUsesLocalCoords; GR_DECLARE_GEOMETRY_PROCESSOR_TEST; diff --git a/src/gpu/gl/GrGLPrimitiveProcessor.cpp b/src/gpu/gl/GrGLPrimitiveProcessor.cpp index d719774a66..3213ffa8e2 100644 --- a/src/gpu/gl/GrGLPrimitiveProcessor.cpp +++ b/src/gpu/gl/GrGLPrimitiveProcessor.cpp @@ -31,18 +31,28 @@ SkMatrix GrGLPrimitiveProcessor::GetTransformMatrix(const SkMatrix& localMatrix, return combined; } -void GrGLPrimitiveProcessor::setupUniformColor(GrGLGPBuilder* pb, - const char* outputName, - UniformHandle* colorUniform) { +void +GrGLPrimitiveProcessor::setupColorPassThrough(GrGLGPBuilder* pb, + GrGPInput inputType, + const char* outputName, + const GrGeometryProcessor::Attribute* colorAttr, + UniformHandle* colorUniform) { GrGLFragmentBuilder* fs = pb->getFragmentShaderBuilder(); - SkASSERT(colorUniform); - const char* stagedLocalVarName; - *colorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, - kVec4f_GrSLType, - kDefault_GrSLPrecision, - "Color", - &stagedLocalVarName); - fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName); + if (kUniform_GrGPInput == inputType) { + SkASSERT(colorUniform); + const char* stagedLocalVarName; + *colorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, + kVec4f_GrSLType, + kDefault_GrSLPrecision, + "Color", + &stagedLocalVarName); + fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName); + } else if (kAttribute_GrGPInput == inputType) { + SkASSERT(colorAttr); + pb->addPassThroughAttribute(colorAttr, outputName); + } else if (kAllOnes_GrGPInput == inputType) { + fs->codeAppendf("%s = vec4(1);", outputName); + } } void GrGLPrimitiveProcessor::addUniformViewMatrix(GrGLGPBuilder* pb) { diff --git a/src/gpu/gl/GrGLPrimitiveProcessor.h b/src/gpu/gl/GrGLPrimitiveProcessor.h index 90ee2038f8..30b1c178cd 100644 --- a/src/gpu/gl/GrGLPrimitiveProcessor.h +++ b/src/gpu/gl/GrGLPrimitiveProcessor.h @@ -74,7 +74,16 @@ public: static SkMatrix GetTransformMatrix(const SkMatrix& localMatrix, const GrCoordTransform&); protected: - void setupUniformColor(GrGLGPBuilder* pb, const char* outputName, UniformHandle* colorUniform); + /** a helper which can setup vertex, constant, or uniform color depending on inputType. + * This function will only do the minimum required to emit the correct shader code. If + * inputType == attribute, then colorAttr must not be NULL. Likewise, if inputType == Uniform + * then colorUniform must not be NULL. + */ + void setupColorPassThrough(GrGLGPBuilder* pb, + GrGPInput inputType, + const char* inputName, + const GrPrimitiveProcessor::Attribute* colorAttr, + UniformHandle* colorUniform); const char* uViewM() const { return fViewMatrixName; } -- cgit v1.2.3