GrPorterDuffXferProcessor.h revision 50785a3d10b53bea5beb6e18431a2449860be237
1/* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#ifndef GrPorterDuffXferProcessor_DEFINED 9#define GrPorterDuffXferProcessor_DEFINED 10 11#include "GrTypes.h" 12#include "GrXferProcessor.h" 13#include "SkXfermode.h" 14 15class GrDrawTargetCaps; 16class GrProcOptInfo; 17 18class GrPorterDuffXferProcessor : public GrXferProcessor { 19public: 20 static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, 21 GrColor constant, const GrDeviceCoordTexture* dstCopy, 22 bool willReadDstColor) { 23 return SkNEW_ARGS(GrPorterDuffXferProcessor, (srcBlend, dstBlend, constant, dstCopy, 24 willReadDstColor)); 25 } 26 27 ~GrPorterDuffXferProcessor() SK_OVERRIDE; 28 29 const char* name() const SK_OVERRIDE { return "Porter Duff"; } 30 31 GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; 32 33 bool hasSecondaryOutput() const SK_OVERRIDE; 34 35 /////////////////////////////////////////////////////////////////////////// 36 /// @name Stage Output Types 37 //// 38 39 enum PrimaryOutputType { 40 kNone_PrimaryOutputType, 41 kColor_PrimaryOutputType, 42 kCoverage_PrimaryOutputType, 43 // Modulate color and coverage, write result as the color output. 44 kModulate_PrimaryOutputType, 45 }; 46 47 enum SecondaryOutputType { 48 // There is no secondary output 49 kNone_SecondaryOutputType, 50 // Writes coverage as the secondary output. Only set if dual source blending is supported 51 // and primary output is kModulate. 52 kCoverage_SecondaryOutputType, 53 // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending 54 // is supported and primary output is kModulate. 55 kCoverageISA_SecondaryOutputType, 56 // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source 57 // blending is supported and primary output is kModulate. 58 kCoverageISC_SecondaryOutputType, 59 60 kSecondaryOutputTypeCnt, 61 }; 62 63 PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; } 64 SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputType; } 65 66 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, 67 const GrProcOptInfo& coveragePOI, 68 bool doesStencilWrite, 69 GrColor* overrideColor, 70 const GrDrawTargetCaps& caps) SK_OVERRIDE; 71 72 void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE { 73 blendInfo->fSrcBlend = fSrcBlend; 74 blendInfo->fDstBlend = fDstBlend; 75 blendInfo->fBlendConstant = fBlendConstant; 76 } 77 78private: 79 GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant, 80 const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); 81 82 void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; 83 84 bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { 85 const GrPorterDuffXferProcessor& xp = xpBase.cast<GrPorterDuffXferProcessor>(); 86 if (fSrcBlend != xp.fSrcBlend || 87 fDstBlend != xp.fDstBlend || 88 fBlendConstant != xp.fBlendConstant || 89 fPrimaryOutputType != xp.fPrimaryOutputType || 90 fSecondaryOutputType != xp.fSecondaryOutputType) { 91 return false; 92 } 93 return true; 94 } 95 96 GrXferProcessor::OptFlags internalGetOptimizations(const GrProcOptInfo& colorPOI, 97 const GrProcOptInfo& coveragePOI, 98 bool doesStencilWrite); 99 100 void calcOutputTypes(GrXferProcessor::OptFlags blendOpts, const GrDrawTargetCaps& caps, 101 bool hasSolidCoverage); 102 103 GrBlendCoeff fSrcBlend; 104 GrBlendCoeff fDstBlend; 105 GrColor fBlendConstant; 106 PrimaryOutputType fPrimaryOutputType; 107 SecondaryOutputType fSecondaryOutputType; 108 109 typedef GrXferProcessor INHERITED; 110}; 111 112/////////////////////////////////////////////////////////////////////////////// 113 114class GrPorterDuffXPFactory : public GrXPFactory { 115public: 116 static GrXPFactory* Create(SkXfermode::Mode mode); 117 118 static GrXPFactory* Create(SkXfermode::Coeff src, SkXfermode::Coeff dst) { 119 return SkNEW_ARGS(GrPorterDuffXPFactory, ((GrBlendCoeff)(src), (GrBlendCoeff)(dst))); 120 } 121 122 static GrXPFactory* Create(GrBlendCoeff src, GrBlendCoeff dst) { 123 return SkNEW_ARGS(GrPorterDuffXPFactory, (src, dst)); 124 } 125 126 bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE; 127 128 bool canApplyCoverage(const GrProcOptInfo& colorPOI, 129 const GrProcOptInfo& coveragePOI) const SK_OVERRIDE; 130 131 bool canTweakAlphaForCoverage() const SK_OVERRIDE; 132 133 void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, 134 GrXPFactory::InvariantOutput*) const SK_OVERRIDE; 135 136private: 137 GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst); 138 139 GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI, 140 const GrProcOptInfo& coveragePOI, 141 const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; 142 143 bool willReadDstColor() const SK_OVERRIDE; 144 145 bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE { 146 const GrPorterDuffXPFactory& xpf = xpfBase.cast<GrPorterDuffXPFactory>(); 147 return (fSrcCoeff == xpf.fSrcCoeff && fDstCoeff == xpf.fDstCoeff); 148 } 149 150 GR_DECLARE_XP_FACTORY_TEST; 151 152 GrBlendCoeff fSrcCoeff; 153 GrBlendCoeff fDstCoeff; 154 155 typedef GrXPFactory INHERITED; 156}; 157 158#endif 159