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>
diff --git a/include/gpu/GrFragmentProcessor.h b/include/gpu/GrFragmentProcessor.h
index acbc63e..00f2dbd 100644
--- a/include/gpu/GrFragmentProcessor.h
+++ b/include/gpu/GrFragmentProcessor.h
@@ -23,7 +23,7 @@
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 @@
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 5469181..d101368 100644
--- a/include/gpu/GrProcessor.h
+++ b/include/gpu/GrProcessor.h
@@ -61,7 +61,7 @@
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 @@
}
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 @@
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 @@
uint32_t fClassID;
RequiredFeatures fRequiredFeatures;
-
- typedef GrProgramElement INHERITED;
};
GR_MAKE_BITFIELD_OPS(GrProcessor::RequiredFeatures);
@@ -195,12 +191,12 @@
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 2538680..425f57a 100644
--- a/include/gpu/GrProgramElement.h
+++ b/include/gpu/GrProgramElement.h
@@ -17,15 +17,10 @@
* 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 @@
* 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 @@
delete this;
return;
} else {
- static_cast<const DERIVED*>(this)->removeRefs();
+ this->removeRefs();
}
}
this->validate();
@@ -85,7 +85,7 @@
void addPendingExecution() const {
this->validate();
if (0 == fPendingExecutions) {
- static_cast<const DERIVED*>(this)->addPendingIOs();
+ this->addPendingIOs();
}
++fPendingExecutions;
this->validate();
@@ -99,13 +99,17 @@
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 @@
// 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 d1f5931..193c320 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -50,7 +50,7 @@
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 @@
}
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 a2a332f..b08b4ba 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -131,7 +131,7 @@
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 @@
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 @@
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 76fa6c5..d078ac5 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -38,7 +38,7 @@
* 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 @@
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 9361764..a76a10b8 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -47,7 +47,7 @@
}
}
if (this->isFinalized() && this->xferProcessor()) {
- this->xferProcessor()->completedExecution();
+ this->xferProcessor()->unref();
}
}
@@ -168,12 +168,9 @@
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 072d238..a632aa6 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -43,6 +43,10 @@
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 bf5bc59..27c8a96 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -167,11 +167,11 @@
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 bfc6dd7..3aecf3e 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 @@
* 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 @@
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 @@
};
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 @@
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 551685a..e75a588 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -207,10 +207,11 @@
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 5de068c..ba04a2e 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.h
+++ b/src/gpu/effects/GrCoverageSetOpXP.h
@@ -30,9 +30,10 @@
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 2cc8228..970c289 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -213,10 +213,10 @@
: 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 @@
#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 ca0b134..14464f7 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -74,11 +74,12 @@
}
///////////////////////////////////////////////////////////////////////////////
-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 e6ae134..7470444 100644
--- a/src/gpu/effects/GrDisableColorXP.h
+++ b/src/gpu/effects/GrDisableColorXP.h
@@ -31,10 +31,10 @@
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 e5e2c1c..b4d917a 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -518,8 +518,8 @@
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 @@
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 @@
}
}
-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 @@
}
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 @@
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 @@
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 7ec0d58..c5680ca 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.h
@@ -23,12 +23,13 @@
/** 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 @@
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 4066d28..f4b74c7 100644
--- a/tests/GrPorterDuffTest.cpp
+++ b/tests/GrPorterDuffTest.cpp
@@ -79,7 +79,7 @@
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 @@
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 @@
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.");