1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/effects/GrCoverageSetOpXP.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrColor.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrPipeline.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrXferProcessor.h" 14cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLBlend.h" 15cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" 16cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLUniformHandler.h" 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciclass CoverageSetOpXP : public GrXferProcessor { 19cb93a386Sopenharmony_cipublic: 20cb93a386Sopenharmony_ci CoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage) 21cb93a386Sopenharmony_ci : INHERITED(kCoverageSetOpXP_ClassID) 22cb93a386Sopenharmony_ci , fRegionOp(regionOp) 23cb93a386Sopenharmony_ci , fInvertCoverage(invertCoverage) {} 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ci const char* name() const override { return "Coverage Set Op"; } 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci SkString getShaderDfxInfo() const override; 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci std::unique_ptr<ProgramImpl> makeProgramImpl() const override; 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ciprivate: 32cb93a386Sopenharmony_ci void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override; 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci bool onIsEqual(const GrXferProcessor& xpBase) const override { 37cb93a386Sopenharmony_ci const CoverageSetOpXP& xp = xpBase.cast<CoverageSetOpXP>(); 38cb93a386Sopenharmony_ci return (fRegionOp == xp.fRegionOp && 39cb93a386Sopenharmony_ci fInvertCoverage == xp.fInvertCoverage); 40cb93a386Sopenharmony_ci } 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci SkRegion::Op fRegionOp; 43cb93a386Sopenharmony_ci bool fInvertCoverage; 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci using INHERITED = GrXferProcessor; 46cb93a386Sopenharmony_ci}; 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ciSkString CoverageSetOpXP::getShaderDfxInfo() const 49cb93a386Sopenharmony_ci{ 50cb93a386Sopenharmony_ci SkString format; 51cb93a386Sopenharmony_ci format.printf("ShaderDfx_CoverageSetOpXP_%d", fInvertCoverage); 52cb93a386Sopenharmony_ci return format; 53cb93a386Sopenharmony_ci} 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_civoid CoverageSetOpXP::onAddToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const { 56cb93a386Sopenharmony_ci b->addBool(fInvertCoverage, "invert coverage"); 57cb93a386Sopenharmony_ci} 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_cistd::unique_ptr<GrXferProcessor::ProgramImpl> CoverageSetOpXP::makeProgramImpl() const { 60cb93a386Sopenharmony_ci class Impl : public ProgramImpl { 61cb93a386Sopenharmony_ci private: 62cb93a386Sopenharmony_ci void emitOutputsForBlendState(const EmitArgs& args) override { 63cb93a386Sopenharmony_ci const CoverageSetOpXP& xp = args.fXP.cast<CoverageSetOpXP>(); 64cb93a386Sopenharmony_ci GrGLSLXPFragmentBuilder* fb = args.fXPFragBuilder; 65cb93a386Sopenharmony_ci if (xp.fInvertCoverage) { 66cb93a386Sopenharmony_ci fb->codeAppendf("%s = 1.0 - %s;", args.fOutputPrimary, args.fInputCoverage); 67cb93a386Sopenharmony_ci } else { 68cb93a386Sopenharmony_ci fb->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage); 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci }; 72cb93a386Sopenharmony_ci return std::make_unique<Impl>(); 73cb93a386Sopenharmony_ci} 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_civoid CoverageSetOpXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const { 76cb93a386Sopenharmony_ci switch (fRegionOp) { 77cb93a386Sopenharmony_ci case SkRegion::kReplace_Op: 78cb93a386Sopenharmony_ci blendInfo->fSrcBlend = kOne_GrBlendCoeff; 79cb93a386Sopenharmony_ci blendInfo->fDstBlend = kZero_GrBlendCoeff; 80cb93a386Sopenharmony_ci break; 81cb93a386Sopenharmony_ci case SkRegion::kIntersect_Op: 82cb93a386Sopenharmony_ci blendInfo->fSrcBlend = kDC_GrBlendCoeff; 83cb93a386Sopenharmony_ci blendInfo->fDstBlend = kZero_GrBlendCoeff; 84cb93a386Sopenharmony_ci break; 85cb93a386Sopenharmony_ci case SkRegion::kUnion_Op: 86cb93a386Sopenharmony_ci blendInfo->fSrcBlend = kOne_GrBlendCoeff; 87cb93a386Sopenharmony_ci blendInfo->fDstBlend = kISC_GrBlendCoeff; 88cb93a386Sopenharmony_ci break; 89cb93a386Sopenharmony_ci case SkRegion::kXOR_Op: 90cb93a386Sopenharmony_ci blendInfo->fSrcBlend = kIDC_GrBlendCoeff; 91cb93a386Sopenharmony_ci blendInfo->fDstBlend = kISC_GrBlendCoeff; 92cb93a386Sopenharmony_ci break; 93cb93a386Sopenharmony_ci case SkRegion::kDifference_Op: 94cb93a386Sopenharmony_ci blendInfo->fSrcBlend = kZero_GrBlendCoeff; 95cb93a386Sopenharmony_ci blendInfo->fDstBlend = kISC_GrBlendCoeff; 96cb93a386Sopenharmony_ci break; 97cb93a386Sopenharmony_ci case SkRegion::kReverseDifference_Op: 98cb93a386Sopenharmony_ci blendInfo->fSrcBlend = kIDC_GrBlendCoeff; 99cb93a386Sopenharmony_ci blendInfo->fDstBlend = kZero_GrBlendCoeff; 100cb93a386Sopenharmony_ci break; 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci blendInfo->fBlendConstant = SK_PMColor4fTRANSPARENT; 103cb93a386Sopenharmony_ci} 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ciconstexpr GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp, 108cb93a386Sopenharmony_ci bool invertCoverage) 109cb93a386Sopenharmony_ci : fRegionOp(regionOp), fInvertCoverage(invertCoverage) {} 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ciconst GrXPFactory* GrCoverageSetOpXPFactory::Get(SkRegion::Op regionOp, bool invertCoverage) { 112cb93a386Sopenharmony_ci switch (regionOp) { 113cb93a386Sopenharmony_ci case SkRegion::kReplace_Op: { 114cb93a386Sopenharmony_ci if (invertCoverage) { 115cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gReplaceCDXPFI( 116cb93a386Sopenharmony_ci SkRegion::kReplace_Op, true); 117cb93a386Sopenharmony_ci return &gReplaceCDXPFI; 118cb93a386Sopenharmony_ci } else { 119cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gReplaceCDXPF(SkRegion::kReplace_Op, 120cb93a386Sopenharmony_ci false); 121cb93a386Sopenharmony_ci return &gReplaceCDXPF; 122cb93a386Sopenharmony_ci } 123cb93a386Sopenharmony_ci } 124cb93a386Sopenharmony_ci case SkRegion::kIntersect_Op: { 125cb93a386Sopenharmony_ci if (invertCoverage) { 126cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gIntersectCDXPFI( 127cb93a386Sopenharmony_ci SkRegion::kIntersect_Op, true); 128cb93a386Sopenharmony_ci return &gIntersectCDXPFI; 129cb93a386Sopenharmony_ci } else { 130cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gIntersectCDXPF( 131cb93a386Sopenharmony_ci SkRegion::kIntersect_Op, false); 132cb93a386Sopenharmony_ci return &gIntersectCDXPF; 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci } 135cb93a386Sopenharmony_ci case SkRegion::kUnion_Op: { 136cb93a386Sopenharmony_ci if (invertCoverage) { 137cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gUnionCDXPFI(SkRegion::kUnion_Op, 138cb93a386Sopenharmony_ci true); 139cb93a386Sopenharmony_ci return &gUnionCDXPFI; 140cb93a386Sopenharmony_ci } else { 141cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gUnionCDXPF(SkRegion::kUnion_Op, 142cb93a386Sopenharmony_ci false); 143cb93a386Sopenharmony_ci return &gUnionCDXPF; 144cb93a386Sopenharmony_ci } 145cb93a386Sopenharmony_ci } 146cb93a386Sopenharmony_ci case SkRegion::kXOR_Op: { 147cb93a386Sopenharmony_ci if (invertCoverage) { 148cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gXORCDXPFI(SkRegion::kXOR_Op, true); 149cb93a386Sopenharmony_ci return &gXORCDXPFI; 150cb93a386Sopenharmony_ci } else { 151cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gXORCDXPF(SkRegion::kXOR_Op, false); 152cb93a386Sopenharmony_ci return &gXORCDXPF; 153cb93a386Sopenharmony_ci } 154cb93a386Sopenharmony_ci } 155cb93a386Sopenharmony_ci case SkRegion::kDifference_Op: { 156cb93a386Sopenharmony_ci if (invertCoverage) { 157cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gDifferenceCDXPFI( 158cb93a386Sopenharmony_ci SkRegion::kDifference_Op, true); 159cb93a386Sopenharmony_ci return &gDifferenceCDXPFI; 160cb93a386Sopenharmony_ci } else { 161cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gDifferenceCDXPF( 162cb93a386Sopenharmony_ci SkRegion::kDifference_Op, false); 163cb93a386Sopenharmony_ci return &gDifferenceCDXPF; 164cb93a386Sopenharmony_ci } 165cb93a386Sopenharmony_ci } 166cb93a386Sopenharmony_ci case SkRegion::kReverseDifference_Op: { 167cb93a386Sopenharmony_ci if (invertCoverage) { 168cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gRevDiffCDXPFI( 169cb93a386Sopenharmony_ci SkRegion::kReverseDifference_Op, true); 170cb93a386Sopenharmony_ci return &gRevDiffCDXPFI; 171cb93a386Sopenharmony_ci } else { 172cb93a386Sopenharmony_ci static constexpr const GrCoverageSetOpXPFactory gRevDiffCDXPF( 173cb93a386Sopenharmony_ci SkRegion::kReverseDifference_Op, false); 174cb93a386Sopenharmony_ci return &gRevDiffCDXPF; 175cb93a386Sopenharmony_ci } 176cb93a386Sopenharmony_ci } 177cb93a386Sopenharmony_ci } 178cb93a386Sopenharmony_ci SK_ABORT("Unknown region op."); 179cb93a386Sopenharmony_ci} 180cb93a386Sopenharmony_ci 181cb93a386Sopenharmony_cisk_sp<const GrXferProcessor> GrCoverageSetOpXPFactory::makeXferProcessor( 182cb93a386Sopenharmony_ci const GrProcessorAnalysisColor&, 183cb93a386Sopenharmony_ci GrProcessorAnalysisCoverage, 184cb93a386Sopenharmony_ci const GrCaps& caps, 185cb93a386Sopenharmony_ci GrClampType) const { 186cb93a386Sopenharmony_ci return sk_sp<GrXferProcessor>(new CoverageSetOpXP(fRegionOp, fInvertCoverage)); 187cb93a386Sopenharmony_ci} 188cb93a386Sopenharmony_ci 189cb93a386Sopenharmony_ciGR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory); 190cb93a386Sopenharmony_ci 191cb93a386Sopenharmony_ci#if GR_TEST_UTILS 192cb93a386Sopenharmony_ciconst GrXPFactory* GrCoverageSetOpXPFactory::TestGet(GrProcessorTestData* d) { 193cb93a386Sopenharmony_ci SkRegion::Op regionOp = SkRegion::Op(d->fRandom->nextULessThan(SkRegion::kLastOp + 1)); 194cb93a386Sopenharmony_ci bool invertCoverage = d->fRandom->nextBool(); 195cb93a386Sopenharmony_ci return GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage); 196cb93a386Sopenharmony_ci} 197cb93a386Sopenharmony_ci#endif 198