aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ops
diff options
context:
space:
mode:
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;