1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2017 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/core/SkBlendModePriv.h"
9cb93a386Sopenharmony_ci#include "src/gpu/GrAppliedClip.h"
10cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h"
11cb93a386Sopenharmony_ci#include "src/gpu/GrProcessorSet.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrUserStencilSettings.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrXferProcessor.h"
14cb93a386Sopenharmony_ci#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ciconst GrProcessorSet& GrProcessorSet::EmptySet() {
17cb93a386Sopenharmony_ci    static GrProcessorSet gEmpty(GrProcessorSet::Empty::kEmpty);
18cb93a386Sopenharmony_ci    return gEmpty;
19cb93a386Sopenharmony_ci}
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_ciGrProcessorSet GrProcessorSet::MakeEmptySet() {
22cb93a386Sopenharmony_ci    return GrProcessorSet(GrProcessorSet::Empty::kEmpty);
23cb93a386Sopenharmony_ci}
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ciGrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) {
26cb93a386Sopenharmony_ci    fColorFragmentProcessor = std::move(paint.fColorFragmentProcessor);
27cb93a386Sopenharmony_ci    fCoverageFragmentProcessor = std::move(paint.fCoverageFragmentProcessor);
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ci    SkDEBUGCODE(paint.fAlive = false;)
30cb93a386Sopenharmony_ci}
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ciGrProcessorSet::GrProcessorSet(SkBlendMode mode) : fXP(SkBlendMode_AsXPFactory(mode)) {}
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ciGrProcessorSet::GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP)
35cb93a386Sopenharmony_ci        : fXP((const GrXPFactory*)nullptr) {
36cb93a386Sopenharmony_ci    SkASSERT(colorFP);
37cb93a386Sopenharmony_ci    fColorFragmentProcessor = std::move(colorFP);
38cb93a386Sopenharmony_ci}
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ciGrProcessorSet::GrProcessorSet(GrProcessorSet&& that)
41cb93a386Sopenharmony_ci        : fColorFragmentProcessor(std::move(that.fColorFragmentProcessor))
42cb93a386Sopenharmony_ci        , fCoverageFragmentProcessor(std::move(that.fCoverageFragmentProcessor))
43cb93a386Sopenharmony_ci        , fXP(std::move(that.fXP))
44cb93a386Sopenharmony_ci        , fFlags(that.fFlags) {}
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_ciGrProcessorSet::~GrProcessorSet() {
47cb93a386Sopenharmony_ci    if (this->isFinalized() && this->xferProcessor()) {
48cb93a386Sopenharmony_ci        this->xferProcessor()->unref();
49cb93a386Sopenharmony_ci    }
50cb93a386Sopenharmony_ci}
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ci#if GR_TEST_UTILS
53cb93a386Sopenharmony_ciSkString GrProcessorSet::dumpProcessors() const {
54cb93a386Sopenharmony_ci    SkString result;
55cb93a386Sopenharmony_ci    if (this->hasColorFragmentProcessor()) {
56cb93a386Sopenharmony_ci        result.append("Color Fragment Processor:\n");
57cb93a386Sopenharmony_ci        result += this->colorFragmentProcessor()->dumpTreeInfo();
58cb93a386Sopenharmony_ci    } else {
59cb93a386Sopenharmony_ci        result.append("No color fragment processor.\n");
60cb93a386Sopenharmony_ci    }
61cb93a386Sopenharmony_ci    if (this->hasCoverageFragmentProcessor()) {
62cb93a386Sopenharmony_ci        result.append("Coverage Fragment Processor:\n");
63cb93a386Sopenharmony_ci        result += this->coverageFragmentProcessor()->dumpTreeInfo();
64cb93a386Sopenharmony_ci    } else {
65cb93a386Sopenharmony_ci        result.append("No coverage fragment processors.\n");
66cb93a386Sopenharmony_ci    }
67cb93a386Sopenharmony_ci    if (this->isFinalized()) {
68cb93a386Sopenharmony_ci        result.append("Xfer Processor: ");
69cb93a386Sopenharmony_ci        if (this->xferProcessor()) {
70cb93a386Sopenharmony_ci            result.appendf("%s\n", this->xferProcessor()->name());
71cb93a386Sopenharmony_ci        } else {
72cb93a386Sopenharmony_ci            result.append("SrcOver\n");
73cb93a386Sopenharmony_ci        }
74cb93a386Sopenharmony_ci    } else {
75cb93a386Sopenharmony_ci        result.append("XP Factory dumping not implemented.\n");
76cb93a386Sopenharmony_ci    }
77cb93a386Sopenharmony_ci    return result;
78cb93a386Sopenharmony_ci}
79cb93a386Sopenharmony_ci#endif
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_cibool GrProcessorSet::operator==(const GrProcessorSet& that) const {
82cb93a386Sopenharmony_ci    SkASSERT(this->isFinalized());
83cb93a386Sopenharmony_ci    SkASSERT(that.isFinalized());
84cb93a386Sopenharmony_ci    if (((fFlags ^ that.fFlags) & ~kFinalized_Flag) ||
85cb93a386Sopenharmony_ci        this->hasColorFragmentProcessor() != that.hasColorFragmentProcessor() ||
86cb93a386Sopenharmony_ci        this->hasCoverageFragmentProcessor() != that.hasCoverageFragmentProcessor()) {
87cb93a386Sopenharmony_ci        return false;
88cb93a386Sopenharmony_ci    }
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ci    if (this->hasColorFragmentProcessor()) {
91cb93a386Sopenharmony_ci        if (!colorFragmentProcessor()->isEqual(*that.colorFragmentProcessor())) {
92cb93a386Sopenharmony_ci            return false;
93cb93a386Sopenharmony_ci        }
94cb93a386Sopenharmony_ci    }
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci    if (this->hasCoverageFragmentProcessor()) {
97cb93a386Sopenharmony_ci        if (!coverageFragmentProcessor()->isEqual(*that.coverageFragmentProcessor())) {
98cb93a386Sopenharmony_ci            return false;
99cb93a386Sopenharmony_ci        }
100cb93a386Sopenharmony_ci    }
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_ci    // Most of the time both of these are null
103cb93a386Sopenharmony_ci    if (!this->xferProcessor() && !that.xferProcessor()) {
104cb93a386Sopenharmony_ci        return true;
105cb93a386Sopenharmony_ci    }
106cb93a386Sopenharmony_ci    const GrXferProcessor& thisXP = this->xferProcessor()
107cb93a386Sopenharmony_ci                                            ? *this->xferProcessor()
108cb93a386Sopenharmony_ci                                            : GrPorterDuffXPFactory::SimpleSrcOverXP();
109cb93a386Sopenharmony_ci    const GrXferProcessor& thatXP = that.xferProcessor()
110cb93a386Sopenharmony_ci                                            ? *that.xferProcessor()
111cb93a386Sopenharmony_ci                                            : GrPorterDuffXPFactory::SimpleSrcOverXP();
112cb93a386Sopenharmony_ci    return thisXP.isEqual(thatXP);
113cb93a386Sopenharmony_ci}
114cb93a386Sopenharmony_ci
115cb93a386Sopenharmony_ciGrProcessorSet::Analysis GrProcessorSet::finalize(
116cb93a386Sopenharmony_ci        const GrProcessorAnalysisColor& colorInput, const GrProcessorAnalysisCoverage coverageInput,
117cb93a386Sopenharmony_ci        const GrAppliedClip* clip, const GrUserStencilSettings* userStencil,
118cb93a386Sopenharmony_ci        const GrCaps& caps, GrClampType clampType, SkPMColor4f* overrideInputColor) {
119cb93a386Sopenharmony_ci    SkASSERT(!this->isFinalized());
120cb93a386Sopenharmony_ci
121cb93a386Sopenharmony_ci    GrProcessorSet::Analysis analysis;
122cb93a386Sopenharmony_ci    analysis.fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput;
123cb93a386Sopenharmony_ci
124cb93a386Sopenharmony_ci    GrColorFragmentProcessorAnalysis colorAnalysis(colorInput, &fColorFragmentProcessor,
125cb93a386Sopenharmony_ci                                                   this->hasColorFragmentProcessor() ? 1 : 0);
126cb93a386Sopenharmony_ci    bool hasCoverageFP = this->hasCoverageFragmentProcessor();
127cb93a386Sopenharmony_ci    bool coverageUsesLocalCoords = false;
128cb93a386Sopenharmony_ci    if (hasCoverageFP) {
129cb93a386Sopenharmony_ci        if (!fCoverageFragmentProcessor->compatibleWithCoverageAsAlpha()) {
130cb93a386Sopenharmony_ci            analysis.fCompatibleWithCoverageAsAlpha = false;
131cb93a386Sopenharmony_ci        }
132cb93a386Sopenharmony_ci        coverageUsesLocalCoords |= fCoverageFragmentProcessor->usesSampleCoords();
133cb93a386Sopenharmony_ci    }
134cb93a386Sopenharmony_ci    if (clip && clip->hasCoverageFragmentProcessor()) {
135cb93a386Sopenharmony_ci        hasCoverageFP = true;
136cb93a386Sopenharmony_ci        const GrFragmentProcessor* clipFP = clip->coverageFragmentProcessor();
137cb93a386Sopenharmony_ci        analysis.fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
138cb93a386Sopenharmony_ci        coverageUsesLocalCoords |= clipFP->usesSampleCoords();
139cb93a386Sopenharmony_ci    }
140cb93a386Sopenharmony_ci    int colorFPsToEliminate = colorAnalysis.initialProcessorsToEliminate(overrideInputColor);
141cb93a386Sopenharmony_ci    analysis.fInputColorType = static_cast<Analysis::PackedInputColorType>(
142cb93a386Sopenharmony_ci            colorFPsToEliminate ? Analysis::kOverridden_InputColorType
143cb93a386Sopenharmony_ci                                : Analysis::kOriginal_InputColorType);
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_ci    GrProcessorAnalysisCoverage outputCoverage;
146cb93a386Sopenharmony_ci    if (GrProcessorAnalysisCoverage::kLCD == coverageInput) {
147cb93a386Sopenharmony_ci        outputCoverage = GrProcessorAnalysisCoverage::kLCD;
148cb93a386Sopenharmony_ci    } else if (hasCoverageFP || GrProcessorAnalysisCoverage::kSingleChannel == coverageInput) {
149cb93a386Sopenharmony_ci        outputCoverage = GrProcessorAnalysisCoverage::kSingleChannel;
150cb93a386Sopenharmony_ci    } else {
151cb93a386Sopenharmony_ci        outputCoverage = GrProcessorAnalysisCoverage::kNone;
152cb93a386Sopenharmony_ci    }
153cb93a386Sopenharmony_ci
154cb93a386Sopenharmony_ci    GrXPFactory::AnalysisProperties props = GrXPFactory::GetAnalysisProperties(
155cb93a386Sopenharmony_ci            this->xpFactory(), colorAnalysis.outputColor(), outputCoverage, caps, clampType);
156cb93a386Sopenharmony_ci    analysis.fRequiresDstTexture = (props & GrXPFactory::AnalysisProperties::kRequiresDstTexture) ||
157cb93a386Sopenharmony_ci                                   colorAnalysis.requiresDstTexture(caps);
158cb93a386Sopenharmony_ci    analysis.fCompatibleWithCoverageAsAlpha &=
159cb93a386Sopenharmony_ci            SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithCoverageAsAlpha);
160cb93a386Sopenharmony_ci    analysis.fRequiresNonOverlappingDraws =
161cb93a386Sopenharmony_ci            (props & GrXPFactory::AnalysisProperties::kRequiresNonOverlappingDraws) ||
162cb93a386Sopenharmony_ci            analysis.fRequiresDstTexture;
163cb93a386Sopenharmony_ci    analysis.fUsesNonCoherentHWBlending =
164cb93a386Sopenharmony_ci            SkToBool(props & GrXPFactory::AnalysisProperties::kUsesNonCoherentHWBlending);
165cb93a386Sopenharmony_ci    analysis.fUnaffectedByDstValue =
166cb93a386Sopenharmony_ci            SkToBool(props & GrXPFactory::AnalysisProperties::kUnaffectedByDstValue);
167cb93a386Sopenharmony_ci    if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) {
168cb93a386Sopenharmony_ci        colorFPsToEliminate = this->hasColorFragmentProcessor() ? 1 : 0;
169cb93a386Sopenharmony_ci        analysis.fInputColorType =
170cb93a386Sopenharmony_ci                static_cast<Analysis::PackedInputColorType>(Analysis::kIgnored_InputColorType);
171cb93a386Sopenharmony_ci        analysis.fUsesLocalCoords = coverageUsesLocalCoords;
172cb93a386Sopenharmony_ci    } else {
173cb93a386Sopenharmony_ci        analysis.fCompatibleWithCoverageAsAlpha &=
174cb93a386Sopenharmony_ci            colorAnalysis.allProcessorsCompatibleWithCoverageAsAlpha();
175cb93a386Sopenharmony_ci        analysis.fUsesLocalCoords = coverageUsesLocalCoords || colorAnalysis.usesLocalCoords();
176cb93a386Sopenharmony_ci    }
177cb93a386Sopenharmony_ci    if (colorFPsToEliminate) {
178cb93a386Sopenharmony_ci        SkASSERT(colorFPsToEliminate == 1);
179cb93a386Sopenharmony_ci        fColorFragmentProcessor = nullptr;
180cb93a386Sopenharmony_ci    }
181cb93a386Sopenharmony_ci    analysis.fHasColorFragmentProcessor = this->hasColorFragmentProcessor();
182cb93a386Sopenharmony_ci
183cb93a386Sopenharmony_ci    auto xp = GrXPFactory::MakeXferProcessor(this->xpFactory(), colorAnalysis.outputColor(),
184cb93a386Sopenharmony_ci                                             outputCoverage, caps, clampType);
185cb93a386Sopenharmony_ci    fXP.fProcessor = xp.release();
186cb93a386Sopenharmony_ci
187cb93a386Sopenharmony_ci    fFlags |= kFinalized_Flag;
188cb93a386Sopenharmony_ci    analysis.fIsInitialized = true;
189cb93a386Sopenharmony_ci#ifdef SK_DEBUG
190cb93a386Sopenharmony_ci    bool hasXferBarrier =
191cb93a386Sopenharmony_ci            fXP.fProcessor &&
192cb93a386Sopenharmony_ci            GrXferBarrierType::kNone_GrXferBarrierType != fXP.fProcessor->xferBarrierType(caps);
193cb93a386Sopenharmony_ci    bool needsNonOverlappingDraws = analysis.fRequiresDstTexture || hasXferBarrier;
194cb93a386Sopenharmony_ci    SkASSERT(analysis.fRequiresNonOverlappingDraws == needsNonOverlappingDraws);
195cb93a386Sopenharmony_ci#endif
196cb93a386Sopenharmony_ci    return analysis;
197cb93a386Sopenharmony_ci}
198cb93a386Sopenharmony_ci
199cb93a386Sopenharmony_civoid GrProcessorSet::visitProxies(const GrVisitProxyFunc& func) const {
200cb93a386Sopenharmony_ci    if (this->hasColorFragmentProcessor()) {
201cb93a386Sopenharmony_ci        fColorFragmentProcessor->visitProxies(func);
202cb93a386Sopenharmony_ci    }
203cb93a386Sopenharmony_ci    if (this->hasCoverageFragmentProcessor()) {
204cb93a386Sopenharmony_ci        fCoverageFragmentProcessor->visitProxies(func);
205cb93a386Sopenharmony_ci    }
206cb93a386Sopenharmony_ci}
207