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#ifndef GrGLSLPrimitiveProcessor_DEFINED
9#define GrGLSLPrimitiveProcessor_DEFINED
10
11#include "GrFragmentProcessor.h"
12#include "GrPrimitiveProcessor.h"
13#include "glsl/GrGLSLProgramDataManager.h"
14#include "glsl/GrGLSLUniformHandler.h"
15
16class GrPrimitiveProcessor;
17class GrGLSLFPFragmentBuilder;
18class GrGLSLGeometryBuilder;
19class GrGLSLGPBuilder;
20class GrGLSLVaryingHandler;
21class GrGLSLVertexBuilder;
22class GrShaderCaps;
23
24class GrGLSLPrimitiveProcessor {
25public:
26    using FPCoordTransformIter = GrFragmentProcessor::CoordTransformIter;
27
28    virtual ~GrGLSLPrimitiveProcessor() {}
29
30    using UniformHandle      = GrGLSLProgramDataManager::UniformHandle;
31    using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
32    using TexelBufferHandle  = GrGLSLUniformHandler::TexelBufferHandle;
33
34    /**
35     * This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a
36     * GrPipeline. It is also used by the primitive processor to specify the fragment shader
37     * variable that will hold the transformed coords for each GrCoordTransform. It is required that
38     * the primitive processor iterate over each coord transform and insert a shader var result for
39     * each. The GrGLSLFragmentProcessors will reference these variables in their fragment code.
40     */
41    class FPCoordTransformHandler : public SkNoncopyable {
42    public:
43        FPCoordTransformHandler(const GrPipeline& pipeline,
44                                SkTArray<GrShaderVar>* transformedCoordVars)
45                : fIter(pipeline)
46                , fTransformedCoordVars(transformedCoordVars) {}
47
48        ~FPCoordTransformHandler() { SkASSERT(!this->nextCoordTransform());}
49
50        const GrCoordTransform* nextCoordTransform();
51
52        // 'args' are constructor params to GrShaderVar.
53        template<typename... Args>
54        void specifyCoordsForCurrCoordTransform(Args&&... args) {
55            SkASSERT(!fAddedCoord);
56            fTransformedCoordVars->emplace_back(std::forward<Args>(args)...);
57            SkDEBUGCODE(fAddedCoord = true;)
58        }
59
60    private:
61        GrFragmentProcessor::CoordTransformIter fIter;
62        SkDEBUGCODE(bool                        fAddedCoord = false;)
63        SkDEBUGCODE(const GrCoordTransform*     fCurr = nullptr;)
64        SkTArray<GrShaderVar>*                  fTransformedCoordVars;
65    };
66
67    struct EmitArgs {
68        EmitArgs(GrGLSLVertexBuilder* vertBuilder,
69                 GrGLSLGeometryBuilder* geomBuilder,
70                 GrGLSLFPFragmentBuilder* fragBuilder,
71                 GrGLSLVaryingHandler* varyingHandler,
72                 GrGLSLUniformHandler* uniformHandler,
73                 const GrShaderCaps* caps,
74                 const GrPrimitiveProcessor& gp,
75                 const char* outputColor,
76                 const char* outputCoverage,
77                 const char* rtAdjustName,
78                 const SamplerHandle* texSamplers,
79                 const TexelBufferHandle* texelBuffers,
80                 FPCoordTransformHandler* transformHandler)
81            : fVertBuilder(vertBuilder)
82            , fGeomBuilder(geomBuilder)
83            , fFragBuilder(fragBuilder)
84            , fVaryingHandler(varyingHandler)
85            , fUniformHandler(uniformHandler)
86            , fShaderCaps(caps)
87            , fGP(gp)
88            , fOutputColor(outputColor)
89            , fOutputCoverage(outputCoverage)
90            , fRTAdjustName(rtAdjustName)
91            , fTexSamplers(texSamplers)
92            , fTexelBuffers(texelBuffers)
93            , fFPCoordTransformHandler(transformHandler) {}
94        GrGLSLVertexBuilder* fVertBuilder;
95        GrGLSLGeometryBuilder* fGeomBuilder;
96        GrGLSLFPFragmentBuilder* fFragBuilder;
97        GrGLSLVaryingHandler* fVaryingHandler;
98        GrGLSLUniformHandler* fUniformHandler;
99        const GrShaderCaps* fShaderCaps;
100        const GrPrimitiveProcessor& fGP;
101        const char* fOutputColor;
102        const char* fOutputCoverage;
103        const char* fRTAdjustName;
104        const SamplerHandle* fTexSamplers;
105        const TexelBufferHandle* fTexelBuffers;
106        FPCoordTransformHandler* fFPCoordTransformHandler;
107    };
108
109    /**
110     * This is similar to emitCode() in the base class, except it takes a full shader builder.
111     * This allows the effect subclass to emit vertex code.
112     */
113    virtual void emitCode(EmitArgs&) = 0;
114
115    /**
116     * A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
117     * produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
118     * uploads any uniform variables required  by the shaders created in emitCode(). The
119     * GrPrimitiveProcessor parameter is guaranteed to be of the same type and to have an
120     * identical processor key as the GrPrimitiveProcessor that created this
121     * GrGLSLPrimitiveProcessor.
122     * The subclass may use the transform iterator to perform any setup required for the particular
123     * set of fp transform matrices, such as uploading via uniforms. The iterator will iterate over
124     * the transforms in the same order as the TransformHandler passed to emitCode.
125     */
126    virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
127                         FPCoordTransformIter&&) = 0;
128
129    static SkMatrix GetTransformMatrix(const SkMatrix& localMatrix, const GrCoordTransform&);
130
131protected:
132    void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
133                           GrGLSLUniformHandler* uniformHandler,
134                           const char* outputName,
135                           UniformHandle* colorUniform);
136};
137
138#endif
139