}
GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
gp.reset(GrConicEffect::Create(color, SkMatrix::I(), et,
- *tt.target()->caps(), SkMatrix::I(), false));
+ *tt.target()->caps(), SkMatrix::I()));
if (!gp) {
continue;
}
}
GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
gp.reset(GrQuadEffect::Create(color, SkMatrix::I(), et,
- *tt.target()->caps(), SkMatrix::I(), false));
+ *tt.target()->caps(), SkMatrix::I()));
if (!gp) {
continue;
}
static const GrColor color = 0xff000000;
SkAutoTUnref<const GrGeometryProcessor> gp(
- GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType, color,
- false, false));
+ GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType, color));
SkScalar y = 0;
for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
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() {}
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:
args.fPB->addVarying("QuadEdge", &v);
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName);
+ const BatchTracker& local = args.fBT.cast<BatchTracker>();
+
// 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);
const GrBatchTracker& bt,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
+ const BatchTracker& local = bt.cast<BatchTracker>();
const QuadEdgeEffect& qee = gp.cast<QuadEdgeEffect>();
- 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<QuadEdgeEffect>();
- if (qe.color() != fColor) {
+ const BatchTracker& local = bt.cast<BatchTracker>();
+ 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;
}
}
return SkNEW_ARGS(GLProcessor, (*this, bt));
}
+ void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override {
+ BatchTracker* local = bt->cast<BatchTracker>();
+ 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<QuadEdgeEffect>();
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;
// Doesn't work without derivative instructions.
return caps.shaderCaps()->shaderDerivativeSupport() ?
QuadEdgeEffect::Create(GrRandomColor(random),
- GrTest::TestMatrix(random),
- random->nextBool()) : NULL;
+ GrTest::TestMatrix(random)) : NULL;
}
///////////////////////////////////////////////////////////////////////////////
}
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 {
// Setup GrGeometryProcessor
SkAutoTUnref<const GrGeometryProcessor> 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 ?
}
// Setup GrGeometryProcessor
- SkAutoTUnref<GrGeometryProcessor> quadProcessor(
- QuadEdgeEffect::Create(this->color(), invert, this->usesLocalCoords()));
+ SkAutoTUnref<GrGeometryProcessor> 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];
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;
this->viewMatrix(),
atlas->getTexture(),
params,
- flags,
- this->usesLocalCoords()));
+ flags));
- batchTarget->initDraw(dfProcessor, pipeline);
+ this->initDraw(batchTarget, dfProcessor, pipeline);
FlushInfo flushInfo;
&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);
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();
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;
SkAutoTUnref<const GrGeometryProcessor> lineGP(
GrDefaultGeoProcFactory::Create(gpFlags,
this->color(),
- this->usesLocalCoords(),
- this->coverageIgnored(),
*geometryProcessorViewM,
*geometryProcessorLocalM,
this->coverage()));
kHairlineAA_GrProcessorEdgeType,
batchTarget->caps(),
*geometryProcessorLocalM,
- this->usesLocalCoords(),
this->coverage()));
SkAutoTUnref<const GrGeometryProcessor> conicGP(
kHairlineAA_GrProcessorEdgeType,
batchTarget->caps(),
*geometryProcessorLocalM,
- this->usesLocalCoords(),
this->coverage()));
// This is hand inlined for maximum performance.
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;
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,
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,
}
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;
}
}
SkAutoTUnref<const GrGeometryProcessor> 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) :
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<AAFillRectBatch>();
}
SkAutoTUnref<const GrGeometryProcessor> 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 ?
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<AAStrokeRectBatch>();
texture,
params,
fMaskFormat,
- localMatrix,
- this->usesLocalCoords()));
+ localMatrix));
}
FlushInfo flushInfo;
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;
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,
}
}
+ 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();
texture,
params,
widthAdjust,
- flags,
- this->usesLocalCoords());
+ flags);
} else {
flags |= kColorAttr_DistanceFieldEffectFlag;
#ifdef SK_GAMMA_APPLY_TO_A8
texture,
params,
correction,
- flags,
- this->usesLocalCoords());
+ flags);
#else
return GrDistanceFieldA8TextGeoProc::Create(color,
viewMatrix,
texture,
params,
- flags,
- this->usesLocalCoords());
+ flags);
#endif
}
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(); }
SkAutoTUnref<const GrGeometryProcessor> 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));
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<StrokeRectBatch>();
int* colorOffset,
int* texOffset,
GrColor color,
- const SkMatrix& viewMatrix,
- bool coverageIgnored) {
+ const SkMatrix& viewMatrix) {
*texOffset = -1;
*colorOffset = -1;
uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType;
*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 {
int colorOffset = -1, texOffset = -1;
SkAutoTUnref<const GrGeometryProcessor> 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)
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<DrawVerticesBatch>();
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"; }
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<BatchTracker>();
+ 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:
GrGLGPBuilder* pb = args.fPB;
GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
GrGLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
+ const BatchTracker& local = args.fBT.cast<BatchTracker>();
// 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());
}
// 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);
}
}
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
const DefaultGeoProc& def = gp.cast<DefaultGeoProc>();
+ const BatchTracker& local = bt.cast<BatchTracker>();
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);
}
const DefaultGeoProc& dgp = gp.cast<DefaultGeoProc>();
this->setUniformViewMatrix(pdman, dgp.viewMatrix());
- if (dgp.color() != fColor && !dgp.hasVertexColor()) {
+ const BatchTracker& local = bt.cast<BatchTracker>();
+ 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;
}
}
GrColor color,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix,
- uint8_t coverage,
- bool usesLocalCoords,
- bool coverageIgnored)
+ uint8_t coverage)
: fInPosition(NULL)
, fInColor(NULL)
, fInLocalCoords(NULL)
, fViewMatrix(viewMatrix)
, fLocalMatrix(localMatrix)
, fCoverage(coverage)
- , fFlags(gpTypeFlags)
- , fUsesLocalCoords(usesLocalCoords)
- , fCoverageIgnored(coverageIgnored) {
+ , fFlags(gpTypeFlags) {
this->initClassID<DefaultGeoProc>();
bool hasColor = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kColor_GPType);
bool hasLocalCoord = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kLocalCoord_GPType);
}
if (hasLocalCoord) {
fInLocalCoords = &this->addVertexAttrib(Attribute("inLocalCoord",
- kVec2f_GrVertexAttribType));
+ kVec2f_GrVertexAttribType));
this->setHasLocalCoords();
}
if (hasCoverage) {
}
}
+ struct BatchTracker {
+ GrGPInput fInputColorType;
+ GrGPInput fInputCoverageType;
+ GrColor fColor;
+ GrColor fCoverage;
+ bool fUsesLocalCoords;
+ };
+
const Attribute* fInPosition;
const Attribute* fInColor;
const Attribute* fInLocalCoords;
SkMatrix fLocalMatrix;
uint8_t fCoverage;
uint32_t fFlags;
- bool fUsesLocalCoords;
- bool fCoverageIgnored;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
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) {
color,
viewMatrix,
localMatrix,
- usesLocalCoords,
- coverageIgnored,
coverage);
}
// 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);
SkAutoTUnref<const GrGeometryProcessor> gp(
GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
this->color(),
- this->usesLocalCoords(),
- this->coverageIgnored(),
this->viewMatrix(),
SkMatrix::I(),
this->coverage()));
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
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;
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,
}
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.
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"; }
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>();
GrGLGPBuilder* pb = args.fPB;
+ const BatchTracker& local = args.fBT.cast<BatchTracker>();
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
// emit attributes
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);
const GrBatchTracker& bt,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
+ const BatchTracker& local = bt.cast<BatchTracker>();
const CircleEdgeEffect& ce = gp.cast<CircleEdgeEffect>();
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<CircleEdgeEffect>();
- if (ce.color() != fColor) {
+ const BatchTracker& local = bt.cast<BatchTracker>();
+ 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;
}
}
return SkNEW_ARGS(GLProcessor, (*this, bt));
}
+ void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override {
+ BatchTracker* local = bt->cast<BatchTracker>();
+ 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<CircleEdgeEffect>();
fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
fInCircleEdge = &this->addVertexAttrib(Attribute("inCircleEdge",
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;
GrTexture* textures[]) {
return CircleEdgeEffect::Create(GrRandomColor(random),
random->nextBool(),
- GrTest::TestMatrix(random),
- random->nextBool());
+ GrTest::TestMatrix(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() {}
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; }
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>();
GrGLGPBuilder* pb = args.fPB;
+ const BatchTracker& local = args.fBT.cast<BatchTracker>();
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
// emit attributes
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);
const GrBatchTracker& bt,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
+ const BatchTracker& local = bt.cast<BatchTracker>();
const EllipseEdgeEffect& ee = gp.cast<EllipseEdgeEffect>();
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<EllipseEdgeEffect>();
- if (ee.color() != fColor) {
+
+ const BatchTracker& local = bt.cast<BatchTracker>();
+ 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;
}
}
return SkNEW_ARGS(GLProcessor, (*this, bt));
}
+ void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override {
+ BatchTracker* local = bt->cast<BatchTracker>();
+ 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<EllipseEdgeEffect>();
fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
fInEllipseOffset = &this->addVertexAttrib(Attribute("inEllipseOffset",
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;
GrTexture* textures[]) {
return EllipseEdgeEffect::Create(GrRandomColor(random),
random->nextBool(),
- GrTest::TestMatrix(random),
- random->nextBool());
+ GrTest::TestMatrix(random));
}
///////////////////////////////////////////////////////////////////////////////
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() {}
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; }
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>();
GrGLGPBuilder* pb = args.fPB;
+ const BatchTracker& local = args.fBT.cast<BatchTracker>();
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
// emit attributes
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());
const GrBatchTracker& bt,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
+ const BatchTracker& local = bt.cast<BatchTracker>();
const DIEllipseEdgeEffect& ellipseEffect = gp.cast<DIEllipseEdgeEffect>();
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,
const DIEllipseEdgeEffect& dee = gp.cast<DIEllipseEdgeEffect>();
this->setUniformViewMatrix(pdman, dee.viewMatrix());
- if (dee.color() != fColor) {
+ const BatchTracker& local = bt.cast<BatchTracker>();
+ 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;
}
}
return SkNEW_ARGS(GLProcessor, (*this, bt));
}
+ void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override {
+ BatchTracker* local = bt->cast<BatchTracker>();
+ 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<DIEllipseEdgeEffect>();
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;
GrTexture* textures[]) {
return DIEllipseEdgeEffect::Create(GrRandomColor(random),
GrTest::TestMatrix(random),
- (Mode)(random->nextRangeU(0,2)),
- random->nextBool());
+ (Mode)(random->nextRangeU(0,2)));
}
///////////////////////////////////////////////////////////////////////////////
// Setup geometry processor
SkAutoTUnref<GrGeometryProcessor> 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));
// Setup geometry processor
SkAutoTUnref<GrGeometryProcessor> 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();
// Setup geometry processor
SkAutoTUnref<GrGeometryProcessor> 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));
// Setup geometry processor
SkAutoTUnref<GrGeometryProcessor> 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));
// Setup geometry processor
SkAutoTUnref<GrGeometryProcessor> 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));
const PathBatchTracker& mine = m.cast<PathBatchTracker>();
const PathBatchTracker& theirs = t.cast<PathBatchTracker>();
- 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,
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<GrPathProcessor>();
+ const GrPathProcessor& right = r.cast<GrPathProcessor>();
+ if (leftUsesLocalCoords && !left.localMatrix().cheapEqualTo(right.localMatrix())) {
+ return false;
+ }
+ return true;
+ }
+
bool hasExplicitLocalCoords() const override { return false; }
GrColor fColor;
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());
}
}
}
SkAutoTUnref<const GrGeometryProcessor> 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 ?
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<RectBatch>();
LOG("got %d pts, %d contours\n", maxPts, contourCnt);
uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType;
SkAutoTUnref<const GrGeometryProcessor> 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<Vertex*> contours(SkNEW_ARRAY(Vertex *, contourCnt));
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);
}
#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&,
const GrConicEffect& ce = primProc.cast<GrConicEffect>();
this->setUniformViewMatrix(pdman, ce.viewMatrix());
- if (ce.color() != fColor) {
+ const ConicBatchTracker& local = bt.cast<ConicBatchTracker>();
+ 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;
}
}
GrGLGPBuilder* pb = args.fPB;
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
+ const ConicBatchTracker& local = args.fBT.cast<ConicBatchTracker>();
// emit attributes
vsBuilder->emitAttributes(gp);
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());
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,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
const GrConicEffect& ce = gp.cast<GrConicEffect>();
+ const ConicBatchTracker& local = bt.cast<ConicBatchTracker>();
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);
}
}
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<GrConicEffect>();
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<ConicBatchTracker>();
+ local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
+ local->fCoverageScale = fCoverageScale;
+ local->fUsesLocalCoords = init.fUsesLocalCoords;
}
//////////////////////////////////////////////////////////////////////////////
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;
}
// Quad
//////////////////////////////////////////////////////////////////////////////
+struct QuadBatchTracker {
+ GrGPInput fInputColorType;
+ GrColor fColor;
+ uint8_t fCoverageScale;
+ bool fUsesLocalCoords;
+};
+
class GrGLQuadEffect : public GrGLGeometryProcessor {
public:
GrGLQuadEffect(const GrGeometryProcessor&,
const GrQuadEffect& qe = primProc.cast<GrQuadEffect>();
this->setUniformViewMatrix(pdman, qe.viewMatrix());
- if (qe.color() != fColor) {
+ const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
+ 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;
}
}
GrGLGPBuilder* pb = args.fPB;
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
+ const QuadBatchTracker& local = args.fBT.cast<QuadBatchTracker>();
// emit attributes
vsBuilder->emitAttributes(gp);
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());
SkFAIL("Shouldn't get here");
}
- if (0xff != gp.coverageScale()) {
+ if (0xff != local.fCoverageScale) {
const char* coverageScale;
fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
const GrQuadEffect& ce = gp.cast<GrQuadEffect>();
+ const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
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);
}
}
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<GrQuadEffect>();
kVec4f_GrVertexAttribType));
}
+void GrQuadEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const {
+ QuadBatchTracker* local = bt->cast<QuadBatchTracker>();
+ local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
+ local->fCoverageScale = fCoverageScale;
+ local->fUsesLocalCoords = init.fUsesLocalCoords;
+}
+
//////////////////////////////////////////////////////////////////////////////
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
gp = GrQuadEffect::Create(GrRandomColor(random),
GrTest::TestMatrix(random),
edgeType, caps,
- GrTest::TestMatrix(random),
- random->nextBool());
+ GrTest::TestMatrix(random));
} while (NULL == gp);
return gp;
}
// Cubic
//////////////////////////////////////////////////////////////////////////////
+struct CubicBatchTracker {
+ GrGPInput fInputColorType;
+ GrColor fColor;
+ bool fUsesLocalCoords;
+};
+
class GrGLCubicEffect : public GrGLGeometryProcessor {
public:
GrGLCubicEffect(const GrGeometryProcessor&,
const GrCubicEffect& ce = primProc.cast<GrCubicEffect>();
this->setUniformViewMatrix(pdman, ce.viewMatrix());
- if (ce.color() != fColor) {
+ const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
+ 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;
}
}
void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
+ const CubicBatchTracker& local = args.fBT.cast<CubicBatchTracker>();
// emit attributes
vsBuilder->emitAttributes(gp);
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());
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
const GrCubicEffect& ce = gp.cast<GrCubicEffect>();
+ const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
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);
}
kVec4f_GrVertexAttribType));
}
+void GrCubicEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const {
+ CubicBatchTracker* local = bt->cast<CubicBatchTracker>();
+ local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
+ local->fUsesLocalCoords = init.fUsesLocalCoords;
+}
+
//////////////////////////////////////////////////////////////////////////////
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
const GrPrimitiveEdgeType edgeType,
const GrDrawTargetCaps& caps,
const SkMatrix& localMatrix,
- bool usesLocalCoords,
uint8_t coverage = 0xff) {
switch (edgeType) {
case kFillAA_GrProcessorEdgeType:
}
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;
}
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,
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;
const GrPrimitiveEdgeType edgeType,
const GrDrawTargetCaps& caps,
const SkMatrix& localMatrix,
- bool usesLocalCoords,
uint8_t coverage = 0xff) {
switch (edgeType) {
case kFillAA_GrProcessorEdgeType:
}
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;
}
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,
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;
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,
virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt,
const GrGLSLCaps&) const override;
+ void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const override;
+
private:
GrCubicEffect(GrColor, const SkMatrix& viewMatrix, GrPrimitiveEdgeType);
#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&)
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>();
+ const BitmapTextBatchTracker& local = args.fBT.cast<BitmapTextBatchTracker>();
GrGLGPBuilder* pb = args.fPB;
GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
}
// 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);
virtual void setData(const GrGLProgramDataManager& pdman,
const GrPrimitiveProcessor& gp,
const GrBatchTracker& bt) override {
- const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>();
- if (btgp.color() != fColor && !btgp.hasVertexColor()) {
+ const BitmapTextBatchTracker& local = bt.cast<BitmapTextBatchTracker>();
+ 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;
}
}
const GrBatchTracker& bt,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
+ const BitmapTextBatchTracker& local = bt.cast<BitmapTextBatchTracker>();
+ // 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<GrBitmapTextGeoProc>();
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:
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<GrBitmapTextGeoProc>();
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));
return SkNEW_ARGS(GrGLBitmapTextGeoProc, (*this, bt));
}
+void GrBitmapTextGeoProc::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const {
+ BitmapTextBatchTracker* local = bt->cast<BitmapTextBatchTracker>();
+ local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
+ SkToBool(fInColor));
+ local->fUsesLocalCoords = init.fUsesLocalCoords;
+}
+
///////////////////////////////////////////////////////////////////////////////
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc);
}
return GrBitmapTextGeoProc::Create(GrRandomColor(random), textures[texIdx], params,
- format, GrTest::TestMatrix(random), random->nextBool());
+ format, GrTest::TestMatrix(random));
}
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() {}
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,
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;
static GrGeometryProcessor* create_dash_gp(GrColor,
DashAAMode aaMode,
DashCap cap,
- const SkMatrix& localMatrix,
- bool usesLocalCoords);
+ const SkMatrix& localMatrix);
class DashBatch : public GrBatch {
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();
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;
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.
static GrGeometryProcessor* Create(GrColor,
DashAAMode aaMode,
- const SkMatrix& localMatrix,
- bool usesLocalCoords);
+ const SkMatrix& localMatrix);
const char* name() const override { return "DashingCircleEffect"; }
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;
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;
void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>();
+ const DashingCircleBatchTracker local = args.fBT.cast<DashingCircleBatchTracker>();
GrGLGPBuilder* pb = args.fPB;
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
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);
void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman,
const GrPrimitiveProcessor& processor,
const GrBatchTracker& bt) {
- const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>();
- if (dce.color() != fColor) {
+ const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>();
+ 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;
}
}
const GrBatchTracker& bt,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
+ const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>();
const DashingCircleEffect& dce = gp.cast<DashingCircleEffect>();
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,
DashingCircleEffect::DashingCircleEffect(GrColor color,
DashAAMode aaMode,
- const SkMatrix& localMatrix,
- bool usesLocalCoords)
+ const SkMatrix& localMatrix)
: fColor(color)
, fLocalMatrix(localMatrix)
- , fUsesLocalCoords(usesLocalCoords)
, fAAMode(aaMode) {
this->initClassID<DashingCircleEffect>();
fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
kVec2f_GrVertexAttribType));
}
+void DashingCircleEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const {
+ DashingCircleBatchTracker* local = bt->cast<DashingCircleBatchTracker>();
+ local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
+ local->fUsesLocalCoords = init.fUsesLocalCoords;
+}
+
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect);
GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random,
GrTexture*[]) {
DashAAMode aaMode = static_cast<DashAAMode>(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.
static GrGeometryProcessor* Create(GrColor,
DashAAMode aaMode,
- const SkMatrix& localMatrix,
- bool usesLocalCoords);
+ const SkMatrix& localMatrix);
const char* name() const override { return "DashingEffect"; }
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;
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;
void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
const DashingLineEffect& de = args.fGP.cast<DashingLineEffect>();
+ const DashingLineBatchTracker& local = args.fBT.cast<DashingLineBatchTracker>();
GrGLGPBuilder* pb = args.fPB;
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
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);
void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman,
const GrPrimitiveProcessor& processor,
const GrBatchTracker& bt) {
- const DashingLineEffect& de = processor.cast<DashingLineEffect>();
- if (de.color() != fColor) {
+ const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>();
+ 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;
}
}
const GrBatchTracker& bt,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
+ const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>();
const DashingLineEffect& de = gp.cast<DashingLineEffect>();
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,
DashingLineEffect::DashingLineEffect(GrColor color,
DashAAMode aaMode,
- const SkMatrix& localMatrix,
- bool usesLocalCoords)
+ const SkMatrix& localMatrix)
: fColor(color)
, fLocalMatrix(localMatrix)
- , fUsesLocalCoords(usesLocalCoords)
, fAAMode(aaMode) {
this->initClassID<DashingLineEffect>();
fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
fInRectParams = &this->addVertexAttrib(Attribute("inRect", kVec4f_GrVertexAttribType));
}
+void DashingLineEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const {
+ DashingLineBatchTracker* local = bt->cast<DashingLineBatchTracker>();
+ local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
+ local->fUsesLocalCoords = init.fUsesLocalCoords;
+}
+
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect);
GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random,
GrTexture*[]) {
DashAAMode aaMode = static_cast<DashAAMode>(random->nextULessThan(kDashAAModeCount));
return DashingLineEffect::Create(GrRandomColor(random),
- aaMode, GrTest::TestMatrix(random), random->nextBool());
+ aaMode, GrTest::TestMatrix(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.");
}
// 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&,
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldA8TextGeoProc& dfTexEffect =
args.fGP.cast<GrDistanceFieldA8TextGeoProc>();
+ const DistanceFieldBatchTracker& local = args.fBT.cast<DistanceFieldBatchTracker>();
GrGLGPBuilder* pb = args.fPB;
GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
SkAssertResult(fsBuilder->enableFeature(
#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());
const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast<GrDistanceFieldA8TextGeoProc>();
this->setUniformViewMatrix(pdman, dfa8gp.viewMatrix());
- if (dfa8gp.color() != fColor && !dfa8gp.hasVertexColor()) {
+ const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
+ 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;
}
}
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldA8TextGeoProc>();
+ const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
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);
}
#ifdef SK_GAMMA_APPLY_TO_A8
float distanceAdjust,
#endif
- uint32_t flags,
- bool usesLocalCoords)
+ uint32_t flags)
: fColor(color)
, fViewMatrix(viewMatrix)
, fTextureAccess(texture, params)
, fDistanceAdjust(distanceAdjust)
#endif
, fFlags(flags & kNonLCD_DistanceFieldEffectMask)
- , fInColor(NULL)
- , fUsesLocalCoords(usesLocalCoords) {
+ , fInColor(NULL) {
SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
this->initClassID<GrDistanceFieldA8TextGeoProc>();
fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
return SkNEW_ARGS(GrGLDistanceFieldA8TextGeoProc, (*this, bt));
}
+void GrDistanceFieldA8TextGeoProc::initBatchTracker(GrBatchTracker* bt,
+ const GrPipelineInfo& init) const {
+ DistanceFieldBatchTracker* local = bt->cast<DistanceFieldBatchTracker>();
+ local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
+ SkToBool(fInColor));
+ local->fUsesLocalCoords = init.fUsesLocalCoords;
+}
+
///////////////////////////////////////////////////////////////////////////////
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldA8TextGeoProc);
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&,
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>();
+ const DistanceFieldPathBatchTracker& local = args.fBT.cast<DistanceFieldPathBatchTracker>();
GrGLGPBuilder* pb = args.fPB;
GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
SkAssertResult(fsBuilder->enableFeature(
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
const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathGeoProc>();
this->setUniformViewMatrix(pdman, dfpgp.viewMatrix());
- if (dfpgp.color() != fColor) {
+ const DistanceFieldPathBatchTracker& local = bt.cast<DistanceFieldPathBatchTracker>();
+ 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;
}
}
GrProcessorKeyBuilder* b) {
const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast<GrDistanceFieldPathGeoProc>();
+ const DistanceFieldPathBatchTracker& local = bt.cast<DistanceFieldPathBatchTracker>();
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);
}
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<GrDistanceFieldPathGeoProc>();
fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
}
fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
- kVec2f_GrVertexAttribType));
+ kVec2f_GrVertexAttribType));
this->addTextureAccess(&fTextureAccess);
}
return SkNEW_ARGS(GrGLDistanceFieldPathGeoProc, (*this, bt));
}
+void GrDistanceFieldPathGeoProc::initBatchTracker(GrBatchTracker* bt,
+ const GrPipelineInfo& init) const {
+ DistanceFieldPathBatchTracker* local = bt->cast<DistanceFieldPathBatchTracker>();
+ local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
+ SkToBool(fInColor));
+ local->fUsesLocalCoords = init.fUsesLocalCoords;
+}
+
///////////////////////////////////////////////////////////////////////////////
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldPathGeoProc);
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&)
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldLCDTextGeoProc& dfTexEffect =
args.fGP.cast<GrDistanceFieldLCDTextGeoProc>();
+ const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldLCDBatchTracker>();
GrGLGPBuilder* pb = args.fPB;
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
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());
this->setUniformViewMatrix(pdman, dfTexEffect.viewMatrix());
- if (dfTexEffect.color() != fColor) {
+ const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
+ 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;
}
}
GrProcessorKeyBuilder* b) {
const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldLCDTextGeoProc>();
+ const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
uint32_t key = dfTexEffect.getFlags();
- key |= dfTexEffect.colorIgnored() << 16;
+ key |= local.fInputColorType << 16;
key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25;
b->add32(key);
}
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<GrDistanceFieldLCDTextGeoProc>();
fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
- kVec2s_GrVertexAttribType));
+ kVec2s_GrVertexAttribType));
this->addTextureAccess(&fTextureAccess);
}
return SkNEW_ARGS(GrGLDistanceFieldLCDTextGeoProc, (*this, bt));
}
+void GrDistanceFieldLCDTextGeoProc::initBatchTracker(GrBatchTracker* bt,
+ const GrPipelineInfo& init) const {
+ DistanceFieldLCDBatchTracker* local = bt->cast<DistanceFieldLCDBatchTracker>();
+ local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
+ local->fUsesLocalCoords = init.fUsesLocalCoords;
+}
+
///////////////////////////////////////////////////////////////////////////////
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextGeoProc);
GrTest::TestMatrix(random),
textures[texIdx], params,
wa,
- flags,
- random->nextBool());
+ flags);
}
#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
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
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;
const Attribute* fInPosition;
const Attribute* fInColor;
const Attribute* fInTextureCoords;
- bool fUsesLocalCoords;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
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() {}
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,
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;
const Attribute* fInPosition;
const Attribute* fInColor;
const Attribute* fInTextureCoords;
- bool fUsesLocalCoords;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
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() {}
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,
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;
uint32_t fFlags;
const Attribute* fInPosition;
const Attribute* fInTextureCoords;
- bool fUsesLocalCoords;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
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) {
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; }