aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
blob: 73a1aa0d7bf04f1da379c5a0098d15e5f00d7ce4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrGLSLPrimitiveProcessor_DEFINED
#define GrGLSLPrimitiveProcessor_DEFINED

#include "GrFragmentProcessor.h"
#include "GrPrimitiveProcessor.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"

class GrPrimitiveProcessor;
class GrGLSLFPFragmentBuilder;
class GrGLSLGeometryBuilder;
class GrGLSLGPBuilder;
class GrGLSLVaryingHandler;
class GrGLSLVertexBuilder;
class GrShaderCaps;

class GrGLSLPrimitiveProcessor {
public:
    using FPCoordTransformIter = GrFragmentProcessor::CoordTransformIter;

    virtual ~GrGLSLPrimitiveProcessor() {}

    using UniformHandle      = GrGLSLProgramDataManager::UniformHandle;
    using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;

    /**
     * This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a
     * GrPipeline. It is also used by the primitive processor to specify the fragment shader
     * variable that will hold the transformed coords for each GrCoordTransform. It is required that
     * the primitive processor iterate over each coord transform and insert a shader var result for
     * each. The GrGLSLFragmentProcessors will reference these variables in their fragment code.
     */
    class FPCoordTransformHandler : public SkNoncopyable {
    public:
        FPCoordTransformHandler(const GrPipeline& pipeline,
                                SkTArray<GrShaderVar>* transformedCoordVars)
                : fIter(pipeline)
                , fTransformedCoordVars(transformedCoordVars) {}

        ~FPCoordTransformHandler() { SkASSERT(!this->nextCoordTransform());}

        const GrCoordTransform* nextCoordTransform();

        // 'args' are constructor params to GrShaderVar.
        template<typename... Args>
        void specifyCoordsForCurrCoordTransform(Args&&... args) {
            SkASSERT(!fAddedCoord);
            fTransformedCoordVars->emplace_back(std::forward<Args>(args)...);
            SkDEBUGCODE(fAddedCoord = true;)
        }

    private:
        GrFragmentProcessor::CoordTransformIter fIter;
        SkDEBUGCODE(bool                        fAddedCoord = false;)
        SkDEBUGCODE(const GrCoordTransform*     fCurr = nullptr;)
        SkTArray<GrShaderVar>*                  fTransformedCoordVars;
    };

    struct EmitArgs {
        EmitArgs(GrGLSLVertexBuilder* vertBuilder,
                 GrGLSLGeometryBuilder* geomBuilder,
                 GrGLSLFPFragmentBuilder* fragBuilder,
                 GrGLSLVaryingHandler* varyingHandler,
                 GrGLSLUniformHandler* uniformHandler,
                 const GrShaderCaps* caps,
                 const GrPrimitiveProcessor& gp,
                 const char* outputColor,
                 const char* outputCoverage,
                 const char* rtAdjustName,
                 const SamplerHandle* texSamplers,
                 FPCoordTransformHandler* transformHandler)
            : fVertBuilder(vertBuilder)
            , fGeomBuilder(geomBuilder)
            , fFragBuilder(fragBuilder)
            , fVaryingHandler(varyingHandler)
            , fUniformHandler(uniformHandler)
            , fShaderCaps(caps)
            , fGP(gp)
            , fOutputColor(outputColor)
            , fOutputCoverage(outputCoverage)
            , fRTAdjustName(rtAdjustName)
            , fTexSamplers(texSamplers)
            , fFPCoordTransformHandler(transformHandler) {}
        GrGLSLVertexBuilder* fVertBuilder;
        GrGLSLGeometryBuilder* fGeomBuilder;
        GrGLSLFPFragmentBuilder* fFragBuilder;
        GrGLSLVaryingHandler* fVaryingHandler;
        GrGLSLUniformHandler* fUniformHandler;
        const GrShaderCaps* fShaderCaps;
        const GrPrimitiveProcessor& fGP;
        const char* fOutputColor;
        const char* fOutputCoverage;
        const char* fRTAdjustName;
        const SamplerHandle* fTexSamplers;
        FPCoordTransformHandler* fFPCoordTransformHandler;
    };

    /**
     * This is similar to emitCode() in the base class, except it takes a full shader builder.
     * This allows the effect subclass to emit vertex code.
     */
    virtual void emitCode(EmitArgs&) = 0;

    /**
     * A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
     * produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
     * uploads any uniform variables required  by the shaders created in emitCode(). The
     * GrPrimitiveProcessor parameter is guaranteed to be of the same type and to have an
     * identical processor key as the GrPrimitiveProcessor that created this
     * GrGLSLPrimitiveProcessor.
     * The subclass may use the transform iterator to perform any setup required for the particular
     * set of fp transform matrices, such as uploading via uniforms. The iterator will iterate over
     * the transforms in the same order as the TransformHandler passed to emitCode.
     */
    virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
                         FPCoordTransformIter&&) = 0;

    static SkMatrix GetTransformMatrix(const SkMatrix& localMatrix, const GrCoordTransform&);

protected:
    void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
                           GrGLSLUniformHandler* uniformHandler,
                           const char* outputName,
                           UniformHandle* colorUniform);
};

#endif