192ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon/*
292ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon * Copyright 2017 Google Inc.
392ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon *
492ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon * Use of this source code is governed by a BSD-style license that can be
592ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon * found in the LICENSE file.
692ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon */
792ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon
892ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon#include "GrProcessorSet.h"
95298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon#include "GrAppliedClip.h"
105298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon#include "GrCaps.h"
11318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon#include "GrXferProcessor.h"
12477d0efcf2d90c70a87c5a126349e76ac57d9649Brian Salomon#include "SkBlendModePriv.h"
1348d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon#include "effects/GrPorterDuffXferProcessor.h"
1492ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon
15292bf7a163729330ec6d337992ddd2403a0ed8a2Brian Salomonconst GrProcessorSet& GrProcessorSet::EmptySet() {
16292bf7a163729330ec6d337992ddd2403a0ed8a2Brian Salomon    static const GrProcessorSet gEmpty(GrProcessorSet::Empty::kEmpty);
17292bf7a163729330ec6d337992ddd2403a0ed8a2Brian Salomon    return gEmpty;
18292bf7a163729330ec6d337992ddd2403a0ed8a2Brian Salomon}
196d4b65e9dad972a09aa1928d28a1739ab6c77d4cBrian Salomon
2048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian SalomonGrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) {
21f87e2b95f098dd1b43f0704a95057818251d4b5cBrian Salomon    fFlags = 0;
228d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon    if (paint.numColorFragmentProcessors() <= kMaxColorProcessors) {
238d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon        fColorFragmentProcessorCnt = paint.numColorFragmentProcessors();
248d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon        fFragmentProcessors.reset(paint.numTotalFragmentProcessors());
258d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon        int i = 0;
268d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon        for (auto& fp : paint.fColorFragmentProcessors) {
275f970fe6bed7a40ba95365bfe3220f18699a9176Brian Salomon            SkASSERT(fp.get());
288d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon            fFragmentProcessors[i++] = fp.release();
298d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon        }
308d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon        for (auto& fp : paint.fCoverageFragmentProcessors) {
315f970fe6bed7a40ba95365bfe3220f18699a9176Brian Salomon            SkASSERT(fp.get());
328d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon            fFragmentProcessors[i++] = fp.release();
338d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon        }
348d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon    } else {
358d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon        SkDebugf("Insane number of color fragment processors in paint. Dropping all processors.");
368d2f90b37b9caa120599a71530545dd11853c0bcBrian Salomon        fColorFragmentProcessorCnt = 0;
37f87e2b95f098dd1b43f0704a95057818251d4b5cBrian Salomon    }
3892ce5946855aa8d55bb4a0dd0a47d58746d67d0aBrian Salomon}
395298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon
40477d0efcf2d90c70a87c5a126349e76ac57d9649Brian SalomonGrProcessorSet::GrProcessorSet(SkBlendMode mode)
41477d0efcf2d90c70a87c5a126349e76ac57d9649Brian Salomon        : fXP(SkBlendMode_AsXPFactory(mode))
42477d0efcf2d90c70a87c5a126349e76ac57d9649Brian Salomon        , fColorFragmentProcessorCnt(0)
43477d0efcf2d90c70a87c5a126349e76ac57d9649Brian Salomon        , fFragmentProcessorOffset(0)
44477d0efcf2d90c70a87c5a126349e76ac57d9649Brian Salomon        , fFlags(0) {}
45477d0efcf2d90c70a87c5a126349e76ac57d9649Brian Salomon
4682ddc94aff0c8400a35f8006ee448574347c0c28Brian SalomonGrProcessorSet::GrProcessorSet(sk_sp<GrFragmentProcessor> colorFP)
4782ddc94aff0c8400a35f8006ee448574347c0c28Brian Salomon        : fFragmentProcessors(1)
4882ddc94aff0c8400a35f8006ee448574347c0c28Brian Salomon        , fXP((const GrXPFactory*)nullptr)
4982ddc94aff0c8400a35f8006ee448574347c0c28Brian Salomon        , fColorFragmentProcessorCnt(1)
5082ddc94aff0c8400a35f8006ee448574347c0c28Brian Salomon        , fFragmentProcessorOffset(0)
5182ddc94aff0c8400a35f8006ee448574347c0c28Brian Salomon        , fFlags(0) {
5282ddc94aff0c8400a35f8006ee448574347c0c28Brian Salomon    SkASSERT(colorFP);
5382ddc94aff0c8400a35f8006ee448574347c0c28Brian Salomon    fFragmentProcessors[0] = colorFP.release();
5482ddc94aff0c8400a35f8006ee448574347c0c28Brian Salomon}
5582ddc94aff0c8400a35f8006ee448574347c0c28Brian Salomon
5654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian SalomonGrProcessorSet::~GrProcessorSet() {
5770288c0a9179f308fc7de1b07899baef4446e444Brian Salomon    for (int i = fFragmentProcessorOffset; i < fFragmentProcessors.count(); ++i) {
5848d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        if (this->isFinalized()) {
5970288c0a9179f308fc7de1b07899baef4446e444Brian Salomon            fFragmentProcessors[i]->completedExecution();
6070288c0a9179f308fc7de1b07899baef4446e444Brian Salomon        } else {
6170288c0a9179f308fc7de1b07899baef4446e444Brian Salomon            fFragmentProcessors[i]->unref();
6254d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon        }
6354d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon    }
6448d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    if (this->isFinalized() && this->xferProcessor()) {
65d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomon        this->xferProcessor()->unref();
6654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon    }
6754d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon}
6854d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon
6982dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian SalomonSkString dump_fragment_processor_tree(const GrFragmentProcessor* fp, int indentCnt) {
7082dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    SkString result;
7182dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    SkString indentString;
7282dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    for (int i = 0; i < indentCnt; ++i) {
7382dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        indentString.append("    ");
7482dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    }
7582dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    result.appendf("%s%s %s \n", indentString.c_str(), fp->name(), fp->dumpInfo().c_str());
7682dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    if (fp->numChildProcessors()) {
7782dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        for (int i = 0; i < fp->numChildProcessors(); ++i) {
7882dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            result += dump_fragment_processor_tree(&fp->childProcessor(i), indentCnt + 1);
7982dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        }
8082dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    }
8182dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    return result;
8282dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon}
8382dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon
8482dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian SalomonSkString GrProcessorSet::dumpProcessors() const {
8582dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    SkString result;
8682dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    if (this->numFragmentProcessors()) {
8782dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        if (this->numColorFragmentProcessors()) {
8882dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            result.append("Color Fragment Processors:\n");
8982dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            for (int i = 0; i < this->numColorFragmentProcessors(); ++i) {
9082dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon                result += dump_fragment_processor_tree(this->colorFragmentProcessor(i), 1);
9182dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            }
9282dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        } else {
9382dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            result.append("No color fragment processors.\n");
9482dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        }
9582dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        if (this->numCoverageFragmentProcessors()) {
9682dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            result.append("Coverage Fragment Processors:\n");
9782dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            for (int i = 0; i < this->numColorFragmentProcessors(); ++i) {
9882dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon                result += dump_fragment_processor_tree(this->coverageFragmentProcessor(i), 1);
9982dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            }
10082dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        } else {
10182dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            result.append("No coverage fragment processors.\n");
10282dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        }
10382dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    } else {
10482dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        result.append("No color or coverage fragment processors.\n");
10582dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    }
10682dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    if (this->isFinalized()) {
10782dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        result.append("Xfer Processor: ");
10882dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        if (this->xferProcessor()) {
10982dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            result.appendf("%s\n", this->xferProcessor()->name());
11082dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        } else {
11182dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon            result.append("SrcOver\n");
11282dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        }
11382dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    } else {
11482dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        result.append("XP Factory dumping not implemented.\n");
11582dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    }
11682dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon    return result;
11782dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon}
11882dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon
11954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomonbool GrProcessorSet::operator==(const GrProcessorSet& that) const {
12048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    SkASSERT(this->isFinalized());
12148d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    SkASSERT(that.isFinalized());
12270288c0a9179f308fc7de1b07899baef4446e444Brian Salomon    int fpCount = this->numFragmentProcessors();
12348d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    if (((fFlags ^ that.fFlags) & ~kFinalized_Flag) || fpCount != that.numFragmentProcessors() ||
12454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon        fColorFragmentProcessorCnt != that.fColorFragmentProcessorCnt) {
12554d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon        return false;
12654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon    }
12770288c0a9179f308fc7de1b07899baef4446e444Brian Salomon
12870288c0a9179f308fc7de1b07899baef4446e444Brian Salomon    for (int i = 0; i < fpCount; ++i) {
12970288c0a9179f308fc7de1b07899baef4446e444Brian Salomon        int a = i + fFragmentProcessorOffset;
13070288c0a9179f308fc7de1b07899baef4446e444Brian Salomon        int b = i + that.fFragmentProcessorOffset;
13170288c0a9179f308fc7de1b07899baef4446e444Brian Salomon        if (!fFragmentProcessors[a]->isEqual(*that.fFragmentProcessors[b])) {
13254d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon            return false;
13354d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon        }
13454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon    }
13548d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    // Most of the time both of these are null
13648d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    if (!this->xferProcessor() && !that.xferProcessor()) {
13748d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        return true;
13854d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon    }
13948d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    const GrXferProcessor& thisXP = this->xferProcessor()
14048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                                            ? *this->xferProcessor()
14148d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                                            : GrPorterDuffXPFactory::SimpleSrcOverXP();
14248d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    const GrXferProcessor& thatXP = that.xferProcessor()
14348d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                                            ? *that.xferProcessor()
14448d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                                            : GrPorterDuffXPFactory::SimpleSrcOverXP();
14548d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    return thisXP.isEqual(thatXP);
14654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon}
14754d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon
14848d1b4c2b2c0f41a10376ed657cde043d8f11979Brian SalomonGrProcessorSet::Analysis GrProcessorSet::finalize(const GrProcessorAnalysisColor& colorInput,
14948d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                                                  const GrProcessorAnalysisCoverage coverageInput,
15048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                                                  const GrAppliedClip* clip, bool isMixedSamples,
15148d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                                                  const GrCaps& caps, GrColor* overrideInputColor) {
15248d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    SkASSERT(!this->isFinalized());
15348d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    SkASSERT(!fFragmentProcessorOffset);
15448d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon
15548d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    GrProcessorSet::Analysis analysis;
15648d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon
15748d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    const GrFragmentProcessor* clipFP = clip ? clip->clipCoverageFragmentProcessor() : nullptr;
15848d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    GrColorFragmentProcessorAnalysis colorAnalysis(colorInput);
15948d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    analysis.fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput;
16048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon
16148d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    const GrFragmentProcessor* const* fps = fFragmentProcessors.get() + fFragmentProcessorOffset;
16248d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    colorAnalysis.analyzeProcessors(fps, fColorFragmentProcessorCnt);
16348d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    analysis.fCompatibleWithCoverageAsAlpha &=
16448d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon            colorAnalysis.allProcessorsCompatibleWithCoverageAsAlpha();
16548d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    fps += fColorFragmentProcessorCnt;
16648d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    int n = this->numCoverageFragmentProcessors();
1675298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon    bool hasCoverageFP = n > 0;
168318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon    bool coverageUsesLocalCoords = false;
169bfafcba05a54e1bc9c3074353a155d61119d095cBrian Salomon    for (int i = 0; i < n; ++i) {
1705298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon        if (!fps[i]->compatibleWithCoverageAsAlpha()) {
17148d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon            analysis.fCompatibleWithCoverageAsAlpha = false;
1725298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon            // Other than tests that exercise atypical behavior we expect all coverage FPs to be
1735298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon            // compatible with the coverage-as-alpha optimization.
1745298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon            GrCapsDebugf(&caps, "Coverage FP is not compatible with coverage as alpha.\n");
1755298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon        }
176318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon        coverageUsesLocalCoords |= fps[i]->usesLocalCoords();
1775298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon    }
1785298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon
1795298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon    if (clipFP) {
18048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        analysis.fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
181318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon        coverageUsesLocalCoords |= clipFP->usesLocalCoords();
1825298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon        hasCoverageFP = true;
1835298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon    }
18448d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    int colorFPsToEliminate = colorAnalysis.initialProcessorsToEliminate(overrideInputColor);
18548d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    analysis.fInputColorType = static_cast<Analysis::PackedInputColorType>(
18648d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon            colorFPsToEliminate ? Analysis::kOverridden_InputColorType
18748d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                                : Analysis::kOriginal_InputColorType);
1885298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon
189a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon    GrProcessorAnalysisCoverage outputCoverage;
190a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon    if (GrProcessorAnalysisCoverage::kLCD == coverageInput) {
191a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon        outputCoverage = GrProcessorAnalysisCoverage::kLCD;
192a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon    } else if (hasCoverageFP || GrProcessorAnalysisCoverage::kSingleChannel == coverageInput) {
193a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon        outputCoverage = GrProcessorAnalysisCoverage::kSingleChannel;
1945298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon    } else {
195a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon        outputCoverage = GrProcessorAnalysisCoverage::kNone;
196318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon    }
197318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon
198318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon    GrXPFactory::AnalysisProperties props = GrXPFactory::GetAnalysisProperties(
19948d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon            this->xpFactory(), colorAnalysis.outputColor(), outputCoverage, caps);
20048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    if (!this->numCoverageFragmentProcessors() &&
201a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon        GrProcessorAnalysisCoverage::kNone == coverageInput) {
20248d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        analysis.fCanCombineOverlappedStencilAndCover = SkToBool(
203318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon                props & GrXPFactory::AnalysisProperties::kCanCombineOverlappedStencilAndCover);
204318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon    } else {
205318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon        // If we have non-clipping coverage processors we don't try to merge stencil steps as its
206318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon        // unclear whether it will be correct. We don't expect this to happen in practice.
20748d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        analysis.fCanCombineOverlappedStencilAndCover = false;
208318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon    }
20948d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    analysis.fRequiresDstTexture =
21048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon            SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresDstTexture);
21148d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    analysis.fCompatibleWithCoverageAsAlpha &=
212318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon            SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithAlphaAsCoverage);
21348d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    analysis.fRequiresBarrierBetweenOverlappingDraws = SkToBool(
2144fc774060036ef04fbc1d92a018e42df8704ff50Brian Salomon            props & GrXPFactory::AnalysisProperties::kRequiresBarrierBetweenOverlappingDraws);
215318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon    if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) {
21648d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        colorFPsToEliminate = this->numColorFragmentProcessors();
21748d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        analysis.fInputColorType =
21848d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                static_cast<Analysis::PackedInputColorType>(Analysis::kIgnored_InputColorType);
21948d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        analysis.fUsesLocalCoords = coverageUsesLocalCoords;
220318538484f99253b6a2acf97d4d1b420e628b289Brian Salomon    } else {
22148d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        analysis.fUsesLocalCoords = coverageUsesLocalCoords | colorAnalysis.usesLocalCoords();
2225298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon    }
22348d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    for (int i = 0; i < colorFPsToEliminate; ++i) {
22448d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        fFragmentProcessors[i]->unref();
22548d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        fFragmentProcessors[i] = nullptr;
22648d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    }
22748d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    for (int i = colorFPsToEliminate; i < fFragmentProcessors.count(); ++i) {
22848d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        fFragmentProcessors[i]->addPendingExecution();
22948d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon        fFragmentProcessors[i]->unref();
23048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    }
23148d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    fFragmentProcessorOffset = colorFPsToEliminate;
23248d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    fColorFragmentProcessorCnt -= colorFPsToEliminate;
23348d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon
23448d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    auto xp = GrXPFactory::MakeXferProcessor(this->xpFactory(), colorAnalysis.outputColor(),
23548d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon                                             outputCoverage, isMixedSamples, caps);
236d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomon    fXP.fProcessor = xp.release();
23748d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon
238d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomon    fFlags |= kFinalized_Flag;
23948d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    analysis.fIsInitialized = true;
24048d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon    return analysis;
24170288c0a9179f308fc7de1b07899baef4446e444Brian Salomon}
242