aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-04-10 10:54:25 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-04-10 15:38:47 +0000
commitd61c9d93b126dca0af17eff89be8536944dadf81 (patch)
tree975f3418b8f1f303a2530a2a4b67a97c82c86dcc
parentf9aa9e51691d83970039f42c623c1fd354552378 (diff)
Move ref counting out of GrProcessor and into subclasses.
This will allow different subclasses to use different models for lifetime management. GrXferProcessor moves to simple ref counting since they don't own GrGpuResources. This also constifies GrXferProcessor factories. Change-Id: I6bea0ea8de718874063224232f9da50887868b16 Reviewed-on: https://skia-review.googlesource.com/11792 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
-rw-r--r--include/gpu/GrFragmentProcessor.h6
-rw-r--r--include/gpu/GrProcessor.h22
-rw-r--r--include/gpu/GrProgramElement.h42
-rw-r--r--src/gpu/GrPipeline.cpp21
-rw-r--r--src/gpu/GrPipeline.h5
-rw-r--r--src/gpu/GrPrimitiveProcessor.h5
-rw-r--r--src/gpu/GrProcessorSet.cpp9
-rw-r--r--src/gpu/GrProcessorSet.h4
-rw-r--r--src/gpu/GrXferProcessor.cpp10
-rw-r--r--src/gpu/GrXferProcessor.h23
-rw-r--r--src/gpu/effects/GrCoverageSetOpXP.cpp9
-rw-r--r--src/gpu/effects/GrCoverageSetOpXP.h7
-rw-r--r--src/gpu/effects/GrCustomXfermode.cpp17
-rw-r--r--src/gpu/effects/GrDisableColorXP.cpp11
-rw-r--r--src/gpu/effects/GrDisableColorXP.h8
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.cpp20
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.h17
-rw-r--r--tests/GrPorterDuffTest.cpp7
18 files changed, 127 insertions, 116 deletions
diff --git a/include/gpu/GrFragmentProcessor.h b/include/gpu/GrFragmentProcessor.h
index acbc63ea77..00f2dbd9d8 100644
--- a/include/gpu/GrFragmentProcessor.h
+++ b/include/gpu/GrFragmentProcessor.h
@@ -23,7 +23,7 @@ class GrSwizzle;
GrCoordTransforms to receive a transformation of the local coordinates that map from local space
to the fragment being processed.
*/
-class GrFragmentProcessor : public GrResourceIOProcessor {
+class GrFragmentProcessor : public GrResourceIOProcessor, public GrProgramElement {
public:
/**
* In many instances (e.g. SkShader::asFragmentProcessor() implementations) it is desirable to
@@ -300,6 +300,10 @@ protected:
void setWillUseDistanceVectorField() { fFlags |= kUsesDistanceVectorField_Flag; }
private:
+ void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
+ void removeRefs() const override { GrResourceIOProcessor::removeRefs(); }
+ void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); }
+
void notifyRefCntIsZero() const final;
virtual GrColor4f constantOutputForConstantInput(GrColor4f /* inputColor */) const {
diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h
index 54691812e1..d10136846a 100644
--- a/include/gpu/GrProcessor.h
+++ b/include/gpu/GrProcessor.h
@@ -61,7 +61,7 @@ private:
Dynamically allocated GrProcessors are managed by a per-thread memory pool. The ref count of an
processor must reach 0 before the thread terminates and the pool is destroyed.
*/
-class GrProcessor : public GrProgramElement<GrProcessor> {
+class GrProcessor {
public:
virtual ~GrProcessor() = default;
@@ -123,6 +123,9 @@ protected:
}
private:
+ GrProcessor(const GrProcessor&) = delete;
+ GrProcessor& operator=(const GrProcessor&) = delete;
+
static uint32_t GenClassID() {
// fCurrProcessorClassID has been initialized to kIllegalProcessorClassID. The
// atomic inc returns the old value not the incremented value. So we add
@@ -135,11 +138,6 @@ private:
return id;
}
- friend class GrProgramElement<GrProcessor>;
- virtual void addPendingIOs() const {}
- virtual void removeRefs() const {}
- virtual void pendingIOComplete() const {}
-
enum {
kIllegalProcessorClassID = 0,
};
@@ -147,8 +145,6 @@ private:
uint32_t fClassID;
RequiredFeatures fRequiredFeatures;
-
- typedef GrProgramElement INHERITED;
};
GR_MAKE_BITFIELD_OPS(GrProcessor::RequiredFeatures);
@@ -195,12 +191,12 @@ protected:
bool hasSameSamplersAndAccesses(const GrResourceIOProcessor&) const;
-private:
- friend class GrProgramElement<GrProcessor>;
- void addPendingIOs() const override;
- void removeRefs() const override;
- void pendingIOComplete() const override;
+ // These methods can be used by derived classes that also derive from GrProgramElement.
+ void addPendingIOs() const;
+ void removeRefs() const;
+ void pendingIOComplete() const;
+private:
SkSTArray<4, const TextureSampler*, true> fTextureSamplers;
SkSTArray<1, const BufferAccess*, true> fBufferAccesses;
SkSTArray<1, const ImageStorageAccess*, true> fImageStorageAccesses;
diff --git a/include/gpu/GrProgramElement.h b/include/gpu/GrProgramElement.h
index 2538680302..425f57a59d 100644
--- a/include/gpu/GrProgramElement.h
+++ b/include/gpu/GrProgramElement.h
@@ -17,15 +17,10 @@ class GrGpuResourceRef;
* Note: We are converting GrProcessor from ref counting to a single owner model using move
* semantics. This class will be removed.
*
- * Base class for GrProcessor. This exists to manage transitioning a GrProcessor from being owned by
- * a client to being scheduled for execution. While a GrProcessor is ref'ed by drawing code its
- * GrGpu resources must also be ref'ed to prevent incorrectly recycling them through the cache.
- * However, once the GrProcessor is baked into a GrPipeline and the drawing code has stopped ref'ing
- * it, it's internal resources can be recycled in some cases.
- *
- * We track this using two types of refs on GrProgramElement. A regular ref is owned by any client
- * that may continue to issue draws that use the GrProgramElement. The GrPipeline owns "pending
- * executions" instead of refs. A pending execution is cleared by ~GrPipeline().
+ * This is used to track "refs" for two separate types GrProcessor ownership. A regular ref is owned
+ * by any client that may continue to issue draws that use the GrProgramElement. A recorded op or
+ * GrPipeline uses "pending executions" instead of refs. A pending execution is cleared after the
+ * draw is executed (or aborted).
*
* While a GrProgramElement is ref'ed any resources it owns are also ref'ed. However, once it gets
* into the state where it has pending executions AND no refs then it converts its ownership of
@@ -33,13 +28,18 @@ class GrGpuResourceRef;
* safe to recycle a resource even though we still have buffered GrOps that read or write to the
* the resource.
*
- * To make this work the subclass, GrProcessor, implements addPendingIOs and pendingIOComplete. The
- * former adds pending reads/writes as appropriate when the processor is recorded in a GrOpList. The
- * latter removes them after the op list executes the operation. These calls must propagate to any
- * children processors. Similarly, the subclass implements a removeRefs function in order to remove
- * refs from resources once the processor is only owned for pending execution.
+ * To make this work the subclass GrProcessor implements addPendingIOs, removeRefs, and
+ * pendingIOComplete. addPendingIOs adds pending reads/writes to GrGpuResources owned by the
+ * processor as appropriate when the processor is recorded in a GrOpList. removeRefs is called when
+ * the ref count reaches 0 and the GrProcessor is only owned by "pending executions".
+ * pendingIOComplete occurs if the resource is still owned by a ref but all recorded draws have been
+ * completed. Whenever pending executions and refs reach zero the processor is deleted.
+ *
+ * The GrProcessor may also implement notifyRefCntIsZero in order to change its ownership of child
+ * processors from ref to pending execution when the processor is first owned exclusively in pending
+ * execution mode.
*/
-template<typename DERIVED> class GrProgramElement : public SkNoncopyable {
+class GrProgramElement : public SkNoncopyable {
public:
virtual ~GrProgramElement() {
// fRefCnt can be one when an effect is created statically using GR_CREATE_STATIC_EFFECT
@@ -65,7 +65,7 @@ public:
delete this;
return;
} else {
- static_cast<const DERIVED*>(this)->removeRefs();
+ this->removeRefs();
}
}
this->validate();
@@ -85,7 +85,7 @@ protected:
void addPendingExecution() const {
this->validate();
if (0 == fPendingExecutions) {
- static_cast<const DERIVED*>(this)->addPendingIOs();
+ this->addPendingIOs();
}
++fPendingExecutions;
this->validate();
@@ -99,13 +99,17 @@ protected:
delete this;
return;
} else {
- static_cast<const DERIVED*>(this)->pendingIOComplete();
+ this->pendingIOComplete();
}
}
this->validate();
}
private:
+ virtual void addPendingIOs() const = 0;
+ virtual void removeRefs() const = 0;
+ virtual void pendingIOComplete() const = 0;
+
/** This will be called when the ref cnt is zero. The object may or may not have pending
executions. */
virtual void notifyRefCntIsZero() const = 0;
@@ -114,7 +118,7 @@ private:
// Count of deferred executions not yet issued to the 3D API.
mutable int32_t fPendingExecutions;
- // Only this class can access addPendingExecution() and completedExecution().
+ // Only these classes can access addPendingExecution() and completedExecution().
template <typename T> friend class GrPendingProgramElement;
friend class GrProcessorSet;
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index d1f5931d9a..193c32020f 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -50,7 +50,7 @@ void GrPipeline::init(const InitArgs& args) {
fDrawFace = static_cast<int16_t>(args.fDrawFace);
- fXferProcessor.reset(args.fProcessors->xferProcessor());
+ fXferProcessor = args.fProcessors->refXferProcessor();
if (args.fDstTexture.texture()) {
fDstTexture.reset(args.fDstTexture.texture());
@@ -103,16 +103,15 @@ void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const {
}
GrPipeline::GrPipeline(GrRenderTarget* rt, SkBlendMode blendmode)
- : fRenderTarget(rt)
- , fScissorState()
- , fWindowRectsState()
- , fUserStencilSettings(&GrUserStencilSettings::kUnused)
- , fDrawFace(static_cast<uint16_t>(GrDrawFace::kBoth))
- , fFlags()
- , fXferProcessor(GrPorterDuffXPFactory::CreateNoCoverageXP(blendmode).get())
- , fFragmentProcessors()
- , fNumColorProcessors(0) {
-}
+ : fRenderTarget(rt)
+ , fScissorState()
+ , fWindowRectsState()
+ , fUserStencilSettings(&GrUserStencilSettings::kUnused)
+ , fDrawFace(static_cast<uint16_t>(GrDrawFace::kBoth))
+ , fFlags()
+ , fXferProcessor(GrPorterDuffXPFactory::MakeNoCoverageXP(blendmode))
+ , fFragmentProcessors()
+ , fNumColorProcessors(0) {}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index a2a332fc36..b08b4baa1f 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -131,7 +131,7 @@ public:
int numFragmentProcessors() const { return fFragmentProcessors.count(); }
const GrXferProcessor& getXferProcessor() const {
- if (fXferProcessor.get()) {
+ if (fXferProcessor) {
return *fXferProcessor.get();
} else {
// A null xp member means the common src-over case. GrXferProcessor's ref'ing
@@ -228,7 +228,6 @@ private:
using DstTexture = GrPendingIOResource<GrTexture, kRead_GrIOType>;
using PendingFragmentProcessor = GrPendingProgramElement<const GrFragmentProcessor>;
using FragmentProcessorArray = SkAutoSTArray<8, PendingFragmentProcessor>;
- using ProgramXferProcessor = GrPendingProgramElement<const GrXferProcessor>;
DstTexture fDstTexture;
SkIPoint fDstTextureOffset;
@@ -238,7 +237,7 @@ private:
const GrUserStencilSettings* fUserStencilSettings;
uint16_t fDrawFace;
uint16_t fFlags;
- ProgramXferProcessor fXferProcessor;
+ sk_sp<const GrXferProcessor> fXferProcessor;
FragmentProcessorArray fFragmentProcessors;
// This value is also the index in fFragmentProcessors where coverage processors begin.
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index 76fa6c591e..d078ac5072 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -38,7 +38,7 @@ class GrGLSLPrimitiveProcessor;
* GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
* pipelines, and they must provide some notion of equality
*/
-class GrPrimitiveProcessor : public GrResourceIOProcessor {
+class GrPrimitiveProcessor : public GrResourceIOProcessor, public GrProgramElement {
public:
// Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
// we put these calls on the base class to prevent having to cast
@@ -114,6 +114,9 @@ protected:
size_t fVertexStride;
private:
+ void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
+ void removeRefs() const override { GrResourceIOProcessor::removeRefs(); }
+ void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); }
void notifyRefCntIsZero() const final {}
virtual bool hasExplicitLocalCoords() const = 0;
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index 93617649a3..a76a10b8f9 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -47,7 +47,7 @@ GrProcessorSet::~GrProcessorSet() {
}
}
if (this->isFinalized() && this->xferProcessor()) {
- this->xferProcessor()->completedExecution();
+ this->xferProcessor()->unref();
}
}
@@ -168,12 +168,9 @@ GrProcessorSet::Analysis GrProcessorSet::finalize(const GrProcessorAnalysisColor
auto xp = GrXPFactory::MakeXferProcessor(this->xpFactory(), colorAnalysis.outputColor(),
outputCoverage, isMixedSamples, caps);
- fXP.fProcessor = xp.get();
- if (fXP.fProcessor) {
- fXP.fProcessor->addPendingExecution();
- }
- fFlags |= kFinalized_Flag;
+ fXP.fProcessor = xp.release();
+ fFlags |= kFinalized_Flag;
analysis.fIsInitialized = true;
return analysis;
}
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index 072d2388c9..a632aa6cb9 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -43,6 +43,10 @@ public:
SkASSERT(this->isFinalized());
return fXP.fProcessor;
}
+ sk_sp<const GrXferProcessor> refXferProcessor() const {
+ SkASSERT(this->isFinalized());
+ return sk_ref_sp(fXP.fProcessor);
+ }
bool usesDistanceVectorField() const { return SkToBool(fFlags & kUseDistanceVectorField_Flag); }
bool disableOutputConversionToSRGB() const {
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index bf5bc592d9..27c8a963e4 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -167,11 +167,11 @@ GrXPFactory::AnalysisProperties GrXPFactory::GetAnalysisProperties(
return result;
}
-sk_sp<GrXferProcessor> GrXPFactory::MakeXferProcessor(const GrXPFactory* factory,
- const GrProcessorAnalysisColor& color,
- GrProcessorAnalysisCoverage coverage,
- bool hasMixedSamples,
- const GrCaps& caps) {
+sk_sp<const GrXferProcessor> GrXPFactory::MakeXferProcessor(const GrXPFactory* factory,
+ const GrProcessorAnalysisColor& color,
+ GrProcessorAnalysisCoverage coverage,
+ bool hasMixedSamples,
+ const GrCaps& caps) {
SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
if (factory) {
return factory->makeXferProcessor(color, coverage, hasMixedSamples, caps);
diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h
index bfc6dd71c5..3aecf3e686 100644
--- a/src/gpu/GrXferProcessor.h
+++ b/src/gpu/GrXferProcessor.h
@@ -10,6 +10,7 @@
#include "GrBlend.h"
#include "GrColor.h"
+#include "GrNonAtomicRef.h"
#include "GrProcessor.h"
#include "GrProcessorSet.h"
#include "GrTexture.h"
@@ -46,7 +47,7 @@ GR_STATIC_ASSERT(SkToBool(kNone_GrXferBarrierType) == false);
* A GrXferProcessor is never installed directly into our draw state, but instead is created from a
* GrXPFactory once we have finalized the state of our draw.
*/
-class GrXferProcessor : public GrProcessor {
+class GrXferProcessor : public GrProcessor, public GrNonAtomicRef<GrXferProcessor> {
public:
/**
* A texture that contains the dst pixel values and an integer coord offset from device space
@@ -177,8 +178,6 @@ protected:
GrXferProcessor(bool willReadDstColor, bool hasMixedSamples);
private:
- void notifyRefCntIsZero() const final {}
-
/**
* Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
* processor's GL backend implementation.
@@ -268,11 +267,11 @@ public:
};
GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(AnalysisProperties);
- static sk_sp<GrXferProcessor> MakeXferProcessor(const GrXPFactory*,
- const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const GrCaps& caps);
+ static sk_sp<const GrXferProcessor> MakeXferProcessor(const GrXPFactory*,
+ const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples,
+ const GrCaps& caps);
static AnalysisProperties GetAnalysisProperties(const GrXPFactory*,
const GrProcessorAnalysisColor&,
@@ -283,10 +282,10 @@ protected:
constexpr GrXPFactory() {}
private:
- virtual sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const GrCaps&) const = 0;
+ virtual sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples,
+ const GrCaps&) const = 0;
/**
* Subclass analysis implementation. This should not return kNeedsDstInTexture as that will be
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp
index 551685aa50..e75a588cff 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -207,10 +207,11 @@ const GrXPFactory* GrCoverageSetOpXPFactory::Get(SkRegion::Op regionOp, bool inv
return nullptr;
}
-sk_sp<GrXferProcessor> GrCoverageSetOpXPFactory::makeXferProcessor(const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const GrCaps& caps) const {
+sk_sp<const GrXferProcessor> GrCoverageSetOpXPFactory::makeXferProcessor(
+ const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples,
+ const GrCaps& caps) const {
// We don't support inverting coverage with mixed samples. We don't expect to ever want this in
// the future, however we could at some point make this work using an inverted coverage
// modulation table. Note that an inverted table still won't work if there are coverage procs.
diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h
index 5de068cb89..ba04a2eb4c 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.h
+++ b/src/gpu/effects/GrCoverageSetOpXP.h
@@ -30,9 +30,10 @@ public:
private:
constexpr GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
- sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage, bool hasMixedSamples,
- const GrCaps&) const override;
+ sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples,
+ const GrCaps&) const override;
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index 2cc8228ee5..970c28909e 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -213,10 +213,10 @@ public:
: fMode(mode), fHWBlendEquation(hw_blend_equation(mode)) {}
private:
- sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const GrCaps&) const override;
+ sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples,
+ const GrCaps&) const override;
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
@@ -233,10 +233,11 @@ private:
#pragma GCC diagnostic pop
#endif
-sk_sp<GrXferProcessor> CustomXPFactory::makeXferProcessor(const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage coverage,
- bool hasMixedSamples,
- const GrCaps& caps) const {
+sk_sp<const GrXferProcessor> CustomXPFactory::makeXferProcessor(
+ const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage coverage,
+ bool hasMixedSamples,
+ const GrCaps& caps) const {
SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) {
return sk_sp<GrXferProcessor>(new CustomXP(fMode, fHWBlendEquation));
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
index ca0b134e0d..14464f78e3 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -74,11 +74,12 @@ void DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const
}
///////////////////////////////////////////////////////////////////////////////
-sk_sp<GrXferProcessor> GrDisableColorXPFactory::makeXferProcessor(const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const GrCaps& caps) const {
- return sk_sp<GrXferProcessor>(new DisableColorXP);
+sk_sp<const GrXferProcessor> GrDisableColorXPFactory::makeXferProcessor(
+ const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples,
+ const GrCaps& caps) const {
+ return sk_sp<const GrXferProcessor>(new DisableColorXP);
}
GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory);
diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h
index e6ae134090..7470444a21 100644
--- a/src/gpu/effects/GrDisableColorXP.h
+++ b/src/gpu/effects/GrDisableColorXP.h
@@ -31,10 +31,10 @@ private:
AnalysisProperties::kIgnoresInputColor;
}
- sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const GrCaps&) const override;
+ sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples,
+ const GrCaps&) const override;
GR_DECLARE_XP_FACTORY_TEST;
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index e5e2c1c57f..b4d917af17 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -518,8 +518,8 @@ GrGLSLXferProcessor* ShaderPDXferProcessor::createGLSLInstance() const {
class PDLCDXferProcessor : public GrXferProcessor {
public:
- static sk_sp<GrXferProcessor> Make(SkBlendMode xfermode,
- const GrProcessorAnalysisColor& inputColor);
+ static sk_sp<const GrXferProcessor> Make(SkBlendMode mode,
+ const GrProcessorAnalysisColor& inputColor);
~PDLCDXferProcessor() override;
@@ -600,9 +600,9 @@ PDLCDXferProcessor::PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha)
this->initClassID<PDLCDXferProcessor>();
}
-sk_sp<GrXferProcessor> PDLCDXferProcessor::Make(SkBlendMode xfermode,
- const GrProcessorAnalysisColor& color) {
- if (SkBlendMode::kSrcOver != xfermode) {
+sk_sp<const GrXferProcessor> PDLCDXferProcessor::Make(SkBlendMode mode,
+ const GrProcessorAnalysisColor& color) {
+ if (SkBlendMode::kSrcOver != mode) {
return nullptr;
}
GrColor blendConstant;
@@ -696,7 +696,7 @@ const GrXPFactory* GrPorterDuffXPFactory::Get(SkBlendMode blendMode) {
}
}
-sk_sp<GrXferProcessor> GrPorterDuffXPFactory::makeXferProcessor(
+sk_sp<const GrXferProcessor> GrPorterDuffXPFactory::makeXferProcessor(
const GrProcessorAnalysisColor& color, GrProcessorAnalysisCoverage coverage,
bool hasMixedSamples, const GrCaps& caps) const {
BlendFormula blendFormula;
@@ -716,9 +716,9 @@ sk_sp<GrXferProcessor> GrPorterDuffXPFactory::makeXferProcessor(
}
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
- return sk_sp<GrXferProcessor>(new ShaderPDXferProcessor(hasMixedSamples, fBlendMode));
+ return sk_sp<const GrXferProcessor>(new ShaderPDXferProcessor(hasMixedSamples, fBlendMode));
}
- return sk_sp<GrXferProcessor>(new PorterDuffXferProcessor(blendFormula));
+ return sk_sp<const GrXferProcessor>(new PorterDuffXferProcessor(blendFormula));
}
static inline GrXPFactory::AnalysisProperties analysis_properties(
@@ -801,7 +801,7 @@ const GrXferProcessor& GrPorterDuffXPFactory::SimpleSrcOverXP() {
return gSrcOverXP;
}
-sk_sp<GrXferProcessor> GrPorterDuffXPFactory::MakeSrcOverXferProcessor(
+sk_sp<const GrXferProcessor> GrPorterDuffXPFactory::MakeSrcOverXferProcessor(
const GrProcessorAnalysisColor& color, GrProcessorAnalysisCoverage coverage,
bool hasMixedSamples, const GrCaps& caps) {
// We want to not make an xfer processor if possible. Thus for the simple case where we are not
@@ -833,7 +833,7 @@ sk_sp<GrXferProcessor> GrPorterDuffXPFactory::MakeSrcOverXferProcessor(
return sk_sp<GrXferProcessor>(new PorterDuffXferProcessor(blendFormula));
}
-sk_sp<GrXferProcessor> GrPorterDuffXPFactory::CreateNoCoverageXP(SkBlendMode blendmode) {
+sk_sp<const GrXferProcessor> GrPorterDuffXPFactory::MakeNoCoverageXP(SkBlendMode blendmode) {
BlendFormula formula = get_blend_formula(false, false, false, blendmode);
return sk_make_sp<PorterDuffXferProcessor>(formula);
}
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.h b/src/gpu/effects/GrPorterDuffXferProcessor.h
index 7ec0d58238..c5680ca294 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.h
@@ -23,12 +23,13 @@ public:
/** Because src-over is so common we special case it for performance reasons. If this returns
null then the SimpleSrcOverXP() below should be used. */
- static sk_sp<GrXferProcessor> MakeSrcOverXferProcessor(const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage,
- bool hasMixedSamples, const GrCaps&);
+ static sk_sp<const GrXferProcessor> MakeSrcOverXferProcessor(const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples,
+ const GrCaps&);
/** Returns a simple non-LCD porter duff blend XP with no optimizations or coverage. */
- static sk_sp<GrXferProcessor> CreateNoCoverageXP(SkBlendMode);
+ static sk_sp<const GrXferProcessor> MakeNoCoverageXP(SkBlendMode);
/** This XP implements non-LCD src-over using hw blend with no optimizations. It is returned
by reference because it is global and its ref-cnting methods are not thread safe. */
@@ -41,10 +42,10 @@ public:
private:
constexpr GrPorterDuffXPFactory(SkBlendMode);
- sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const GrCaps&) const override;
+ sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples,
+ const GrCaps&) const override;
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp
index 4066d28503..f4b74c7cda 100644
--- a/tests/GrPorterDuffTest.cpp
+++ b/tests/GrPorterDuffTest.cpp
@@ -79,7 +79,7 @@ public:
fCompatibleWithCoverageAsAlpha = analysis.isCompatibleWithCoverageAsAlpha();
fCanCombineOverlappedStencilAndCover = analysis.canCombineOverlappedStencilAndCover();
fIgnoresInputColor = analysis.inputColorIsIgnored();
- sk_sp<GrXferProcessor> xp(
+ sk_sp<const GrXferProcessor> xp(
GrXPFactory::MakeXferProcessor(xpf, inputColor, inputCoverage, false, caps));
TEST_ASSERT(!analysis.requiresDstTexture());
GetXPOutputTypes(xp.get(), &fPrimaryOutputType, &fSecondaryOutputType);
@@ -1006,7 +1006,8 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const
GrProcessorAnalysisCoverage coverage = GrProcessorAnalysisCoverage::kLCD;
SkASSERT(!(GrXPFactory::GetAnalysisProperties(xpf, color, coverage, caps) &
GrXPFactory::AnalysisProperties::kRequiresDstTexture));
- sk_sp<GrXferProcessor> xp(GrXPFactory::MakeXferProcessor(xpf, color, coverage, false, caps));
+ sk_sp<const GrXferProcessor> xp(
+ GrXPFactory::MakeXferProcessor(xpf, color, coverage, false, caps));
if (!xp) {
ERRORF(reporter, "Failed to create an XP with LCD coverage.");
return;
@@ -1054,7 +1055,7 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) {
for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
SkBlendMode xfermode = static_cast<SkBlendMode>(m);
const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode);
- sk_sp<GrXferProcessor> xp(
+ sk_sp<const GrXferProcessor> xp(
GrXPFactory::MakeXferProcessor(xpf, colorInput, coverageType, false, caps));
if (!xp) {
ERRORF(reporter, "Failed to create an XP without dual source blending.");