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 "src/gpu/GrFragmentProcessor.h" |
12 | #include "src/gpu/GrPrimitiveProcessor.h" |
13 | #include "src/gpu/glsl/GrGLSLProgramDataManager.h" |
14 | #include "src/gpu/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 UniformHandle = GrGLSLProgramDataManager::UniformHandle; |
27 | using SamplerHandle = GrGLSLUniformHandler::SamplerHandle; |
28 | |
29 | virtual ~GrGLSLPrimitiveProcessor() {} |
30 | |
31 | /** |
32 | * This class provides access to each GrFragmentProcessor in a GrPipeline that requires varying |
33 | * local coords to be produced by the primitive processor. It is also used by the primitive |
34 | * processor to specify the fragment shader variable that will hold the transformed coords for |
35 | * each of those GrFragmentProcessors. It is required that the primitive processor iterate over |
36 | * each fragment processor and insert a shader var result for each. The GrGLSLFragmentProcessors |
37 | * will reference these variables in their fragment code. |
38 | */ |
39 | class FPCoordTransformHandler : public SkNoncopyable { |
40 | public: |
41 | FPCoordTransformHandler(const GrPipeline&, SkTArray<GrShaderVar>*); |
42 | ~FPCoordTransformHandler() { SkASSERT(!fIter); } |
43 | |
44 | operator bool() const { return (bool)fIter; } |
45 | |
46 | // Gets the current GrFragmentProcessor |
47 | const GrFragmentProcessor& get() const; |
48 | |
49 | FPCoordTransformHandler& operator++(); |
50 | |
51 | void specifyCoordsForCurrCoordTransform(GrShaderVar varyingVar) { |
52 | SkASSERT(!fAddedCoord); |
53 | fTransformedCoordVars->push_back(varyingVar); |
54 | SkDEBUGCODE(fAddedCoord = true;) |
55 | } |
56 | |
57 | private: |
58 | GrFragmentProcessor::CIter fIter; |
59 | SkDEBUGCODE(bool fAddedCoord = false;) |
60 | SkTArray<GrShaderVar>* fTransformedCoordVars; |
61 | }; |
62 | |
63 | struct EmitArgs { |
64 | EmitArgs(GrGLSLVertexBuilder* vertBuilder, |
65 | GrGLSLGeometryBuilder* geomBuilder, |
66 | GrGLSLFPFragmentBuilder* fragBuilder, |
67 | GrGLSLVaryingHandler* varyingHandler, |
68 | GrGLSLUniformHandler* uniformHandler, |
69 | const GrShaderCaps* caps, |
70 | const GrPrimitiveProcessor& gp, |
71 | const char* outputColor, |
72 | const char* outputCoverage, |
73 | const char* rtAdjustName, |
74 | const SamplerHandle* texSamplers, |
75 | FPCoordTransformHandler* transformHandler) |
76 | : fVertBuilder(vertBuilder) |
77 | , fGeomBuilder(geomBuilder) |
78 | , fFragBuilder(fragBuilder) |
79 | , fVaryingHandler(varyingHandler) |
80 | , fUniformHandler(uniformHandler) |
81 | , fShaderCaps(caps) |
82 | , fGP(gp) |
83 | , fOutputColor(outputColor) |
84 | , fOutputCoverage(outputCoverage) |
85 | , fRTAdjustName(rtAdjustName) |
86 | , fTexSamplers(texSamplers) |
87 | , fFPCoordTransformHandler(transformHandler) {} |
88 | GrGLSLVertexBuilder* fVertBuilder; |
89 | GrGLSLGeometryBuilder* fGeomBuilder; |
90 | GrGLSLFPFragmentBuilder* fFragBuilder; |
91 | GrGLSLVaryingHandler* fVaryingHandler; |
92 | GrGLSLUniformHandler* fUniformHandler; |
93 | const GrShaderCaps* fShaderCaps; |
94 | const GrPrimitiveProcessor& fGP; |
95 | const char* fOutputColor; |
96 | const char* fOutputCoverage; |
97 | const char* fRTAdjustName; |
98 | const SamplerHandle* fTexSamplers; |
99 | FPCoordTransformHandler* fFPCoordTransformHandler; |
100 | }; |
101 | |
102 | /** |
103 | * This is similar to emitCode() in the base class, except it takes a full shader builder. |
104 | * This allows the effect subclass to emit vertex code. |
105 | */ |
106 | virtual void emitCode(EmitArgs&) = 0; |
107 | |
108 | /** |
109 | * Called after all effect emitCode() functions, to give the processor a chance to write out |
110 | * additional transformation code now that all uniforms have been emitted. |
111 | */ |
112 | virtual void emitTransformCode(GrGLSLVertexBuilder* vb, |
113 | GrGLSLUniformHandler* uniformHandler) {} |
114 | /** |
115 | * A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that |
116 | * produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and |
117 | * uploads any uniform variables required by the shaders created in emitCode(). The |
118 | * GrPrimitiveProcessor parameter is guaranteed to be of the same type and to have an |
119 | * identical processor key as the GrPrimitiveProcessor that created this |
120 | * GrGLSLPrimitiveProcessor. |
121 | * The subclass should use the transform range to perform any setup required for the coord |
122 | * transforms of the FPs that are part of the same program, such as updating matrix uniforms. |
123 | * The range will iterate over the transforms in the same order as the TransformHandler passed |
124 | * to emitCode. |
125 | */ |
126 | virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) = 0; |
127 | |
128 | protected: |
129 | void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder, |
130 | GrGLSLUniformHandler* uniformHandler, |
131 | const char* outputName, |
132 | UniformHandle* colorUniform); |
133 | }; |
134 | |
135 | #endif |
136 | |