Chromium Code Reviews| 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 virtual ~GrGLCoverageSetOpXP() {} | |
| 24 | |
| 25 virtual 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 virtual void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}; | |
| 37 | |
|
bsalomon
2014/12/16 17:35:56
don't need virtuals on these overrides. Also can d
egdaniel
2014/12/17 21:12:37
Done.
| |
| 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 default: | |
|
bsalomon
2014/12/16 17:35:56
If you've exhausted all the possible values for k*
egdaniel
2014/12/17 21:12:37
Done.
| |
| 106 SkASSERT(false); | |
| 107 break; | |
| 108 } | |
| 109 blendInfo->fBlendConstant = 0; | |
| 110 } | |
| 111 | |
| 112 /////////////////////////////////////////////////////////////////////////////// | |
| 113 | |
| 114 GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool i nvertCoverage) | |
| 115 : fRegionOp(regionOp) | |
| 116 , fInvertCoverage(invertCoverage) { | |
| 117 this->initClassID<GrCoverageSetOpXPFactory>(); | |
| 118 } | |
| 119 | |
| 120 GrXPFactory* GrCoverageSetOpXPFactory::Create(SkRegion::Op regionOp, bool invert Coverage) { | |
| 121 switch (regionOp) { | |
| 122 case SkRegion::kReplace_Op: { | |
| 123 if (invertCoverage) { | |
| 124 static GrCoverageSetOpXPFactory gReplaceCDXPFI(regionOp, invertC overage); | |
| 125 return SkRef(&gReplaceCDXPFI); | |
| 126 } else { | |
| 127 static GrCoverageSetOpXPFactory gReplaceCDXPF(regionOp, invertCo verage); | |
| 128 return SkRef(&gReplaceCDXPF); | |
| 129 } | |
| 130 break; | |
| 131 } | |
| 132 case SkRegion::kIntersect_Op: { | |
| 133 if (invertCoverage) { | |
| 134 static GrCoverageSetOpXPFactory gIntersectCDXPFI(regionOp, inver tCoverage); | |
| 135 return SkRef(&gIntersectCDXPFI); | |
| 136 } else { | |
| 137 static GrCoverageSetOpXPFactory gIntersectCDXPF(regionOp, invert Coverage); | |
| 138 return SkRef(&gIntersectCDXPF); | |
| 139 } | |
| 140 break; | |
| 141 } | |
| 142 case SkRegion::kUnion_Op: { | |
| 143 if (invertCoverage) { | |
| 144 static GrCoverageSetOpXPFactory gUnionCDXPFI(regionOp, invertCov erage); | |
| 145 return SkRef(&gUnionCDXPFI); | |
| 146 } else { | |
| 147 static GrCoverageSetOpXPFactory gUnionCDXPF(regionOp, invertCove rage); | |
| 148 return SkRef(&gUnionCDXPF); | |
| 149 } | |
| 150 break; | |
| 151 } | |
| 152 case SkRegion::kXOR_Op: { | |
| 153 if (invertCoverage) { | |
| 154 static GrCoverageSetOpXPFactory gXORCDXPFI(regionOp, invertCover age); | |
| 155 return SkRef(&gXORCDXPFI); | |
| 156 } else { | |
| 157 static GrCoverageSetOpXPFactory gXORCDXPF(regionOp, invertCovera ge); | |
| 158 return SkRef(&gXORCDXPF); | |
| 159 } | |
| 160 break; | |
| 161 } | |
| 162 case SkRegion::kDifference_Op: { | |
| 163 if (invertCoverage) { | |
| 164 static GrCoverageSetOpXPFactory gDifferenceCDXPFI(regionOp, inve rtCoverage); | |
| 165 return SkRef(&gDifferenceCDXPFI); | |
| 166 } else { | |
| 167 static GrCoverageSetOpXPFactory gDifferenceCDXPF(regionOp, inver tCoverage); | |
| 168 return SkRef(&gDifferenceCDXPF); | |
| 169 } | |
| 170 break; | |
| 171 } | |
| 172 case SkRegion::kReverseDifference_Op: { | |
| 173 if (invertCoverage) { | |
| 174 static GrCoverageSetOpXPFactory gRevDiffCDXPFI(regionOp, invertC overage); | |
| 175 return SkRef(&gRevDiffCDXPFI); | |
| 176 } else { | |
| 177 static GrCoverageSetOpXPFactory gRevDiffCDXPF(regionOp, invertCo verage); | |
| 178 return SkRef(&gRevDiffCDXPF); | |
| 179 } | |
| 180 break; | |
| 181 } | |
| 182 default: | |
| 183 return NULL; | |
| 184 } | |
| 185 } | |
| 186 | |
| 187 GrXferProcessor* GrCoverageSetOpXPFactory::createXferProcessor(const GrProcOptIn fo& /* colorPOI*/, | |
| 188 const GrProcOptIn fo& covPOI) const { | |
| 189 if (!covPOI.isFourChannelOutput()) { | |
| 190 return GrCoverageSetOpXP::Create(fRegionOp, fInvertCoverage); | |
| 191 } else { | |
| 192 return NULL; | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 bool GrCoverageSetOpXPFactory::willBlendWithDst(const GrProcOptInfo& colorPOI, | |
| 197 const GrProcOptInfo& coveragePOI , | |
| 198 bool colorWriteDisabled) const { | |
| 199 // TODO: once all SkXferEffects are XP's then we will never reads dst here s ince only XP's | |
| 200 // will readDst and this XP doesn't read dst. | |
| 201 if (coveragePOI.readsDst()) { | |
| 202 return true; | |
| 203 } | |
| 204 | |
| 205 // Besides Replace all other SkRegion ops will either have a src coeff that references dst or a | |
| 206 // non zero dst coeff | |
| 207 return SkRegion::kReplace_Op != fRegionOp; | |
| 208 } | |
| 209 | |
| 210 bool GrCoverageSetOpXPFactory::getOpaqueAndKnownColor(const GrProcOptInfo& color POI, | |
|
bsalomon
2014/12/16 17:35:56
This is kind of confusing now that we have a cover
egdaniel
2014/12/17 21:12:37
As per our conversation, I will clean up these fun
| |
| 211 const GrProcOptInfo& cover agePOI, | |
| 212 GrColor* solidColor, | |
| 213 uint32_t* solidColorKnownC omponents) const { | |
| 214 if (!coveragePOI.isSolidWhite()) { | |
| 215 return false; | |
| 216 } | |
| 217 | |
| 218 SkASSERT((NULL == solidColor) == (NULL == solidColorKnownComponents)); | |
| 219 | |
| 220 bool opaque = SkRegion::kReplace_Op == fRegionOp; | |
| 221 if (solidColor) { | |
| 222 if (opaque) { | |
| 223 *solidColor = GrColor_WHITE; | |
| 224 *solidColorKnownComponents = kRGBA_GrColorComponentFlags; | |
| 225 } else { | |
| 226 solidColorKnownComponents = 0; | |
| 227 } | |
| 228 } | |
| 229 return opaque; | |
| 230 } | |
| 231 | |
| 232 GR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory); | |
| 233 | |
| 234 GrXPFactory* GrCoverageSetOpXPFactory::TestCreate(SkRandom* random, | |
| 235 GrContext*, | |
| 236 const GrDrawTargetCaps&, | |
| 237 GrTexture*[]) { | |
| 238 SkRegion::Op regionOp = SkRegion::Op(random->nextULessThan(SkRegion::kLastOp + 1)); | |
| 239 bool invertCoverage = random->nextBool(); | |
| 240 return GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage); | |
| 241 } | |
| 242 | |
| OLD | NEW |