diff options
34 files changed, 317 insertions, 303 deletions
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp index 07fc977882..bcce9dbafb 100644 --- a/gm/beziereffects.cpp +++ b/gm/beziereffects.cpp @@ -193,7 +193,7 @@ protected: canvas->drawRect(bounds, boundsPaint); GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); std::unique_ptr<GrDrawOp> op = BezierCubicOrConicTestOp::Make(gp, bounds, color, klmEqs, klmSigns[c]); @@ -326,7 +326,7 @@ protected: canvas->drawRect(bounds, boundsPaint); GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); std::unique_ptr<GrDrawOp> op = BezierCubicOrConicTestOp::Make(gp, bounds, color, klmEqs, 1.f); @@ -540,7 +540,7 @@ protected: canvas->drawRect(bounds, boundsPaint); GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); GrPathUtils::QuadUVMatrix DevToUV(pts); diff --git a/gm/bigrrectaaeffect.cpp b/gm/bigrrectaaeffect.cpp index 21e49ebbc9..d8034a4384 100644 --- a/gm/bigrrectaaeffect.cpp +++ b/gm/bigrrectaaeffect.cpp @@ -75,7 +75,7 @@ protected: canvas->drawRect(testBounds, paint); GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); SkRRect rrect = fRRect; rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap)); diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp index db0b02e6b3..5927d5d0c7 100644 --- a/gm/convexpolyeffect.cpp +++ b/gm/convexpolyeffect.cpp @@ -180,7 +180,7 @@ protected: } GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); grPaint.addCoverageFragmentProcessor(std::move(fp)); std::unique_ptr<GrDrawOp> op = PolyBoundsOp::Make(p.getBounds(), 0xff000000); @@ -220,7 +220,7 @@ protected: } GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); grPaint.addCoverageFragmentProcessor(std::move(fp)); std::unique_ptr<GrDrawOp> op = PolyBoundsOp::Make(rect, 0xff000000); diff --git a/gm/rrects.cpp b/gm/rrects.cpp index a0518018e7..33de77f11d 100644 --- a/gm/rrects.cpp +++ b/gm/rrects.cpp @@ -103,7 +103,7 @@ protected: if (kEffect_Type == fType) { #if SK_SUPPORT_GPU GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); SkRRect rrect = fRRects[curRRect]; rrect.offset(SkIntToScalar(x), SkIntToScalar(y)); diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp index 9ff694d281..f2c5fd4652 100644 --- a/gm/texturedomaineffect.cpp +++ b/gm/texturedomaineffect.cpp @@ -113,7 +113,7 @@ protected: for (int m = 0; m < GrTextureDomain::kModeCount; ++m) { GrTextureDomain::Mode mode = (GrTextureDomain::Mode) m; GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); sk_sp<GrFragmentProcessor> fp( GrTextureDomainEffect::Make(texture.get(), nullptr, textureMatrices[tm], GrTextureDomain::MakeTexelDomain(texture.get(), diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp index ab04a9d87b..103c2e41ff 100644 --- a/gm/yuvtorgbeffect.cpp +++ b/gm/yuvtorgbeffect.cpp @@ -111,7 +111,7 @@ protected: for (int i = 0; i < 6; ++i) { GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); sk_sp<GrFragmentProcessor> fp( GrYUVEffect::MakeYUVToRGB(texture[indices[i][0]].get(), texture[indices[i][1]].get(), @@ -228,7 +228,7 @@ protected: SkScalar x = kDrawPad + kTestPad; GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); sk_sp<GrFragmentProcessor> fp( GrYUVEffect::MakeYUVToRGB(texture[0].get(), texture[1].get(), texture[2].get(), sizes, static_cast<SkYUVColorSpace>(space), true)); diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h index 6cdc2de09c..6bbd66cbce 100644 --- a/include/gpu/GrPaint.h +++ b/include/gpu/GrPaint.h @@ -84,13 +84,9 @@ public: setAllowSRGBInputs(gammaCorrect); } - void setXPFactory(sk_sp<GrXPFactory> xpFactory) { - fXPFactory = std::move(xpFactory); - } + void setXPFactory(const GrXPFactory* xpFactory) { fXPFactory = xpFactory; } - void setPorterDuffXPFactory(SkBlendMode mode) { - fXPFactory = GrPorterDuffXPFactory::Make(mode); - } + void setPorterDuffXPFactory(SkBlendMode mode) { fXPFactory = GrPorterDuffXPFactory::Get(mode); } void setCoverageSetOpXPFactory(SkRegion::Op, bool invertCoverage = false); @@ -127,9 +123,7 @@ public: int numTotalFragmentProcessors() const { return this->numColorFragmentProcessors() + this->numCoverageFragmentProcessors(); } - GrXPFactory* getXPFactory() const { - return fXPFactory.get(); - } + const GrXPFactory* getXPFactory() const { return fXPFactory; } GrFragmentProcessor* getColorFragmentProcessor(int i) const { return fColorFragmentProcessors[i].get(); @@ -173,7 +167,7 @@ public: private: bool internalIsConstantBlendedColor(GrColor paintColor, GrColor* constantColor) const; - mutable sk_sp<GrXPFactory> fXPFactory; + const GrXPFactory* fXPFactory; SkSTArray<4, sk_sp<GrFragmentProcessor>> fColorFragmentProcessors; SkSTArray<2, sk_sp<GrFragmentProcessor>> fCoverageFragmentProcessors; diff --git a/include/gpu/GrProcessorUnitTest.h b/include/gpu/GrProcessorUnitTest.h index d398aae9e4..0826e3d653 100644 --- a/include/gpu/GrProcessorUnitTest.h +++ b/include/gpu/GrProcessorUnitTest.h @@ -18,6 +18,7 @@ class GrContext; class GrRenderTargetContext; struct GrProcessorTestData; class GrTexture; +class GrXPFactory; namespace GrProcessorUnitTest { @@ -65,7 +66,7 @@ struct GrProcessorTestData { class GrProcessor; class GrTexture; -template <class Processor> class GrProcessorTestFactory : SkNoncopyable { +template <class Processor> class GrProcessorTestFactory : private SkNoncopyable { public: typedef sk_sp<Processor> (*MakeProc)(GrProcessorTestData*); @@ -88,20 +89,44 @@ public: /** Use factory function at Index idx to create a processor. */ static sk_sp<Processor> MakeIdx(int idx, GrProcessorTestData* data) { GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx]; - return factory->fMakeProc(data); + sk_sp<Processor> processor = factory->fMakeProc(data); + SkASSERT(processor); + return processor; } - /* +private: + /** * A test function which verifies the count of factories. */ static void VerifyFactoryCount(); -private: MakeProc fMakeProc; static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories(); }; +class GrXPFactoryTestFactory : private SkNoncopyable { +public: + using GetFn = const GrXPFactory*(GrProcessorTestData*); + + GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); } + + static const GrXPFactory* Get(GrProcessorTestData* data) { + VerifyFactoryCount(); + SkASSERT(GetFactories()->count()); + uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1); + const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data); + SkASSERT(xpf); + return xpf; + } + +private: + static void VerifyFactoryCount(); + + GetFn* fGetProc; + static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories(); +}; + /** GrProcessor subclasses should insert this macro in their declaration to be included in the * program generation unit test. */ @@ -114,21 +139,21 @@ private: static sk_sp<GrFragmentProcessor> TestCreate(GrProcessorTestData*) #define GR_DECLARE_XP_FACTORY_TEST \ - static GrProcessorTestFactory<GrXPFactory> gTestFactory SK_UNUSED; \ - static sk_sp<GrXPFactory> TestCreate(GrProcessorTestData*) + static GrXPFactoryTestFactory gTestFactory SK_UNUSED; \ + static const GrXPFactory* TestGet(GrProcessorTestData*) /** GrProcessor subclasses should insert this macro in their implementation file. They must then * also implement this static function: * GrProcessor* TestCreate(GrProcessorTestData*); */ #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \ - GrProcessorTestFactory<GrFragmentProcessor> Effect :: gTestFactory(Effect :: TestCreate) - -#define GR_DEFINE_XP_FACTORY_TEST(Factory) \ - GrProcessorTestFactory<GrXPFactory> Factory :: gTestFactory(Factory :: TestCreate) + GrProcessorTestFactory<GrFragmentProcessor> Effect::gTestFactory(Effect::TestCreate) #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \ - GrProcessorTestFactory<GrGeometryProcessor> Effect :: gTestFactory(Effect :: TestCreate) + GrProcessorTestFactory<GrGeometryProcessor> Effect::gTestFactory(Effect::TestCreate) + +#define GR_DEFINE_XP_FACTORY_TEST(Factory) \ + GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet) #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS @@ -140,15 +165,15 @@ private: // The unit test relies on static initializers. Just declare the TestCreate function so that // its definitions will compile. -#define GR_DECLARE_XP_FACTORY_TEST \ - static sk_sp<GrXPFactory> TestCreate(GrProcessorTestData*) -#define GR_DEFINE_XP_FACTORY_TEST(X) - -// The unit test relies on static initializers. Just declare the TestCreate function so that -// its definitions will compile. #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \ static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*) #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X) +// The unit test relies on static initializers. Just declare the TestGet function so that +// its definitions will compile. +#define GR_DECLARE_XP_FACTORY_TEST \ + const GrXPFactory* TestGet(GrProcessorTestData*) +#define GR_DEFINE_XP_FACTORY_TEST(X) + #endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS #endif diff --git a/include/gpu/GrXferProcessor.h b/include/gpu/GrXferProcessor.h index e97c0b92c7..17cd2c7bf3 100644 --- a/include/gpu/GrXferProcessor.h +++ b/include/gpu/GrXferProcessor.h @@ -289,8 +289,22 @@ GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags); * Before the XP is created, the XPF is able to answer queries about what functionality the XPs it * creates will have. For example, can it create an XP that supports RGB coverage or will the XP * blend with the destination color. + * + * GrXPFactories are intended to be static immutable objects. We pass them around as raw pointers + * and expect the pointers to always be valid and for the factories to be reusable and thread safe. + * Equality is tested for using pointer comparison. GrXPFactory destructors must be no-ops. */ -class GrXPFactory : public SkRefCnt { + +// In order to construct GrXPFactory subclass instances as constexpr the subclass, and therefore +// GrXPFactory, must be a literal type. One requirement is having a trivial destructor. This is ok +// since these objects have no need for destructors. However, GCC and clang throw a warning when a +// class has virtual functions and a non-virtual destructor. We suppress that warning here and +// for the subclasses. +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif +class GrXPFactory { public: typedef GrXferProcessor::DstTexture DstTexture; GrXferProcessor* createXferProcessor(const GrPipelineAnalysis&, @@ -317,29 +331,8 @@ public: bool willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis&) const; - bool isEqual(const GrXPFactory& that) const { - if (this->classID() != that.classID()) { - return false; - } - return this->onIsEqual(that); - } - - /** - * Helper for down-casting to a GrXPFactory subclass - */ - template <typename T> const T& cast() const { return *static_cast<const T*>(this); } - - uint32_t classID() const { SkASSERT(kIllegalXPFClassID != fClassID); return fClassID; } - protected: - GrXPFactory() : fClassID(kIllegalXPFClassID) {} - - template <typename XPF_SUBCLASS> void initClassID() { - static uint32_t kClassID = GenClassID(); - fClassID = kClassID; - } - - uint32_t fClassID; + constexpr GrXPFactory() {} private: virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, @@ -347,34 +340,17 @@ private: bool hasMixedSamples, const DstTexture*) const = 0; - virtual bool onIsEqual(const GrXPFactory&) const = 0; - bool willReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const; + /** * Returns true if the XP generated by this factory will explicitly read dst in the fragment * shader. */ virtual bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const = 0; - - static uint32_t GenClassID() { - // fCurrXPFactoryID has been initialized to kIllegalXPFactoryID. The - // atomic inc returns the old value not the incremented value. So we add - // 1 to the returned value. - uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&gCurrXPFClassID)) + 1; - if (!id) { - SkFAIL("This should never wrap as it should only be called once for each GrXPFactory " - "subclass."); - } - return id; - } - - enum { - kIllegalXPFClassID = 0, - }; - static int32_t gCurrXPFClassID; - - typedef GrProgramElement INHERITED; }; +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic pop +#endif #endif diff --git a/include/gpu/effects/GrCoverageSetOpXP.h b/include/gpu/effects/GrCoverageSetOpXP.h index 2aae7be41d..ca71abc4e0 100644 --- a/include/gpu/effects/GrCoverageSetOpXP.h +++ b/include/gpu/effects/GrCoverageSetOpXP.h @@ -14,6 +14,12 @@ class GrProcOptInfo; +// See the comment above GrXPFactory's definition about this warning suppression. +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif + /** * This xfer processor directly blends the the src coverage with the dst using a set operator. It is * useful for rendering coverage masks using CSG. It can optionally invert the src coverage before @@ -21,13 +27,13 @@ class GrProcOptInfo; */ class GrCoverageSetOpXPFactory : public GrXPFactory { public: - static sk_sp<GrXPFactory> Make(SkRegion::Op regionOp, bool invertCoverage = false); + static const GrXPFactory* Get(SkRegion::Op regionOp, bool invertCoverage = false); void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, GrXPFactory::InvariantBlendedColor*) const override; private: - GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage); + constexpr GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage); GrXferProcessor* onCreateXferProcessor(const GrCaps&, const GrPipelineAnalysis&, @@ -38,11 +44,6 @@ private: return false; } - bool onIsEqual(const GrXPFactory& xpfBase) const override { - const GrCoverageSetOpXPFactory& xpf = xpfBase.cast<GrCoverageSetOpXPFactory>(); - return fRegionOp == xpf.fRegionOp; - } - GR_DECLARE_XP_FACTORY_TEST; SkRegion::Op fRegionOp; @@ -50,5 +51,8 @@ private: typedef GrXPFactory INHERITED; }; +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic pop +#endif #endif diff --git a/include/gpu/effects/GrCustomXfermode.h b/include/gpu/effects/GrCustomXfermode.h index a8c868e034..54309ddafc 100644 --- a/include/gpu/effects/GrCustomXfermode.h +++ b/include/gpu/effects/GrCustomXfermode.h @@ -20,7 +20,7 @@ class GrXPFactory; */ namespace GrCustomXfermode { bool IsSupportedMode(SkBlendMode mode); - sk_sp<GrXPFactory> MakeXPFactory(SkBlendMode mode); + const GrXPFactory* Get(SkBlendMode mode); }; #endif diff --git a/include/gpu/effects/GrPorterDuffXferProcessor.h b/include/gpu/effects/GrPorterDuffXferProcessor.h index 29d56ab29a..ca14275926 100644 --- a/include/gpu/effects/GrPorterDuffXferProcessor.h +++ b/include/gpu/effects/GrPorterDuffXferProcessor.h @@ -14,9 +14,14 @@ class GrProcOptInfo; +// See the comment above GrXPFactory's definition about this warning suppression. +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif class GrPorterDuffXPFactory : public GrXPFactory { public: - static sk_sp<GrXPFactory> Make(SkBlendMode mode); + static const GrXPFactory* Get(SkBlendMode blendMode); void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, GrXPFactory::InvariantBlendedColor*) const override; @@ -51,7 +56,7 @@ public: static bool SrcOverWillNeedDstTexture(const GrCaps&, const GrPipelineAnalysis&); private: - GrPorterDuffXPFactory(SkBlendMode); + constexpr GrPorterDuffXPFactory(SkBlendMode); GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysis&, @@ -60,18 +65,16 @@ private: bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override; - bool onIsEqual(const GrXPFactory& xpfBase) const override { - const GrPorterDuffXPFactory& xpf = xpfBase.cast<GrPorterDuffXPFactory>(); - return fXfermode == xpf.fXfermode; - } - GR_DECLARE_XP_FACTORY_TEST; static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary); - SkBlendMode fXfermode; + SkBlendMode fBlendMode; friend class GrPorterDuffTest; // for TestGetXPOutputTypes() typedef GrXPFactory INHERITED; }; +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic pop +#endif #endif diff --git a/src/core/SkBlendModePriv.h b/src/core/SkBlendModePriv.h index 29df639842..0d0589c29c 100644 --- a/src/core/SkBlendModePriv.h +++ b/src/core/SkBlendModePriv.h @@ -17,7 +17,7 @@ bool SkBlendMode_AppendStages(SkBlendMode, SkRasterPipeline* = nullptr); #if SK_SUPPORT_GPU #include "GrXferProcessor.h" -sk_sp<GrXPFactory> SkBlendMode_AsXPFactory(SkBlendMode); +const GrXPFactory* SkBlendMode_AsXPFactory(SkBlendMode); #endif diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 9c1ae4495d..6f470f6dbe 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -1001,7 +1001,7 @@ sk_sp<GrFragmentProcessor> SkXfermode::makeFragmentProcessorForImageFilter( return nullptr; } -sk_sp<GrXPFactory> SkXfermode::asXPFactory() const { +const GrXPFactory* SkXfermode::asXPFactory() const { // This should never be called. // TODO: make pure virtual in SkXfermode once Android update lands SkASSERT(0); @@ -1254,15 +1254,15 @@ sk_sp<GrFragmentProcessor> SkProcCoeffXfermode::makeFragmentProcessorForImageFil return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(dst), fMode); } -sk_sp<GrXPFactory> SkProcCoeffXfermode::asXPFactory() const { +const GrXPFactory* SkProcCoeffXfermode::asXPFactory() const { if (CANNOT_USE_COEFF != fSrcCoeff) { - sk_sp<GrXPFactory> result(GrPorterDuffXPFactory::Make(fMode)); + const GrXPFactory* result(GrPorterDuffXPFactory::Get(fMode)); SkASSERT(result); return result; } SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); - return GrCustomXfermode::MakeXPFactory(fMode); + return GrCustomXfermode::Get(fMode); } #endif @@ -1469,16 +1469,16 @@ bool SkXfermode::IsOpaque(SkBlendMode mode, SrcColorOpacity opacityType) { } #if SK_SUPPORT_GPU -sk_sp<GrXPFactory> SkBlendMode_AsXPFactory(SkBlendMode mode) { +const GrXPFactory* SkBlendMode_AsXPFactory(SkBlendMode mode) { const ProcCoeff rec = gProcCoeffs[(int)mode]; if (CANNOT_USE_COEFF != rec.fSC) { - sk_sp<GrXPFactory> result(GrPorterDuffXPFactory::Make(mode)); + const GrXPFactory* result = GrPorterDuffXPFactory::Get(mode); SkASSERT(result); return result; } SkASSERT(GrCustomXfermode::IsSupportedMode(mode)); - return GrCustomXfermode::MakeXPFactory(mode); + return GrCustomXfermode::Get(mode); } #endif diff --git a/src/core/SkXfermodePriv.h b/src/core/SkXfermodePriv.h index 208925ed18..2fae2c0ed0 100644 --- a/src/core/SkXfermodePriv.h +++ b/src/core/SkXfermodePriv.h @@ -246,7 +246,7 @@ public: The xfermode will return a factory for which the caller will get a ref. It is up to the caller to install it. XferProcessors cannot use a background texture. */ - virtual sk_sp<GrXPFactory> asXPFactory() const; + virtual const GrXPFactory* asXPFactory() const; #endif SK_TO_STRING_PUREVIRT() diff --git a/src/core/SkXfermode_proccoeff.h b/src/core/SkXfermode_proccoeff.h index 8a7b62f0a2..372453218a 100644 --- a/src/core/SkXfermode_proccoeff.h +++ b/src/core/SkXfermode_proccoeff.h @@ -46,7 +46,7 @@ public: #if SK_SUPPORT_GPU sk_sp<GrFragmentProcessor> makeFragmentProcessorForImageFilter( sk_sp<GrFragmentProcessor>) const override; - sk_sp<GrXPFactory> asXPFactory() const override; + const GrXPFactory* asXPFactory() const override; #endif SK_TO_STRING_OVERRIDE() diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp index 3eaf3cc49f..c85d5c378d 100644 --- a/src/effects/SkArithmeticMode.cpp +++ b/src/effects/SkArithmeticMode.cpp @@ -36,7 +36,7 @@ public: #if SK_SUPPORT_GPU sk_sp<GrFragmentProcessor> makeFragmentProcessorForImageFilter( sk_sp<GrFragmentProcessor> dst) const override; - sk_sp<GrXPFactory> asXPFactory() const override { + const GrXPFactory* asXPFactory() const override { SkFAIL("This should only be used as a FP."); return nullptr; } diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp index 0954505b80..8d9347b3bf 100644 --- a/src/gpu/GrPaint.cpp +++ b/src/gpu/GrPaint.cpp @@ -13,13 +13,14 @@ #include "effects/GrSimpleTextureEffect.h" GrPaint::GrPaint() - : fDisableOutputConversionToSRGB(false) - , fAllowSRGBInputs(false) - , fUsesDistanceVectorField(false) - , fColor(GrColor4f::OpaqueWhite()) {} + : fXPFactory(nullptr) + , fDisableOutputConversionToSRGB(false) + , fAllowSRGBInputs(false) + , fUsesDistanceVectorField(false) + , fColor(GrColor4f::OpaqueWhite()) {} void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) { - fXPFactory = GrCoverageSetOpXPFactory::Make(regionOp, invertCoverage); + fXPFactory = GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage); } void GrPaint::addColorTextureProcessor(GrTexture* texture, diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp index bd433fc72a..5741471398 100644 --- a/src/gpu/GrPipelineBuilder.cpp +++ b/src/gpu/GrPipelineBuilder.cpp @@ -29,7 +29,7 @@ GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrAAType aaType) fCoverageFragmentProcessors.emplace_back(SkRef(paint.getCoverageFragmentProcessor(i))); } - fXPFactory.reset(SkSafeRef(paint.getXPFactory())); + fXPFactory = paint.getXPFactory(); this->setState(GrPipelineBuilder::kHWAntialias_Flag, GrAATypeIsHW(aaType)); this->setState(GrPipelineBuilder::kDisableOutputConversionToSRGB_Flag, diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index 1bc9002c70..0d039f9040 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -145,21 +145,15 @@ public: * Installs a GrXPFactory. This object controls how src color, fractional pixel coverage, * and the dst color are blended. */ - void setXPFactory(sk_sp<GrXPFactory> xpFactory) { - fXPFactory = std::move(xpFactory); - } + void setXPFactory(const GrXPFactory* xpFactory) { fXPFactory = xpFactory; } /** * Sets a GrXPFactory that disables color writes to the destination. This is useful when * rendering to the stencil buffer. */ - void setDisableColorXPFactory() { - fXPFactory = GrDisableColorXPFactory::Make(); - } + void setDisableColorXPFactory() { fXPFactory = GrDisableColorXPFactory::Get(); } - const GrXPFactory* getXPFactory() const { - return fXPFactory.get(); - } + const GrXPFactory* getXPFactory() const { return fXPFactory; } /** * Checks whether the xp will need destination in a texture to correctly blend. @@ -304,7 +298,7 @@ private: uint32_t fFlags; const GrUserStencilSettings* fUserStencilSettings; GrDrawFace fDrawFace; - mutable sk_sp<GrXPFactory> fXPFactory; + const GrXPFactory* fXPFactory; FragmentProcessorArray fColorFragmentProcessors; FragmentProcessorArray fCoverageFragmentProcessors; diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index 991aa90453..0512aa85fe 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -32,19 +32,17 @@ GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() { } template<> -SkTArray<GrProcessorTestFactory<GrXPFactory>*, true>* -GrProcessorTestFactory<GrXPFactory>::GetFactories() { - static SkTArray<GrProcessorTestFactory<GrXPFactory>*, true> gFactories; - return &gFactories; -} - -template<> SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>* GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() { static SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true> gFactories; return &gFactories; } +SkTArray<GrXPFactoryTestFactory*, true>* GrXPFactoryTestFactory::GetFactories() { + static SkTArray<GrXPFactoryTestFactory*, true> gFactories; + return &gFactories; +} + /* * To ensure we always have successful static initialization, before creating from the factories * we verify the count is as expected. If a new factory is added, then these numbers must be @@ -72,8 +70,7 @@ void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() { } } -template<> -void GrProcessorTestFactory<GrXPFactory>::VerifyFactoryCount() { +void GrXPFactoryTestFactory::VerifyFactoryCount() { if (kXPFactoryCount != GetFactories()->count()) { SkDebugf("\nExpected %d xp factory factories, found %d.\n", kXPFactoryCount, GetFactories()->count()); @@ -229,8 +226,3 @@ GrProcessor::ImageStorageAccess::ImageStorageAccess(sk_sp<GrTexture> texture, Gr break; } } - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -// Initial static variable from GrXPFactory -int32_t GrXPFactory::gCurrXPFClassID = GrXPFactory::kIllegalXPFClassID; diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp index 9802f87755..9f3b225c00 100644 --- a/src/gpu/GrReducedClip.cpp +++ b/src/gpu/GrReducedClip.cpp @@ -780,7 +780,7 @@ bool GrReducedClip::drawStencilClipMask(GrContext* context, GrShape shape(clipPath, GrStyle::SimpleFill()); if (canRenderDirectToStencil) { GrPaint paint; - paint.setXPFactory(GrDisableColorXPFactory::Make()); + paint.setXPFactory(GrDisableColorXPFactory::Get()); GrPathRenderer::DrawPathArgs args; args.fResourceProvider = context->resourceProvider(); @@ -817,7 +817,7 @@ bool GrReducedClip::drawStencilClipMask(GrContext* context, } else { GrShape shape(clipPath, GrStyle::SimpleFill()); GrPaint paint; - paint.setXPFactory(GrDisableColorXPFactory::Make()); + paint.setXPFactory(GrDisableColorXPFactory::Get()); GrPathRenderer::DrawPathArgs args; args.fResourceProvider = context->resourceProvider(); args.fPaint = &paint; diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index e9325fafec..5e14f6bc61 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -268,7 +268,7 @@ void GrRenderTargetContextPriv::absClear(const SkIRect* clearRect, const GrColor // target before the target is read. GrPaint paint; paint.setColor4f(GrColor4f::FromGrColor(color)); - paint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); // We don't call drawRect() here to avoid the cropping to the, possibly smaller, // RenderTargetProxy bounds @@ -329,7 +329,7 @@ void GrRenderTargetContext::internalClear(const GrFixedClip& clip, GrPaint paint; paint.setColor4f(GrColor4f::FromGrColor(color)); - paint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); this->drawRect(clip, paint, GrAA::kNo, SkMatrix::I(), SkRect::Make(clearRect)); } else if (isFull) { @@ -675,7 +675,7 @@ void GrRenderTargetContextPriv::stencilRect(const GrClip& clip, AutoCheckFlush acf(fRenderTargetContext->fDrawingManager); GrPaint paint; - paint.setXPFactory(GrDisableColorXPFactory::Make()); + paint.setXPFactory(GrDisableColorXPFactory::Get()); fRenderTargetContext->drawNonAAFilledRect(clip, paint, viewMatrix, rect, nullptr, nullptr, ss, aaType); diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp index 73adc49d96..5fbd046453 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.cpp +++ b/src/gpu/effects/GrCoverageSetOpXP.cpp @@ -236,77 +236,79 @@ GrGLSLXferProcessor* ShaderCSOXferProcessor::createGLSLInstance() const { /////////////////////////////////////////////////////////////////////////////// // -GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) - : fRegionOp(regionOp) - , fInvertCoverage(invertCoverage) { - this->initClassID<GrCoverageSetOpXPFactory>(); -} +constexpr GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp, + bool invertCoverage) + : fRegionOp(regionOp), fInvertCoverage(invertCoverage) {} -sk_sp<GrXPFactory> GrCoverageSetOpXPFactory::Make(SkRegion::Op regionOp, bool invertCoverage) { +const GrXPFactory* GrCoverageSetOpXPFactory::Get(SkRegion::Op regionOp, bool invertCoverage) { switch (regionOp) { case SkRegion::kReplace_Op: { if (invertCoverage) { - static GrCoverageSetOpXPFactory gReplaceCDXPFI(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gReplaceCDXPFI)); + static constexpr const GrCoverageSetOpXPFactory gReplaceCDXPFI( + SkRegion::kReplace_Op, true); + return &gReplaceCDXPFI; } else { - static GrCoverageSetOpXPFactory gReplaceCDXPF(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gReplaceCDXPF)); + static constexpr const GrCoverageSetOpXPFactory gReplaceCDXPF(SkRegion::kReplace_Op, + false); + return &gReplaceCDXPF; } - break; } case SkRegion::kIntersect_Op: { if (invertCoverage) { - static GrCoverageSetOpXPFactory gIntersectCDXPFI(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gIntersectCDXPFI)); + static constexpr const GrCoverageSetOpXPFactory gIntersectCDXPFI( + SkRegion::kIntersect_Op, true); + return &gIntersectCDXPFI; } else { - static GrCoverageSetOpXPFactory gIntersectCDXPF(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gIntersectCDXPF)); + static constexpr const GrCoverageSetOpXPFactory gIntersectCDXPF( + SkRegion::kIntersect_Op, false); + return &gIntersectCDXPF; } - break; } case SkRegion::kUnion_Op: { if (invertCoverage) { - static GrCoverageSetOpXPFactory gUnionCDXPFI(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gUnionCDXPFI)); + static constexpr const GrCoverageSetOpXPFactory gUnionCDXPFI(SkRegion::kUnion_Op, + true); + return &gUnionCDXPFI; } else { - static GrCoverageSetOpXPFactory gUnionCDXPF(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gUnionCDXPF)); + static constexpr const GrCoverageSetOpXPFactory gUnionCDXPF(SkRegion::kUnion_Op, + false); + return &gUnionCDXPF; } - break; } case SkRegion::kXOR_Op: { if (invertCoverage) { - static GrCoverageSetOpXPFactory gXORCDXPFI(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gXORCDXPFI)); + static constexpr const GrCoverageSetOpXPFactory gXORCDXPFI(SkRegion::kXOR_Op, true); + return &gXORCDXPFI; } else { - static GrCoverageSetOpXPFactory gXORCDXPF(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gXORCDXPF)); + static constexpr const GrCoverageSetOpXPFactory gXORCDXPF(SkRegion::kXOR_Op, false); + return &gXORCDXPF; } - break; } case SkRegion::kDifference_Op: { if (invertCoverage) { - static GrCoverageSetOpXPFactory gDifferenceCDXPFI(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gDifferenceCDXPFI)); + static constexpr const GrCoverageSetOpXPFactory gDifferenceCDXPFI( + SkRegion::kDifference_Op, true); + return &gDifferenceCDXPFI; } else { - static GrCoverageSetOpXPFactory gDifferenceCDXPF(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gDifferenceCDXPF)); + static constexpr const GrCoverageSetOpXPFactory gDifferenceCDXPF( + SkRegion::kDifference_Op, false); + return &gDifferenceCDXPF; } - break; } case SkRegion::kReverseDifference_Op: { if (invertCoverage) { - static GrCoverageSetOpXPFactory gRevDiffCDXPFI(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gRevDiffCDXPFI)); + static constexpr const GrCoverageSetOpXPFactory gRevDiffCDXPFI( + SkRegion::kReverseDifference_Op, true); + return &gRevDiffCDXPFI; } else { - static GrCoverageSetOpXPFactory gRevDiffCDXPF(regionOp, invertCoverage); - return sk_sp<GrXPFactory>(SkRef(&gRevDiffCDXPF)); + static constexpr const GrCoverageSetOpXPFactory gRevDiffCDXPF( + SkRegion::kReverseDifference_Op, false); + return &gRevDiffCDXPF; } - break; } - default: - return nullptr; } + SkFAIL("Unknown region op."); + return nullptr; } GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps, @@ -335,8 +337,8 @@ void GrCoverageSetOpXPFactory::getInvariantBlendedColor(const GrProcOptInfo& col GR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory); -sk_sp<GrXPFactory> GrCoverageSetOpXPFactory::TestCreate(GrProcessorTestData* d) { +const GrXPFactory* GrCoverageSetOpXPFactory::TestGet(GrProcessorTestData* d) { SkRegion::Op regionOp = SkRegion::Op(d->fRandom->nextULessThan(SkRegion::kLastOp + 1)); bool invertCoverage = !d->fRenderTargetContext->hasMixedSamples() && d->fRandom->nextBool(); - return GrCoverageSetOpXPFactory::Make(regionOp, invertCoverage); + return GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage); } diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index 239c3043cd..8d1c5e8d5f 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -31,25 +31,26 @@ bool GrCustomXfermode::IsSupportedMode(SkBlendMode mode) { // Static helpers /////////////////////////////////////////////////////////////////////////////// -static GrBlendEquation hw_blend_equation(SkBlendMode mode) { - enum { kOffset = kOverlay_GrBlendEquation - (int)SkBlendMode::kOverlay }; - return static_cast<GrBlendEquation>((int)mode + kOffset); - - GR_STATIC_ASSERT(kOverlay_GrBlendEquation == (int)SkBlendMode::kOverlay + kOffset); - GR_STATIC_ASSERT(kDarken_GrBlendEquation == (int)SkBlendMode::kDarken + kOffset); - GR_STATIC_ASSERT(kLighten_GrBlendEquation == (int)SkBlendMode::kLighten + kOffset); - GR_STATIC_ASSERT(kColorDodge_GrBlendEquation == (int)SkBlendMode::kColorDodge + kOffset); - GR_STATIC_ASSERT(kColorBurn_GrBlendEquation == (int)SkBlendMode::kColorBurn + kOffset); - GR_STATIC_ASSERT(kHardLight_GrBlendEquation == (int)SkBlendMode::kHardLight + kOffset); - GR_STATIC_ASSERT(kSoftLight_GrBlendEquation == (int)SkBlendMode::kSoftLight + kOffset); - GR_STATIC_ASSERT(kDifference_GrBlendEquation == (int)SkBlendMode::kDifference + kOffset); - GR_STATIC_ASSERT(kExclusion_GrBlendEquation == (int)SkBlendMode::kExclusion + kOffset); - GR_STATIC_ASSERT(kMultiply_GrBlendEquation == (int)SkBlendMode::kMultiply + kOffset); - GR_STATIC_ASSERT(kHSLHue_GrBlendEquation == (int)SkBlendMode::kHue + kOffset); - GR_STATIC_ASSERT(kHSLSaturation_GrBlendEquation == (int)SkBlendMode::kSaturation + kOffset); - GR_STATIC_ASSERT(kHSLColor_GrBlendEquation == (int)SkBlendMode::kColor + kOffset); - GR_STATIC_ASSERT(kHSLLuminosity_GrBlendEquation == (int)SkBlendMode::kLuminosity + kOffset); - GR_STATIC_ASSERT(kGrBlendEquationCnt == (int)SkBlendMode::kLastMode + 1 + kOffset); +static constexpr GrBlendEquation hw_blend_equation(SkBlendMode mode) { +// In C++14 this could be a constexpr int variable. +#define EQ_OFFSET (kOverlay_GrBlendEquation - (int)SkBlendMode::kOverlay) + GR_STATIC_ASSERT(kOverlay_GrBlendEquation == (int)SkBlendMode::kOverlay + EQ_OFFSET); + GR_STATIC_ASSERT(kDarken_GrBlendEquation == (int)SkBlendMode::kDarken + EQ_OFFSET); + GR_STATIC_ASSERT(kLighten_GrBlendEquation == (int)SkBlendMode::kLighten + EQ_OFFSET); + GR_STATIC_ASSERT(kColorDodge_GrBlendEquation == (int)SkBlendMode::kColorDodge + EQ_OFFSET); + GR_STATIC_ASSERT(kColorBurn_GrBlendEquation == (int)SkBlendMode::kColorBurn + EQ_OFFSET); + GR_STATIC_ASSERT(kHardLight_GrBlendEquation == (int)SkBlendMode::kHardLight + EQ_OFFSET); + GR_STATIC_ASSERT(kSoftLight_GrBlendEquation == (int)SkBlendMode::kSoftLight + EQ_OFFSET); + GR_STATIC_ASSERT(kDifference_GrBlendEquation == (int)SkBlendMode::kDifference + EQ_OFFSET); + GR_STATIC_ASSERT(kExclusion_GrBlendEquation == (int)SkBlendMode::kExclusion + EQ_OFFSET); + GR_STATIC_ASSERT(kMultiply_GrBlendEquation == (int)SkBlendMode::kMultiply + EQ_OFFSET); + GR_STATIC_ASSERT(kHSLHue_GrBlendEquation == (int)SkBlendMode::kHue + EQ_OFFSET); + GR_STATIC_ASSERT(kHSLSaturation_GrBlendEquation == (int)SkBlendMode::kSaturation + EQ_OFFSET); + GR_STATIC_ASSERT(kHSLColor_GrBlendEquation == (int)SkBlendMode::kColor + EQ_OFFSET); + GR_STATIC_ASSERT(kHSLLuminosity_GrBlendEquation == (int)SkBlendMode::kLuminosity + EQ_OFFSET); + GR_STATIC_ASSERT(kGrBlendEquationCnt == (int)SkBlendMode::kLastMode + 1 + EQ_OFFSET); + return static_cast<GrBlendEquation>((int)mode + EQ_OFFSET); +#undef EQ_OFFSET } static bool can_use_hw_blend_equation(GrBlendEquation equation, @@ -319,9 +320,16 @@ void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const { } /////////////////////////////////////////////////////////////////////////////// + +// See the comment above GrXPFactory's definition about this warning suppression. +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif class CustomXPFactory : public GrXPFactory { public: - CustomXPFactory(SkBlendMode mode); + constexpr CustomXPFactory(SkBlendMode mode) + : fMode(mode), fHWBlendEquation(hw_blend_equation(mode)) {} void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, GrXPFactory::InvariantBlendedColor*) const override; @@ -334,10 +342,6 @@ private: bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override; - bool onIsEqual(const GrXPFactory& xpfBase) const override { - const CustomXPFactory& xpf = xpfBase.cast<CustomXPFactory>(); - return fMode == xpf.fMode; - } GR_DECLARE_XP_FACTORY_TEST; @@ -346,18 +350,15 @@ private: typedef GrXPFactory INHERITED; }; - -CustomXPFactory::CustomXPFactory(SkBlendMode mode) - : fMode(mode), - fHWBlendEquation(hw_blend_equation(mode)) { - SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); - this->initClassID<CustomXPFactory>(); -} +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic pop +#endif GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysis& analysis, bool hasMixedSamples, const DstTexture* dstTexture) const { + SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); if (can_use_hw_blend_equation(fHWBlendEquation, analysis, caps)) { SkASSERT(!dstTexture || !dstTexture->texture()); return new CustomXP(fMode, fHWBlendEquation); @@ -377,16 +378,16 @@ void CustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, } GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory); -sk_sp<GrXPFactory> CustomXPFactory::TestCreate(GrProcessorTestData* d) { +const GrXPFactory* CustomXPFactory::TestGet(GrProcessorTestData* d) { int mode = d->fRandom->nextRangeU((int)SkBlendMode::kLastCoeffMode + 1, (int)SkBlendMode::kLastSeparableMode); - return sk_sp<GrXPFactory>(new CustomXPFactory(static_cast<SkBlendMode>(mode))); + return GrCustomXfermode::Get((SkBlendMode)mode); } /////////////////////////////////////////////////////////////////////////////// -sk_sp<GrXPFactory> GrCustomXfermode::MakeXPFactory(SkBlendMode mode) { +const GrXPFactory* GrCustomXfermode::Get(SkBlendMode mode) { static CustomXPFactory gOverlay(SkBlendMode::kOverlay); static CustomXPFactory gDarken(SkBlendMode::kDarken); static CustomXPFactory gLighten(SkBlendMode::kLighten); @@ -403,33 +404,33 @@ sk_sp<GrXPFactory> GrCustomXfermode::MakeXPFactory(SkBlendMode mode) { static CustomXPFactory gLuminosity(SkBlendMode::kLuminosity); switch (mode) { case SkBlendMode::kOverlay: - return sk_sp<GrXPFactory>(SkRef(&gOverlay)); + return &gOverlay; case SkBlendMode::kDarken: - return sk_sp<GrXPFactory>(SkRef(&gDarken)); + return &gDarken; case SkBlendMode::kLighten: - return sk_sp<GrXPFactory>(SkRef(&gLighten)); + return &gLighten; case SkBlendMode::kColorDodge: - return sk_sp<GrXPFactory>(SkRef(&gColorDodge)); + return &gColorDodge; case SkBlendMode::kColorBurn: - return sk_sp<GrXPFactory>(SkRef(&gColorBurn)); + return &gColorBurn; case SkBlendMode::kHardLight: - return sk_sp<GrXPFactory>(SkRef(&gHardLight)); + return &gHardLight; case SkBlendMode::kSoftLight: - return sk_sp<GrXPFactory>(SkRef(&gSoftLight)); + return &gSoftLight; case SkBlendMode::kDifference: - return sk_sp<GrXPFactory>(SkRef(&gDifference)); + return &gDifference; case SkBlendMode::kExclusion: - return sk_sp<GrXPFactory>(SkRef(&gExclusion)); + return &gExclusion; case SkBlendMode::kMultiply: - return sk_sp<GrXPFactory>(SkRef(&gMultiply)); + return &gMultiply; case SkBlendMode::kHue: - return sk_sp<GrXPFactory>(SkRef(&gHue)); + return &gHue; case SkBlendMode::kSaturation: - return sk_sp<GrXPFactory>(SkRef(&gSaturation)); + return &gSaturation; case SkBlendMode::kColor: - return sk_sp<GrXPFactory>(SkRef(&gColor)); + return &gColor; case SkBlendMode::kLuminosity: - return sk_sp<GrXPFactory>(SkRef(&gLuminosity)); + return &gLuminosity; default: SkASSERT(!GrCustomXfermode::IsSupportedMode(mode)); return nullptr; diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp index 0182acc8a6..69c34ecc66 100644 --- a/src/gpu/effects/GrDisableColorXP.cpp +++ b/src/gpu/effects/GrDisableColorXP.cpp @@ -88,11 +88,6 @@ void DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const } /////////////////////////////////////////////////////////////////////////////// - -GrDisableColorXPFactory::GrDisableColorXPFactory() { - this->initClassID<GrDisableColorXPFactory>(); -} - GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysis& analysis, bool hasMixedSamples, @@ -103,6 +98,6 @@ GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& ca GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory); -sk_sp<GrXPFactory> GrDisableColorXPFactory::TestCreate(GrProcessorTestData*) { - return GrDisableColorXPFactory::Make(); +const GrXPFactory* GrDisableColorXPFactory::TestGet(GrProcessorTestData*) { + return GrDisableColorXPFactory::Get(); } diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h index 49e245949a..38624e05f2 100644 --- a/src/gpu/effects/GrDisableColorXP.h +++ b/src/gpu/effects/GrDisableColorXP.h @@ -14,12 +14,14 @@ class GrProcOptInfo; +// See the comment above GrXPFactory's definition about this warning suppression. +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif class GrDisableColorXPFactory : public GrXPFactory { public: - static sk_sp<GrXPFactory> Make() { - static GrDisableColorXPFactory gDisableColorXPFactory; - return sk_sp<GrXPFactory>(SkRef(&gDisableColorXPFactory)); - } + static const GrXPFactory* Get(); void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, GrXPFactory::InvariantBlendedColor* blendedColor) const override { @@ -28,7 +30,7 @@ public: } private: - GrDisableColorXPFactory(); + constexpr GrDisableColorXPFactory() {} GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysis&, @@ -39,13 +41,17 @@ private: return false; } - bool onIsEqual(const GrXPFactory& xpfBase) const override { - return true; - } - GR_DECLARE_XP_FACTORY_TEST; typedef GrXPFactory INHERITED; }; +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic pop +#endif + +inline const GrXPFactory* GrDisableColorXPFactory::Get() { + static constexpr const GrDisableColorXPFactory gDisableColorXPFactory; + return &gDisableColorXPFactory; +} #endif diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index df8b96d374..c8f7160f84 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -675,40 +675,63 @@ GrXferProcessor::OptFlags PDLCDXferProcessor::onGetOptimizations(const GrPipelin /////////////////////////////////////////////////////////////////////////////// -GrPorterDuffXPFactory::GrPorterDuffXPFactory(SkBlendMode xfermode) - : fXfermode(xfermode) { - SkASSERT((unsigned)fXfermode <= (unsigned)SkBlendMode::kLastCoeffMode); - this->initClassID<GrPorterDuffXPFactory>(); -} - -sk_sp<GrXPFactory> GrPorterDuffXPFactory::Make(SkBlendMode xfermode) { - static GrPorterDuffXPFactory gClearPDXPF(SkBlendMode::kClear); - static GrPorterDuffXPFactory gSrcPDXPF(SkBlendMode::kSrc); - static GrPorterDuffXPFactory gDstPDXPF(SkBlendMode::kDst); - static GrPorterDuffXPFactory gSrcOverPDXPF(SkBlendMode::kSrcOver); - static GrPorterDuffXPFactory gDstOverPDXPF(SkBlendMode::kDstOver); - static GrPorterDuffXPFactory gSrcInPDXPF(SkBlendMode::kSrcIn); - static GrPorterDuffXPFactory gDstInPDXPF(SkBlendMode::kDstIn); - static GrPorterDuffXPFactory gSrcOutPDXPF(SkBlendMode::kSrcOut); - static GrPorterDuffXPFactory gDstOutPDXPF(SkBlendMode::kDstOut); - static GrPorterDuffXPFactory gSrcATopPDXPF(SkBlendMode::kSrcATop); - static GrPorterDuffXPFactory gDstATopPDXPF(SkBlendMode::kDstATop); - static GrPorterDuffXPFactory gXorPDXPF(SkBlendMode::kXor); - static GrPorterDuffXPFactory gPlusPDXPF(SkBlendMode::kPlus); - static GrPorterDuffXPFactory gModulatePDXPF(SkBlendMode::kModulate); - static GrPorterDuffXPFactory gScreenPDXPF(SkBlendMode::kScreen); - - static GrPorterDuffXPFactory* gFactories[] = { - &gClearPDXPF, &gSrcPDXPF, &gDstPDXPF, &gSrcOverPDXPF, &gDstOverPDXPF, &gSrcInPDXPF, - &gDstInPDXPF, &gSrcOutPDXPF, &gDstOutPDXPF, &gSrcATopPDXPF, &gDstATopPDXPF, &gXorPDXPF, - &gPlusPDXPF, &gModulatePDXPF, &gScreenPDXPF - }; - GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFactories) == (int)SkBlendMode::kLastCoeffMode + 1); - - if ((int)xfermode < 0 || (int)xfermode > (int)SkBlendMode::kLastCoeffMode) { - return nullptr; +constexpr GrPorterDuffXPFactory::GrPorterDuffXPFactory(SkBlendMode xfermode) + : fBlendMode(xfermode) {} + +const GrXPFactory* GrPorterDuffXPFactory::Get(SkBlendMode blendMode) { + SkASSERT((unsigned)blendMode <= (unsigned)SkBlendMode::kLastCoeffMode); + + static constexpr const GrPorterDuffXPFactory gClearPDXPF(SkBlendMode::kClear); + static constexpr const GrPorterDuffXPFactory gSrcPDXPF(SkBlendMode::kSrc); + static constexpr const GrPorterDuffXPFactory gDstPDXPF(SkBlendMode::kDst); + static constexpr const GrPorterDuffXPFactory gSrcOverPDXPF(SkBlendMode::kSrcOver); + static constexpr const GrPorterDuffXPFactory gDstOverPDXPF(SkBlendMode::kDstOver); + static constexpr const GrPorterDuffXPFactory gSrcInPDXPF(SkBlendMode::kSrcIn); + static constexpr const GrPorterDuffXPFactory gDstInPDXPF(SkBlendMode::kDstIn); + static constexpr const GrPorterDuffXPFactory gSrcOutPDXPF(SkBlendMode::kSrcOut); + static constexpr const GrPorterDuffXPFactory gDstOutPDXPF(SkBlendMode::kDstOut); + static constexpr const GrPorterDuffXPFactory gSrcATopPDXPF(SkBlendMode::kSrcATop); + static constexpr const GrPorterDuffXPFactory gDstATopPDXPF(SkBlendMode::kDstATop); + static constexpr const GrPorterDuffXPFactory gXorPDXPF(SkBlendMode::kXor); + static constexpr const GrPorterDuffXPFactory gPlusPDXPF(SkBlendMode::kPlus); + static constexpr const GrPorterDuffXPFactory gModulatePDXPF(SkBlendMode::kModulate); + static constexpr const GrPorterDuffXPFactory gScreenPDXPF(SkBlendMode::kScreen); + + switch (blendMode) { + case SkBlendMode::kClear: + return &gClearPDXPF; + case SkBlendMode::kSrc: + return &gSrcPDXPF; + case SkBlendMode::kDst: + return &gDstPDXPF; + case SkBlendMode::kSrcOver: + return &gSrcOverPDXPF; + case SkBlendMode::kDstOver: + return &gDstOverPDXPF; + case SkBlendMode::kSrcIn: + return &gSrcInPDXPF; + case SkBlendMode::kDstIn: + return &gDstInPDXPF; + case SkBlendMode::kSrcOut: + return &gSrcOutPDXPF; + case SkBlendMode::kDstOut: + return &gDstOutPDXPF; + case SkBlendMode::kSrcATop: + return &gSrcATopPDXPF; + case SkBlendMode::kDstATop: + return &gDstATopPDXPF; + case SkBlendMode::kXor: + return &gXorPDXPF; + case SkBlendMode::kPlus: + return &gPlusPDXPF; + case SkBlendMode::kModulate: + return &gModulatePDXPF; + case SkBlendMode::kScreen: + return &gScreenPDXPF; + default: + SkFAIL("Unexpected blend mode."); + return nullptr; } - return sk_sp<GrXPFactory>(SkRef(gFactories[(int)xfermode])); } GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, @@ -716,27 +739,27 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps bool hasMixedSamples, const DstTexture* dstTexture) const { if (analysis.fUsesPLSDstRead) { - return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode); + return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fBlendMode); } BlendFormula blendFormula; if (analysis.fCoveragePOI.isFourChannelOutput()) { - if (SkBlendMode::kSrcOver == fXfermode && + if (SkBlendMode::kSrcOver == fBlendMode && kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() && !caps.shaderCaps()->dualSourceBlendingSupport() && !caps.shaderCaps()->dstReadInShaderSupport()) { // If we don't have dual source blending or in shader dst reads, we fall back to this // trick for rendering SrcOver LCD text instead of doing a dst copy. SkASSERT(!dstTexture || !dstTexture->texture()); - return PDLCDXferProcessor::Create(fXfermode, analysis.fColorPOI); + return PDLCDXferProcessor::Create(fBlendMode, analysis.fColorPOI); } - blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, fXfermode); + blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, fBlendMode); } else { blendFormula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, hasMixedSamples, - fXfermode); + fBlendMode); } if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) { - return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode); + return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fBlendMode); } SkASSERT(!dstTexture || !dstTexture->texture()); @@ -746,7 +769,7 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, InvariantBlendedColor* blendedColor) const { // Find the blended color info based on the formula that does not have coverage. - BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][(int)fXfermode]; + BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][(int)fBlendMode]; if (colorFormula.usesDstColor()) { blendedColor->fWillBlendWithDst = true; blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; @@ -784,12 +807,12 @@ bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps, // blend. The one exception is when we are using srcover mode and we know the input color into // the XP. if (analysis.fCoveragePOI.isFourChannelOutput()) { - if (SkBlendMode::kSrcOver == fXfermode && + if (SkBlendMode::kSrcOver == fBlendMode && kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() && !caps.shaderCaps()->dstReadInShaderSupport()) { return false; } - return get_lcd_blend_formula(analysis.fCoveragePOI, fXfermode).hasSecondaryOutput(); + return get_lcd_blend_formula(analysis.fCoveragePOI, fBlendMode).hasSecondaryOutput(); } // We fallback on the shader XP when the blend formula would use dual source blending but we @@ -797,15 +820,15 @@ bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps, static const bool kHasMixedSamples = false; SkASSERT(!caps.usesMixedSamples()); // We never use mixed samples without dual source blending. auto formula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, kHasMixedSamples, - fXfermode); + fBlendMode); return formula.hasSecondaryOutput(); } GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); -sk_sp<GrXPFactory> GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) { +const GrXPFactory* GrPorterDuffXPFactory::TestGet(GrProcessorTestData* d) { SkBlendMode mode = SkBlendMode(d->fRandom->nextULessThan((int)SkBlendMode::kLastCoeffMode)); - return GrPorterDuffXPFactory::Make(mode); + return GrPorterDuffXPFactory::Get(mode); } void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index d9e0110c06..cbad5f2a40 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -596,7 +596,7 @@ void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) { SkASSERT(!args.fShape->inverseFilled()); GrPaint paint; - paint.setXPFactory(GrDisableColorXPFactory::Make()); + paint.setXPFactory(GrDisableColorXPFactory::Get()); this->internalDrawPath(args.fRenderTargetContext, paint, args.fAAType, GrUserStencilSettings::kUnused, *args.fClip, *args.fViewMatrix, diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp index 207567beff..cc6781cac4 100644 --- a/src/gpu/ops/GrMSAAPathRenderer.cpp +++ b/src/gpu/ops/GrMSAAPathRenderer.cpp @@ -718,7 +718,7 @@ void GrMSAAPathRenderer::onStencilPath(const StencilPathArgs& args) { SkASSERT(!args.fShape->mayBeInverseFilledAfterStyling()); GrPaint paint; - paint.setXPFactory(GrDisableColorXPFactory::Make()); + paint.setXPFactory(GrDisableColorXPFactory::Get()); this->internalDrawPath(args.fRenderTargetContext, paint, args.fAAType, GrUserStencilSettings::kUnused, *args.fClip, *args.fViewMatrix, diff --git a/tests/DFPathRendererTest.cpp b/tests/DFPathRendererTest.cpp index c499c081e0..ca437da4ed 100644 --- a/tests/DFPathRendererTest.cpp +++ b/tests/DFPathRendererTest.cpp @@ -42,7 +42,7 @@ static void test_far_from_origin(GrRenderTargetContext* renderTargetContext, GrP shape = shape.applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, 1.f); GrPaint paint; - paint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); GrNoClip noClip; GrPathRenderer::DrawPathArgs args; diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp index 0ab7a1ecb0..94abd1c9ee 100644 --- a/tests/GLProgramsTest.cpp +++ b/tests/GLProgramsTest.cpp @@ -167,9 +167,7 @@ static sk_sp<GrRenderTargetContext> random_render_target_context(GrContext* cont } static void set_random_xpf(GrPaint* paint, GrProcessorTestData* d) { - sk_sp<GrXPFactory> xpf(GrProcessorTestFactory<GrXPFactory>::Make(d)); - SkASSERT(xpf); - paint->setXPFactory(std::move(xpf)); + paint->setXPFactory(GrXPFactoryTestFactory::Get(d)); } static sk_sp<GrFragmentProcessor> create_random_proc_tree(GrProcessorTestData* d, @@ -368,7 +366,7 @@ bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages) { GrProcessorTestData ptd(&random, context, context->caps(), renderTargetContext.get(), dummyTextures); GrPaint grPaint; - grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); sk_sp<GrFragmentProcessor> fp( GrProcessorTestFactory<GrFragmentProcessor>::MakeIdx(i, &ptd)); diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp index 19ba7b8e54..3132feeff8 100644 --- a/tests/GrPorterDuffTest.cpp +++ b/tests/GrPorterDuffTest.cpp @@ -67,7 +67,7 @@ public: struct XPInfo { XPInfo(skiatest::Reporter* reporter, SkBlendMode xfermode, const GrCaps& caps, const GrPipelineAnalysis& analysis) { - sk_sp<GrXPFactory> xpf(GrPorterDuffXPFactory::Make(xfermode)); + const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode); sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps)); TEST_ASSERT(!xpf->willNeedDstTexture(caps, analysis)); xpf->getInvariantBlendedColor(analysis.fColorPOI, &fBlendedColor); @@ -1097,7 +1097,7 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); SkASSERT(covPOI.isFourChannelOutput()); - sk_sp<GrXPFactory> xpf(GrPorterDuffXPFactory::Make(SkBlendMode::kSrcOver)); + const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(SkBlendMode::kSrcOver); TEST_ASSERT(!xpf->willNeedDstTexture(caps, analysis)); sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps)); @@ -1171,7 +1171,7 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) { } for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); - sk_sp<GrXPFactory> xpf(GrPorterDuffXPFactory::Make(xfermode)); + const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode); GrXferProcessor::DstTexture* dstTexture = xpf->willNeedDstTexture(caps, analysis) ? &fakeDstTexture : 0; sk_sp<GrXferProcessor> xp( diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp index ccc24a4aa8..fc93772106 100644 --- a/tests/TessellatingPathRendererTests.cpp +++ b/tests/TessellatingPathRendererTests.cpp @@ -254,7 +254,7 @@ static void test_path(GrRenderTargetContext* renderTargetContext, GrResourceProv GrTessellatingPathRenderer tess; GrPaint paint; - paint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc)); + paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); GrNoClip noClip; GrStyle style(SkStrokeRec::kFill_InitStyle); |