Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / builders / GrGLProgramBuilder.h
1 /*
2  * Copyright 2014 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 GrGLProgramBuilder_DEFINED
9 #define GrGLProgramBuilder_DEFINED
10
11 #include "GrGLFragmentShaderBuilder.h"
12 #include "GrGLGeometryShaderBuilder.h"
13 #include "GrGLVertexShaderBuilder.h"
14 #include "../GrGLProgramDataManager.h"
15 #include "../GrGLUniformHandle.h"
16 #include "../GrGLGeometryProcessor.h"
17
18 /*
19  * This is the base class for a series of interfaces.  This base class *MUST* remain abstract with
20  * NO data members because it is used in multiple interface inheritance.
21  * Heirarchy:
22  *                      GrGLUniformBuilder
23  *                     /                  \
24  *                GrGLFPBuilder       GrGLGPBuilder
25  *                     \                  /
26  *                     GrGLProgramBuilder(internal use only)
27  */
28 class GrGLUniformBuilder {
29 public:
30     enum ShaderVisibility {
31         kVertex_Visibility   = 0x1,
32         kGeometry_Visibility = 0x2,
33         kFragment_Visibility = 0x4,
34     };
35
36     virtual ~GrGLUniformBuilder() {}
37
38     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
39
40     /** Add a uniform variable to the current program, that has visibility in one or more shaders.
41         visibility is a bitfield of ShaderVisibility values indicating from which shaders the
42         uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
43         supported at this time. The actual uniform name will be mangled. If outName is not NULL then
44         it will refer to the final uniform name after return. Use the addUniformArray variant to add
45         an array of uniforms. */
46     virtual UniformHandle addUniform(uint32_t visibility,
47                                      GrSLType type,
48                                      const char* name,
49                                      const char** outName = NULL) = 0;
50     virtual UniformHandle addUniformArray(uint32_t visibility,
51                                           GrSLType type,
52                                           const char* name,
53                                           int arrayCount,
54                                           const char** outName = NULL) = 0;
55
56     virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const = 0;
57
58     /**
59      * Shortcut for getUniformVariable(u).c_str()
60      */
61     virtual const char* getUniformCStr(UniformHandle u) const = 0;
62
63     virtual const GrGLContextInfo& ctxInfo() const = 0;
64
65     virtual GrGpuGL* gpu() const = 0;
66
67     /*
68      * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
69      */
70 };
71
72 // TODO move this into GrGLGPBuilder and move them both out of this file
73 class GrGLVarying {
74 public:
75     bool vsVarying() const { return kVertToFrag_Varying == fVarying ||
76                                     kVertToGeo_Varying == fVarying; }
77     bool fsVarying() const { return kVertToFrag_Varying == fVarying ||
78                                     kGeoToFrag_Varying == fVarying; }
79     const char* vsOut() const { return fVsOut; }
80     const char* gsIn() const { return fGsIn; }
81     const char* gsOut() const { return fGsOut; }
82     const char* fsIn() const { return fFsIn; }
83
84 protected:
85     enum Varying {
86         kVertToFrag_Varying,
87         kVertToGeo_Varying,
88         kGeoToFrag_Varying,
89     };
90
91     GrGLVarying(GrSLType type, Varying varying)
92         : fVarying(varying), fType(type), fVsOut(NULL), fGsIn(NULL), fGsOut(NULL),
93           fFsIn(NULL) {}
94
95     Varying fVarying;
96
97 private:
98     GrSLType fType;
99     const char* fVsOut;
100     const char* fGsIn;
101     const char* fGsOut;
102     const char* fFsIn;
103
104     friend class GrGLVertexBuilder;
105     friend class GrGLGeometryBuilder;
106     friend class GrGLFragmentShaderBuilder;
107 };
108
109 struct GrGLVertToFrag : public GrGLVarying {
110     GrGLVertToFrag(GrSLType type)
111         : GrGLVarying(type, kVertToFrag_Varying) {}
112 };
113
114 struct GrGLVertToGeo : public GrGLVarying {
115     GrGLVertToGeo(GrSLType type)
116         : GrGLVarying(type, kVertToGeo_Varying) {}
117 };
118
119 struct GrGLGeoToFrag : public GrGLVarying {
120     GrGLGeoToFrag(GrSLType type)
121         : GrGLVarying(type, kGeoToFrag_Varying) {}
122 };
123
124 /* a specialization of the above for GPs.  Lets the user add uniforms, varyings, and VS / FS code */
125 class GrGLGPBuilder : public virtual GrGLUniformBuilder {
126 public:
127     virtual void addVarying(const char* name,
128                             GrGLVarying*,
129                             GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) = 0;
130
131     // TODO rename getFragmentBuilder
132     virtual GrGLGPFragmentBuilder* getFragmentShaderBuilder() = 0;
133     virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0;
134
135     /*
136      * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
137      */
138 };
139
140 /* a specializations for FPs. Lets the user add uniforms and FS code */
141 class GrGLFPBuilder : public virtual GrGLUniformBuilder {
142 public:
143     virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() = 0;
144
145     /*
146      * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
147      */
148 };
149
150 struct GrGLInstalledProc;
151 struct GrGLInstalledGeoProc;
152 struct GrGLInstalledFragProc;
153 struct GrGLInstalledFragProcs;
154
155 /*
156  * Please note - no diamond problems because of virtual inheritance.  Also, both base classes
157  * are pure virtual with no data members.  This is the base class for program building.
158  * Subclasses are nearly identical but each has their own way of emitting transforms.  State for
159  * each of the elements of the shader pipeline, ie vertex, fragment, geometry, etc, lives in those
160  * respective builders
161 */
162 class GrGLProgramBuilder : public GrGLGPBuilder,
163                            public GrGLFPBuilder {
164 public:
165     /** Generates a shader program.
166      *
167      * The program implements what is specified in the stages given as input.
168      * After successful generation, the builder result objects are available
169      * to be used.
170      * @return true if generation was successful.
171      */
172     static GrGLProgram* CreateProgram(const GrOptDrawState&, GrGpu::DrawType, GrGpuGL*);
173
174     virtual UniformHandle addUniform(uint32_t visibility,
175                                      GrSLType type,
176                                      const char* name,
177                                      const char** outName = NULL) SK_OVERRIDE {
178         return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
179     }
180     virtual UniformHandle addUniformArray(uint32_t visibility,
181                                           GrSLType type,
182                                           const char* name,
183                                           int arrayCount,
184                                           const char** outName = NULL) SK_OVERRIDE;
185
186     virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const SK_OVERRIDE {
187         return fUniforms[u.toShaderBuilderIndex()].fVariable;
188     }
189
190     virtual const char* getUniformCStr(UniformHandle u) const SK_OVERRIDE {
191         return this->getUniformVariable(u).c_str();
192     }
193
194     virtual const GrGLContextInfo& ctxInfo() const SK_OVERRIDE;
195
196     virtual GrGpuGL* gpu() const SK_OVERRIDE { return fGpu; }
197
198     virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() SK_OVERRIDE { return &fFS; }
199     virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fVS; }
200
201     virtual void addVarying(
202             const char* name,
203             GrGLVarying*,
204             GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) SK_OVERRIDE;
205
206     // Handles for program uniforms (other than per-effect uniforms)
207     struct BuiltinUniformHandles {
208         UniformHandle       fViewMatrixUni;
209         UniformHandle       fRTAdjustmentUni;
210         UniformHandle       fColorUni;
211         UniformHandle       fCoverageUni;
212
213         // We use the render target height to provide a y-down frag coord when specifying
214         // origin_upper_left is not supported.
215         UniformHandle       fRTHeightUni;
216
217         // Uniforms for computing texture coords to do the dst-copy lookup
218         UniformHandle       fDstCopyTopLeftUni;
219         UniformHandle       fDstCopyScaleUni;
220         UniformHandle       fDstCopySamplerUni;
221     };
222
223 protected:
224     typedef GrProgramDesc::ProcKeyProvider ProcKeyProvider;
225     typedef GrGLProgramDataManager::UniformInfo UniformInfo;
226     typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
227
228     static GrGLProgramBuilder* CreateProgramBuilder(const GrOptDrawState&,
229                                                     GrGpu::DrawType,
230                                                     bool hasGeometryProcessor,
231                                                     GrGpuGL*);
232
233     GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&);
234
235     const GrOptDrawState& optState() const { return fOptState; }
236     const GrProgramDesc& desc() const { return fDesc; }
237     const GrProgramDesc::KeyHeader& header() const { return fDesc.header(); }
238
239     // Generates a name for a variable. The generated string will be name prefixed by the prefix
240     // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
241     // generating stage code.
242     void nameVariable(SkString* out, char prefix, const char* name);
243     void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr1* inputCoverage);
244     void emitAndInstallProcs(const GrOptDrawState& optState,
245                              GrGLSLExpr4* inputColor,
246                              GrGLSLExpr4* inputCoverage);
247     void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
248     template <class Proc>
249     void emitAndInstallProc(const Proc&,
250                             int index,
251                             const ProcKeyProvider&,
252                             const GrGLSLExpr4& input,
253                             GrGLSLExpr4* output);
254
255     // these emit functions help to keep the createAndEmitProcessors template general
256     void emitAndInstallProc(const GrFragmentStage&,
257                             const GrProcessorKey&,
258                             const char* outColor,
259                             const char* inColor);
260     void emitAndInstallProc(const GrGeometryProcessor&,
261                             const GrProcessorKey&,
262                             const char* outColor,
263                             const char* inColor);
264     void verify(const GrGeometryProcessor&);
265     void verify(const GrFragmentProcessor&);
266     void emitSamplers(const GrProcessor&,
267                       GrGLProcessor::TextureSamplerArray* outSamplers,
268                       GrGLInstalledProc*);
269
270     // each specific program builder has a distinct transform and must override this function
271     virtual void emitTransforms(const GrFragmentStage&,
272                                 GrGLProcessor::TransformedCoordsArray* outCoords,
273                                 GrGLInstalledFragProc*);
274     GrGLProgram* finalize();
275     void bindUniformLocations(GrGLuint programID);
276     bool checkLinkStatus(GrGLuint programID);
277     void resolveUniformLocations(GrGLuint programID);
278     void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs);
279     void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs);
280
281     // Subclasses create different programs
282     virtual GrGLProgram* createProgram(GrGLuint programID);
283
284     void appendUniformDecls(ShaderVisibility, SkString*) const;
285
286     // reset is called by program creator between each processor's emit code.  It increments the
287     // stage offset for variable name mangling, and also ensures verfication variables in the
288     // fragment shader are cleared.
289     void reset() {
290         this->enterStage();
291         this->addStage();
292         fFS.reset();
293     }
294     void addStage() { fStageIndex++; }
295
296     // This simple class exits the stage and then restores the stage when it goes out of scope
297     class AutoStageRestore {
298     public:
299         AutoStageRestore(GrGLProgramBuilder* pb)
300             : fPB(pb), fOutOfStage(pb->fOutOfStage) { pb->exitStage(); }
301         ~AutoStageRestore() { fPB->fOutOfStage = fOutOfStage; }
302     private:
303         GrGLProgramBuilder* fPB;
304         bool fOutOfStage;
305     };
306     class AutoStageAdvance {
307     public:
308         AutoStageAdvance(GrGLProgramBuilder* pb) : fPB(pb) { fPB->reset(); }
309         ~AutoStageAdvance() { fPB->exitStage(); }
310     private:
311         GrGLProgramBuilder* fPB;
312     };
313     void exitStage() { fOutOfStage = true; }
314     void enterStage() { fOutOfStage = false; }
315     int stageIndex() const { return fStageIndex; }
316
317     // number of each input/output type in a single allocation block, used by many builders
318     static const int kVarsPerBlock;
319
320     BuiltinUniformHandles fUniformHandles;
321     GrGLVertexBuilder fVS;
322     GrGLGeometryBuilder fGS;
323     GrGLFragmentShaderBuilder fFS;
324     bool fOutOfStage;
325     int fStageIndex;
326
327     GrGLInstalledGeoProc* fGeometryProcessor;
328     SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
329
330     const GrOptDrawState& fOptState;
331     const GrProgramDesc& fDesc;
332     GrGpuGL* fGpu;
333     UniformInfoArray fUniforms;
334
335     friend class GrGLShaderBuilder;
336     friend class GrGLVertexBuilder;
337     friend class GrGLFragmentShaderBuilder;
338     friend class GrGLGeometryBuilder;
339 };
340
341 /**
342  * The below structs represent processors installed in programs.  All processors can have texture
343  * samplers, but only frag processors have coord transforms, hence the need for different structs
344  */
345 struct GrGLInstalledProc {
346      typedef GrGLProgramDataManager::UniformHandle UniformHandle;
347
348      struct Sampler {
349          SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
350          UniformHandle  fUniform;
351          int            fTextureUnit;
352      };
353      SkSTArray<4, Sampler, true> fSamplers;
354 };
355
356 struct GrGLInstalledGeoProc : public GrGLInstalledProc {
357     SkAutoTDelete<GrGLGeometryProcessor> fGLProc;
358 };
359
360 struct GrGLInstalledFragProc : public GrGLInstalledProc {
361     GrGLInstalledFragProc(bool useLocalCoords) : fGLProc(NULL), fLocalCoordAttrib(useLocalCoords) {}
362     class ShaderVarHandle {
363     public:
364         bool isValid() const { return fHandle > -1; }
365         ShaderVarHandle() : fHandle(-1) {}
366         ShaderVarHandle(int value) : fHandle(value) { SkASSERT(this->isValid()); }
367         int handle() const { SkASSERT(this->isValid()); return fHandle; }
368         UniformHandle convertToUniformHandle() {
369             SkASSERT(this->isValid());
370             return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fHandle);
371         }
372
373     private:
374         int fHandle;
375     };
376
377     struct Transform {
378         Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidMatrix(); }
379         ShaderVarHandle fHandle;
380         SkMatrix       fCurrentValue;
381         GrSLType       fType;
382     };
383
384     SkAutoTDelete<GrGLFragmentProcessor> fGLProc;
385     SkSTArray<2, Transform, true>        fTransforms;
386     bool                                 fLocalCoordAttrib;
387 };
388
389 struct GrGLInstalledFragProcs : public SkRefCnt {
390     virtual ~GrGLInstalledFragProcs();
391     SkSTArray<8, GrGLInstalledFragProc*, true> fProcs;
392 };
393
394 #endif