Line data Source code
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 GrGLSLFragmentProcessor_DEFINED
9 : #define GrGLSLFragmentProcessor_DEFINED
10 :
11 : #include "GrFragmentProcessor.h"
12 : #include "GrShaderVar.h"
13 : #include "glsl/GrGLSLProgramDataManager.h"
14 : #include "glsl/GrGLSLUniformHandler.h"
15 :
16 : class GrProcessor;
17 : class GrProcessorKeyBuilder;
18 : class GrGLSLFPBuilder;
19 : class GrGLSLFPFragmentBuilder;
20 :
21 : class GrGLSLFragmentProcessor {
22 : public:
23 0 : GrGLSLFragmentProcessor() {}
24 :
25 0 : virtual ~GrGLSLFragmentProcessor() {
26 0 : for (int i = 0; i < fChildProcessors.count(); ++i) {
27 0 : delete fChildProcessors[i];
28 : }
29 0 : }
30 :
31 : using UniformHandle = GrGLSLUniformHandler::UniformHandle;
32 : using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
33 : using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
34 :
35 : private:
36 : /**
37 : * This class allows the shader builder to provide each GrGLSLFragmentProcesor with an array of
38 : * generated variables where each generated variable corresponds to an element of an array on
39 : * the GrFragmentProcessor that generated the GLSLFP. For example, this is used to provide a
40 : * variable holding transformed coords for each GrCoordTransform owned by the FP.
41 : */
42 : template <typename T, typename FPBASE, int (FPBASE::*COUNT)() const>
43 : class BuilderInputProvider {
44 : public:
45 0 : BuilderInputProvider(const GrFragmentProcessor* fp, const T* ts) : fFP(fp) , fTs(ts) {}
46 :
47 0 : const T& operator[] (int i) const {
48 0 : SkASSERT(i >= 0 && i < (fFP->*COUNT)());
49 0 : return fTs[i];
50 : }
51 :
52 0 : BuilderInputProvider childInputs(int childIdx) const {
53 0 : const GrFragmentProcessor* child = &fFP->childProcessor(childIdx);
54 0 : GrFragmentProcessor::Iter iter(fFP);
55 0 : int numToSkip = 0;
56 0 : while (true) {
57 0 : const GrFragmentProcessor* fp = iter.next();
58 0 : if (fp == child) {
59 0 : return BuilderInputProvider(child, fTs + numToSkip);
60 : }
61 0 : numToSkip += (fp->*COUNT)();
62 : }
63 : }
64 :
65 : private:
66 : const GrFragmentProcessor* fFP;
67 : const T* fTs;
68 : };
69 :
70 : public:
71 : using TransformedCoordVars = BuilderInputProvider<GrShaderVar, GrFragmentProcessor,
72 : &GrFragmentProcessor::numCoordTransforms>;
73 : using TextureSamplers = BuilderInputProvider<SamplerHandle, GrResourceIOProcessor,
74 : &GrResourceIOProcessor::numTextureSamplers>;
75 : using BufferSamplers = BuilderInputProvider<SamplerHandle, GrResourceIOProcessor,
76 : &GrResourceIOProcessor::numBuffers>;
77 : using ImageStorages = BuilderInputProvider<ImageStorageHandle, GrResourceIOProcessor,
78 : &GrResourceIOProcessor::numImageStorages>;
79 :
80 : /** Called when the program stage should insert its code into the shaders. The code in each
81 : shader will be in its own block ({}) and so locally scoped names will not collide across
82 : stages.
83 :
84 : @param fragBuilder Interface used to emit code in the shaders.
85 : @param fp The processor that generated this program stage.
86 : @param key The key that was computed by GenKey() from the generating
87 : GrProcessor.
88 : @param outputColor A predefined vec4 in the FS in which the stage should place its
89 : output color (or coverage).
90 : @param inputColor A vec4 that holds the input color to the stage in the FS. This may
91 : be nullptr in which case the implied input is solid white (all
92 : ones). TODO: Better system for communicating optimization info
93 : (e.g. input color is solid white, trans black, known to be opaque,
94 : etc.) that allows the processor to communicate back similar known
95 : info about its output.
96 : @param transformedCoords Fragment shader variables containing the coords computed using
97 : each of the GrFragmentProcessor's GrCoordTransforms.
98 : @param texSamplers Contains one entry for each TextureSampler of the GrProcessor.
99 : These can be passed to the builder to emit texture reads in the
100 : generated code.
101 : @param bufferSamplers Contains one entry for each BufferAccess of the GrProcessor. These
102 : can be passed to the builder to emit buffer reads in the generated
103 : code.
104 : @param imageStorages Contains one entry for each ImageStorageAccess of the GrProcessor.
105 : These can be passed to the builder to emit image loads and stores
106 : in the generated code.
107 : @param gpImplementsDistanceVector
108 : Does the GrGeometryProcessor implement the feature where it
109 : provides a vector to the nearest edge of the shape being rendered.
110 : */
111 : struct EmitArgs {
112 0 : EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
113 : GrGLSLUniformHandler* uniformHandler,
114 : const GrShaderCaps* caps,
115 : const GrFragmentProcessor& fp,
116 : const char* outputColor,
117 : const char* inputColor,
118 : const TransformedCoordVars& transformedCoordVars,
119 : const TextureSamplers& textureSamplers,
120 : const BufferSamplers& bufferSamplers,
121 : const ImageStorages& imageStorages,
122 : bool gpImplementsDistanceVector)
123 0 : : fFragBuilder(fragBuilder)
124 : , fUniformHandler(uniformHandler)
125 : , fShaderCaps(caps)
126 : , fFp(fp)
127 : , fOutputColor(outputColor)
128 : , fInputColor(inputColor)
129 : , fTransformedCoords(transformedCoordVars)
130 : , fTexSamplers(textureSamplers)
131 : , fBufferSamplers(bufferSamplers)
132 : , fImageStorages(imageStorages)
133 0 : , fGpImplementsDistanceVector(gpImplementsDistanceVector) {}
134 : GrGLSLFPFragmentBuilder* fFragBuilder;
135 : GrGLSLUniformHandler* fUniformHandler;
136 : const GrShaderCaps* fShaderCaps;
137 : const GrFragmentProcessor& fFp;
138 : const char* fOutputColor;
139 : const char* fInputColor;
140 : const TransformedCoordVars& fTransformedCoords;
141 : const TextureSamplers& fTexSamplers;
142 : const BufferSamplers& fBufferSamplers;
143 : const ImageStorages& fImageStorages;
144 : bool fGpImplementsDistanceVector;
145 : };
146 :
147 : virtual void emitCode(EmitArgs&) = 0;
148 :
149 : void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor);
150 :
151 0 : static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*) {}
152 :
153 0 : int numChildProcessors() const { return fChildProcessors.count(); }
154 :
155 0 : GrGLSLFragmentProcessor* childProcessor(int index) {
156 0 : return fChildProcessors[index];
157 : }
158 :
159 : /** Will emit the code of a child proc in its own scope. Pass in the parent's EmitArgs and
160 : * emitChild will automatically extract the coords and samplers of that child and pass them
161 : * on to the child's emitCode(). Also, any uniforms or functions emitted by the child will
162 : * have their names mangled to prevent redefinitions. The output color name is also mangled
163 : * therefore in an in/out param. It will be declared in mangled form by emitChild(). It is
164 : * legal to pass nullptr as inputColor, since all fragment processors are required to work
165 : * without an input color.
166 : */
167 : void emitChild(int childIndex, const char* inputColor, SkString* outputColor,
168 : EmitArgs& parentArgs);
169 :
170 : /** Variation that uses the parent's output color variable to hold the child's output.*/
171 : void emitChild(int childIndex, const char* inputColor, EmitArgs& parentArgs);
172 :
173 : /**
174 : * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
175 : * GLSLFPS. This agrees with the traversal order of GrFragmentProcessor::Iter
176 : */
177 0 : class Iter : public SkNoncopyable {
178 : public:
179 : explicit Iter(GrGLSLFragmentProcessor* fp) { fFPStack.push_back(fp); }
180 0 : explicit Iter(GrGLSLFragmentProcessor* fps[], int cnt) {
181 0 : for (int i = cnt - 1; i >= 0; --i) {
182 0 : fFPStack.push_back(fps[i]);
183 : }
184 0 : }
185 : GrGLSLFragmentProcessor* next();
186 :
187 : private:
188 : SkSTArray<4, GrGLSLFragmentProcessor*, true> fFPStack;
189 : };
190 :
191 : protected:
192 : /** A GrGLSLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces
193 : the same stage key; this function reads data from a GrFragmentProcessor and uploads any
194 : uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
195 : parameter is guaranteed to be of the same type that created this GrGLSLFragmentProcessor and
196 : to have an identical processor key as the one that created this GrGLSLFragmentProcessor. */
197 0 : virtual void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) {}
198 :
199 : private:
200 : void internalEmitChild(int, const char*, const char*, EmitArgs&);
201 :
202 : SkTArray<GrGLSLFragmentProcessor*, true> fChildProcessors;
203 :
204 : friend class GrFragmentProcessor;
205 : };
206 :
207 : #endif
|