| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 | 
|  | 2 /* | 
|  | 3  * Copyright 2014 Google Inc. | 
|  | 4  * | 
|  | 5  * Use of this source code is governed by a BSD-style license that can be | 
|  | 6  * found in the LICENSE file. | 
|  | 7  */ | 
|  | 8 | 
|  | 9 #include "effects/GrCoverageSetOpXP.h" | 
|  | 10 #include "GrColor.h" | 
|  | 11 #include "GrDrawTargetCaps.h" | 
|  | 12 #include "GrInvariantOutput.h" | 
|  | 13 #include "GrProcessor.h" | 
|  | 14 #include "GrProcOptInfo.h" | 
|  | 15 #include "gl/GrGLXferProcessor.h" | 
|  | 16 #include "gl/builders/GrGLFragmentShaderBuilder.h" | 
|  | 17 #include "gl/builders/GrGLProgramBuilder.h" | 
|  | 18 | 
|  | 19 class GrGLCoverageSetOpXP : public GrGLXferProcessor { | 
|  | 20 public: | 
|  | 21     GrGLCoverageSetOpXP(const GrProcessor&) {} | 
|  | 22 | 
|  | 23     ~GrGLCoverageSetOpXP() SK_OVERRIDE {} | 
|  | 24 | 
|  | 25     void emitCode(const EmitArgs& args) SK_OVERRIDE { | 
|  | 26         const GrCoverageSetOpXP& xp = args.fXP.cast<GrCoverageSetOpXP>(); | 
|  | 27         GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 
|  | 28 | 
|  | 29         if (xp.invertCoverage()) { | 
|  | 30             fsBuilder->codeAppendf("%s = 1.0 - %s;", args.fOutputPrimary, args.f
     InputCoverage); | 
|  | 31         } else { | 
|  | 32             fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputC
     overage); | 
|  | 33         } | 
|  | 34     } | 
|  | 35 | 
|  | 36     void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERR
     IDE {}; | 
|  | 37 | 
|  | 38     static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, | 
|  | 39                        GrProcessorKeyBuilder* b) { | 
|  | 40         const GrCoverageSetOpXP& xp = processor.cast<GrCoverageSetOpXP>(); | 
|  | 41         uint32_t key = xp.invertCoverage() ?  0x0 : 0x1; | 
|  | 42         b->add32(key); | 
|  | 43     }; | 
|  | 44 | 
|  | 45 private: | 
|  | 46     typedef GrGLXferProcessor INHERITED; | 
|  | 47 }; | 
|  | 48 | 
|  | 49 /////////////////////////////////////////////////////////////////////////////// | 
|  | 50 | 
|  | 51 GrCoverageSetOpXP::GrCoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage) | 
|  | 52     : fRegionOp(regionOp) | 
|  | 53     , fInvertCoverage(invertCoverage) { | 
|  | 54     this->initClassID<GrCoverageSetOpXP>(); | 
|  | 55 } | 
|  | 56 | 
|  | 57 GrCoverageSetOpXP::~GrCoverageSetOpXP() { | 
|  | 58 } | 
|  | 59 | 
|  | 60 void GrCoverageSetOpXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBu
     ilder* b) const { | 
|  | 61     GrGLCoverageSetOpXP::GenKey(*this, caps, b); | 
|  | 62 } | 
|  | 63 | 
|  | 64 GrGLXferProcessor* GrCoverageSetOpXP::createGLInstance() const { | 
|  | 65     return SkNEW_ARGS(GrGLCoverageSetOpXP, (*this)); | 
|  | 66 } | 
|  | 67 | 
|  | 68 GrXferProcessor::OptFlags | 
|  | 69 GrCoverageSetOpXP::getOptimizations(const GrProcOptInfo& colorPOI, | 
|  | 70                                     const GrProcOptInfo& coveragePOI, | 
|  | 71                                     bool colorWriteDisabled, | 
|  | 72                                     bool doesStencilWrite, | 
|  | 73                                     GrColor* color, | 
|  | 74                                     const GrDrawTargetCaps& caps) { | 
|  | 75     // We never look at the color input | 
|  | 76     return GrXferProcessor::kIgnoreColor_OptFlag; | 
|  | 77 } | 
|  | 78 | 
|  | 79 void GrCoverageSetOpXP::getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) cons
     t { | 
|  | 80     switch (fRegionOp) { | 
|  | 81         case SkRegion::kReplace_Op: | 
|  | 82             blendInfo->fSrcBlend = kOne_GrBlendCoeff; | 
|  | 83             blendInfo->fDstBlend = kZero_GrBlendCoeff; | 
|  | 84             break; | 
|  | 85         case SkRegion::kIntersect_Op: | 
|  | 86             blendInfo->fSrcBlend = kDC_GrBlendCoeff; | 
|  | 87             blendInfo->fDstBlend = kZero_GrBlendCoeff; | 
|  | 88             break; | 
|  | 89         case SkRegion::kUnion_Op: | 
|  | 90             blendInfo->fSrcBlend = kOne_GrBlendCoeff; | 
|  | 91             blendInfo->fDstBlend = kISC_GrBlendCoeff; | 
|  | 92             break; | 
|  | 93         case SkRegion::kXOR_Op: | 
|  | 94             blendInfo->fSrcBlend = kIDC_GrBlendCoeff; | 
|  | 95             blendInfo->fDstBlend = kISC_GrBlendCoeff; | 
|  | 96             break; | 
|  | 97         case SkRegion::kDifference_Op: | 
|  | 98             blendInfo->fSrcBlend = kZero_GrBlendCoeff; | 
|  | 99             blendInfo->fDstBlend = kISC_GrBlendCoeff; | 
|  | 100             break; | 
|  | 101         case SkRegion::kReverseDifference_Op: | 
|  | 102             blendInfo->fSrcBlend = kIDC_GrBlendCoeff; | 
|  | 103             blendInfo->fDstBlend = kZero_GrBlendCoeff; | 
|  | 104             break; | 
|  | 105     } | 
|  | 106     blendInfo->fBlendConstant = 0; | 
|  | 107 } | 
|  | 108 | 
|  | 109 /////////////////////////////////////////////////////////////////////////////// | 
|  | 110 | 
|  | 111 GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool i
     nvertCoverage) | 
|  | 112     : fRegionOp(regionOp) | 
|  | 113     , fInvertCoverage(invertCoverage) { | 
|  | 114     this->initClassID<GrCoverageSetOpXPFactory>(); | 
|  | 115 } | 
|  | 116 | 
|  | 117 GrXPFactory* GrCoverageSetOpXPFactory::Create(SkRegion::Op regionOp, bool invert
     Coverage) { | 
|  | 118     switch (regionOp) { | 
|  | 119         case SkRegion::kReplace_Op: { | 
|  | 120             if (invertCoverage) { | 
|  | 121                 static GrCoverageSetOpXPFactory gReplaceCDXPFI(regionOp, invertC
     overage); | 
|  | 122                 return SkRef(&gReplaceCDXPFI); | 
|  | 123             } else { | 
|  | 124                 static GrCoverageSetOpXPFactory gReplaceCDXPF(regionOp, invertCo
     verage); | 
|  | 125                 return SkRef(&gReplaceCDXPF); | 
|  | 126             } | 
|  | 127             break; | 
|  | 128         } | 
|  | 129         case SkRegion::kIntersect_Op: { | 
|  | 130             if (invertCoverage) { | 
|  | 131                 static GrCoverageSetOpXPFactory gIntersectCDXPFI(regionOp, inver
     tCoverage); | 
|  | 132                 return SkRef(&gIntersectCDXPFI); | 
|  | 133             } else { | 
|  | 134                 static GrCoverageSetOpXPFactory gIntersectCDXPF(regionOp, invert
     Coverage); | 
|  | 135                 return SkRef(&gIntersectCDXPF); | 
|  | 136             } | 
|  | 137             break; | 
|  | 138         } | 
|  | 139         case SkRegion::kUnion_Op: { | 
|  | 140             if (invertCoverage) { | 
|  | 141                 static GrCoverageSetOpXPFactory gUnionCDXPFI(regionOp, invertCov
     erage); | 
|  | 142                 return SkRef(&gUnionCDXPFI); | 
|  | 143             } else { | 
|  | 144                 static GrCoverageSetOpXPFactory gUnionCDXPF(regionOp, invertCove
     rage); | 
|  | 145                 return SkRef(&gUnionCDXPF); | 
|  | 146             } | 
|  | 147             break; | 
|  | 148         } | 
|  | 149         case SkRegion::kXOR_Op: { | 
|  | 150             if (invertCoverage) { | 
|  | 151                 static GrCoverageSetOpXPFactory gXORCDXPFI(regionOp, invertCover
     age); | 
|  | 152                 return SkRef(&gXORCDXPFI); | 
|  | 153             } else { | 
|  | 154                 static GrCoverageSetOpXPFactory gXORCDXPF(regionOp, invertCovera
     ge); | 
|  | 155                 return SkRef(&gXORCDXPF); | 
|  | 156             } | 
|  | 157             break; | 
|  | 158         } | 
|  | 159         case SkRegion::kDifference_Op: { | 
|  | 160             if (invertCoverage) { | 
|  | 161                 static GrCoverageSetOpXPFactory gDifferenceCDXPFI(regionOp, inve
     rtCoverage); | 
|  | 162                 return SkRef(&gDifferenceCDXPFI); | 
|  | 163             } else { | 
|  | 164                 static GrCoverageSetOpXPFactory gDifferenceCDXPF(regionOp, inver
     tCoverage); | 
|  | 165                 return SkRef(&gDifferenceCDXPF); | 
|  | 166             } | 
|  | 167             break; | 
|  | 168         } | 
|  | 169         case SkRegion::kReverseDifference_Op: { | 
|  | 170             if (invertCoverage) { | 
|  | 171                 static GrCoverageSetOpXPFactory gRevDiffCDXPFI(regionOp, invertC
     overage); | 
|  | 172                 return SkRef(&gRevDiffCDXPFI); | 
|  | 173             } else { | 
|  | 174                 static GrCoverageSetOpXPFactory gRevDiffCDXPF(regionOp, invertCo
     verage); | 
|  | 175                 return SkRef(&gRevDiffCDXPF); | 
|  | 176             } | 
|  | 177             break; | 
|  | 178         } | 
|  | 179         default: | 
|  | 180             return NULL; | 
|  | 181     } | 
|  | 182 } | 
|  | 183 | 
|  | 184 GrXferProcessor* GrCoverageSetOpXPFactory::createXferProcessor(const GrProcOptIn
     fo& /* colorPOI*/, | 
|  | 185                                                                const GrProcOptIn
     fo& covPOI) const { | 
|  | 186     return GrCoverageSetOpXP::Create(fRegionOp, fInvertCoverage); | 
|  | 187 } | 
|  | 188 | 
|  | 189 bool GrCoverageSetOpXPFactory::willBlendWithDst(const GrProcOptInfo& colorPOI, | 
|  | 190                                                 const GrProcOptInfo& coveragePOI
     , | 
|  | 191                                                 bool colorWriteDisabled) const { | 
|  | 192     // TODO: once all SkXferEffects are XP's then we will never reads dst here s
     ince only XP's | 
|  | 193     // will readDst and this XP doesn't read dst. | 
|  | 194     if (coveragePOI.readsDst()) { | 
|  | 195         return true; | 
|  | 196     } | 
|  | 197 | 
|  | 198     // Besides Replace all other SkRegion ops will either have a src coeff that 
     references dst or a | 
|  | 199     // non zero dst coeff | 
|  | 200     return SkRegion::kReplace_Op != fRegionOp; | 
|  | 201 } | 
|  | 202 | 
|  | 203 bool GrCoverageSetOpXPFactory::getOpaqueAndKnownColor(const GrProcOptInfo& color
     POI, | 
|  | 204                                                       const GrProcOptInfo& cover
     agePOI, | 
|  | 205                                                       GrColor* solidColor, | 
|  | 206                                                       uint32_t* solidColorKnownC
     omponents) const { | 
|  | 207     if (!coveragePOI.isSolidWhite()) { | 
|  | 208         return false; | 
|  | 209     } | 
|  | 210 | 
|  | 211     SkASSERT((NULL == solidColor) == (NULL == solidColorKnownComponents)); | 
|  | 212 | 
|  | 213     bool opaque = SkRegion::kReplace_Op == fRegionOp; | 
|  | 214     if (solidColor) { | 
|  | 215         if (opaque) { | 
|  | 216             *solidColor = GrColor_WHITE; | 
|  | 217             *solidColorKnownComponents = kRGBA_GrColorComponentFlags; | 
|  | 218         } else { | 
|  | 219             solidColorKnownComponents = 0; | 
|  | 220         } | 
|  | 221     } | 
|  | 222     return opaque; | 
|  | 223 } | 
|  | 224 | 
|  | 225 GR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory); | 
|  | 226 | 
|  | 227 GrXPFactory* GrCoverageSetOpXPFactory::TestCreate(SkRandom* random, | 
|  | 228                                                   GrContext*, | 
|  | 229                                                   const GrDrawTargetCaps&, | 
|  | 230                                                   GrTexture*[]) { | 
|  | 231     SkRegion::Op regionOp = SkRegion::Op(random->nextULessThan(SkRegion::kLastOp
      + 1)); | 
|  | 232     bool invertCoverage = random->nextBool(); | 
|  | 233     return GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage); | 
|  | 234 } | 
|  | 235 | 
| OLD | NEW | 
|---|