aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-03-21 14:22:38 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-21 23:55:32 +0000
commit54d212e1bfaea0be88c3c40820d0b1ae0daebecf (patch)
treece606e9d88dfd04d592d406881b7e6e5d9a855cf
parent337432dc092619431eaa62f13e6347f2272f1fa7 (diff)
Revert "Revert "Remove GrPipeline from GrDrawOp.""
This reverts commit c48af934608bbb65650641f66adb51f2102d4274. Change-Id: I4ba78fd7e5a7d406b88223ca6f7245c029b60f76 Reviewed-on: https://skia-review.googlesource.com/9981 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
-rw-r--r--include/gpu/GrProgramElement.h1
-rw-r--r--src/gpu/GrAppliedClip.h28
-rw-r--r--src/gpu/GrOpFlushState.cpp15
-rw-r--r--src/gpu/GrOpFlushState.h22
-rw-r--r--src/gpu/GrPipeline.cpp36
-rw-r--r--src/gpu/GrPrimitiveProcessor.h7
-rw-r--r--src/gpu/GrProcessorSet.cpp38
-rw-r--r--src/gpu/GrProcessorSet.h22
-rw-r--r--src/gpu/GrRenderTargetContext.cpp127
-rw-r--r--src/gpu/GrRenderTargetContext.h7
-rw-r--r--src/gpu/GrRenderTargetOpList.cpp67
-rw-r--r--src/gpu/GrRenderTargetOpList.h50
-rw-r--r--src/gpu/GrTextureOpList.cpp2
-rw-r--r--src/gpu/GrXferProcessor.cpp17
-rw-r--r--src/gpu/GrXferProcessor.h28
-rw-r--r--src/gpu/effects/GrCoverageSetOpXP.h4
-rw-r--r--src/gpu/effects/GrCustomXfermode.cpp2
-rw-r--r--src/gpu/effects/GrDisableColorXP.h2
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.cpp11
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.h6
-rw-r--r--src/gpu/instanced/GLInstancedRendering.cpp7
-rw-r--r--src/gpu/instanced/GLInstancedRendering.h2
-rw-r--r--src/gpu/instanced/InstancedRendering.cpp158
-rw-r--r--src/gpu/instanced/InstancedRendering.h55
-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
-rw-r--r--src/gpu/text/GrStencilAndCoverTextContext.cpp17
-rw-r--r--tests/GpuSampleLocationsTest.cpp2
-rw-r--r--tests/GrPorterDuffTest.cpp165
34 files changed, 764 insertions, 481 deletions
diff --git a/include/gpu/GrProgramElement.h b/include/gpu/GrProgramElement.h
index 0e065c231f..2538680302 100644
--- a/include/gpu/GrProgramElement.h
+++ b/include/gpu/GrProgramElement.h
@@ -84,7 +84,6 @@ protected:
void addPendingExecution() const {
this->validate();
- SkASSERT(fRefCnt > 0);
if (0 == fPendingExecutions) {
static_cast<const DERIVED*>(this)->addPendingIOs();
}
diff --git a/src/gpu/GrAppliedClip.h b/src/gpu/GrAppliedClip.h
index 57314ec7d4..8488dc4d5d 100644
--- a/src/gpu/GrAppliedClip.h
+++ b/src/gpu/GrAppliedClip.h
@@ -16,8 +16,12 @@
* Produced by GrClip. It provides a set of modifications to the drawing state that are used to
* create the final GrPipeline for a GrOp.
*/
-class GrAppliedClip : public SkNoncopyable {
+class GrAppliedClip {
public:
+ GrAppliedClip() = default;
+ GrAppliedClip(GrAppliedClip&& that) = default;
+ GrAppliedClip(const GrAppliedClip&) = delete;
+
const GrScissorState& scissorState() const { return fScissorState; }
const GrWindowRectsState& windowRectsState() const { return fWindowRectsState; }
GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP.get(); }
@@ -52,12 +56,32 @@ public:
fHasStencilClip = true;
}
+ bool doesClip() const {
+ return fScissorState.enabled() || fClipCoverageFP || fHasStencilClip ||
+ fWindowRectsState.enabled();
+ }
+
+ bool operator==(const GrAppliedClip& that) const {
+ if (fScissorState != that.fScissorState || fHasStencilClip != that.fHasStencilClip) {
+ return false;
+ }
+ if (SkToBool(fClipCoverageFP)) {
+ if (!SkToBool(that.fClipCoverageFP) ||
+ !that.fClipCoverageFP->isEqual(*fClipCoverageFP)) {
+ return false;
+ }
+ } else if (SkToBool(that.fClipCoverageFP)) {
+ return false;
+ }
+ return fWindowRectsState == that.fWindowRectsState;
+ }
+ bool operator!=(const GrAppliedClip& that) const { return !(*this == that); }
+
private:
GrScissorState fScissorState;
GrWindowRectsState fWindowRectsState;
sk_sp<GrFragmentProcessor> fClipCoverageFP;
bool fHasStencilClip = false;
- typedef SkNoncopyable INHERITED;
};
#endif
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index 2dddbba2a2..c6f5d38383 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -11,13 +11,14 @@
#include "GrPipeline.h"
GrOpFlushState::GrOpFlushState(GrGpu* gpu, GrResourceProvider* resourceProvider)
- : fGpu(gpu)
- , fResourceProvider(resourceProvider)
- , fCommandBuffer(nullptr)
- , fVertexPool(gpu)
- , fIndexPool(gpu)
- , fLastIssuedToken(GrDrawOpUploadToken::AlreadyFlushedToken())
- , fLastFlushedToken(0) {}
+ : fGpu(gpu)
+ , fResourceProvider(resourceProvider)
+ , fCommandBuffer(nullptr)
+ , fVertexPool(gpu)
+ , fIndexPool(gpu)
+ , fLastIssuedToken(GrDrawOpUploadToken::AlreadyFlushedToken())
+ , fLastFlushedToken(0)
+ , fOpArgs(nullptr) {}
void* GrOpFlushState::makeVertexSpace(size_t vertexSize, int vertexCount,
const GrBuffer** buffer, int* startVertex) {
diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h
index ed77c3b468..d7ed4e0b47 100644
--- a/src/gpu/GrOpFlushState.h
+++ b/src/gpu/GrOpFlushState.h
@@ -96,22 +96,30 @@ public:
fIndexPool.reset();
}
-private:
+ /** Additional data required on a per-op basis when executing GrDrawOps. */
+ struct DrawOpArgs {
+ GrRenderTarget* fRenderTarget;
+ const GrAppliedClip* fAppliedClip;
+ GrXferProcessor::DstTexture fDstTexture;
+ };
+
+ void setDrawOpArgs(DrawOpArgs* opArgs) { fOpArgs = opArgs; }
+
+ const DrawOpArgs& drawOpArgs() const {
+ SkASSERT(fOpArgs);
+ return *fOpArgs;
+ }
+private:
GrGpu* fGpu;
-
GrResourceProvider* fResourceProvider;
-
GrGpuCommandBuffer* fCommandBuffer;
-
GrVertexBufferAllocPool fVertexPool;
GrIndexBufferAllocPool fIndexPool;
-
SkSTArray<4, GrDrawOp::DeferredUploadFn> fAsapUploads;
-
GrDrawOpUploadToken fLastIssuedToken;
-
GrDrawOpUploadToken fLastFlushedToken;
+ DrawOpArgs* fOpArgs;
};
/**
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 845ae4488d..7ab5cbfac6 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -24,27 +24,31 @@ GrPipelineOptimizations GrPipeline::init(const InitArgs& args) {
SkASSERT(args.fRenderTarget);
fRenderTarget.reset(args.fRenderTarget);
- fScissorState = args.fAppliedClip->scissorState();
- fWindowRectsState = args.fAppliedClip->windowRectsState();
- fUserStencilSettings = args.fUserStencil;
- fDrawFace = static_cast<int16_t>(args.fDrawFace);
fFlags = args.fFlags;
+ if (args.fAppliedClip) {
+ fScissorState = args.fAppliedClip->scissorState();
+ if (args.fAppliedClip->hasStencilClip()) {
+ fFlags |= kHasStencilClip_Flag;
+ }
+ fWindowRectsState = args.fAppliedClip->windowRectsState();
+ }
if (args.fProcessors->usesDistanceVectorField()) {
fFlags |= kUsesDistanceVectorField_Flag;
}
- if (args.fAppliedClip->hasStencilClip()) {
- fFlags |= kHasStencilClip_Flag;
- }
- if (!args.fUserStencil->isDisabled(args.fAppliedClip->hasStencilClip())) {
- fFlags |= kStencilEnabled_Flag;
- }
if (args.fProcessors->disableOutputConversionToSRGB()) {
fFlags |= kDisableOutputConversionToSRGB_Flag;
}
if (args.fProcessors->allowSRGBInputs()) {
fFlags |= kAllowSRGBInputs_Flag;
}
+ if (!args.fUserStencil->isDisabled(fFlags & kHasStencilClip_Flag)) {
+ fFlags |= kStencilEnabled_Flag;
+ }
+
+ fUserStencilSettings = args.fUserStencil;
+
+ fDrawFace = static_cast<int16_t>(args.fDrawFace);
bool isHWAA = kHWAntialias_Flag & args.fFlags;
@@ -86,7 +90,7 @@ GrPipelineOptimizations GrPipeline::init(const InitArgs& args) {
fNumColorProcessors = args.fProcessors->numColorFragmentProcessors() - colorFPsToEliminate;
int numTotalProcessors =
fNumColorProcessors + args.fProcessors->numCoverageFragmentProcessors();
- if (args.fAppliedClip->clipCoverageFragmentProcessor()) {
+ if (args.fAppliedClip && args.fAppliedClip->clipCoverageFragmentProcessor()) {
++numTotalProcessors;
}
fFragmentProcessors.reset(numTotalProcessors);
@@ -101,8 +105,10 @@ GrPipelineOptimizations GrPipeline::init(const InitArgs& args) {
const GrFragmentProcessor* fp = args.fProcessors->coverageFragmentProcessor(i);
fFragmentProcessors[currFPIdx].reset(fp);
}
- if (const GrFragmentProcessor* fp = args.fAppliedClip->clipCoverageFragmentProcessor()) {
- fFragmentProcessors[currFPIdx].reset(fp);
+ if (args.fAppliedClip) {
+ if (const GrFragmentProcessor* fp = args.fAppliedClip->clipCoverageFragmentProcessor()) {
+ fFragmentProcessors[currFPIdx].reset(fp);
+ }
}
// Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
@@ -118,10 +124,6 @@ GrPipelineOptimizations GrPipeline::init(const InitArgs& args) {
if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
optimizations.fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag;
}
-
- if (GrXPFactory::WillReadDst(xpFactory, *args.fAnalysis)) {
- optimizations.fFlags |= GrPipelineOptimizations::kXPReadsDst_Flag;
- }
return optimizations;
}
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index f5b8fe9cf0..4c439433f5 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -70,11 +70,6 @@ public:
return false;
}
- /**
- * Returns true if the color written to the output pixel depends on the pixels previous value.
- */
- bool xpReadsDst() const { return SkToBool(kXPReadsDst_Flag & fFlags); }
-
private:
enum {
// If this is not set the primitive processor need not produce local coordinates
@@ -87,8 +82,6 @@ private:
// If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its
// output color. If not set fOverrideColor is to be ignored.
kUseOverrideColor_Flag = 0x4,
-
- kXPReadsDst_Flag = 0x8,
};
uint32_t fFlags;
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index c4b82621d1..94e2004546 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -38,6 +38,44 @@ GrProcessorSet::GrProcessorSet(GrPaint&& paint) {
}
}
+GrProcessorSet::~GrProcessorSet() {
+ if (this->isPendingExecution()) {
+ for (auto fp : fFragmentProcessors) {
+ fp->completedExecution();
+ }
+ } else {
+ for (auto fp : fFragmentProcessors) {
+ fp->unref();
+ }
+ }
+}
+
+void GrProcessorSet::makePendingExecution() {
+ SkASSERT(!(kPendingExecution_Flag & fFlags));
+ fFlags |= kPendingExecution_Flag;
+ for (int i = 0; i < fFragmentProcessors.count(); ++i) {
+ fFragmentProcessors[i]->addPendingExecution();
+ fFragmentProcessors[i]->unref();
+ }
+}
+
+bool GrProcessorSet::operator==(const GrProcessorSet& that) const {
+ if (((fFlags ^ that.fFlags) & ~kPendingExecution_Flag) ||
+ fFragmentProcessors.count() != that.fFragmentProcessors.count() ||
+ fColorFragmentProcessorCnt != that.fColorFragmentProcessorCnt) {
+ return false;
+ }
+ for (int i = 0; i < fFragmentProcessors.count(); ++i) {
+ if (!fFragmentProcessors[i]->isEqual(*that.fFragmentProcessors[i])) {
+ return false;
+ }
+ }
+ if (fXPFactory != that.fXPFactory) {
+ return false;
+ }
+ return true;
+}
+
//////////////////////////////////////////////////////////////////////////////
void GrProcessorSet::FragmentProcessorAnalysis::internalInit(const GrPipelineInput& colorInput,
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index 8203491435..18a52fd9b7 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -20,13 +20,15 @@ class GrProcessorSet : private SkNoncopyable {
public:
GrProcessorSet(GrPaint&& paint);
- ~GrProcessorSet() {
- // We are deliberately not using sk_sp here because this will be updated to work with
- // "pending execution" refs.
- for (auto fp : fFragmentProcessors) {
- fp->unref();
- }
- }
+ ~GrProcessorSet();
+
+ /**
+ * If an op is recorded with this processor set then this must be called to ensure pending
+ * reads and writes are propagated to resources referred to by the processors. Otherwise,
+ * data hazards may occur.
+ */
+ void makePendingExecution();
+ bool isPendingExecution() const { return SkToBool(kPendingExecution_Flag & fFlags); }
int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
int numCoverageFragmentProcessors() const {
@@ -50,6 +52,9 @@ public:
}
bool allowSRGBInputs() const { return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
+ bool operator==(const GrProcessorSet& that) const;
+ bool operator!=(const GrProcessorSet& that) const { return !(*this == that); }
+
/**
* This is used to track analysis of color and coverage values through the fragment processors.
*/
@@ -156,7 +161,8 @@ private:
enum Flags : uint16_t {
kUseDistanceVectorField_Flag = 0x1,
kDisableOutputConversionToSRGB_Flag = 0x2,
- kAllowSRGBInputs_Flag = 0x4
+ kAllowSRGBInputs_Flag = 0x4,
+ kPendingExecution_Flag = 0x8
};
const GrXPFactory* fXPFactory = nullptr;
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index bd73c8bc66..70d4485468 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -507,22 +507,17 @@ bool GrRenderTargetContext::drawFilledRect(const GrClip& clip,
return true;
}
- GrAAType aaType;
-
- if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
+ if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
+ (!ss || ss->isDisabled(false))) {
InstancedRendering* ir = this->getOpList()->instancedRendering();
- std::unique_ptr<GrDrawOp> op = ir->recordRect(croppedRect, viewMatrix, paint.getColor(), aa,
- fInstancedPipelineInfo, &aaType);
+ std::unique_ptr<GrDrawOp> op = ir->recordRect(croppedRect, viewMatrix, std::move(paint), aa,
+ fInstancedPipelineInfo);
if (op) {
- GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- if (ss) {
- pipelineBuilder.setUserStencil(ss);
- }
- this->addDrawOp(pipelineBuilder, clip, std::move(op));
+ this->addDrawOp(clip, std::move(op));
return true;
}
}
- aaType = this->decideAAType(aa);
+ GrAAType aaType = this->decideAAType(aa);
if (GrAAType::kCoverage == aaType) {
// The fill path can handle rotation but not skew.
if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
@@ -811,21 +806,18 @@ void GrRenderTargetContext::fillRectToRect(const GrClip& clip,
}
AutoCheckFlush acf(this->drawingManager());
- GrAAType aaType;
if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
InstancedRendering* ir = this->getOpList()->instancedRendering();
- std::unique_ptr<GrDrawOp> op(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
- croppedLocalRect, aa, fInstancedPipelineInfo,
- &aaType));
+ std::unique_ptr<GrDrawOp> op(ir->recordRect(croppedRect, viewMatrix, std::move(paint),
+ croppedLocalRect, aa, fInstancedPipelineInfo));
if (op) {
- GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->addDrawOp(pipelineBuilder, clip, std::move(op));
+ this->addDrawOp(clip, std::move(op));
return;
}
}
- aaType = this->decideAAType(aa);
+ GrAAType aaType = this->decideAAType(aa);
if (GrAAType::kCoverage != aaType) {
this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect,
&croppedLocalRect, nullptr, nullptr, aaType);
@@ -833,10 +825,10 @@ void GrRenderTargetContext::fillRectToRect(const GrClip& clip,
}
if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
- std::unique_ptr<GrDrawOp> op = GrAAFillRectOp::MakeWithLocalRect(
+ std::unique_ptr<GrMeshDrawOp> op = GrAAFillRectOp::MakeWithLocalRect(
paint.getColor(), viewMatrix, croppedRect, croppedLocalRect);
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->addDrawOp(pipelineBuilder, clip, std::move(op));
+ this->addMeshDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
@@ -870,21 +862,18 @@ void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip,
}
AutoCheckFlush acf(this->drawingManager());
- GrAAType aaType;
if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
InstancedRendering* ir = this->getOpList()->instancedRendering();
- std::unique_ptr<GrDrawOp> op(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
- localMatrix, aa, fInstancedPipelineInfo,
- &aaType));
+ std::unique_ptr<GrDrawOp> op(ir->recordRect(croppedRect, viewMatrix, std::move(paint),
+ localMatrix, aa, fInstancedPipelineInfo));
if (op) {
- GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->addDrawOp(pipelineBuilder, clip, std::move(op));
+ this->addDrawOp(clip, std::move(op));
return;
}
}
- aaType = this->decideAAType(aa);
+ GrAAType aaType = this->decideAAType(aa);
if (GrAAType::kCoverage != aaType) {
this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect, nullptr,
&localMatrix, nullptr, aaType);
@@ -1024,21 +1013,19 @@ void GrRenderTargetContext::drawRRect(const GrClip& origClip,
AutoCheckFlush acf(this->drawingManager());
const SkStrokeRec stroke = style.strokeRec();
- GrAAType aaType;
if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
stroke.isFillStyle()) {
InstancedRendering* ir = this->getOpList()->instancedRendering();
- std::unique_ptr<GrDrawOp> op(ir->recordRRect(rrect, viewMatrix, paint.getColor(), aa,
- fInstancedPipelineInfo, &aaType));
+ std::unique_ptr<GrDrawOp> op(
+ ir->recordRRect(rrect, viewMatrix, std::move(paint), aa, fInstancedPipelineInfo));
if (op) {
- GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->addDrawOp(pipelineBuilder, *clip, std::move(op));
+ this->addDrawOp(*clip, std::move(op));
return;
}
}
- aaType = this->decideAAType(aa);
+ GrAAType aaType = this->decideAAType(aa);
if (GrAAType::kCoverage == aaType) {
const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
std::unique_ptr<GrMeshDrawOp> op =
@@ -1103,21 +1090,18 @@ bool GrRenderTargetContext::drawFilledDRRect(const GrClip& clip,
const SkRRect& origInner) {
SkASSERT(!origInner.isEmpty());
SkASSERT(!origOuter.isEmpty());
- GrAAType aaType;
if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
InstancedRendering* ir = this->getOpList()->instancedRendering();
- std::unique_ptr<GrDrawOp> op(ir->recordDRRect(origOuter, origInner, viewMatrix,
- paint.getColor(), aa, fInstancedPipelineInfo,
- &aaType));
+ std::unique_ptr<GrDrawOp> op(ir->recordDRRect(
+ origOuter, origInner, viewMatrix, std::move(paint), aa, fInstancedPipelineInfo));
if (op) {
- GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->addDrawOp(pipelineBuilder, clip, std::move(op));
+ this->addDrawOp(clip, std::move(op));
return true;
}
}
- aaType = this->decideAAType(aa);
+ GrAAType aaType = this->decideAAType(aa);
GrPrimitiveEdgeType innerEdgeType, outerEdgeType;
if (GrAAType::kCoverage == aaType) {
@@ -1254,21 +1238,19 @@ void GrRenderTargetContext::drawOval(const GrClip& clip,
AutoCheckFlush acf(this->drawingManager());
const SkStrokeRec& stroke = style.strokeRec();
- GrAAType aaType;
if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
stroke.isFillStyle()) {
InstancedRendering* ir = this->getOpList()->instancedRendering();
- std::unique_ptr<GrDrawOp> op(ir->recordOval(oval, viewMatrix, paint.getColor(), aa,
- fInstancedPipelineInfo, &aaType));
+ std::unique_ptr<GrDrawOp> op(
+ ir->recordOval(oval, viewMatrix, std::move(paint), aa, fInstancedPipelineInfo));
if (op) {
- GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->addDrawOp(pipelineBuilder, clip, std::move(op));
+ this->addDrawOp(clip, std::move(op));
return;
}
}
- aaType = this->decideAAType(aa);
+ GrAAType aaType = this->decideAAType(aa);
if (GrAAType::kCoverage == aaType) {
const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
std::unique_ptr<GrMeshDrawOp> op =
@@ -1672,21 +1654,60 @@ static void op_bounds(SkRect* bounds, const GrOp* op) {
}
}
+uint32_t GrRenderTargetContext::addDrawOp(const GrClip& clip, std::unique_ptr<GrDrawOp> op) {
+ ASSERT_SINGLE_OWNER
+ if (this->drawingManager()->wasAbandoned()) {
+ return SK_InvalidUniqueID;
+ }
+ SkDEBUGCODE(this->validate();)
+ GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::addDrawOp");
+
+ // Setup clip
+ SkRect bounds;
+ op_bounds(&bounds, op.get());
+ GrAppliedClip appliedClip;
+ GrDrawOp::FixedFunctionFlags fixedFunctionFlags = op->fixedFunctionFlags();
+ if (!clip.apply(fContext, this, fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesHWAA,
+ fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesStencil, &appliedClip,
+ &bounds)) {
+ return SK_InvalidUniqueID;
+ }
+
+ // This forces instantiation of the render target.
+ GrRenderTarget* rt = this->accessRenderTarget();
+ if (!rt) {
+ return SK_InvalidUniqueID;
+ }
+
+ if (fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesStencil ||
+ appliedClip.hasStencilClip()) {
+ if (!fContext->resourceProvider()->attachStencilAttachment(rt)) {
+ SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
+ return SK_InvalidUniqueID;
+ }
+ }
+
+ GrXferProcessor::DstTexture dstTexture;
+ if (op->xpRequiresDstTexture(*this->caps(), &appliedClip)) {
+ this->setupDstTexture(rt, clip, op->bounds(), &dstTexture);
+ if (!dstTexture.texture()) {
+ return SK_InvalidUniqueID;
+ }
+ }
+
+ op->setClippedBounds(bounds);
+ return this->getOpList()->addOp(std::move(op), this, std::move(appliedClip), dstTexture);
+}
+
uint32_t GrRenderTargetContext::addMeshDrawOp(const GrPipelineBuilder& pipelineBuilder,
const GrClip& clip,
std::unique_ptr<GrMeshDrawOp> op) {
- return this->addDrawOp(pipelineBuilder, clip, std::move(op));
-}
-
-uint32_t GrRenderTargetContext::addDrawOp(const GrPipelineBuilder& pipelineBuilder,
- const GrClip& clip,
- std::unique_ptr<GrDrawOp> op) {
ASSERT_SINGLE_OWNER
if (this->drawingManager()->wasAbandoned()) {
return SK_InvalidUniqueID;
}
SkDEBUGCODE(this->validate();)
- GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::addDrawOp");
+ GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::addMeshDrawOp");
// Setup clip
SkRect bounds;
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index fc2fc0e881..acb7f77278 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -22,8 +22,8 @@ class GrClip;
class GrDrawingManager;
class GrDrawOp;
class GrFixedClip;
-class GrPipelineBuilder;
class GrMeshDrawOp;
+class GrPipelineBuilder;
class GrRenderTarget;
class GrRenderTargetContextPriv;
class GrRenderTargetOpList;
@@ -477,9 +477,8 @@ private:
// These perform processing specific to Gr[Mesh]DrawOp-derived ops before recording them into
// the op list. They return the id of the opList to which the op was added, or 0, if it was
// dropped (e.g., due to clipping).
- uint32_t addDrawOp(const GrPipelineBuilder&, const GrClip&, std::unique_ptr<GrDrawOp>);
- uint32_t addMeshDrawOp(const GrPipelineBuilder&, const GrClip&,
- std::unique_ptr<GrMeshDrawOp> op);
+ uint32_t addDrawOp(const GrClip&, std::unique_ptr<GrDrawOp>);
+ uint32_t addMeshDrawOp(const GrPipelineBuilder&, const GrClip&, std::unique_ptr<GrMeshDrawOp>);
// Makes a copy of the dst if it is necessary for the draw and returns the texture that should
// be used by GrXferProcessor to access the destination color. If the texture is nullptr then
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index ba096dc149..d1aca0c308 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -30,10 +30,12 @@ static const int kDefaultMaxOpLookahead = 10;
GrRenderTargetOpList::GrRenderTargetOpList(GrRenderTargetProxy* rtp, GrGpu* gpu,
GrResourceProvider* resourceProvider,
GrAuditTrail* auditTrail, const Options& options)
- : INHERITED(rtp, auditTrail)
- , fGpu(SkRef(gpu))
- , fResourceProvider(resourceProvider)
- , fLastClipStackGenID(SK_InvalidUniqueID) {
+ : INHERITED(rtp, auditTrail)
+ , fGpu(SkRef(gpu))
+ , fResourceProvider(resourceProvider)
+ , fLastClipStackGenID(SK_InvalidUniqueID)
+ , fClipAllocator(fClipAllocatorStorage, sizeof(fClipAllocatorStorage),
+ sizeof(fClipAllocatorStorage)) {
fMaxOpLookback = (options.fMaxOpCombineLookback < 0) ? kDefaultMaxOpLookback
: options.fMaxOpCombineLookback;
@@ -93,7 +95,17 @@ void GrRenderTargetOpList::prepareOps(GrOpFlushState* flushState) {
// Loop over the ops that haven't yet been prepared.
for (int i = 0; i < fRecordedOps.count(); ++i) {
if (fRecordedOps[i].fOp) {
+ GrOpFlushState::DrawOpArgs opArgs;
+ if (fRecordedOps[i].fRenderTarget) {
+ opArgs = {
+ fRecordedOps[i].fRenderTarget.get(),
+ fRecordedOps[i].fAppliedClip,
+ fRecordedOps[i].fDstTexture
+ };
+ }
+ flushState->setDrawOpArgs(&opArgs);
fRecordedOps[i].fOp->prepare(flushState);
+ flushState->setDrawOpArgs(nullptr);
}
}
@@ -133,7 +145,17 @@ bool GrRenderTargetOpList::executeOps(GrOpFlushState* flushState) {
}
flushState->setCommandBuffer(commandBuffer.get());
}
+ GrOpFlushState::DrawOpArgs opArgs;
+ if (fRecordedOps[i].fRenderTarget) {
+ opArgs = {
+ fRecordedOps[i].fRenderTarget.get(),
+ fRecordedOps[i].fAppliedClip,
+ fRecordedOps[i].fDstTexture
+ };
+ flushState->setDrawOpArgs(&opArgs);
+ }
fRecordedOps[i].fOp->execute(flushState);
+ flushState->setDrawOpArgs(nullptr);
}
if (commandBuffer) {
commandBuffer->end();
@@ -224,8 +246,33 @@ static inline bool can_reorder(const SkRect& a, const SkRect& b) {
b.fRight <= a.fLeft || b.fBottom <= a.fTop;
}
+bool GrRenderTargetOpList::combineIfPossible(const RecordedOp& a, GrOp* b,
+ const GrAppliedClip* bClip,
+ const DstTexture* bDstTexture) {
+ if (a.fAppliedClip) {
+ if (!bClip) {
+ return false;
+ }
+ if (*a.fAppliedClip != *bClip) {
+ return false;
+ }
+ } else if (bClip) {
+ return false;
+ }
+ if (bDstTexture) {
+ if (a.fDstTexture != *bDstTexture) {
+ return false;
+ }
+ } else if (a.fDstTexture.texture()) {
+ return false;
+ }
+ return a.fOp->combineIfPossible(b, *this->caps());
+}
+
GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op,
- GrRenderTargetContext* renderTargetContext) {
+ GrRenderTargetContext* renderTargetContext,
+ GrAppliedClip* clip,
+ const DstTexture* dstTexture) {
GrRenderTarget* renderTarget =
renderTargetContext ? renderTargetContext->accessRenderTarget()
: nullptr;
@@ -260,7 +307,7 @@ GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op,
candidate.fOp->uniqueID());
break;
}
- if (candidate.fOp->combineIfPossible(op.get(), *this->caps())) {
+ if (this->combineIfPossible(candidate, op.get(), clip, dstTexture)) {
GrOP_INFO("\t\tCombining with (%s, B%u)\n", candidate.fOp->name(),
candidate.fOp->uniqueID());
GrOP_INFO("\t\t\tCombined op info:\n");
@@ -284,7 +331,10 @@ GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op,
GrOP_INFO("\t\tFirstOp\n");
}
GR_AUDIT_TRAIL_OP_RESULT_NEW(fAuditTrail, op);
- fRecordedOps.emplace_back(std::move(op), renderTarget);
+ if (clip) {
+ clip = fClipAllocator.make<GrAppliedClip>(std::move(*clip));
+ }
+ fRecordedOps.emplace_back(std::move(op), renderTarget, clip, dstTexture);
fRecordedOps.back().fOp->wasRecorded();
fLastFullClearOp = nullptr;
fLastFullClearRenderTargetID.makeInvalid();
@@ -312,7 +362,8 @@ void GrRenderTargetOpList::forwardCombine() {
candidate.fOp->uniqueID());
break;
}
- if (op->combineIfPossible(candidate.fOp.get(), *this->caps())) {
+ if (this->combineIfPossible(fRecordedOps[i], candidate.fOp.get(),
+ candidate.fAppliedClip, &candidate.fDstTexture)) {
GrOP_INFO("\t\tCombining with (%s, B%u)\n", candidate.fOp->name(),
candidate.fOp->uniqueID());
GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, op, candidate.fOp.get());
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index ab744f35e6..c44c3416e3 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -8,9 +8,11 @@
#ifndef GrRenderTargetOpList_DEFINED
#define GrRenderTargetOpList_DEFINED
+#include "GrAppliedClip.h"
#include "GrOpList.h"
-#include "GrPrimitiveProcessor.h"
#include "GrPathRendering.h"
+#include "GrPrimitiveProcessor.h"
+#include "SkArenaAlloc.h"
#include "SkClipStack.h"
#include "SkMatrix.h"
#include "SkStringUtils.h"
@@ -22,12 +24,14 @@
class GrAuditTrail;
class GrClearOp;
class GrCaps;
-class GrClip;
class GrOp;
class GrPipelineBuilder;
class GrRenderTargetProxy;
class GrRenderTargetOpList final : public GrOpList {
+private:
+ using DstTexture = GrXferProcessor::DstTexture;
+
public:
/** Options for GrRenderTargetOpList behavior. */
struct Options {
@@ -68,7 +72,13 @@ public:
const GrCaps* caps() const { return fGpu->caps(); }
uint32_t addOp(std::unique_ptr<GrOp> op, GrRenderTargetContext* renderTargetContext) {
- this->recordOp(std::move(op), renderTargetContext);
+ this->recordOp(std::move(op), renderTargetContext, nullptr, nullptr);
+ return this->uniqueID();
+ }
+ uint32_t addOp(std::unique_ptr<GrOp> op, GrRenderTargetContext* renderTargetContext,
+ GrAppliedClip&& clip, const DstTexture& dstTexture) {
+ this->recordOp(std::move(op), renderTargetContext, clip.doesClip() ? &clip : nullptr,
+ &dstTexture);
return this->uniqueID();
}
@@ -107,23 +117,34 @@ public:
private:
friend class GrRenderTargetContextPriv; // for clearStencilClip and stencil clip state.
+ struct RecordedOp {
+ RecordedOp(std::unique_ptr<GrOp> op, GrRenderTarget* rt, const GrAppliedClip* appliedClip,
+ const DstTexture* dstTexture)
+ : fOp(std::move(op)), fRenderTarget(rt), fAppliedClip(appliedClip) {
+ if (dstTexture) {
+ fDstTexture = *dstTexture;
+ }
+ }
+ std::unique_ptr<GrOp> fOp;
+ // TODO: These ops will all to target the same render target and this won't be needed.
+ GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
+ DstTexture fDstTexture;
+ const GrAppliedClip* fAppliedClip;
+ };
+
// If the input op is combined with an earlier op, this returns the combined op. Otherwise, it
// returns the input op.
- GrOp* recordOp(std::unique_ptr<GrOp>, GrRenderTargetContext*);
+ GrOp* recordOp(std::unique_ptr<GrOp>, GrRenderTargetContext*, GrAppliedClip* = nullptr,
+ const DstTexture* = nullptr);
void forwardCombine();
// Used only via GrRenderTargetContextPriv.
void clearStencilClip(const GrFixedClip&, bool insideStencilMask, GrRenderTargetContext*);
- struct RecordedOp {
- RecordedOp(std::unique_ptr<GrOp> op, GrRenderTarget* rt)
- : fOp(std::move(op)), fRenderTarget(rt) {}
- std::unique_ptr<GrOp> fOp;
- // TODO: These ops will all to target the same render target and this won't be needed.
- GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
- };
- SkSTArray<256, RecordedOp, true> fRecordedOps;
+ // If this returns true then b has been merged into a's op.
+ bool combineIfPossible(const RecordedOp& a, GrOp* b, const GrAppliedClip* bClip,
+ const DstTexture* bDstTexture);
GrClearOp* fLastFullClearOp = nullptr;
GrGpuResource::UniqueID fLastFullClearRenderTargetID = GrGpuResource::UniqueID::InvalidID();
@@ -139,6 +160,11 @@ private:
int32_t fLastClipStackGenID;
SkIRect fLastDevClipBounds;
+ SkSTArray<256, RecordedOp, true> fRecordedOps;
+
+ char fClipAllocatorStorage[4096];
+ SkArenaAlloc fClipAllocator;
+
typedef GrOpList INHERITED;
};
diff --git a/src/gpu/GrTextureOpList.cpp b/src/gpu/GrTextureOpList.cpp
index d396b2a5ea..2a021d231a 100644
--- a/src/gpu/GrTextureOpList.cpp
+++ b/src/gpu/GrTextureOpList.cpp
@@ -50,6 +50,7 @@ void GrTextureOpList::prepareOps(GrOpFlushState* flushState) {
// Loop over the ops that haven't yet generated their geometry
for (int i = 0; i < fRecordedOps.count(); ++i) {
if (fRecordedOps[i]) {
+ // We do not call flushState->setDrawOpArgs as this op list does not support GrDrawOps.
fRecordedOps[i]->prepare(flushState);
}
}
@@ -61,6 +62,7 @@ bool GrTextureOpList::executeOps(GrOpFlushState* flushState) {
}
for (int i = 0; i < fRecordedOps.count(); ++i) {
+ // We do not call flushState->setDrawOpArgs as this op list does not support GrDrawOps.
fRecordedOps[i]->execute(flushState);
}
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index 4d877d6b27..32ab45c65e 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -176,14 +176,6 @@ SkString GrXferProcessor::BlendInfo::dump() const {
///////////////////////////////////////////////////////////////////////////////
-bool GrXPFactory::WillReadDst(const GrXPFactory* factory,
- const GrProcessorSet::FragmentProcessorAnalysis& analysis) {
- if (factory) {
- return factory->willReadsDst(analysis);
- }
- return GrPorterDuffXPFactory::WillSrcOverReadDst(analysis);
-}
-
bool GrXPFactory::WillNeedDstTexture(const GrXPFactory* factory, const GrCaps& caps,
const GrProcessorSet::FragmentProcessorAnalysis& analysis) {
bool result;
@@ -193,7 +185,6 @@ bool GrXPFactory::WillNeedDstTexture(const GrXPFactory* factory, const GrCaps& c
} else {
result = GrPorterDuffXPFactory::WillSrcOverNeedDstTexture(caps, analysis);
}
- SkASSERT(!(result && !WillReadDst(factory, analysis)));
return result;
}
@@ -204,6 +195,14 @@ bool GrXPFactory::CompatibleWithCoverageAsAlpha(const GrXPFactory* factory, bool
return GrPorterDuffXPFactory::SrcOverIsCompatibleWithCoverageAsAlpha();
}
+bool GrXPFactory::CanCombineOverlappedStencilAndCover(const GrXPFactory* factory,
+ bool colorIsOpaque) {
+ if (factory) {
+ return factory->canCombineOverlappedStencilAndCover(colorIsOpaque);
+ }
+ return GrPorterDuffXPFactory::SrcOverCanCombineOverlappedStencilAndCover(colorIsOpaque);
+}
+
GrXferProcessor* GrXPFactory::createXferProcessor(const FragmentProcessorAnalysis& analysis,
bool hasMixedSamples,
const DstTexture* dstTexture,
diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h
index 7f3fd30e8d..35ce5fa4a2 100644
--- a/src/gpu/GrXferProcessor.h
+++ b/src/gpu/GrXferProcessor.h
@@ -65,9 +65,7 @@ public:
}
DstTexture(GrTexture* texture, const SkIPoint& offset)
- : fTexture(SkSafeRef(texture))
- , fOffset(offset) {
- }
+ : fTexture(SkSafeRef(texture)), fOffset(texture ? offset : SkIPoint{0, 0}) {}
DstTexture& operator=(const DstTexture& other) {
fTexture = other.fTexture;
@@ -75,6 +73,11 @@ public:
return *this;
}
+ bool operator==(const DstTexture& that) const {
+ return fTexture == that.fTexture && fOffset == that.fOffset;
+ }
+ bool operator!=(const DstTexture& that) const { return !(*this == that); }
+
const SkIPoint& offset() const { return fOffset; }
void setOffset(const SkIPoint& offset) { fOffset = offset; }
@@ -84,6 +87,9 @@ public:
void setTexture(sk_sp<GrTexture> texture) {
fTexture = std::move(texture);
+ if (!fTexture) {
+ fOffset = {0, 0};
+ }
}
private:
@@ -301,11 +307,6 @@ public:
const GrCaps& caps) const;
/**
- * Is the destination color required either in the shader or fixed function blending.
- */
- static bool WillReadDst(const GrXPFactory*, const FragmentProcessorAnalysis&);
-
- /**
* This will return true if the xfer processor needs the dst color in the shader and the way
* that the color will be made available to the xfer processor is by sampling a texture.
*/
@@ -315,13 +316,17 @@ public:
static bool CompatibleWithCoverageAsAlpha(const GrXPFactory*, bool colorIsOpaque);
+ /**
+ * This indicates whether the the xfer processor will produce the same bleneded color result
+ * if a series of overlapping stencil and cover operations are replaced by a series of stencil
+ * operations and a single cover. A uniform src color is assumed.
+ **/
+ static bool CanCombineOverlappedStencilAndCover(const GrXPFactory*, bool colorIsOpaque);
+
protected:
constexpr GrXPFactory() {}
private:
- /** Subclass-specific implementation of WillReadDst(). */
- virtual bool willReadsDst(const FragmentProcessorAnalysis& pipelineAnalysis) const = 0;
-
virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const FragmentProcessorAnalysis&,
bool hasMixedSamples,
@@ -334,6 +339,7 @@ private:
virtual bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const = 0;
virtual bool compatibleWithCoverageAsAlpha(bool colorIsOpaque) const = 0;
+ virtual bool canCombineOverlappedStencilAndCover(bool colorIsOpaque) const { return false; }
};
#if defined(__GNUC__) || defined(__clang)
#pragma GCC diagnostic pop
diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h
index 807a2b0fc6..184ef4e56c 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.h
+++ b/src/gpu/effects/GrCoverageSetOpXP.h
@@ -32,10 +32,6 @@ public:
private:
constexpr GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
- bool willReadsDst(const FragmentProcessorAnalysis&) const override {
- return fRegionOp != SkRegion::kReplace_Op;
- }
-
GrXferProcessor* onCreateXferProcessor(const GrCaps&,
const FragmentProcessorAnalysis&,
bool hasMixedSamples,
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index 31c42ebfd7..37e4c16765 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -327,8 +327,6 @@ private:
bool hasMixedSamples,
const DstTexture*) const override;
- bool willReadsDst(const FragmentProcessorAnalysis&) const override { return true; }
-
bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override;
bool compatibleWithCoverageAsAlpha(bool colorIsOpaque) const override { return true; }
diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h
index f9206f7c19..78442f4125 100644
--- a/src/gpu/effects/GrDisableColorXP.h
+++ b/src/gpu/effects/GrDisableColorXP.h
@@ -24,8 +24,6 @@ public:
static const GrXPFactory* Get();
private:
- bool willReadsDst(const FragmentProcessorAnalysis&) const override { return false; }
-
constexpr GrDisableColorXPFactory() {}
bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override {
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 8b35bb996a..f98435515a 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -759,10 +759,11 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(
return new PorterDuffXferProcessor(blendFormula);
}
-bool GrPorterDuffXPFactory::willReadsDst(const FragmentProcessorAnalysis& analysis) const {
- BlendFormula colorFormula = gBlendTable[analysis.isOutputColorOpaque()][0][(int)fBlendMode];
+bool GrPorterDuffXPFactory::canCombineOverlappedStencilAndCover(bool colorIsOpaque) const {
+ // Ignore the effect of coverage here.
+ BlendFormula colorFormula = gBlendTable[colorIsOpaque][0][(int)fBlendMode];
SkASSERT(kAdd_GrBlendEquation == colorFormula.fBlendEquation);
- return (colorFormula.usesDstColor() || analysis.hasCoverage());
+ return !colorFormula.usesDstColor();
}
bool GrPorterDuffXPFactory::willReadDstInShader(const GrCaps& caps,
@@ -869,10 +870,6 @@ sk_sp<GrXferProcessor> GrPorterDuffXPFactory::CreateNoCoverageXP(SkBlendMode ble
return sk_make_sp<PorterDuffXferProcessor>(formula);
}
-bool GrPorterDuffXPFactory::WillSrcOverReadDst(const FragmentProcessorAnalysis& analysis) {
- return analysis.hasCoverage() || !analysis.isOutputColorOpaque();
-}
-
bool GrPorterDuffXPFactory::WillSrcOverNeedDstTexture(const GrCaps& caps,
const FragmentProcessorAnalysis& analysis) {
if (caps.shaderCaps()->dstReadInShaderSupport() ||
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.h b/src/gpu/effects/GrPorterDuffXferProcessor.h
index dd790e8431..719bd18527 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.h
@@ -37,14 +37,16 @@ public:
by reference because it is global and its ref-cnting methods are not thread safe. */
static const GrXferProcessor& SimpleSrcOverXP();
- static bool WillSrcOverReadDst(const FragmentProcessorAnalysis& analysis);
static bool WillSrcOverNeedDstTexture(const GrCaps&, const FragmentProcessorAnalysis&);
static bool SrcOverIsCompatibleWithCoverageAsAlpha() { return true; }
+ static bool SrcOverCanCombineOverlappedStencilAndCover(bool colorIsOpaque) {
+ return colorIsOpaque;
+ }
private:
constexpr GrPorterDuffXPFactory(SkBlendMode);
- bool willReadsDst(const FragmentProcessorAnalysis&) const override;
+ bool canCombineOverlappedStencilAndCover(bool colorIsOpaque) const override;
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const FragmentProcessorAnalysis&,
diff --git a/src/gpu/instanced/GLInstancedRendering.cpp b/src/gpu/instanced/GLInstancedRendering.cpp
index 0d2a2ddb9c..bfdb9601f9 100644
--- a/src/gpu/instanced/GLInstancedRendering.cpp
+++ b/src/gpu/instanced/GLInstancedRendering.cpp
@@ -19,7 +19,8 @@ class GLInstancedRendering::GLOp final : public InstancedRendering::Op {
public:
DEFINE_OP_CLASS_ID
- GLOp(GLInstancedRendering* instRendering) : INHERITED(ClassID(), instRendering) {}
+ GLOp(GLInstancedRendering* instRendering, GrPaint&& paint)
+ : INHERITED(ClassID(), std::move(paint), instRendering) {}
int numGLCommands() const { return 1 + fNumChangesInGeometry; }
private:
@@ -60,8 +61,8 @@ inline GrGLGpu* GLInstancedRendering::glGpu() const {
return static_cast<GrGLGpu*>(this->gpu());
}
-std::unique_ptr<InstancedRendering::Op> GLInstancedRendering::makeOp() {
- return std::unique_ptr<Op>(new GLOp(this));
+std::unique_ptr<InstancedRendering::Op> GLInstancedRendering::makeOp(GrPaint&& paint) {
+ return std::unique_ptr<Op>(new GLOp(this, std::move(paint)));
}
void GLInstancedRendering::onBeginFlush(GrResourceProvider* rp) {
diff --git a/src/gpu/instanced/GLInstancedRendering.h b/src/gpu/instanced/GLInstancedRendering.h
index 0088217bb2..d1affba2bd 100644
--- a/src/gpu/instanced/GLInstancedRendering.h
+++ b/src/gpu/instanced/GLInstancedRendering.h
@@ -33,7 +33,7 @@ private:
GrGLGpu* glGpu() const;
- std::unique_ptr<Op> makeOp() override;
+ std::unique_ptr<Op> makeOp(GrPaint&& paint) override;
void onBeginFlush(GrResourceProvider*) override;
void onDraw(const GrPipeline&, const InstanceProcessor&, const Op*) override;
diff --git a/src/gpu/instanced/InstancedRendering.cpp b/src/gpu/instanced/InstancedRendering.cpp
index ef2264b0ef..179552c852 100644
--- a/src/gpu/instanced/InstancedRendering.cpp
+++ b/src/gpu/instanced/InstancedRendering.cpp
@@ -22,32 +22,31 @@ InstancedRendering::InstancedRendering(GrGpu* gpu)
}
std::unique_ptr<GrDrawOp> InstancedRendering::recordRect(const SkRect& rect,
- const SkMatrix& viewMatrix, GrColor color,
- GrAA aa,
- const GrInstancedPipelineInfo& info,
- GrAAType* aaType) {
- return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect, aa, info, aaType);
+ const SkMatrix& viewMatrix,
+ GrPaint&& paint, GrAA aa,
+ const GrInstancedPipelineInfo& info) {
+ return this->recordShape(ShapeType::kRect, rect, viewMatrix, std::move(paint), rect, aa, info);
}
std::unique_ptr<GrDrawOp> InstancedRendering::recordRect(const SkRect& rect,
- const SkMatrix& viewMatrix, GrColor color,
- const SkRect& localRect, GrAA aa,
- const GrInstancedPipelineInfo& info,
- GrAAType* aaType) {
- return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, localRect, aa, info,
- aaType);
+ const SkMatrix& viewMatrix,
+ GrPaint&& paint, const SkRect& localRect,
+ GrAA aa,
+ const GrInstancedPipelineInfo& info) {
+ return this->recordShape(ShapeType::kRect, rect, viewMatrix, std::move(paint), localRect, aa,
+ info);
}
std::unique_ptr<GrDrawOp> InstancedRendering::recordRect(const SkRect& rect,
- const SkMatrix& viewMatrix, GrColor color,
+ const SkMatrix& viewMatrix,
+ GrPaint&& paint,
const SkMatrix& localMatrix, GrAA aa,
- const GrInstancedPipelineInfo& info,
- GrAAType* aaType) {
+ const GrInstancedPipelineInfo& info) {
if (localMatrix.hasPerspective()) {
return nullptr; // Perspective is not yet supported in the local matrix.
}
- if (std::unique_ptr<Op> op = this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect,
- aa, info, aaType)) {
+ if (std::unique_ptr<Op> op = this->recordShape(ShapeType::kRect, rect, viewMatrix,
+ std::move(paint), rect, aa, info)) {
op->getSingleInstance().fInfo |= kLocalMatrix_InfoFlag;
op->appendParamsTexel(localMatrix.getScaleX(), localMatrix.getSkewX(),
localMatrix.getTranslateX());
@@ -60,39 +59,39 @@ std::unique_ptr<GrDrawOp> InstancedRendering::recordRect(const SkRect& rect,
}
std::unique_ptr<GrDrawOp> InstancedRendering::recordOval(const SkRect& oval,
- const SkMatrix& viewMatrix, GrColor color,
- GrAA aa,
- const GrInstancedPipelineInfo& info,
- GrAAType* aaType) {
- return this->recordShape(ShapeType::kOval, oval, viewMatrix, color, oval, aa, info, aaType);
+ const SkMatrix& viewMatrix,
+ GrPaint&& paint, GrAA aa,
+ const GrInstancedPipelineInfo& info) {
+ return this->recordShape(ShapeType::kOval, oval, viewMatrix, std::move(paint), oval, aa, info);
}
std::unique_ptr<GrDrawOp> InstancedRendering::recordRRect(const SkRRect& rrect,
- const SkMatrix& viewMatrix, GrColor color,
- GrAA aa,
- const GrInstancedPipelineInfo& info,
- GrAAType* aaType) {
+ const SkMatrix& viewMatrix,
+ GrPaint&& paint, GrAA aa,
+ const GrInstancedPipelineInfo& info) {
if (std::unique_ptr<Op> op =
- this->recordShape(GetRRectShapeType(rrect), rrect.rect(), viewMatrix, color,
- rrect.rect(), aa, info, aaType)) {
+ this->recordShape(GetRRectShapeType(rrect), rrect.rect(), viewMatrix,
+ std::move(paint), rrect.rect(), aa, info)) {
op->appendRRectParams(rrect);
return std::move(op);
}
return nullptr;
}
-std::unique_ptr<GrDrawOp> InstancedRendering::recordDRRect(
- const SkRRect& outer, const SkRRect& inner, const SkMatrix& viewMatrix, GrColor color,
- GrAA aa, const GrInstancedPipelineInfo& info, GrAAType* aaType) {
+std::unique_ptr<GrDrawOp> InstancedRendering::recordDRRect(const SkRRect& outer,
+ const SkRRect& inner,
+ const SkMatrix& viewMatrix,
+ GrPaint&& paint, GrAA aa,
+ const GrInstancedPipelineInfo& info) {
if (inner.getType() > SkRRect::kSimple_Type) {
return nullptr; // Complex inner round rects are not yet supported.
}
if (SkRRect::kEmpty_Type == inner.getType()) {
- return this->recordRRect(outer, viewMatrix, color, aa, info, aaType);
+ return this->recordRRect(outer, viewMatrix, std::move(paint), aa, info);
}
if (std::unique_ptr<Op> op =
- this->recordShape(GetRRectShapeType(outer), outer.rect(), viewMatrix, color,
- outer.rect(), aa, info, aaType)) {
+ this->recordShape(GetRRectShapeType(outer), outer.rect(), viewMatrix,
+ std::move(paint), outer.rect(), aa, info)) {
op->appendRRectParams(outer);
ShapeType innerShapeType = GetRRectShapeType(inner);
op->fInfo.fInnerShapeTypes |= GetShapeFlag(innerShapeType);
@@ -105,28 +104,31 @@ std::unique_ptr<GrDrawOp> InstancedRendering::recordDRRect(
}
std::unique_ptr<InstancedRendering::Op> InstancedRendering::recordShape(
- ShapeType type, const SkRect& bounds, const SkMatrix& viewMatrix, GrColor color,
- const SkRect& localRect, GrAA aa, const GrInstancedPipelineInfo& info, GrAAType* aaType) {
+ ShapeType type, const SkRect& bounds, const SkMatrix& viewMatrix, GrPaint&& paint,
+ const SkRect& localRect, GrAA aa, const GrInstancedPipelineInfo& info) {
SkASSERT(State::kRecordingDraws == fState);
if (info.fIsRenderingToFloat && fGpu->caps()->avoidInstancedDrawsToFPTargets()) {
return nullptr;
}
- if (!this->selectAntialiasMode(viewMatrix, aa, info, aaType)) {
+ GrAAType aaType;
+ if (!this->selectAntialiasMode(viewMatrix, aa, info, &aaType)) {
return nullptr;
}
- std::unique_ptr<Op> op = this->makeOp();
- op->fInfo.setAAType(*aaType);
+ GrColor color = paint.getColor();
+ std::unique_ptr<Op> op = this->makeOp(std::move(paint));
+ op->fInfo.setAAType(aaType);
op->fInfo.fShapeTypes = GetShapeFlag(type);
op->fInfo.fCannotDiscard = true;
-
+ op->fDrawColorsAreOpaque = GrColorIsOpaque(color);
+ op->fDrawColorsAreSame = true;
Instance& instance = op->getSingleInstance();
instance.fInfo = (int)type << kShapeType_InfoBit;
Op::HasAABloat aaBloat =
- (*aaType == GrAAType::kCoverage) ? Op::HasAABloat::kYes : Op::HasAABloat::kNo;
+ (aaType == GrAAType::kCoverage) ? Op::HasAABloat::kYes : Op::HasAABloat::kNo;
Op::IsZeroArea zeroArea = (bounds.isEmpty()) ? Op::IsZeroArea::kYes : Op::IsZeroArea::kNo;
// The instanced shape renderer draws rectangles of [-1, -1, +1, +1], so we find the matrix that
@@ -229,9 +231,10 @@ inline bool InstancedRendering::selectAntialiasMode(const SkMatrix& viewMatrix,
return false;
}
-InstancedRendering::Op::Op(uint32_t classID, InstancedRendering* ir)
+InstancedRendering::Op::Op(uint32_t classID, GrPaint&& paint, InstancedRendering* ir)
: INHERITED(classID)
, fInstancedRendering(ir)
+ , fProcessors(std::move(paint))
, fIsTracked(false)
, fNumDraws(1)
, fNumChangesInGeometry(0) {
@@ -329,20 +332,17 @@ void InstancedRendering::Op::appendParamsTexel(SkScalar x, SkScalar y, SkScalar
fInfo.fHasParams = true;
}
-void InstancedRendering::Op::getFragmentProcessorAnalysisInputs(
- FragmentProcessorAnalysisInputs* input) const {
- input->colorInput()->setToConstant(this->getSingleInstance().fColor);
-
+bool InstancedRendering::Op::xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) {
+ GrProcessorSet::FragmentProcessorAnalysis analysis;
+ GrPipelineInput coverageInput;
if (GrAAType::kCoverage == fInfo.aaType() ||
(GrAAType::kNone == fInfo.aaType() && !fInfo.isSimpleRects() && fInfo.fCannotDiscard)) {
- input->coverageInput()->setToUnknown();
+ coverageInput = GrPipelineInput();
} else {
- input->coverageInput()->setToSolidCoverage();
+ coverageInput = GrColor_WHITE;
}
-}
+ analysis.init(this->getSingleInstance().fColor, coverageInput, fProcessors, clip, caps);
-void InstancedRendering::Op::applyPipelineOptimizations(
- const GrPipelineOptimizations& optimizations) {
Draw& draw = this->getSingleDraw(); // This will assert if we have > 1 command.
SkASSERT(draw.fGeometry.isEmpty());
SkASSERT(SkIsPow2(fInfo.fShapeTypes));
@@ -363,17 +363,23 @@ void InstancedRendering::Op::applyPipelineOptimizations(
}
GrColor overrideColor;
- if (optimizations.getOverrideColorIfSet(&overrideColor)) {
+ if (analysis.initialColorProcessorsToEliminate(&overrideColor)) {
SkASSERT(State::kRecordingDraws == fInstancedRendering->fState);
- this->getSingleInstance().fColor = overrideColor;
+ this->getSingleDraw().fInstance.fColor = overrideColor;
}
- fInfo.fUsesLocalCoords = optimizations.readsLocalCoords();
- fInfo.fCannotTweakAlphaForCoverage = !optimizations.canTweakAlphaForCoverage();
+ fInfo.fCannotTweakAlphaForCoverage =
+ !analysis.isCompatibleWithCoverageAsAlpha() ||
+ !GrXPFactory::CompatibleWithCoverageAsAlpha(fProcessors.xpFactory(),
+ analysis.isOutputColorOpaque());
+
+ fInfo.fUsesLocalCoords = analysis.usesLocalCoords();
+ return GrXPFactory::WillNeedDstTexture(fProcessors.xpFactory(), caps, analysis);
}
void InstancedRendering::Op::wasRecorded() {
SkASSERT(!fIsTracked);
fInstancedRendering->fTrackedOps.addToTail(this);
+ fProcessors.makePendingExecution();
fIsTracked = true;
}
@@ -383,9 +389,7 @@ bool InstancedRendering::Op::onCombineIfPossible(GrOp* other, const GrCaps& caps
SkASSERT(fTailDraw);
SkASSERT(that->fTailDraw);
- if (!OpInfo::CanCombine(fInfo, that->fInfo) ||
- !GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
- that->bounds(), caps)) {
+ if (!OpInfo::CanCombine(fInfo, that->fInfo) || fProcessors != that->fProcessors) {
return false;
}
@@ -406,7 +410,9 @@ bool InstancedRendering::Op::onCombineIfPossible(GrOp* other, const GrCaps& caps
this->joinBounds(*that);
fInfo = combinedInfo;
fPixelLoad += that->fPixelLoad;
-
+ fDrawColorsAreOpaque = fDrawColorsAreOpaque && that->fDrawColorsAreOpaque;
+ fDrawColorsAreSame = fDrawColorsAreSame && that->fDrawColorsAreSame &&
+ fHeadDraw->fInstance.fColor == that->fHeadDraw->fInstance.fColor;
// Adopt the other op's draws.
fNumDraws += that->fNumDraws;
fNumChangesInGeometry += that->fNumChangesInGeometry;
@@ -462,12 +468,40 @@ void InstancedRendering::Op::onExecute(GrOpFlushState* state) {
SkASSERT(state->gpu() == fInstancedRendering->gpu());
state->gpu()->handleDirtyContext();
- if (GrXferBarrierType barrierType = this->pipeline()->xferBarrierType(*state->gpu()->caps())) {
- state->gpu()->xferBarrier(this->pipeline()->getRenderTarget(), barrierType);
- }
+ GrProcessorSet::FragmentProcessorAnalysis analysis;
+ GrPipelineInput coverageInput;
+ if (GrAAType::kCoverage == fInfo.aaType() ||
+ (GrAAType::kNone == fInfo.aaType() && !fInfo.isSimpleRects() && fInfo.fCannotDiscard)) {
+ coverageInput = GrPipelineInput();
+ } else {
+ coverageInput = GrColor_WHITE;
+ }
+ GrPipelineInput colorInput;
+ if (fDrawColorsAreSame) {
+ colorInput = fHeadDraw->fInstance.fColor;
+ } else if (fDrawColorsAreOpaque) {
+ colorInput = GrPipelineInput::Opaque::kYes;
+ }
+ const GrAppliedClip* clip = state->drawOpArgs().fAppliedClip;
+ analysis.init(colorInput, coverageInput, fProcessors, clip, state->caps());
+
+ GrPipeline pipeline;
+ GrPipeline::InitArgs args;
+ args.fAnalysis = &analysis;
+ args.fAppliedClip = clip;
+ args.fCaps = &state->caps();
+ args.fProcessors = &fProcessors;
+ args.fFlags = GrAATypeIsHW(fInfo.aaType()) ? GrPipeline::kHWAntialias_Flag : 0;
+ args.fRenderTarget = state->drawOpArgs().fRenderTarget;
+ args.fDstTexture = state->drawOpArgs().fDstTexture;
+ pipeline.init(args);
+
+ if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*state->gpu()->caps())) {
+ state->gpu()->xferBarrier(pipeline.getRenderTarget(), barrierType);
+ }
InstanceProcessor instProc(fInfo, fInstancedRendering->fParamsBuffer.get());
- fInstancedRendering->onDraw(*this->pipeline(), instProc, this);
+ fInstancedRendering->onDraw(pipeline, instProc, this);
}
void InstancedRendering::endFlush() {
diff --git a/src/gpu/instanced/InstancedRendering.h b/src/gpu/instanced/InstancedRendering.h
index 778e8b4511..c2db768121 100644
--- a/src/gpu/instanced/InstancedRendering.h
+++ b/src/gpu/instanced/InstancedRendering.h
@@ -46,35 +46,31 @@ public:
* draws between beginFlush() and endFlush().
*/
std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
- GrColor, GrAA,
- const GrInstancedPipelineInfo&,
- GrAAType*);
+ GrPaint&&, GrAA,
+ const GrInstancedPipelineInfo&);
std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
- GrColor, const SkRect& localRect,
- GrAA, const GrInstancedPipelineInfo&,
- GrAAType*);
+ GrPaint&&, const SkRect& localRect,
+ GrAA,
+ const GrInstancedPipelineInfo&);
std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
- GrColor, const SkMatrix& localMatrix,
- GrAA, const GrInstancedPipelineInfo&,
- GrAAType*);
+ GrPaint&&,
+ const SkMatrix& localMatrix, GrAA,
+ const GrInstancedPipelineInfo&);
std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordOval(const SkRect&, const SkMatrix&,
- GrColor, GrAA,
- const GrInstancedPipelineInfo&,
- GrAAType*);
+ GrPaint&&, GrAA,
+ const GrInstancedPipelineInfo&);
std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRRect(const SkRRect&, const SkMatrix&,
- GrColor, GrAA,
- const GrInstancedPipelineInfo&,
- GrAAType*);
+ GrPaint&&, GrAA,
+ const GrInstancedPipelineInfo&);
std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordDRRect(const SkRRect& outer,
const SkRRect& inner,
- const SkMatrix&, GrColor, GrAA,
- const GrInstancedPipelineInfo&,
- GrAAType*);
+ const SkMatrix&, GrPaint&&, GrAA,
+ const GrInstancedPipelineInfo&);
/**
* Compiles all recorded draws into GPU buffers and allows the client to begin flushing the
@@ -122,7 +118,6 @@ protected:
fIsTracked,
fNumDraws,
fNumChangesInGeometry);
- string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
return string;
}
@@ -140,27 +135,32 @@ protected:
void appendParamsTexel(const SkScalar* vals, int count);
void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z, SkScalar w);
void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z);
+ FixedFunctionFlags fixedFunctionFlags() const override {
+ return GrAATypeIsHW(fInfo.aaType()) ? FixedFunctionFlags::kUsesHWAA
+ : FixedFunctionFlags::kNone;
+ }
+ bool xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*) override;
// Registers the op with the InstancedRendering list of tracked ops.
void wasRecorded() override;
protected:
- Op(uint32_t classID, InstancedRendering* ir);
+ Op(uint32_t classID, GrPaint&&, InstancedRendering*);
InstancedRendering* const fInstancedRendering;
OpInfo fInfo;
SkScalar fPixelLoad;
+ GrProcessorSet fProcessors;
SkSTArray<5, ParamsTexel, true> fParams;
- bool fIsTracked;
+ bool fIsTracked : 1;
+ bool fDrawColorsAreOpaque : 1;
+ bool fDrawColorsAreSame : 1;
int fNumDraws;
int fNumChangesInGeometry;
Draw* fHeadDraw;
Draw* fTailDraw;
private:
- void getFragmentProcessorAnalysisInputs(
- FragmentProcessorAnalysisInputs* input) const override;
- void applyPipelineOptimizations(const GrPipelineOptimizations&) override;
bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override;
void onPrepare(GrOpFlushState*) override {}
void onExecute(GrOpFlushState*) override;
@@ -190,15 +190,14 @@ private:
};
std::unique_ptr<Op> SK_WARN_UNUSED_RESULT recordShape(ShapeType, const SkRect& bounds,
- const SkMatrix& viewMatrix, GrColor,
+ const SkMatrix& viewMatrix, GrPaint&&,
const SkRect& localRect, GrAA aa,
- const GrInstancedPipelineInfo&,
- GrAAType*);
+ const GrInstancedPipelineInfo&);
bool selectAntialiasMode(const SkMatrix& viewMatrix, GrAA aa, const GrInstancedPipelineInfo&,
GrAAType*);
- virtual std::unique_ptr<Op> makeOp() = 0;
+ virtual std::unique_ptr<Op> makeOp(GrPaint&&) = 0;
const sk_sp<GrGpu> fGpu;
State fState;
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;
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index acd426787b..e572e5d633 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -605,24 +605,13 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
const SkRect bounds = SkRect::MakeIWH(renderTargetContext->width(),
renderTargetContext->height());
+ // The run's "font" overrides the anti-aliasing of the passed in SkPaint!
std::unique_ptr<GrDrawOp> op = GrDrawPathRangeOp::Make(
viewMatrix, fTextRatio, fTextInverseRatio * x, fTextInverseRatio * y,
- grPaint.getColor(), GrPathRendering::kWinding_FillType, glyphs.get(),
+ std::move(grPaint), GrPathRendering::kWinding_FillType, runAA, glyphs.get(),
fInstanceData.get(), bounds);
- // The run's "font" overrides the anti-aliasing of the passed in SkPaint!
- GrAAType aaType = GrAAType::kNone;
- if (GrAA::kYes == runAA) {
- if (renderTargetContext->isUnifiedMultisampled()) {
- aaType = GrAAType::kMSAA;
- } else if (renderTargetContext->isStencilBufferMultisampled()) {
- aaType = GrAAType::kMixedSamples;
- }
- }
- GrPipelineBuilder pipelineBuilder(std::move(grPaint), aaType);
- pipelineBuilder.setUserStencil(&kCoverPass);
-
- renderTargetContext->addDrawOp(pipelineBuilder, clip, std::move(op));
+ renderTargetContext->addDrawOp(clip, std::move(op));
}
if (fFallbackTextBlob) {
diff --git a/tests/GpuSampleLocationsTest.cpp b/tests/GpuSampleLocationsTest.cpp
index 8808b1d8cb..5cb9b606db 100644
--- a/tests/GpuSampleLocationsTest.cpp
+++ b/tests/GpuSampleLocationsTest.cpp
@@ -96,14 +96,12 @@ static void construct_dummy_pipeline(GrRenderTargetContext* dc, GrPipeline* pipe
GrScissorState dummyScissor;
GrWindowRectsState dummyWindows;
- GrAppliedClip dummyAppliedClip;
GrProcessorSet::FragmentProcessorAnalysis analysis;
GrPipeline::InitArgs args;
dummyBuilder.getPipelineInitArgs(&args);
args.fRenderTarget = dc->accessRenderTarget();
args.fAnalysis = &analysis;
args.fCaps = dc->caps();
- args.fAppliedClip = &dummyAppliedClip;
args.fDstTexture = GrXferProcessor::DstTexture();
pipeline->init(args);
}
diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp
index ddca03a497..de1843813a 100644
--- a/tests/GrPorterDuffTest.cpp
+++ b/tests/GrPorterDuffTest.cpp
@@ -9,7 +9,6 @@
#if SK_SUPPORT_GPU
-#include "GrAppliedClip.h"
#include "GrContextFactory.h"
#include "GrContextOptions.h"
#include "GrGpu.h"
@@ -68,7 +67,10 @@ public:
XPInfo(skiatest::Reporter* reporter, SkBlendMode xfermode, const GrCaps& caps,
const GrProcessorSet::FragmentProcessorAnalysis& analysis) {
const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode);
- fReadsDst = GrXPFactory::WillReadDst(xpf, analysis);
+ // The GrXPFactory query assumes no coverage.
+ fCanCombineOverlappedStencilAndCover =
+ !analysis.hasCoverage() && GrXPFactory::CanCombineOverlappedStencilAndCover(
+ xpf, analysis.isOutputColorOpaque());
sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps));
TEST_ASSERT(!GrXPFactory::WillNeedDstTexture(xpf, caps, analysis));
fOptFlags = xp->getOptimizations(analysis);
@@ -78,7 +80,7 @@ public:
TEST_ASSERT(xp->hasSecondaryOutput() == GrBlendCoeffRefsSrc2(fBlendInfo.fDstBlend));
}
- bool fReadsDst;
+ bool fCanCombineOverlappedStencilAndCover;
int fOptFlags;
int fPrimaryOutputType;
int fSecondaryOutputType;
@@ -104,7 +106,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis);
switch (xfermode) {
case SkBlendMode::kClear:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kCoverage_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -114,7 +116,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrc:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType);
@@ -124,7 +126,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDst:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag |
kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
@@ -135,7 +137,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(!xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOver:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kSAModulate_OutputType == xpi.fSecondaryOutputType);
@@ -145,7 +147,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOver:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -155,7 +157,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType);
@@ -165,7 +167,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kISAModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -175,7 +177,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOut:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType);
@@ -185,7 +187,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOut:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kSAModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -195,7 +197,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kSAModulate_OutputType == xpi.fSecondaryOutputType);
@@ -205,7 +207,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kISAModulate_OutputType == xpi.fSecondaryOutputType);
@@ -215,7 +217,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kXor:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kSAModulate_OutputType == xpi.fSecondaryOutputType);
@@ -225,7 +227,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kPlus:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -235,7 +237,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kModulate:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kISCModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -245,7 +247,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kScreen:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -273,7 +275,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis);
switch (xfermode) {
case SkBlendMode::kClear:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kCoverage_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -283,7 +285,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrc:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType);
@@ -293,7 +295,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDst:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag |
kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
@@ -304,7 +306,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(!xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOver:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -314,7 +316,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOver:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -324,7 +326,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType);
@@ -334,7 +336,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kISAModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -344,7 +346,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOut:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType);
@@ -354,7 +356,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOut:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -364,7 +366,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -374,7 +376,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kISAModulate_OutputType == xpi.fSecondaryOutputType);
@@ -384,7 +386,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kXor:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -394,7 +396,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kPlus:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -404,7 +406,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kModulate:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kISCModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -414,7 +416,7 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kScreen:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -443,7 +445,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis);
switch (xfermode) {
case SkBlendMode::kClear:
- TEST_ASSERT(!xpi.fReadsDst);
+ TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kIgnoreColor_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -453,7 +455,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrc:
- TEST_ASSERT(!xpi.fReadsDst);
+ TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -463,7 +465,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDst:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag |
kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
@@ -474,7 +476,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(!xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOver:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -484,7 +486,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOver:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -494,7 +496,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -504,7 +506,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -514,7 +516,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOut:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -524,7 +526,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOut:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -534,7 +536,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -544,7 +546,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -554,7 +556,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kXor:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -564,7 +566,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kPlus:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -574,7 +576,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kModulate:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -584,7 +586,7 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kScreen:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -614,7 +616,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis);
switch (xfermode) {
case SkBlendMode::kClear:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kCoverage_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -624,7 +626,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrc:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -634,7 +636,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDst:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag |
kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
@@ -645,7 +647,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(!xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOver:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -655,7 +657,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOver:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -665,7 +667,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -675,7 +677,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag |
kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
@@ -686,7 +688,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(!xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOut:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -696,7 +698,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOut:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kCoverage_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -706,7 +708,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -716,7 +718,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -726,7 +728,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kXor:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -736,7 +738,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kPlus:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -746,7 +748,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kModulate:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags);
TEST_ASSERT(kISCModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -756,7 +758,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kScreen:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -786,7 +788,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
switch (xfermode) {
case SkBlendMode::kClear:
- TEST_ASSERT(!xpi.fReadsDst);
+ TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kIgnoreColor_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -796,7 +798,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrc:
- TEST_ASSERT(!xpi.fReadsDst);
+ TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -806,7 +808,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDst:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag |
kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
@@ -817,7 +819,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(!xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOver:
- TEST_ASSERT(!xpi.fReadsDst);
+ TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -827,7 +829,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOver:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -837,7 +839,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -847,7 +849,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstIn:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT((kIgnoreColor_OptFlag |
kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
@@ -858,7 +860,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(!xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcOut:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -868,7 +870,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstOut:
- TEST_ASSERT(!xpi.fReadsDst);
+ TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kIgnoreColor_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -878,7 +880,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kSrcATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -888,7 +890,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kDstATop:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -898,7 +900,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kXor:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -908,7 +910,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kPlus:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -918,7 +920,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kModulate:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -928,7 +930,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
TEST_ASSERT(xpi.fBlendInfo.fWriteColor);
break;
case SkBlendMode::kScreen:
- TEST_ASSERT(xpi.fReadsDst);
+ TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover);
TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags);
TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType);
TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType);
@@ -961,15 +963,14 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const
}
void applyPipelineOptimizations(const GrPipelineOptimizations&) override {}
- bool onCombineIfPossible(GrOp*, const GrCaps&) override { return false; }
+ bool onCombineIfPossible(GrOp*, const GrCaps&) override { return false; }
void onPrepareDraws(Target*) const override {}
typedef GrMeshDrawOp INHERITED;
} testLCDCoverageOp;
GrProcessorSet::FragmentProcessorAnalysis analysis;
- GrAppliedClip clip;
- testLCDCoverageOp.analyzeProcessors(&analysis, GrProcessorSet(GrPaint()), &clip, caps);
+ testLCDCoverageOp.analyzeProcessors(&analysis, GrProcessorSet(GrPaint()), nullptr, caps);
SkASSERT(analysis.hasKnownOutputColor());
SkASSERT(analysis.hasLCDCoverage());
@@ -983,8 +984,6 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const
return;
}
- TEST_ASSERT(GrXPFactory::WillReadDst(xpf, analysis));
-
xp->getOptimizations(analysis);
GrXferProcessor::BlendInfo blendInfo;