Coverage Report

Created: 2024-05-20 07:14

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