Coverage Report

Created: 2021-08-22 09:07

/src/skia/src/gpu/effects/GrBezierEffect.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2013 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/GrShaderCaps.h"
9
#include "src/gpu/effects/GrBezierEffect.h"
10
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
11
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
12
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
13
#include "src/gpu/glsl/GrGLSLVarying.h"
14
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
15
16
class GrConicEffect::Impl : public ProgramImpl {
17
public:
18
    void setData(const GrGLSLProgramDataManager& pdman,
19
                 const GrShaderCaps& shaderCaps,
20
0
                 const GrGeometryProcessor& geomProc) override {
21
0
        const GrConicEffect& ce = geomProc.cast<GrConicEffect>();
22
23
0
        SetTransform(pdman, shaderCaps,  fViewMatrixUniform,  ce.fViewMatrix,  &fViewMatrix);
24
0
        SetTransform(pdman, shaderCaps, fLocalMatrixUniform, ce.fLocalMatrix, &fLocalMatrix);
25
26
0
        if (fColor != ce.fColor) {
27
0
            pdman.set4fv(fColorUniform, 1, ce.fColor.vec());
28
0
            fColor = ce.fColor;
29
0
        }
30
31
0
        if (ce.fCoverageScale != 0xff && ce.fCoverageScale != fCoverageScale) {
32
0
            pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.fCoverageScale));
33
0
            fCoverageScale = ce.fCoverageScale;
34
0
        }
35
0
    }
36
37
private:
38
    void onEmitCode(EmitArgs&, GrGPArgs*) override;
39
40
    SkMatrix    fViewMatrix    = SkMatrix::InvalidMatrix();
41
    SkMatrix    fLocalMatrix   = SkMatrix::InvalidMatrix();
42
    SkPMColor4f fColor         = SK_PMColor4fILLEGAL;
43
    uint8_t     fCoverageScale = 0xFF;
44
45
    UniformHandle fColorUniform;
46
    UniformHandle fCoverageScaleUniform;
47
    UniformHandle fViewMatrixUniform;
48
    UniformHandle fLocalMatrixUniform;
49
};
50
51
0
void GrConicEffect::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
52
0
    GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
53
0
    const GrConicEffect& gp = args.fGeomProc.cast<GrConicEffect>();
54
0
    GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
55
0
    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
56
57
    // emit attributes
58
0
    varyingHandler->emitAttributes(gp);
59
60
0
    GrGLSLVarying v(kFloat4_GrSLType);
61
0
    varyingHandler->addVarying("ConicCoeffs", &v);
62
0
    vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs().name());
63
64
0
    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
65
    // Setup pass through color
66
0
    fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
67
0
    this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
68
69
    // Setup position
70
0
    WriteOutputPosition(vertBuilder,
71
0
                        uniformHandler,
72
0
                        *args.fShaderCaps,
73
0
                        gpArgs,
74
0
                        gp.inPosition().name(),
75
0
                        gp.fViewMatrix,
76
0
                        &fViewMatrixUniform);
77
0
    if (gp.fUsesLocalCoords) {
78
0
        WriteLocalCoord(vertBuilder,
79
0
                        uniformHandler,
80
0
                        *args.fShaderCaps,
81
0
                        gpArgs,
82
0
                        gp.inPosition().asShaderVar(),
83
0
                        gp.fLocalMatrix,
84
0
                        &fLocalMatrixUniform);
85
0
    }
86
87
    // TODO: we should check on the number of bits float and half provide and use the smallest one
88
    // that suffices. Additionally we should assert that the upstream code only lets us get here if
89
    // either float or half provides the required number of bits.
90
91
0
    GrShaderVar edgeAlpha("edgeAlpha", kHalf_GrSLType, 0);
92
0
    GrShaderVar dklmdx("dklmdx", kFloat3_GrSLType, 0);
93
0
    GrShaderVar dklmdy("dklmdy", kFloat3_GrSLType, 0);
94
0
    GrShaderVar dfdx("dfdx", kFloat_GrSLType, 0);
95
0
    GrShaderVar dfdy("dfdy", kFloat_GrSLType, 0);
96
0
    GrShaderVar gF("gF", kFloat2_GrSLType, 0);
97
0
    GrShaderVar gFM("gFM", kFloat_GrSLType, 0);
98
0
    GrShaderVar func("func", kFloat_GrSLType, 0);
99
100
0
    fragBuilder->declAppend(edgeAlpha);
101
0
    fragBuilder->declAppend(dklmdx);
102
0
    fragBuilder->declAppend(dklmdy);
103
0
    fragBuilder->declAppend(dfdx);
104
0
    fragBuilder->declAppend(dfdy);
105
0
    fragBuilder->declAppend(gF);
106
0
    fragBuilder->declAppend(gFM);
107
0
    fragBuilder->declAppend(func);
108
109
0
    fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
110
0
    fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
111
0
    fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
112
0
                             dfdx.c_str(),
113
0
                             v.fsIn(), dklmdx.c_str(),
114
0
                             v.fsIn(), dklmdx.c_str(),
115
0
                             v.fsIn(), dklmdx.c_str());
116
0
    fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
117
0
                             dfdy.c_str(),
118
0
                             v.fsIn(), dklmdy.c_str(),
119
0
                             v.fsIn(), dklmdy.c_str(),
120
0
                             v.fsIn(), dklmdy.c_str());
121
0
    fragBuilder->codeAppendf("%s = float2(%s, %s);", gF.c_str(), dfdx.c_str(),
122
0
                             dfdy.c_str());
123
0
    fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
124
0
                             gFM.c_str(), gF.c_str(), gF.c_str());
125
0
    fragBuilder->codeAppendf("%s = %s.x*%s.x - %s.y*%s.z;",
126
0
                             func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
127
0
    fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
128
0
    fragBuilder->codeAppendf("%s = half(%s / %s);",
129
0
                             edgeAlpha.c_str(), func.c_str(), gFM.c_str());
130
0
    fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
131
0
                             edgeAlpha.c_str(), edgeAlpha.c_str());
132
    // Add line below for smooth cubic ramp
133
    // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
134
135
    // TODO should we really be doing this?
136
0
    if (gp.fCoverageScale != 0xff) {
137
0
        const char* coverageScale;
138
0
        fCoverageScaleUniform = uniformHandler->addUniform(nullptr,
139
0
                                                           kFragment_GrShaderFlag,
140
0
                                                           kFloat_GrSLType,
141
0
                                                           "Coverage",
142
0
                                                           &coverageScale);
143
0
        fragBuilder->codeAppendf("half4 %s = half4(half(%s) * %s);",
144
0
                                 args.fOutputCoverage, coverageScale, edgeAlpha.c_str());
145
0
    } else {
146
0
        fragBuilder->codeAppendf("half4 %s = half4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
147
0
    }
148
0
}
149
150
//////////////////////////////////////////////////////////////////////////////
151
152
constexpr GrGeometryProcessor::Attribute GrConicEffect::kAttributes[];
153
154
11
GrConicEffect::~GrConicEffect() = default;
155
156
0
void GrConicEffect::addToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
157
0
    uint32_t key = 0;
158
0
    key |= fCoverageScale == 0xff ? 0x8  : 0x0;
159
0
    key |= fUsesLocalCoords       ? 0x10 : 0x0;
160
0
    key = ProgramImpl::AddMatrixKeys(caps,
161
0
                                     key,
162
0
                                     fViewMatrix,
163
0
                                     fUsesLocalCoords ? fLocalMatrix : SkMatrix::I());
164
0
    b->add32(key);
165
0
}
166
167
std::unique_ptr<GrGeometryProcessor::ProgramImpl> GrConicEffect::makeProgramImpl(
168
0
        const GrShaderCaps&) const {
169
0
    return std::make_unique<Impl>();
170
0
}
171
172
GrConicEffect::GrConicEffect(const SkPMColor4f& color, const SkMatrix& viewMatrix, uint8_t coverage,
173
                             const SkMatrix& localMatrix, bool usesLocalCoords)
174
        : INHERITED(kGrConicEffect_ClassID)
175
        , fColor(color)
176
        , fViewMatrix(viewMatrix)
177
        , fLocalMatrix(viewMatrix)
178
        , fUsesLocalCoords(usesLocalCoords)
179
11
        , fCoverageScale(coverage) {
180
11
    this->setVertexAttributes(kAttributes, SK_ARRAY_COUNT(kAttributes));
181
11
}
182
183
//////////////////////////////////////////////////////////////////////////////
184
185
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
186
187
#if GR_TEST_UTILS
188
0
GrGeometryProcessor* GrConicEffect::TestCreate(GrProcessorTestData* d) {
189
0
    GrColor color = GrTest::RandomColor(d->fRandom);
190
0
    SkMatrix viewMatrix = GrTest::TestMatrix(d->fRandom);
191
0
    SkMatrix localMatrix = GrTest::TestMatrix(d->fRandom);
192
0
    bool usesLocalCoords = d->fRandom->nextBool();
193
0
    return GrConicEffect::Make(d->allocator(),
194
0
                               SkPMColor4f::FromBytes_RGBA(color),
195
0
                               viewMatrix,
196
0
                               *d->caps(),
197
0
                               localMatrix,
198
0
                               usesLocalCoords);
199
0
}
200
#endif
201
202
//////////////////////////////////////////////////////////////////////////////
203
// Quad
204
//////////////////////////////////////////////////////////////////////////////
205
206
class GrQuadEffect::Impl : public ProgramImpl {
207
public:
208
    void setData(const GrGLSLProgramDataManager& pdman,
209
                 const GrShaderCaps& shaderCaps,
210
0
                 const GrGeometryProcessor& geomProc) override {
211
0
        const GrQuadEffect& qe = geomProc.cast<GrQuadEffect>();
212
213
0
        SetTransform(pdman, shaderCaps,  fViewMatrixUniform,  qe.fViewMatrix, &fViewMatrix);
214
0
        SetTransform(pdman, shaderCaps, fLocalMatrixUniform, qe.fLocalMatrix, &fLocalMatrix);
215
216
0
        if (qe.fColor != fColor) {
217
0
            pdman.set4fv(fColorUniform, 1, qe.fColor.vec());
218
0
            fColor = qe.fColor;
219
0
        }
220
221
0
        if (qe.fCoverageScale != 0xff && qe.fCoverageScale != fCoverageScale) {
222
0
            pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.fCoverageScale));
223
0
            fCoverageScale = qe.fCoverageScale;
224
0
        }
225
0
    }
226
227
private:
228
    void onEmitCode(EmitArgs&, GrGPArgs*) override;
229
230
    SkMatrix    fViewMatrix     = SkMatrix::InvalidMatrix();
231
    SkMatrix    fLocalMatrix    = SkMatrix::InvalidMatrix();
232
    SkPMColor4f fColor          = SK_PMColor4fILLEGAL;
233
    uint8_t     fCoverageScale  = 0xFF;
234
235
    UniformHandle fColorUniform;
236
    UniformHandle fCoverageScaleUniform;
237
    UniformHandle fViewMatrixUniform;
238
    UniformHandle fLocalMatrixUniform;
239
};
240
241
0
void GrQuadEffect::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
242
0
    GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
243
0
    const GrQuadEffect& gp = args.fGeomProc.cast<GrQuadEffect>();
244
0
    GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
245
0
    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
246
247
    // emit attributes
248
0
    varyingHandler->emitAttributes(gp);
249
250
0
    GrGLSLVarying v(kHalf4_GrSLType);
251
0
    varyingHandler->addVarying("HairQuadEdge", &v);
252
0
    vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge().name());
253
254
0
    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
255
    // Setup pass through color
256
0
    fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
257
0
    this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
258
259
    // Setup position
260
0
    WriteOutputPosition(vertBuilder,
261
0
                        uniformHandler,
262
0
                        *args.fShaderCaps,
263
0
                        gpArgs,
264
0
                        gp.inPosition().name(),
265
0
                        gp.fViewMatrix,
266
0
                        &fViewMatrixUniform);
267
0
    if (gp.fUsesLocalCoords) {
268
0
        WriteLocalCoord(vertBuilder,
269
0
                        uniformHandler,
270
0
                        *args.fShaderCaps,
271
0
                        gpArgs,
272
0
                        gp.inPosition().asShaderVar(),
273
0
                        gp.fLocalMatrix,
274
0
                        &fLocalMatrixUniform);
275
0
    }
276
277
0
    fragBuilder->codeAppendf("half edgeAlpha;");
278
279
0
    fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn());
280
0
    fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn());
281
0
    fragBuilder->codeAppendf("half2 gF = half2(2.0 * %s.x * duvdx.x - duvdx.y,"
282
0
                             "               2.0 * %s.x * duvdy.x - duvdy.y);",
283
0
                             v.fsIn(), v.fsIn());
284
0
    fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
285
0
                             v.fsIn(), v.fsIn(), v.fsIn());
286
0
    fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
287
0
    fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
288
    // Add line below for smooth cubic ramp
289
    // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
290
291
0
    if (gp.fCoverageScale != 0xFF) {
292
0
        const char* coverageScale;
293
0
        fCoverageScaleUniform = uniformHandler->addUniform(nullptr,
294
0
                                                           kFragment_GrShaderFlag,
295
0
                                                           kHalf_GrSLType,
296
0
                                                           "Coverage",
297
0
                                                           &coverageScale);
298
0
        fragBuilder->codeAppendf("half4 %s = half4(%s * edgeAlpha);", args.fOutputCoverage,
299
0
                                 coverageScale);
300
0
    } else {
301
0
        fragBuilder->codeAppendf("half4 %s = half4(edgeAlpha);", args.fOutputCoverage);
302
0
    }
303
0
}
304
305
//////////////////////////////////////////////////////////////////////////////
306
307
constexpr GrGeometryProcessor::Attribute GrQuadEffect::kAttributes[];
308
309
46
GrQuadEffect::~GrQuadEffect() = default;
310
311
0
void GrQuadEffect::addToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
312
0
    uint32_t key = 0;
313
0
    key |= fCoverageScale != 0xff ? 0x8  : 0x0;
314
0
    key |= fUsesLocalCoords       ? 0x10 : 0x0;
315
0
    key = ProgramImpl::AddMatrixKeys(caps,
316
0
                                     key,
317
0
                                     fViewMatrix,
318
0
                                     fUsesLocalCoords ? fLocalMatrix : SkMatrix::I());
319
0
    b->add32(key);
320
0
}
321
322
std::unique_ptr<GrGeometryProcessor::ProgramImpl> GrQuadEffect::makeProgramImpl(
323
0
        const GrShaderCaps&) const {
324
0
    return std::make_unique<Impl>();
325
0
}
326
327
GrQuadEffect::GrQuadEffect(const SkPMColor4f& color, const SkMatrix& viewMatrix, uint8_t coverage,
328
                           const SkMatrix& localMatrix, bool usesLocalCoords)
329
    : INHERITED(kGrQuadEffect_ClassID)
330
    , fColor(color)
331
    , fViewMatrix(viewMatrix)
332
    , fLocalMatrix(localMatrix)
333
    , fUsesLocalCoords(usesLocalCoords)
334
46
    , fCoverageScale(coverage) {
335
46
    this->setVertexAttributes(kAttributes, SK_ARRAY_COUNT(kAttributes));
336
46
}
337
338
//////////////////////////////////////////////////////////////////////////////
339
340
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
341
342
#if GR_TEST_UTILS
343
0
GrGeometryProcessor* GrQuadEffect::TestCreate(GrProcessorTestData* d) {
344
0
    GrColor color = GrTest::RandomColor(d->fRandom);
345
0
    SkMatrix viewMatrix = GrTest::TestMatrix(d->fRandom);
346
0
    SkMatrix localMatrix = GrTest::TestMatrix(d->fRandom);
347
0
    bool usesLocalCoords = d->fRandom->nextBool();
348
0
    return GrQuadEffect::Make(d->allocator(),
349
0
                              SkPMColor4f::FromBytes_RGBA(color),
350
0
                              viewMatrix,
351
0
                              *d->caps(),
352
0
                              localMatrix,
353
0
                              usesLocalCoords);
354
0
}
355
#endif