Coverage Report

Created: 2024-05-20 07:14

/src/skia/src/gpu/ganesh/glsl/GrGLSLProgramBuilder.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2015 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
#ifndef GrGLSLProgramBuilder_DEFINED
9
#define GrGLSLProgramBuilder_DEFINED
10
11
#include "include/private/base/SkDebug.h"
12
#include "include/private/base/SkTArray.h"
13
#include "include/private/gpu/ganesh/GrTypesPriv.h"
14
#include "src/gpu/Swizzle.h"
15
#include "src/gpu/ganesh/GrCaps.h"
16
#include "src/gpu/ganesh/GrFragmentProcessor.h"
17
#include "src/gpu/ganesh/GrGeometryProcessor.h"
18
#include "src/gpu/ganesh/GrPipeline.h"
19
#include "src/gpu/ganesh/GrProgramInfo.h"
20
#include "src/gpu/ganesh/GrSamplerState.h"
21
#include "src/gpu/ganesh/GrShaderVar.h"
22
#include "src/gpu/ganesh/GrXferProcessor.h"
23
#include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
24
#include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
25
#include "src/gpu/ganesh/glsl/GrGLSLVertexGeoBuilder.h"
26
27
#include <cstdint>
28
#include <memory>
29
#include <string>
30
#include <vector>
31
32
class GrBackendFormat;
33
class GrGLSLVaryingHandler;
34
class GrProgramDesc;
35
class SkString;
36
enum GrSurfaceOrigin : int;
37
struct GrShaderCaps;
38
39
class GrGLSLProgramBuilder {
40
public:
41
    using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
42
    using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
43
44
    virtual ~GrGLSLProgramBuilder();
45
46
    virtual const GrCaps* caps() const = 0;
47
0
    const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
48
49
0
    GrSurfaceOrigin origin() const { return fProgramInfo.origin(); }
50
0
    const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); }
51
0
    const GrGeometryProcessor& geometryProcessor() const { return fProgramInfo.geomProc(); }
52
0
    bool snapVerticesToPixelCenters() const {
53
0
        return fProgramInfo.pipeline().snapVerticesToPixelCenters();
54
0
    }
55
0
    bool hasPointSize() const { return fProgramInfo.primitiveType() == GrPrimitiveType::kPoints; }
56
57
0
    const GrProgramDesc& desc() const { return fDesc; }
58
59
    void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
60
61
0
    const char* samplerVariable(SamplerHandle handle) const {
62
0
        return this->uniformHandler()->samplerVariable(handle);
63
0
    }
64
65
0
    skgpu::Swizzle samplerSwizzle(SamplerHandle handle) const {
66
0
        return this->uniformHandler()->samplerSwizzle(handle);
67
0
    }
68
69
0
    const char* inputSamplerVariable(SamplerHandle handle) const {
70
0
        return this->uniformHandler()->inputSamplerVariable(handle);
71
0
    }
72
73
0
    skgpu::Swizzle inputSamplerSwizzle(SamplerHandle handle) const {
74
0
        return this->uniformHandler()->inputSamplerSwizzle(handle);
75
0
    }
76
77
    // Used to add a uniform for render target flip (used for dFdy, sk_Clockwise, and sk_FragCoord)
78
    // without mangling the name of the uniform inside of a stage.
79
    void addRTFlipUniform(const char* name);
80
81
    // Generates a name for a variable. The generated string will be name prefixed by the prefix
82
    // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
83
    // explicitly asked not to. `nameVariable` can also be used to generate names for functions or
84
    // other types of symbols where unique names are important.
85
    SkString nameVariable(char prefix, const char* name, bool mangle = true);
86
87
    /**
88
     * Emits samplers for TextureEffect fragment processors as needed. `fp` can be a TextureEffect,
89
     * or a tree containing zero or more TextureEffects.
90
     */
91
    bool emitTextureSamplersForFPs(const GrFragmentProcessor& fp,
92
                                   GrFragmentProcessor::ProgramImpl& impl,
93
                                   int* samplerIndex);
94
95
    /**
96
     * advanceStage is called by program creator between each processor's emit code.  It increments
97
     * the stage index for variable name mangling, and also ensures verification variables in the
98
     * fragment shader are cleared.
99
     */
100
0
    void advanceStage() {
101
0
        fStageIndex++;
102
0
        SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();)
103
0
        fFS.nextStage();
104
0
    }
Unexecuted instantiation: GrGLSLProgramBuilder::advanceStage()
Unexecuted instantiation: GrGLSLProgramBuilder::advanceStage()
105
106
    /** Adds the SkSL function that implements an FP assuming its children are already written. */
107
    void writeFPFunction(const GrFragmentProcessor& fp, GrFragmentProcessor::ProgramImpl& impl);
108
109
    /**
110
     * Returns a function-call invocation of `fp` in string form, passing the appropriate
111
     * combination of `inputColor`, `destColor` and `fLocalCoordsVar` for the FP.
112
     */
113
    std::string invokeFP(const GrFragmentProcessor& fp,
114
                         const GrFragmentProcessor::ProgramImpl& impl,
115
                         const char* inputColor,
116
                         const char* destColor,
117
                         const char* coords) const;
118
    /**
119
     * If the FP's coords are unused or all uses have been lifted to interpolated varyings then
120
     * don't put coords in the FP's function signature or call sites.
121
     */
122
    bool fragmentProcessorHasCoordsParam(const GrFragmentProcessor*) const;
123
124
    virtual GrGLSLUniformHandler* uniformHandler() = 0;
125
    virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
126
    virtual GrGLSLVaryingHandler* varyingHandler() = 0;
127
128
    // Used for backend customization of the secondary color variable from the fragment processor.
129
    // Only used if the output is explicitly declared in the shaders.
130
0
    virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {}
131
132
    // number of each input/output type in a single allocation block, used by many builders
133
    static const int kVarsPerBlock;
134
135
    GrGLSLVertexBuilder          fVS;
136
    GrGLSLFragmentShaderBuilder  fFS;
137
138
    const GrProgramDesc&         fDesc;
139
    const GrProgramInfo&         fProgramInfo;
140
141
    GrGLSLBuiltinUniformHandles  fUniformHandles;
142
143
    std::unique_ptr<GrGeometryProcessor::ProgramImpl>               fGPImpl;
144
    std::unique_ptr<GrXferProcessor::ProgramImpl>                   fXPImpl;
145
    std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>>  fFPImpls;
146
147
    SamplerHandle fDstTextureSamplerHandle;
148
    GrSurfaceOrigin fDstTextureOrigin;
149
150
protected:
151
    explicit GrGLSLProgramBuilder(const GrProgramDesc&, const GrProgramInfo&);
152
153
    void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
154
155
    bool emitAndInstallProcs();
156
157
    void finalizeShaders();
158
159
0
    bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); }
160
161
private:
162
    SkString getMangleSuffix() const;
163
164
    // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
165
    void nameExpression(SkString*, const char* baseName);
166
167
    bool emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage);
168
    bool emitAndInstallDstTexture();
169
    /** Adds the root FPs */
170
    bool emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
171
    /** Adds a single root FP tree. */
172
    SkString emitRootFragProc(const GrFragmentProcessor& fp,
173
                              GrFragmentProcessor::ProgramImpl& impl,
174
                              const SkString& input,
175
                              SkString output);
176
    /** Recursive step to write out children FPs' functions before parent's. */
177
    void writeChildFPFunctions(const GrFragmentProcessor& fp,
178
                               GrFragmentProcessor::ProgramImpl& impl);
179
    bool emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
180
    SamplerHandle emitSampler(const GrBackendFormat&, GrSamplerState, const skgpu::Swizzle&,
181
                              const char* name);
182
    SamplerHandle emitInputSampler(const skgpu::Swizzle& swizzle, const char* name);
183
    bool checkSamplerCounts();
184
185
#ifdef SK_DEBUG
186
    void verify(const GrGeometryProcessor&);
187
    void verify(const GrFragmentProcessor&);
188
    void verify(const GrXferProcessor&);
189
#endif
190
191
    // This is used to check that we don't excede the allowable number of resources in a shader.
192
    int fNumFragmentSamplers;
193
194
    GrGeometryProcessor::ProgramImpl::FPCoordsMap fFPCoordsMap;
195
    GrShaderVar                                   fLocalCoordsVar;
196
197
    /**
198
     * Each root processor has an stage index. The GP is stage 0. The first root FP is stage 1,
199
     * the second root FP is stage 2, etc. The XP's stage index is last and its value depends on
200
     * how many root FPs there are. Names are mangled by appending _S<stage-index>.
201
     */
202
    int fStageIndex = -1;
203
204
    /**
205
     * When emitting FP stages we track the children FPs as "substages" and do additional name
206
     * mangling based on where in the FP hierarchy we are. The first FP is stage index 1. It's first
207
     * child would be substage 0 of stage 1. If that FP also has three children then its third child
208
     * would be substage 2 of stubstage 0 of stage 1 and would be mangled as "_S1_c0_c2".
209
     */
210
    skia_private::TArray<int> fSubstageIndices;
211
};
212
213
#endif