aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ops
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-03-16 14:19:07 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-16 19:10:15 +0000
commit2bf4b3a97b770811d9e0558dbbfbdb57cfafbdb7 (patch)
tree3e73ebe67a871db43e4ba9f0a9df3edf15361bca /src/gpu/ops
parent1165b1ef6f069d512c6d5a43ef431b3be6f8c80f (diff)
Remove GrPipeline from GrDrawOp.
GrDrawOp subclasses are now free to construct their pipelines at flush time and now in theory could use multiple GrPipelines for multipass rendering. GrProcessorSet may be used to retain the processors from a GrPaint with "pending execution" style refs. NVPR and Instanced rendering are updated to create their pipelines at flush time without a GrPipelineBuilder. The monolithic pipeline creation/management that was on GrDrawOp is moved to GrMeshDrawOp. However, this is temporary and will be removed in coming changes. Change-Id: I124282e3cea5d070970b5460c8a679fcaf7a8eff Reviewed-on: https://skia-review.googlesource.com/7279 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/ops')
-rw-r--r--src/gpu/ops/GrDrawOp.h74
-rw-r--r--src/gpu/ops/GrDrawPathOp.cpp112
-rw-r--r--src/gpu/ops/GrDrawPathOp.h72
-rw-r--r--src/gpu/ops/GrMeshDrawOp.cpp3
-rw-r--r--src/gpu/ops/GrMeshDrawOp.h67
-rw-r--r--src/gpu/ops/GrOp.h1
-rw-r--r--src/gpu/ops/GrStencilAndCoverPathRenderer.cpp18
7 files changed, 222 insertions, 125 deletions
diff --git a/src/gpu/ops/GrDrawOp.h b/src/gpu/ops/GrDrawOp.h
index 62a16887ee..0458370bcd 100644
--- a/src/gpu/ops/GrDrawOp.h
+++ b/src/gpu/ops/GrDrawOp.h
@@ -12,6 +12,8 @@
#include "GrOp.h"
#include "GrPipeline.h"
+class GrAppliedClip;
+
/**
* GrDrawOps are flushed in two phases (preDraw, and draw). In preDraw uploads to GrGpuResources
* and draws are determined and scheduled. They are issued in the draw phase. GrDrawOpUploadToken is
@@ -56,22 +58,27 @@ public:
GrDrawOp(uint32_t classID) : INHERITED(classID) {}
- void initPipeline(const GrPipeline::InitArgs& args) {
- this->applyPipelineOptimizations(fPipeline.init(args));
- }
+ /**
+ * This information is required to determine how to compute a GrAppliedClip from a GrClip for
+ * this op.
+ */
+ enum class FixedFunctionFlags : uint32_t {
+ kNone = 0x0,
+ /** Indices that the op will enable MSAA or mixed samples rendering. */
+ kUsesHWAA = 0x1,
+ /** Indices that the op reads and/or writes the stencil buffer */
+ kUsesStencil = 0x2,
+ };
+ GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(FixedFunctionFlags);
+ virtual FixedFunctionFlags fixedFunctionFlags() const = 0;
/**
- * Performs analysis of the fragment processors in GrProcessorSet and GrAppliedClip using the
- * initial color and coverage from this op's geometry processor.
+ * This is called after the GrAppliedClip has been computed and just prior to recording the op
+ * or combining it with a previously recorded op. It is used to determine whether a copy of the
+ * destination (or destination texture itself) needs to be provided to the xp when this op
+ * executes.
*/
- void analyzeProcessors(GrProcessorSet::FragmentProcessorAnalysis* analysis,
- const GrProcessorSet& processors,
- const GrAppliedClip* appliedClip,
- const GrCaps& caps) const {
- FragmentProcessorAnalysisInputs input;
- this->getFragmentProcessorAnalysisInputs(&input);
- analysis->init(*input.colorInput(), *input.coverageInput(), processors, appliedClip, caps);
- }
+ virtual bool xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*) = 0;
protected:
static SkString DumpPipelineInfo(const GrPipeline& pipeline) {
@@ -105,53 +112,20 @@ protected:
return string;
}
- const GrPipeline* pipeline() const {
- SkASSERT(fPipeline.isInitialized());
- return &fPipeline;
- }
-
- /**
- * This describes aspects of the GrPrimitiveProcessor produced by a GrDrawOp that are used in
- * pipeline analysis.
- */
- class FragmentProcessorAnalysisInputs {
- public:
- FragmentProcessorAnalysisInputs() = default;
- GrPipelineInput* colorInput() { return &fColorInput; }
- GrPipelineInput* coverageInput() { return &fCoverageInput; }
-
- private:
- GrPipelineInput fColorInput;
- GrPipelineInput fCoverageInput;
- };
-
-private:
- /**
- * Provides information about the GrPrimitiveProccesor color and coverage outputs which become
- * inputs to the first color and coverage fragment processors.
- */
- virtual void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs*) const = 0;
-
- /**
- * After GrPipeline analysis is complete this is called so that the op can use the analysis
- * results when constructing its GrPrimitiveProcessor.
- */
- virtual void applyPipelineOptimizations(const GrPipelineOptimizations&) = 0;
-
-protected:
struct QueuedUpload {
QueuedUpload(DeferredUploadFn&& upload, GrDrawOpUploadToken token)
: fUpload(std::move(upload))
, fUploadBeforeToken(token) {}
- DeferredUploadFn fUpload;
+ DeferredUploadFn fUpload;
GrDrawOpUploadToken fUploadBeforeToken;
};
- SkTArray<QueuedUpload> fInlineUploads;
+ SkTArray<QueuedUpload> fInlineUploads;
private:
- GrPipeline fPipeline;
typedef GrOp INHERITED;
};
+GR_MAKE_BITFIELD_CLASS_OPS(GrDrawOp::FixedFunctionFlags);
+
#endif
diff --git a/src/gpu/ops/GrDrawPathOp.cpp b/src/gpu/ops/GrDrawPathOp.cpp
index 85fb1473d5..fa08ae6d54 100644
--- a/src/gpu/ops/GrDrawPathOp.cpp
+++ b/src/gpu/ops/GrDrawPathOp.cpp
@@ -6,36 +6,78 @@
*/
#include "GrDrawPathOp.h"
-
+#include "GrAppliedClip.h"
+#include "GrRenderTargetContext.h"
#include "GrRenderTargetPriv.h"
+#include "SkTemplates.h"
-static void pre_translate_transform_values(const float* xforms,
- GrPathRendering::PathTransformType type, int count,
- SkScalar x, SkScalar y, float* dst);
-
-void GrDrawPathOpBase::onPrepare(GrOpFlushState*) {
- const GrRenderTargetPriv& rtPriv = this->pipeline()->getRenderTarget()->renderTargetPriv();
- fStencilPassSettings.reset(GrPathRendering::GetStencilPassSettings(fFillType),
- this->pipeline()->hasStencilClip(), rtPriv.numStencilBits());
-}
+GrDrawPathOpBase::GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint,
+ GrPathRendering::FillType fill, GrAA aa)
+ : INHERITED(classID)
+ , fViewMatrix(viewMatrix)
+ , fProcessorSet(std::move(paint))
+ , fAnalysis(paint.getColor())
+ , fFillType(fill)
+ , fAA(aa) {}
SkString GrDrawPathOp::dumpInfo() const {
SkString string;
string.printf("PATH: 0x%p", fPath.get());
- string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
return string;
}
+GrPipelineOptimizations GrDrawPathOpBase::initPipeline(const GrOpFlushState& state,
+ GrPipeline* pipeline) {
+ static constexpr GrUserStencilSettings kCoverPass{
+ GrUserStencilSettings::StaticInit<
+ 0x0000,
+ GrUserStencilTest::kNotEqual,
+ 0xffff,
+ GrUserStencilOp::kZero,
+ GrUserStencilOp::kKeep,
+ 0xffff>()
+ };
+ GrPipeline::InitArgs args;
+ args.fProcessors = &this->processors();
+ args.fFlags = GrAA::kYes == fAA ? GrPipeline::kHWAntialias_Flag : 0;
+ args.fUserStencil = &kCoverPass;
+ args.fAppliedClip = state.drawOpArgs().fAppliedClip;
+ args.fRenderTarget = state.drawOpArgs().fRenderTarget;
+ args.fCaps = &state.caps();
+ args.fDstTexture = state.drawOpArgs().fDstTexture;
+ args.fAnalysis =
+ &this->doFragmentProcessorAnalysis(state.caps(), state.drawOpArgs().fAppliedClip);
+
+ return pipeline->init(args);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void init_stencil_pass_settings(const GrOpFlushState& flushState,
+ GrPathRendering::FillType fillType, GrStencilSettings* stencil) {
+ const GrAppliedClip* appliedClip = flushState.drawOpArgs().fAppliedClip;
+ bool stencilClip = appliedClip && appliedClip->hasStencilClip();
+ stencil->reset(GrPathRendering::GetStencilPassSettings(fillType), stencilClip,
+ flushState.drawOpArgs().fRenderTarget->renderTargetPriv().numStencilBits());
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
void GrDrawPathOp::onExecute(GrOpFlushState* state) {
- GrProgramDesc desc;
+ GrColor color = this->color();
+ GrPipeline pipeline;
+ GrPipelineOptimizations optimizations = this->initPipeline(*state, &pipeline);
+ optimizations.getOverrideColorIfSet(&color);
+ sk_sp<GrPathProcessor> pathProc(GrPathProcessor::Create(color, this->viewMatrix()));
- sk_sp<GrPathProcessor> pathProc(
- GrPathProcessor::Create(this->color(), this->viewMatrix()));
- state->gpu()->pathRendering()->drawPath(*this->pipeline(), *pathProc,
- this->stencilPassSettings(), fPath.get());
+ GrStencilSettings stencil;
+ init_stencil_pass_settings(*state, this->fillType(), &stencil);
+ state->gpu()->pathRendering()->drawPath(pipeline, *pathProc, stencil, fPath.get());
}
+//////////////////////////////////////////////////////////////////////////////
+
SkString GrDrawPathRangeOp::dumpInfo() const {
SkString string;
string.printf("RANGE: 0x%p COUNTS: [", fPathRange.get());
@@ -44,16 +86,15 @@ SkString GrDrawPathRangeOp::dumpInfo() const {
}
string.remove(string.size() - 2, 2);
string.append("]");
- string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
return string;
}
GrDrawPathRangeOp::GrDrawPathRangeOp(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x,
- SkScalar y, GrColor color, GrPathRendering::FillType fill,
- GrPathRange* range, const InstanceData* instanceData,
+ SkScalar y, GrPaint&& paint, GrPathRendering::FillType fill,
+ GrAA aa, GrPathRange* range, const InstanceData* instanceData,
const SkRect& bounds)
- : INHERITED(ClassID(), viewMatrix, color, fill)
+ : INHERITED(ClassID(), viewMatrix, std::move(paint), fill, aa)
, fPathRange(range)
, fTotalPathCount(instanceData->count())
, fScale(scale) {
@@ -61,6 +102,10 @@ GrDrawPathRangeOp::GrDrawPathRangeOp(const SkMatrix& viewMatrix, SkScalar scale,
this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
}
+static void pre_translate_transform_values(const float* xforms,
+ GrPathRendering::PathTransformType type, int count,
+ SkScalar x, SkScalar y, float* dst);
+
bool GrDrawPathRangeOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
GrDrawPathRangeOp* that = t->cast<GrDrawPathRangeOp>();
if (this->fPathRange.get() != that->fPathRange.get() ||
@@ -68,7 +113,7 @@ bool GrDrawPathRangeOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
this->color() != that->color() || !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
return false;
}
- if (!GrPipeline::AreEqual(*this->pipeline(), *that->pipeline())) {
+ if (this->processors() != that->processors()) {
return false;
}
switch (fDraws.head()->fInstanceData->transformType()) {
@@ -98,11 +143,20 @@ bool GrDrawPathRangeOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
// work). Note that it's also possible for overlapping paths to cancel each other's winding
// numbers, and we only partially account for this by not allowing even/odd paths to be
// combined. (Glyphs in the same font tend to wind the same direction so it works out OK.)
+
if (GrPathRendering::kWinding_FillType != this->fillType() ||
- GrPathRendering::kWinding_FillType != that->fillType() || this->xpReadsDst()) {
+ GrPathRendering::kWinding_FillType != that->fillType()) {
+ return false;
+ }
+ // If we have non-clipping coverage processors we don't try to merge as its unclear whether it
+ // will be correct. We don't expect this to happen in practice.
+ if (this->processors().numCoverageFragmentProcessors()) {
+ return false;
+ }
+ bool opaque = this->fragmentProcessorAnalysis().isOutputColorOpaque();
+ if (!GrXPFactory::CanCombineOverlappedStencilAndCover(this->processors().xpFactory(), opaque)) {
return false;
}
- SkASSERT(!that->xpReadsDst());
fTotalPathCount += that->fTotalPathCount;
while (Draw* head = that->fDraws.head()) {
Draw* draw = fDraws.addToTail();
@@ -129,11 +183,15 @@ void GrDrawPathRangeOp::onExecute(GrOpFlushState* state) {
sk_sp<GrPathProcessor> pathProc(
GrPathProcessor::Create(this->color(), drawMatrix, localMatrix));
+ GrPipeline pipeline;
+ this->initPipeline(*state, &pipeline);
+ GrStencilSettings stencil;
+ init_stencil_pass_settings(*state, this->fillType(), &stencil);
if (fDraws.count() == 1) {
const InstanceData& instances = *head.fInstanceData;
- state->gpu()->pathRendering()->drawPaths(*this->pipeline(),
+ state->gpu()->pathRendering()->drawPaths(pipeline,
*pathProc,
- this->stencilPassSettings(),
+ stencil,
fPathRange.get(),
instances.indices(),
GrPathRange::kU16_PathIndexType,
@@ -159,9 +217,9 @@ void GrDrawPathRangeOp::onExecute(GrOpFlushState* state) {
}
SkASSERT(idx == fTotalPathCount);
- state->gpu()->pathRendering()->drawPaths(*this->pipeline(),
+ state->gpu()->pathRendering()->drawPaths(pipeline,
*pathProc,
- this->stencilPassSettings(),
+ stencil,
fPathRange.get(),
indexStorage,
GrPathRange::kU16_PathIndexType,
diff --git a/src/gpu/ops/GrDrawPathOp.h b/src/gpu/ops/GrDrawPathOp.h
index ffe8768cc0..cf3ce2f11c 100644
--- a/src/gpu/ops/GrDrawPathOp.h
+++ b/src/gpu/ops/GrDrawPathOp.h
@@ -14,45 +14,53 @@
#include "GrPath.h"
#include "GrPathProcessor.h"
#include "GrPathRendering.h"
+#include "GrProcessorSet.h"
#include "GrStencilSettings.h"
#include "SkTLList.h"
+class GrPaint;
+
class GrDrawPathOpBase : public GrDrawOp {
protected:
- GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrColor initialColor,
- GrPathRendering::FillType fill)
- : INHERITED(classID), fViewMatrix(viewMatrix), fColor(initialColor), fFillType(fill) {}
-
- const GrStencilSettings& stencilPassSettings() const {
- SkASSERT(!fStencilPassSettings.isDisabled()); // This shouldn't be called before onPrepare.
- return fStencilPassSettings;
+ GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint,
+ GrPathRendering::FillType fill, GrAA aa);
+ FixedFunctionFlags fixedFunctionFlags() const override {
+ return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil;
+ }
+ bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
+ return GrXPFactory::WillNeedDstTexture(fProcessorSet.xpFactory(), caps,
+ this->doFragmentProcessorAnalysis(caps, clip));
}
+ void wasRecorded() override { fProcessorSet.makePendingExecution(); }
+
protected:
const SkMatrix& viewMatrix() const { return fViewMatrix; }
- GrColor color() const { return fColor; }
+ GrColor color() const { return fAnalysis.inputColor(); }
GrPathRendering::FillType fillType() const { return fFillType; }
- bool xpReadsDst() const { return fXPReadsDst; }
-
-private:
- void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override {
- input->colorInput()->setToConstant(fColor);
- input->coverageInput()->setToSolidCoverage();
+ const GrProcessorSet& processors() const { return fProcessorSet; }
+ GrPipelineOptimizations initPipeline(const GrOpFlushState&, GrPipeline*);
+ const GrProcessorSet::FragmentProcessorAnalysis& doFragmentProcessorAnalysis(
+ const GrCaps& caps, const GrAppliedClip* clip) {
+ if (!fAnalysis.isInitializedWithProcessorSet()) {
+ fAnalysis.init(fAnalysis.inputColor(), GrColor_WHITE, fProcessorSet, clip, caps);
+ }
+ return fAnalysis;
}
-
- void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
- optimizations.getOverrideColorIfSet(&fColor);
- fXPReadsDst = optimizations.xpReadsDst();
+ const GrProcessorSet::FragmentProcessorAnalysis& fragmentProcessorAnalysis() const {
+ SkASSERT(fAnalysis.isInitializedWithProcessorSet());
+ return fAnalysis;
}
- void onPrepare(GrOpFlushState*) override; // Initializes fStencilPassSettings.
+private:
+ void onPrepare(GrOpFlushState*) final {}
SkMatrix fViewMatrix;
- GrColor fColor;
+ GrProcessorSet fProcessorSet;
+ GrProcessorSet::FragmentProcessorAnalysis fAnalysis;
GrPathRendering::FillType fFillType;
- GrStencilSettings fStencilPassSettings;
- bool fXPReadsDst;
+ GrAA fAA;
typedef GrDrawOp INHERITED;
};
@@ -61,9 +69,9 @@ class GrDrawPathOp final : public GrDrawPathOpBase {
public:
DEFINE_OP_CLASS_ID
- static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, GrColor color,
- const GrPath* path) {
- return std::unique_ptr<GrDrawOp>(new GrDrawPathOp(viewMatrix, color, path));
+ static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, GrPaint&& paint, GrAA aa,
+ GrPath* path) {
+ return std::unique_ptr<GrDrawOp>(new GrDrawPathOp(viewMatrix, std::move(paint), aa, path));
}
const char* name() const override { return "DrawPath"; }
@@ -71,8 +79,9 @@ public:
SkString dumpInfo() const override;
private:
- GrDrawPathOp(const SkMatrix& viewMatrix, GrColor color, const GrPath* path)
- : GrDrawPathOpBase(ClassID(), viewMatrix, color, path->getFillType()), fPath(path) {
+ GrDrawPathOp(const SkMatrix& viewMatrix, GrPaint&& paint, GrAA aa, const GrPath* path)
+ : GrDrawPathOpBase(ClassID(), viewMatrix, std::move(paint), path->getFillType(), aa)
+ , fPath(path) {
this->setTransformedBounds(path->getBounds(), viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
}
@@ -152,11 +161,12 @@ public:
};
static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x,
- SkScalar y, GrColor color, GrPathRendering::FillType fill,
+ SkScalar y, GrPaint&& paint,
+ GrPathRendering::FillType fill, GrAA aa,
GrPathRange* range, const InstanceData* instanceData,
const SkRect& bounds) {
- return std::unique_ptr<GrDrawOp>(new GrDrawPathRangeOp(viewMatrix, scale, x, y, color, fill,
- range, instanceData, bounds));
+ return std::unique_ptr<GrDrawOp>(new GrDrawPathRangeOp(
+ viewMatrix, scale, x, y, std::move(paint), fill, aa, range, instanceData, bounds));
}
const char* name() const override { return "DrawPathRange"; }
@@ -165,7 +175,7 @@ public:
private:
GrDrawPathRangeOp(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, SkScalar y,
- GrColor color, GrPathRendering::FillType fill, GrPathRange* range,
+ GrPaint&& paint, GrPathRendering::FillType fill, GrAA aa, GrPathRange* range,
const InstanceData* instanceData, const SkRect& bounds);
TransformType transformType() const { return fDraws.head()->fInstanceData->transformType(); }
diff --git a/src/gpu/ops/GrMeshDrawOp.cpp b/src/gpu/ops/GrMeshDrawOp.cpp
index 5d83bd5364..59335d41db 100644
--- a/src/gpu/ops/GrMeshDrawOp.cpp
+++ b/src/gpu/ops/GrMeshDrawOp.cpp
@@ -60,6 +60,9 @@ void* GrMeshDrawOp::QuadHelper::init(Target* target, size_t vertexStride, int qu
}
void GrMeshDrawOp::onExecute(GrOpFlushState* state) {
+ SkASSERT(!state->drawOpArgs().fAppliedClip);
+ SkASSERT(!state->drawOpArgs().fDstTexture.texture());
+ SkASSERT(state->drawOpArgs().fRenderTarget == this->pipeline()->getRenderTarget());
int currUploadIdx = 0;
int currMeshIdx = 0;
diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h
index a7d312f151..4cf7c52672 100644
--- a/src/gpu/ops/GrMeshDrawOp.h
+++ b/src/gpu/ops/GrMeshDrawOp.h
@@ -15,6 +15,7 @@
#include "SkTLList.h"
+class GrCaps;
class GrOpFlushState;
/**
@@ -24,9 +25,39 @@ class GrMeshDrawOp : public GrDrawOp {
public:
class Target;
- GrMeshDrawOp(uint32_t classID);
+ /**
+ * Performs analysis of the fragment processors in GrProcessorSet and GrAppliedClip using the
+ * initial color and coverage from this op's geometry processor.
+ */
+ void analyzeProcessors(GrProcessorSet::FragmentProcessorAnalysis* analysis,
+ const GrProcessorSet& processors,
+ const GrAppliedClip* appliedClip,
+ const GrCaps& caps) const {
+ FragmentProcessorAnalysisInputs input;
+ this->getFragmentProcessorAnalysisInputs(&input);
+ analysis->init(*input.colorInput(), *input.coverageInput(), processors, appliedClip, caps);
+ }
+
+ void initPipeline(const GrPipeline::InitArgs& args) {
+ this->applyPipelineOptimizations(fPipeline.init(args));
+ }
+
+ /**
+ * Mesh draw ops use a legacy system in GrRenderTargetContext where the pipeline is created when
+ * the op is recorded. These methods are unnecessary as this information is in the pipeline.
+ */
+ FixedFunctionFlags fixedFunctionFlags() const override {
+ SkFAIL("This should never be called for mesh draw ops.");
+ return FixedFunctionFlags::kNone;
+ }
+ bool xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*) override {
+ SkFAIL("Should never be called for mesh draw ops.");
+ return false;
+ }
protected:
+ GrMeshDrawOp(uint32_t classID);
+
/** Helper for rendering instances using an instanced index index buffer. This class creates the
space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
class InstancedHelper {
@@ -62,7 +93,39 @@ protected:
typedef InstancedHelper INHERITED;
};
+ const GrPipeline* pipeline() const {
+ SkASSERT(fPipeline.isInitialized());
+ return &fPipeline;
+ }
+
+ /**
+ * This describes aspects of the GrPrimitiveProcessor produced by a GrDrawOp that are used in
+ * pipeline analysis.
+ */
+ class FragmentProcessorAnalysisInputs {
+ public:
+ FragmentProcessorAnalysisInputs() = default;
+ GrPipelineInput* colorInput() { return &fColorInput; }
+ GrPipelineInput* coverageInput() { return &fCoverageInput; }
+
+ private:
+ GrPipelineInput fColorInput;
+ GrPipelineInput fCoverageInput;
+ };
+
private:
+ /**
+ * Provides information about the GrPrimitiveProccesor color and coverage outputs which become
+ * inputs to the first color and coverage fragment processors.
+ */
+ virtual void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs*) const = 0;
+
+ /**
+ * After GrPipeline analysis is complete this is called so that the op can use the analysis
+ * results when constructing its GrPrimitiveProcessor.
+ */
+ virtual void applyPipelineOptimizations(const GrPipelineOptimizations&) = 0;
+
void onPrepare(GrOpFlushState* state) final;
void onExecute(GrOpFlushState* state) final;
@@ -82,7 +145,7 @@ private:
// globally across all ops. This is the offset of the first entry in fQueuedDraws.
// fQueuedDraws[i]'s token is fBaseDrawToken + i.
GrDrawOpUploadToken fBaseDrawToken;
-
+ GrPipeline fPipeline;
SkSTArray<4, GrMesh> fMeshes;
SkSTArray<4, QueuedDraw, true> fQueuedDraws;
diff --git a/src/gpu/ops/GrOp.h b/src/gpu/ops/GrOp.h
index c1bf7f7555..ef752b5d0c 100644
--- a/src/gpu/ops/GrOp.h
+++ b/src/gpu/ops/GrOp.h
@@ -11,6 +11,7 @@
#include "../private/SkAtomics.h"
#include "GrGpuResource.h"
#include "GrNonAtomicRef.h"
+#include "GrXferProcessor.h"
#include "SkMatrix.h"
#include "SkRect.h"
#include "SkString.h"
diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
index 3b3816329d..4c2edf408f 100644
--- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
@@ -145,22 +145,10 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
std::move(coverOp));
}
} else {
- static constexpr GrUserStencilSettings kCoverPass(
- GrUserStencilSettings::StaticInit<
- 0x0000,
- GrUserStencilTest::kNotEqual,
- 0xffff,
- GrUserStencilOp::kZero,
- GrUserStencilOp::kKeep,
- 0xffff>()
- );
-
+ GrAA aa = GrBoolToAA(GrAATypeIsHW(args.fAAType));
std::unique_ptr<GrDrawOp> op =
- GrDrawPathOp::Make(viewMatrix, args.fPaint.getColor(), path.get());
-
- GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
- pipelineBuilder.setUserStencil(&kCoverPass);
- args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
+ GrDrawPathOp::Make(viewMatrix, std::move(args.fPaint), aa, path.get());
+ args.fRenderTargetContext->addDrawOp(*args.fClip, std::move(op));
}
return true;