// drawPathsFromRange is thanks to GrStencilAndCoverTextContext
// TODO: remove once path batches can be created external to GrDrawTarget.
void drawPathsFromRange(const GrPipelineBuilder*,
- const GrPathProcessor*,
+ const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
+ GrColor color,
GrPathRangeDraw* draw,
int /*GrPathRendering::FillType*/ fill);
}
void GrDrawContext::drawPathsFromRange(const GrPipelineBuilder* pipelineBuilder,
- const GrPathProcessor* pathProc,
+ const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
+ GrColor color,
GrPathRangeDraw* draw,
int /*GrPathRendering::FillType*/ fill) {
- fDrawTarget->drawPathsFromRange(*pipelineBuilder, pathProc, draw,
+ fDrawTarget->drawPathsFromRange(*pipelineBuilder, viewMatrix, localMatrix, color, draw,
(GrPathRendering::FillType) fill);
}
}
void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
- const GrPathProcessor* pathProc,
+ const SkMatrix& viewMatrix,
const GrPath* path,
GrPathRendering::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path stenciling.
GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment();
this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
- GrBatch* batch = GrStencilPathBatch::Create(pathProc->viewMatrix(),
+ GrBatch* batch = GrStencilPathBatch::Create(viewMatrix,
pipelineBuilder.isHWAntialias(),
stencilSettings, scissorState,
pipelineBuilder.getRenderTarget(),
}
void GrDrawTarget::drawPath(const GrPipelineBuilder& pipelineBuilder,
- const GrPathProcessor* pathProc,
+ const SkMatrix& viewMatrix,
+ GrColor color,
const GrPath* path,
GrPathRendering::FillType fill) {
SkASSERT(path);
SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
- GrDrawPathBatchBase* batch = GrDrawPathBatch::Create(pathProc, path);
+ GrDrawPathBatchBase* batch = GrDrawPathBatch::Create(viewMatrix, color, path);
this->drawPathBatch(pipelineBuilder, batch, fill);
batch->unref();
}
void GrDrawTarget::drawPathsFromRange(const GrPipelineBuilder& pipelineBuilder,
- const GrPathProcessor* pathProc,
+ const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
+ GrColor color,
GrPathRangeDraw* draw,
GrPathRendering::FillType fill) {
- GrDrawPathBatchBase* batch = GrDrawPathRangeBatch::Create(pathProc, draw);
+ GrDrawPathBatchBase* batch = GrDrawPathRangeBatch::Create(viewMatrix, localMatrix, color, draw);
this->drawPathBatch(pipelineBuilder, batch, fill);
batch->unref();
}
* on the GrPipelineBuilder (if possible in the 3D API). Note, we will never have an inverse
* fill with stencil path
*/
- void stencilPath(const GrPipelineBuilder&, const GrPathProcessor*, const GrPath*,
+ void stencilPath(const GrPipelineBuilder&, const SkMatrix& viewMatrix, const GrPath*,
GrPathRendering::FillType);
/**
*
* TODO: Remove this function and construct the batch outside GrDrawTarget.
*/
- void drawPath(const GrPipelineBuilder&, const GrPathProcessor*, const GrPath*,
- GrPathRendering::FillType);
+ void drawPath(const GrPipelineBuilder&, const SkMatrix& viewMatrix, GrColor color,
+ const GrPath*, GrPathRendering::FillType);
/**
* Draws the aggregate path from combining multiple. Note that this will not
* @param fill Fill type for drawing all the paths
*/
void drawPathsFromRange(const GrPipelineBuilder&,
- const GrPathProcessor*,
+ const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
+ GrColor color,
GrPathRangeDraw* draw,
GrPathRendering::FillType fill);
#include "glsl/GrGLSLCaps.h"
GrPathProcessor::GrPathProcessor(GrColor color,
+ const GrPipelineOptimizations& opts,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix)
: INHERITED(true)
, fColor(color)
, fViewMatrix(viewMatrix)
- , fLocalMatrix(localMatrix) {
+ , fLocalMatrix(localMatrix)
+ , fOpts(opts) {
this->initClassID<GrPathProcessor>();
}
class GrPathProcessor : public GrPrimitiveProcessor {
public:
static GrPathProcessor* Create(GrColor color,
+ const GrPipelineOptimizations& opts,
const SkMatrix& viewMatrix = SkMatrix::I(),
const SkMatrix& localMatrix = SkMatrix::I()) {
- return new GrPathProcessor(color, viewMatrix, localMatrix);
+ return new GrPathProcessor(color, opts, viewMatrix, localMatrix);
}
void initBatchTracker(GrBatchTracker*, const GrPipelineOptimizations&) const override;
const SkMatrix& viewMatrix() const { return fViewMatrix; }
const SkMatrix& localMatrix() const { return fLocalMatrix; }
-
void getInvariantOutputColor(GrInitInvariantOutput* out) const override;
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override;
bool hasTransformedLocalCoords() const override { return false; }
+ const GrPipelineOptimizations& opts() const { return fOpts; }
+
private:
- GrPathProcessor(GrColor color, const SkMatrix& viewMatrix, const SkMatrix& localMatrix);
+ GrPathProcessor(GrColor color, const GrPipelineOptimizations& opts,
+ const SkMatrix& viewMatrix, const SkMatrix& localMatrix);
bool hasExplicitLocalCoords() const override { return false; }
GrColor fColor;
const SkMatrix fViewMatrix;
const SkMatrix fLocalMatrix;
+ GrPipelineOptimizations fOpts;
typedef GrPrimitiveProcessor INHERITED;
};
void GrStencilAndCoverTextContext::flush(GrDrawContext* dc) {
if (fDraw) {
SkASSERT(fDraw->count());
- SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor(),
- fViewMatrix,
- fLocalMatrix));
// We should only be flushing about once every run. However, if this impacts performance
// we could move the creation of the GrPipelineBuilder earlier.
*pipelineBuilder.stencil() = kStencilPass;
- dc->drawPathsFromRange(&pipelineBuilder, pp, fDraw, GrPathRendering::kWinding_FillType);
+ dc->drawPathsFromRange(&pipelineBuilder, fViewMatrix, fLocalMatrix, fPaint.getColor(),
+ fDraw, GrPathRendering::kWinding_FillType);
fDraw->unref();
fDraw = nullptr;
}
void GrDrawPathBatch::onDraw(GrBatchFlushState* state) {
GrProgramDesc desc;
- state->gpu()->buildProgramDesc(&desc, *this->pathProcessor(),
+
+ SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(),
+ this->opts(),
+ this->viewMatrix()));
+ state->gpu()->buildProgramDesc(&desc, *pathProc,
*this->pipeline(), *this->tracker());
- GrPathRendering::DrawPathArgs args(this->pathProcessor(), this->pipeline(),
+ GrPathRendering::DrawPathArgs args(pathProc, this->pipeline(),
&desc, this->tracker(), &this->stencilSettings());
state->gpu()->pathRendering()->drawPath(args, fPath.get());
}
return isWinding;
}
-GrDrawPathRangeBatch::GrDrawPathRangeBatch(const GrPathProcessor* pathProc,
- GrPathRangeDraw* pathRangeDraw)
- : INHERITED(pathProc)
- , fDraws(4) {
+GrDrawPathRangeBatch::GrDrawPathRangeBatch(const SkMatrix& viewMatrix, const SkMatrix& localMatrix,
+ GrColor color, GrPathRangeDraw* pathRangeDraw)
+ : INHERITED(viewMatrix, color)
+ , fDraws(4)
+ , fLocalMatrix(localMatrix) {
SkDEBUGCODE(pathRangeDraw->fUsedInBatch = true;)
this->initClassID<GrDrawPathRangeBatch>();
fDraws.addToHead(SkRef(pathRangeDraw));
if (!GrPipeline::AreEqual(*this->pipeline(), *that->pipeline(), false)) {
return false;
}
- if (!this->pathProcessor()->isEqual(*this->tracker(), *that->pathProcessor(),
- *that->tracker())) {
+ if (this->color() != that->color() ||
+ !this->viewMatrix().cheapEqualTo(that->viewMatrix()) ||
+ !fLocalMatrix.cheapEqualTo(that->fLocalMatrix)) {
return false;
}
// TODO: Check some other things here. (winding, opaque, pathProc color, vm, ...)
void GrDrawPathRangeBatch::onDraw(GrBatchFlushState* state) {
GrProgramDesc desc;
- state->gpu()->buildProgramDesc(&desc, *this->pathProcessor(), *this->pipeline(),
- *this->tracker());
- GrPathRendering::DrawPathArgs args(this->pathProcessor(), this->pipeline(),
+ SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(),
+ this->opts(),
+ this->viewMatrix(),
+ fLocalMatrix));
+ state->gpu()->buildProgramDesc(&desc, *pathProc, *this->pipeline(),
+ *this->tracker());
+ GrPathRendering::DrawPathArgs args(pathProc, this->pipeline(),
&desc, this->tracker(), &this->stencilSettings());
if (fDraws.count() == 1) {
const GrPathRangeDraw& draw = **fDraws.head();
class GrDrawPathBatchBase : public GrDrawBatch {
public:
void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
- this->pathProcessor()->getInvariantOutputColor(out);
+ out->setKnownFourComponents(fColor);
}
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
- this->pathProcessor()->getInvariantOutputCoverage(out);
+ out->setKnownSingleComponent(0xff);
}
void setStencilSettings(const GrStencilSettings& stencil) { fStencilSettings = stencil; }
protected:
- GrDrawPathBatchBase(const GrPathProcessor* pathProc) : fPrimitiveProcessor(pathProc) {}
+ GrDrawPathBatchBase(const SkMatrix& viewMatrix, GrColor initialColor)
+ : fViewMatrix(viewMatrix)
+ , fColor(initialColor) {}
- GrBatchTracker* tracker() { return reinterpret_cast<GrBatchTracker*>(&fWhatchamacallit); }
- const GrPathProcessor* pathProcessor() const { return fPrimitiveProcessor.get(); }
const GrStencilSettings& stencilSettings() const { return fStencilSettings; }
const GrPipelineOptimizations& opts() const { return fOpts; }
+ const SkMatrix& viewMatrix() const { return fViewMatrix; }
+ GrColor color() const { return fColor; }
+
+ // TODO delete
+ const GrBatchTracker* tracker() const { return &fBatchTracker; }
private:
void initBatchTracker(const GrPipelineOptimizations& opts) override {
- this->pathProcessor()->initBatchTracker(this->tracker(), opts);
+ opts.getOverrideColorIfSet(&fColor);
fOpts = opts;
}
- GrPendingProgramElement<const GrPathProcessor> fPrimitiveProcessor;
- PathBatchTracker fWhatchamacallit; // TODO: delete this
+ SkMatrix fViewMatrix;
+ GrColor fColor;
GrStencilSettings fStencilSettings;
GrPipelineOptimizations fOpts;
+ // TODO delete
+ GrBatchTracker fBatchTracker;
+
typedef GrDrawBatch INHERITED;
};
class GrDrawPathBatch final : public GrDrawPathBatchBase {
public:
// This can't return a more abstract type because we install the stencil settings late :(
- static GrDrawPathBatchBase* Create(const GrPathProcessor* primProc, const GrPath* path) {
- return new GrDrawPathBatch(primProc, path);
+ static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, GrColor color,
+ const GrPath* path) {
+ return new GrDrawPathBatch(viewMatrix, color, path);
}
const char* name() const override { return "DrawPath"; }
SkString dumpInfo() const override;
private:
- GrDrawPathBatch(const GrPathProcessor* pathProc, const GrPath* path)
- : INHERITED(pathProc)
+ GrDrawPathBatch(const SkMatrix& viewMatrix, GrColor color, const GrPath* path)
+ : INHERITED(viewMatrix, color)
, fPath(path) {
fBounds = path->getBounds();
- this->pathProcessor()->viewMatrix().mapRect(&fBounds);
+ viewMatrix.mapRect(&fBounds);
this->initClassID<GrDrawPathBatch>();
}
class GrDrawPathRangeBatch final : public GrDrawPathBatchBase {
public:
// This can't return a more abstracet type because we install the stencil settings late :(
- static GrDrawPathBatchBase* Create(const GrPathProcessor* pathProc,
- GrPathRangeDraw* pathRangeDraw) {
- return SkNEW_ARGS(GrDrawPathRangeBatch, (pathProc, pathRangeDraw));
+ static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, const SkMatrix& localMatrix,
+ GrColor color, GrPathRangeDraw* pathRangeDraw) {
+ return SkNEW_ARGS(GrDrawPathRangeBatch, (viewMatrix, localMatrix, color, pathRangeDraw));
}
~GrDrawPathRangeBatch() override;
private:
inline bool isWinding() const;
- GrDrawPathRangeBatch(const GrPathProcessor* pathProc, GrPathRangeDraw* pathRangeDraw);
+ GrDrawPathRangeBatch(const SkMatrix& viewMatrix, const SkMatrix& localMatrix, GrColor color,
+ GrPathRangeDraw* pathRangeDraw);
bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override;
typedef SkTLList<GrPathRangeDraw*> DrawList;
DrawList fDraws;
int fTotalPathCount;
+ SkMatrix fLocalMatrix;
typedef GrDrawPathBatchBase INHERITED;
};
void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
SkASSERT(!args.fPath->isInverseFillType());
- SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE, *args.fViewMatrix));
SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, *args.fStroke));
- args.fTarget->stencilPath(*args.fPipelineBuilder, pp, p,
+ args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fViewMatrix, p,
convert_skpath_filltype(args.fPath->getFillType()));
}
pipelineBuilder->setStencil(kInvertedStencilPass);
// fake inverse with a stencil and cover
- SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE, viewMatrix));
- args.fTarget->stencilPath(*pipelineBuilder, pp, p,
+ args.fTarget->stencilPath(*pipelineBuilder, viewMatrix, p,
convert_skpath_filltype(path.getFillType()));
SkMatrix invert = SkMatrix::I();
0xffff);
pipelineBuilder->setStencil(kStencilPass);
- SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(args.fColor, viewMatrix));
- args.fTarget->drawPath(*pipelineBuilder, pp, p,
+ args.fTarget->drawPath(*pipelineBuilder, viewMatrix, args.fColor, p,
convert_skpath_filltype(path.getFillType()));
}
void GrGLPathProcessor::emitCode(EmitArgs& args) {
GrGLGPBuilder* pb = args.fPB;
GrGLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
- const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>();
+ const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
// emit transforms
this->emitTransforms(args.fPB, args.fTransformsIn, args.fTransformsOut);
// Setup uniform color
- if (kUniform_GrGPInput == local.fInputColorType) {
+ if (pathProc.opts().readsColor()) {
const char* stagedLocalVarName;
fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
}
// setup constant solid coverage
- if (kAllOnes_GrGPInput == local.fInputCoverageType) {
+ if (pathProc.opts().readsCoverage()) {
fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
}
}
-void GrGLPathProcessor::GenKey(const GrPathProcessor&,
+void GrGLPathProcessor::GenKey(const GrPathProcessor& pathProc,
const GrBatchTracker& bt,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
- const PathBatchTracker& local = bt.cast<PathBatchTracker>();
- b->add32(local.fInputColorType | local.fInputCoverageType << 16);
+ b->add32(SkToInt(pathProc.opts().readsColor()) |
+ SkToInt(pathProc.opts().readsCoverage()) << 16);
}
void GrGLPathProcessor::setData(const GrGLProgramDataManager& pdman,
const GrPrimitiveProcessor& primProc,
const GrBatchTracker& bt) {
- const PathBatchTracker& local = bt.cast<PathBatchTracker>();
- if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
+ const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
+ if (pathProc.opts().readsColor() && pathProc.color() != fColor) {
GrGLfloat c[4];
- GrColorToRGBAFloat(local.fColor, c);
+ GrColorToRGBAFloat(pathProc.color(), c);
pdman.set4fv(fColorUniform, 1, c);
- fColor = local.fColor;
+ fColor = pathProc.color();
}
}