diff options
Diffstat (limited to 'src/gpu/effects')
-rw-r--r-- | src/gpu/effects/GrCoverageSetOpXP.cpp | 86 | ||||
-rw-r--r-- | src/gpu/effects/GrCoverageSetOpXP.h | 48 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomXfermode.cpp | 75 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomXfermodePriv.h | 51 | ||||
-rw-r--r-- | src/gpu/effects/GrDisableColorXP.cpp | 64 | ||||
-rw-r--r-- | src/gpu/effects/GrDisableColorXP.h | 42 | ||||
-rw-r--r-- | src/gpu/effects/GrPorterDuffXferProcessor.cpp | 178 |
7 files changed, 323 insertions, 221 deletions
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp index 7025d20395..f0ec1f9b00 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.cpp +++ b/src/gpu/effects/GrCoverageSetOpXP.cpp @@ -15,22 +15,70 @@ #include "gl/builders/GrGLFragmentShaderBuilder.h" #include "gl/builders/GrGLProgramBuilder.h" -class GrGLCoverageSetOpXP : public GrGLXferProcessor { +/** + * 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 + * applying the set operator. + * */ +class CoverageSetOpXP : public GrXferProcessor { public: - GrGLCoverageSetOpXP(const GrProcessor&) {} + static GrXferProcessor* Create(SkRegion::Op regionOp, bool invertCoverage) { + return SkNEW_ARGS(CoverageSetOpXP, (regionOp, invertCoverage)); + } + + ~CoverageSetOpXP() SK_OVERRIDE; + + const char* name() const SK_OVERRIDE { return "Coverage Set Op"; } + + GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; + + bool hasSecondaryOutput() const SK_OVERRIDE { return false; } + + GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* color, + const GrDrawTargetCaps& caps) SK_OVERRIDE; + + void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE; + + bool invertCoverage() const { return fInvertCoverage; } + +private: + CoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage); + + void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + + bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { + const CoverageSetOpXP& xp = xpBase.cast<CoverageSetOpXP>(); + return (fRegionOp == xp.fRegionOp && + fInvertCoverage == xp.fInvertCoverage); + } + + SkRegion::Op fRegionOp; + bool fInvertCoverage; + + typedef GrXferProcessor INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +class GLCoverageSetOpXP : public GrGLXferProcessor { +public: + GLCoverageSetOpXP(const GrProcessor&) {} - ~GrGLCoverageSetOpXP() SK_OVERRIDE {} + ~GLCoverageSetOpXP() SK_OVERRIDE {} static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, GrProcessorKeyBuilder* b) { - const GrCoverageSetOpXP& xp = processor.cast<GrCoverageSetOpXP>(); + const CoverageSetOpXP& xp = processor.cast<CoverageSetOpXP>(); uint32_t key = xp.invertCoverage() ? 0x0 : 0x1; b->add32(key); }; private: void onEmitCode(const EmitArgs& args) SK_OVERRIDE { - const GrCoverageSetOpXP& xp = args.fXP.cast<GrCoverageSetOpXP>(); + const CoverageSetOpXP& xp = args.fXP.cast<CoverageSetOpXP>(); GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); if (xp.invertCoverage()) { @@ -47,34 +95,34 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrCoverageSetOpXP::GrCoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage) +CoverageSetOpXP::CoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage) : fRegionOp(regionOp) , fInvertCoverage(invertCoverage) { - this->initClassID<GrCoverageSetOpXP>(); + this->initClassID<CoverageSetOpXP>(); } -GrCoverageSetOpXP::~GrCoverageSetOpXP() { +CoverageSetOpXP::~CoverageSetOpXP() { } -void GrCoverageSetOpXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { - GrGLCoverageSetOpXP::GenKey(*this, caps, b); +void CoverageSetOpXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { + GLCoverageSetOpXP::GenKey(*this, caps, b); } -GrGLXferProcessor* GrCoverageSetOpXP::createGLInstance() const { - return SkNEW_ARGS(GrGLCoverageSetOpXP, (*this)); +GrGLXferProcessor* CoverageSetOpXP::createGLInstance() const { + return SkNEW_ARGS(GLCoverageSetOpXP, (*this)); } GrXferProcessor::OptFlags -GrCoverageSetOpXP::getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* color, - const GrDrawTargetCaps& caps) { +CoverageSetOpXP::getOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* color, + const GrDrawTargetCaps& caps) { // We never look at the color input return GrXferProcessor::kIgnoreColor_OptFlag; } -void GrCoverageSetOpXP::getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const { +void CoverageSetOpXP::getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const { switch (fRegionOp) { case SkRegion::kReplace_Op: blendInfo->fSrcBlend = kOne_GrBlendCoeff; @@ -183,7 +231,7 @@ GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, const GrDeviceCoordTexture* dstCopy) const { - return GrCoverageSetOpXP::Create(fRegionOp, fInvertCoverage); + return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage); } void GrCoverageSetOpXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h index 0bc9e91170..730d549b74 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.h +++ b/src/gpu/effects/GrCoverageSetOpXP.h @@ -14,54 +14,6 @@ class GrProcOptInfo; -/** - * 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 - * applying the set operator. - * */ -class GrCoverageSetOpXP : public GrXferProcessor { -public: - static GrXferProcessor* Create(SkRegion::Op regionOp, bool invertCoverage) { - return SkNEW_ARGS(GrCoverageSetOpXP, (regionOp, invertCoverage)); - } - - ~GrCoverageSetOpXP() SK_OVERRIDE; - - const char* name() const SK_OVERRIDE { return "Coverage Set Op"; } - - GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; - - bool hasSecondaryOutput() const SK_OVERRIDE { return false; } - - GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* color, - const GrDrawTargetCaps& caps) SK_OVERRIDE; - - void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE; - - bool invertCoverage() const { return fInvertCoverage; } - -private: - GrCoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage); - - void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - - bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { - const GrCoverageSetOpXP& xp = xpBase.cast<GrCoverageSetOpXP>(); - return (fRegionOp == xp.fRegionOp && - fInvertCoverage == xp.fInvertCoverage); - } - - SkRegion::Op fRegionOp; - bool fInvertCoverage; - - typedef GrXferProcessor INHERITED; -}; - -/////////////////////////////////////////////////////////////////////////////// - class GrCoverageSetOpXPFactory : public GrXPFactory { public: static GrXPFactory* Create(SkRegion::Op regionOp, bool invertCoverage = false); diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index b77bf2fad1..c7b82be3a6 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -484,6 +484,53 @@ GrFragmentProcessor* GrCustomXferFP::TestCreate(SkRandom* rand, // Xfer Processor /////////////////////////////////////////////////////////////////////////////// +class CustomXP : public GrXferProcessor { +public: + static GrXferProcessor* Create(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, + bool willReadDstColor) { + if (!GrCustomXfermode::IsSupportedMode(mode)) { + return NULL; + } else { + return SkNEW_ARGS(CustomXP, (mode, dstCopy, willReadDstColor)); + } + } + + ~CustomXP() SK_OVERRIDE {}; + + const char* name() const SK_OVERRIDE { return "Custom Xfermode"; } + + GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; + + bool hasSecondaryOutput() const SK_OVERRIDE { return false; } + + GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) SK_OVERRIDE; + + void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE { + blendInfo->fSrcBlend = kOne_GrBlendCoeff; + blendInfo->fDstBlend = kZero_GrBlendCoeff; + blendInfo->fBlendConstant = 0; + } + + SkXfermode::Mode mode() const { return fMode; } + +private: + CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); + + void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + + bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE; + + SkXfermode::Mode fMode; + + typedef GrXferProcessor INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) { if (!GrCustomXfermode::IsSupportedMode(mode)) { return NULL; @@ -502,13 +549,13 @@ public: static void GenKey(const GrXferProcessor& proc, const GrGLCaps&, GrProcessorKeyBuilder* b) { uint32_t key = proc.numTextures(); SkASSERT(key <= 1); - key |= proc.cast<GrCustomXP>().mode() << 1; + key |= proc.cast<CustomXP>().mode() << 1; b->add32(key); } private: void onEmitCode(const EmitArgs& args) SK_OVERRIDE { - SkXfermode::Mode mode = args.fXP.cast<GrCustomXP>().mode(); + SkXfermode::Mode mode = args.fXP.cast<CustomXP>().mode(); GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); const char* dstColor = fsBuilder->dstColor(); @@ -526,26 +573,26 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrCustomXP::GrCustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, - bool willReadDstColor) +CustomXP::CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, + bool willReadDstColor) : INHERITED(dstCopy, willReadDstColor), fMode(mode) { - this->initClassID<GrCustomXP>(); + this->initClassID<CustomXP>(); } -void GrCustomXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { +void CustomXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { GLCustomXP::GenKey(*this, caps, b); } -GrGLXferProcessor* GrCustomXP::createGLInstance() const { +GrGLXferProcessor* CustomXP::createGLInstance() const { return SkNEW_ARGS(GLCustomXP, (*this)); } -bool GrCustomXP::onIsEqual(const GrXferProcessor& other) const { - const GrCustomXP& s = other.cast<GrCustomXP>(); +bool CustomXP::onIsEqual(const GrXferProcessor& other) const { + const CustomXP& s = other.cast<CustomXP>(); return fMode == s.fMode; } -GrXferProcessor::OptFlags GrCustomXP::getOptimizations(const GrProcOptInfo& colorPOI, +GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, bool doesStencilWrite, GrColor* overrideColor, @@ -560,6 +607,14 @@ GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode) this->initClassID<GrCustomXPFactory>(); } +GrXferProcessor* +GrCustomXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + const GrDeviceCoordTexture* dstCopy) const { + return CustomXP::Create(fMode, dstCopy, this->willReadDstColor()); +} + + void GrCustomXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, GrXPFactory::InvariantOutput* output) const { diff --git a/src/gpu/effects/GrCustomXfermodePriv.h b/src/gpu/effects/GrCustomXfermodePriv.h index 681c805ba7..2a2f69f69e 100644 --- a/src/gpu/effects/GrCustomXfermodePriv.h +++ b/src/gpu/effects/GrCustomXfermodePriv.h @@ -56,53 +56,6 @@ private: // Xfer Processor /////////////////////////////////////////////////////////////////////////////// -class GrCustomXP : public GrXferProcessor { -public: - static GrXferProcessor* Create(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, - bool willReadDstColor) { - if (!GrCustomXfermode::IsSupportedMode(mode)) { - return NULL; - } else { - return SkNEW_ARGS(GrCustomXP, (mode, dstCopy, willReadDstColor)); - } - } - - ~GrCustomXP() SK_OVERRIDE {}; - - const char* name() const SK_OVERRIDE { return "Custom Xfermode"; } - - GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; - - bool hasSecondaryOutput() const SK_OVERRIDE { return false; } - - GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* overrideColor, - const GrDrawTargetCaps& caps) SK_OVERRIDE; - - void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE { - blendInfo->fSrcBlend = kOne_GrBlendCoeff; - blendInfo->fDstBlend = kZero_GrBlendCoeff; - blendInfo->fBlendConstant = 0; - } - - SkXfermode::Mode mode() const { return fMode; } - -private: - GrCustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); - - void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - - bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE; - - SkXfermode::Mode fMode; - - typedef GrXferProcessor INHERITED; -}; - -/////////////////////////////////////////////////////////////////////////////// - class GrCustomXPFactory : public GrXPFactory { public: GrCustomXPFactory(SkXfermode::Mode mode); @@ -126,9 +79,7 @@ public: private: GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, - const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE { - return GrCustomXP::Create(fMode, dstCopy, this->willReadDstColor()); - } + const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; bool willReadDstColor() const SK_OVERRIDE { return true; } diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp index 83b6d23119..637f99baf1 100644 --- a/src/gpu/effects/GrDisableColorXP.cpp +++ b/src/gpu/effects/GrDisableColorXP.cpp @@ -11,11 +11,53 @@ #include "gl/builders/GrGLFragmentShaderBuilder.h" #include "gl/builders/GrGLProgramBuilder.h" -class GrGLDisableColorXP : public GrGLXferProcessor { +/** + * This xfer processor disables color writing. Thus color and coverage and ignored and no blending + * occurs. This XP is usful for things like stenciling. + */ +class DisableColorXP : public GrXferProcessor { +public: + static GrXferProcessor* Create() { + return SkNEW(DisableColorXP); + } + + ~DisableColorXP() SK_OVERRIDE {}; + + const char* name() const SK_OVERRIDE { return "Disable Color"; } + + GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; + + bool hasSecondaryOutput() const SK_OVERRIDE { return false; } + + GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* color, + const GrDrawTargetCaps& caps) SK_OVERRIDE { + return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag; + } + + void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE; + +private: + DisableColorXP(); + + void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + + bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { + return true; + } + + typedef GrXferProcessor INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +class GLDisableColorXP : public GrGLXferProcessor { public: - GrGLDisableColorXP(const GrProcessor&) {} + GLDisableColorXP(const GrProcessor&) {} - ~GrGLDisableColorXP() SK_OVERRIDE {} + ~GLDisableColorXP() SK_OVERRIDE {} static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {} @@ -35,19 +77,19 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrDisableColorXP::GrDisableColorXP() { - this->initClassID<GrDisableColorXP>(); +DisableColorXP::DisableColorXP() { + this->initClassID<DisableColorXP>(); } -void GrDisableColorXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { - GrGLDisableColorXP::GenKey(*this, caps, b); +void DisableColorXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { + GLDisableColorXP::GenKey(*this, caps, b); } -GrGLXferProcessor* GrDisableColorXP::createGLInstance() const { - return SkNEW_ARGS(GrGLDisableColorXP, (*this)); +GrGLXferProcessor* DisableColorXP::createGLInstance() const { + return SkNEW_ARGS(GLDisableColorXP, (*this)); } -void GrDisableColorXP::getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const { +void DisableColorXP::getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const { blendInfo->fWriteColor = false; } @@ -61,7 +103,7 @@ GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, const GrDeviceCoordTexture* dstCopy) const { - return GrDisableColorXP::Create(); + return DisableColorXP::Create(); } GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory); diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h index da6fa4523b..fef0f1ee3b 100644 --- a/src/gpu/effects/GrDisableColorXP.h +++ b/src/gpu/effects/GrDisableColorXP.h @@ -13,48 +13,6 @@ class GrProcOptInfo; -/** - * This xfer processor disables color writing. Thus color and coverage and ignored and no blending - * occurs. This XP is usful for things like stenciling. - */ -class GrDisableColorXP : public GrXferProcessor { -public: - static GrXferProcessor* Create() { - return SkNEW(GrDisableColorXP); - } - - ~GrDisableColorXP() SK_OVERRIDE {}; - - const char* name() const SK_OVERRIDE { return "Disable Color"; } - - GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; - - bool hasSecondaryOutput() const SK_OVERRIDE { return false; } - - GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* color, - const GrDrawTargetCaps& caps) SK_OVERRIDE { - return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag; - } - - void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE; - -private: - GrDisableColorXP(); - - void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - - bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { - return true; - } - - typedef GrXferProcessor INHERITED; -}; - -/////////////////////////////////////////////////////////////////////////////// - class GrDisableColorXPFactory : public GrXPFactory { public: static GrXPFactory* Create() { diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index 320d943392..09ccf4eecc 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -32,34 +32,130 @@ static bool can_tweak_alpha_for_coverage(GrBlendCoeff dstCoeff) { kISC_GrBlendCoeff == dstCoeff; } -class GrGLPorterDuffXferProcessor : public GrGLXferProcessor { +class PorterDuffXferProcessor : public GrXferProcessor { public: - GrGLPorterDuffXferProcessor(const GrProcessor&) {} + static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, + GrColor constant, const GrDeviceCoordTexture* dstCopy, + bool willReadDstColor) { + return SkNEW_ARGS(PorterDuffXferProcessor, (srcBlend, dstBlend, constant, dstCopy, + willReadDstColor)); + } + + ~PorterDuffXferProcessor() SK_OVERRIDE; + + const char* name() const SK_OVERRIDE { return "Porter Duff"; } + + GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; + + bool hasSecondaryOutput() const SK_OVERRIDE; + + /////////////////////////////////////////////////////////////////////////// + /// @name Stage Output Types + //// + + enum PrimaryOutputType { + kNone_PrimaryOutputType, + kColor_PrimaryOutputType, + kCoverage_PrimaryOutputType, + // Modulate color and coverage, write result as the color output. + kModulate_PrimaryOutputType, + }; + + enum SecondaryOutputType { + // There is no secondary output + kNone_SecondaryOutputType, + // Writes coverage as the secondary output. Only set if dual source blending is supported + // and primary output is kModulate. + kCoverage_SecondaryOutputType, + // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending + // is supported and primary output is kModulate. + kCoverageISA_SecondaryOutputType, + // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source + // blending is supported and primary output is kModulate. + kCoverageISC_SecondaryOutputType, + + kSecondaryOutputTypeCnt, + }; + + PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; } + SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputType; } + + GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) SK_OVERRIDE; + + void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE { + blendInfo->fSrcBlend = fSrcBlend; + blendInfo->fDstBlend = fDstBlend; + blendInfo->fBlendConstant = fBlendConstant; + } + +private: + PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant, + const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); + + void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + + bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { + const PorterDuffXferProcessor& xp = xpBase.cast<PorterDuffXferProcessor>(); + if (fSrcBlend != xp.fSrcBlend || + fDstBlend != xp.fDstBlend || + fBlendConstant != xp.fBlendConstant || + fPrimaryOutputType != xp.fPrimaryOutputType || + fSecondaryOutputType != xp.fSecondaryOutputType) { + return false; + } + return true; + } + + GrXferProcessor::OptFlags internalGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite); + + void calcOutputTypes(GrXferProcessor::OptFlags blendOpts, const GrDrawTargetCaps& caps, + bool hasSolidCoverage); + + GrBlendCoeff fSrcBlend; + GrBlendCoeff fDstBlend; + GrColor fBlendConstant; + PrimaryOutputType fPrimaryOutputType; + SecondaryOutputType fSecondaryOutputType; + + typedef GrXferProcessor INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +class GLPorterDuffXferProcessor : public GrGLXferProcessor { +public: + GLPorterDuffXferProcessor(const GrProcessor&) {} - virtual ~GrGLPorterDuffXferProcessor() {} + virtual ~GLPorterDuffXferProcessor() {} static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, GrProcessorKeyBuilder* b) { - const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferProcessor>(); + const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcessor>(); b->add32(xp.primaryOutputType()); b->add32(xp.secondaryOutputType()); }; private: void onEmitCode(const EmitArgs& args) SK_OVERRIDE { - const GrPorterDuffXferProcessor& xp = args.fXP.cast<GrPorterDuffXferProcessor>(); + const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcessor>(); GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); if (xp.hasSecondaryOutput()) { switch(xp.secondaryOutputType()) { - case GrPorterDuffXferProcessor::kCoverage_SecondaryOutputType: + case PorterDuffXferProcessor::kCoverage_SecondaryOutputType: fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage); break; - case GrPorterDuffXferProcessor::kCoverageISA_SecondaryOutputType: + case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType: fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", args.fOutputSecondary, args.fInputColor, args.fInputCoverage); break; - case GrPorterDuffXferProcessor::kCoverageISC_SecondaryOutputType: + case PorterDuffXferProcessor::kCoverageISC_SecondaryOutputType: fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", args.fOutputSecondary, args.fInputColor, args.fInputCoverage); @@ -70,16 +166,16 @@ private: } switch (xp.primaryOutputType()) { - case GrPorterDuffXferProcessor::kNone_PrimaryOutputType: + case PorterDuffXferProcessor::kNone_PrimaryOutputType: fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); break; - case GrPorterDuffXferProcessor::kColor_PrimaryOutputType: + case PorterDuffXferProcessor::kColor_PrimaryOutputType: fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputColor); break; - case GrPorterDuffXferProcessor::kCoverage_PrimaryOutputType: + case PorterDuffXferProcessor::kCoverage_PrimaryOutputType: fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage); break; - case GrPorterDuffXferProcessor::kModulate_PrimaryOutputType: + case PorterDuffXferProcessor::kModulate_PrimaryOutputType: fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor, args.fInputCoverage); break; @@ -95,37 +191,37 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, - GrBlendCoeff dstBlend, - GrColor constant, - const GrDeviceCoordTexture* dstCopy, - bool willReadDstColor) +PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend, + GrBlendCoeff dstBlend, + GrColor constant, + const GrDeviceCoordTexture* dstCopy, + bool willReadDstColor) : fSrcBlend(srcBlend) , fDstBlend(dstBlend) , fBlendConstant(constant) , fPrimaryOutputType(kModulate_PrimaryOutputType) , fSecondaryOutputType(kNone_SecondaryOutputType) { - this->initClassID<GrPorterDuffXferProcessor>(); + this->initClassID<PorterDuffXferProcessor>(); } -GrPorterDuffXferProcessor::~GrPorterDuffXferProcessor() { +PorterDuffXferProcessor::~PorterDuffXferProcessor() { } -void GrPorterDuffXferProcessor::onGetGLProcessorKey(const GrGLCaps& caps, - GrProcessorKeyBuilder* b) const { - GrGLPorterDuffXferProcessor::GenKey(*this, caps, b); +void PorterDuffXferProcessor::onGetGLProcessorKey(const GrGLCaps& caps, + GrProcessorKeyBuilder* b) const { + GLPorterDuffXferProcessor::GenKey(*this, caps, b); } -GrGLXferProcessor* GrPorterDuffXferProcessor::createGLInstance() const { - return SkNEW_ARGS(GrGLPorterDuffXferProcessor, (*this)); +GrGLXferProcessor* PorterDuffXferProcessor::createGLInstance() const { + return SkNEW_ARGS(GLPorterDuffXferProcessor, (*this)); } GrXferProcessor::OptFlags -GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* overrideColor, - const GrDrawTargetCaps& caps) { +PorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) { GrXferProcessor::OptFlags optFlags; // Optimizations when doing RGB Coverage if (coveragePOI.isFourChannelOutput()) { @@ -145,9 +241,9 @@ GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, return optFlags; } -void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags, - const GrDrawTargetCaps& caps, - bool hasSolidCoverage) { +void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags, + const GrDrawTargetCaps& caps, + bool hasSolidCoverage) { if (optFlags & kIgnoreColor_OptFlag) { if (optFlags & kIgnoreCoverage_OptFlag) { fPrimaryOutputType = kNone_PrimaryOutputType; @@ -185,9 +281,9 @@ void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFla } GrXferProcessor::OptFlags -GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite) { +PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite) { bool srcAIsOne; bool hasCoverage; @@ -263,7 +359,7 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO return GrXferProcessor::kNone_Opt; } -bool GrPorterDuffXferProcessor::hasSecondaryOutput() const { +bool PorterDuffXferProcessor::hasSecondaryOutput() const { return kNone_SecondaryOutputType != fSecondaryOutputType; } @@ -361,15 +457,15 @@ GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, const GrDeviceCoordTexture* dstCopy) const { if (!covPOI.isFourChannelOutput()) { - return GrPorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, - this->willReadDstColor()); + return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, + this->willReadDstColor()); } else { if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) { SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); - return GrPorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_GrBlendCoeff, - blendConstant, dstCopy, - this->willReadDstColor()); + return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_GrBlendCoeff, + blendConstant, dstCopy, + this->willReadDstColor()); } else { return NULL; } |