1 /*
2  * Copyright 2012 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 GrGLProgramDataManager_DEFINED
9 #define GrGLProgramDataManager_DEFINED
10 
11 #include "gl/GrGLShaderVar.h"
12 #include "gl/GrGLSL.h"
13 #include "GrAllocator.h"
14 
15 #include "SkTArray.h"
16 
17 class GrGLGpu;
18 class SkMatrix;
19 class GrGLProgram;
20 class GrGLProgramBuilder;
21 
22 /** Manages the resources used by a shader program.
23  * The resources are objects the program uses to communicate with the
24  * application code.
25  */
26 class GrGLProgramDataManager : public SkRefCnt {
27 public:
28     // Opaque handle to a uniform
29     class ShaderResourceHandle {
30     public:
isValid()31         bool isValid() const { return -1 != fValue; }
ShaderResourceHandle()32         ShaderResourceHandle()
33             : fValue(-1) {
34         }
35     protected:
ShaderResourceHandle(int value)36         ShaderResourceHandle(int value)
37             : fValue(value) {
38             SkASSERT(isValid());
39         }
40         int fValue;
41     };
42 
43     class UniformHandle : public ShaderResourceHandle {
44     public:
45         /** Creates a reference to an unifrom of a GrGLShaderBuilder.
46          * The ref can be used to set the uniform with corresponding the GrGLProgramDataManager.*/
47         static UniformHandle CreateFromUniformIndex(int i);
UniformHandle()48         UniformHandle() { }
49         bool operator==(const UniformHandle& other) const { return other.fValue == fValue; }
50     private:
UniformHandle(int value)51         UniformHandle(int value) : ShaderResourceHandle(value) { }
toProgramDataIndex()52         int toProgramDataIndex() const { SkASSERT(isValid()); return fValue; }
toShaderBuilderIndex()53         int toShaderBuilderIndex() const { return toProgramDataIndex(); }
54 
55         friend class GrGLProgramDataManager; // For accessing toProgramDataIndex().
56         friend class GrGLProgramBuilder; // For accessing toShaderBuilderIndex().
57         friend class GrGLGeometryProcessor;
58     };
59 
60     struct UniformInfo {
61         GrGLShaderVar fVariable;
62         uint32_t      fVisibility;
63         GrGLint       fLocation;
64     };
65 
66     // This uses an allocator rather than array so that the GrGLShaderVars don't move in memory
67     // after they are inserted. Users of GrGLShaderBuilder get refs to the vars and ptrs to their
68     // name strings. Otherwise, we'd have to hand out copies.
69     typedef GrTAllocator<UniformInfo> UniformInfoArray;
70 
71     GrGLProgramDataManager(GrGLGpu*, const UniformInfoArray&);
72 
73     /** Functions for uploading uniform values. The varities ending in v can be used to upload to an
74      *  array of uniforms. arrayCount must be <= the array count of the uniform.
75      */
76     void setSampler(UniformHandle, GrGLint texUnit) const;
77     void set1f(UniformHandle, GrGLfloat v0) const;
78     void set1fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
79     void set2f(UniformHandle, GrGLfloat, GrGLfloat) const;
80     void set2fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
81     void set3f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat) const;
82     void set3fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
83     void set4f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat, GrGLfloat) const;
84     void set4fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
85     // matrices are column-major, the first three upload a single matrix, the latter three upload
86     // arrayCount matrices into a uniform array.
87     void setMatrix3f(UniformHandle, const GrGLfloat matrix[]) const;
88     void setMatrix4f(UniformHandle, const GrGLfloat matrix[]) const;
89     void setMatrix3fv(UniformHandle, int arrayCount, const GrGLfloat matrices[]) const;
90     void setMatrix4fv(UniformHandle, int arrayCount, const GrGLfloat matrices[]) const;
91 
92     // convenience method for uploading a SkMatrix to a 3x3 matrix uniform
93     void setSkMatrix(UniformHandle, const SkMatrix&) const;
94 
95 private:
96     enum {
97         kUnusedUniform = -1,
98     };
99 
100     struct Uniform {
101         GrGLint     fVSLocation;
102         GrGLint     fFSLocation;
103         SkDEBUGCODE(
104             GrSLType    fType;
105             int         fArrayCount;
106         );
107     };
108 
109     SkDEBUGCODE(void printUnused(const Uniform&) const;)
110 
111     SkTArray<Uniform, true> fUniforms;
112     GrGLGpu* fGpu;
113 
114     typedef SkRefCnt INHERITED;
115 };
116 #endif
117