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