Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / GrGLProgram.h
1 /*
2  * Copyright 2011 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
9 #ifndef GrGLProgram_DEFINED
10 #define GrGLProgram_DEFINED
11
12 #include "GrDrawState.h"
13 #include "GrGLContext.h"
14 #include "GrGLProgramDesc.h"
15 #include "GrGLShaderBuilder.h"
16 #include "GrGLSL.h"
17 #include "GrGLTexture.h"
18 #include "GrGLProgramDataManager.h"
19
20 #include "SkString.h"
21 #include "SkXfermode.h"
22
23 class GrGLEffect;
24 class GrGLProgramEffects;
25 class GrGLShaderBuilder;
26
27 /**
28  * This class manages a GPU program and records per-program information.
29  * We can specify the attribute locations so that they are constant
30  * across our shaders. But the driver determines the uniform locations
31  * at link time. We don't need to remember the sampler uniform location
32  * because we will bind a texture slot to it and never change it
33  * Uniforms are program-local so we can't rely on fHWState to hold the
34  * previous uniform state after a program change.
35  */
36 class GrGLProgram : public SkRefCnt {
37 public:
38     SK_DECLARE_INST_COUNT(GrGLProgram)
39
40     typedef GrGLShaderBuilder::BuiltinUniformHandles BuiltinUniformHandles;
41
42     static GrGLProgram* Create(GrGpuGL* gpu,
43                                const GrGLProgramDesc& desc,
44                                const GrEffectStage* colorStages[],
45                                const GrEffectStage* coverageStages[]);
46
47     virtual ~GrGLProgram();
48
49     /**
50      * Call to abandon GL objects owned by this program.
51      */
52     void abandon();
53
54     /**
55      * The shader may modify the blend coefficients. Params are in/out.
56      */
57     void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
58
59     const GrGLProgramDesc& getDesc() { return fDesc; }
60
61     /**
62      * Gets the GL program ID for this program.
63      */
64     GrGLuint programID() const { return fProgramID; }
65
66     bool hasVertexShader() const { return fHasVertexShader; }
67
68     /**
69      * Some GL state that is relevant to programs is not stored per-program. In particular color
70      * and coverage attributes can be global state. This struct is read and updated by
71      * GrGLProgram::setColor and GrGLProgram::setCoverage to allow us to avoid setting this state
72      * redundantly.
73      */
74     struct SharedGLState {
75         GrColor fConstAttribColor;
76         int     fConstAttribColorIndex;
77         GrColor fConstAttribCoverage;
78         int     fConstAttribCoverageIndex;
79
80         SharedGLState() { this->invalidate(); }
81         void invalidate() {
82             fConstAttribColor = GrColor_ILLEGAL;
83             fConstAttribColorIndex = -1;
84             fConstAttribCoverage = GrColor_ILLEGAL;
85             fConstAttribCoverageIndex = -1;
86         }
87     };
88
89     /**
90      * The GrDrawState's view matrix along with the aspects of the render target determine the
91      * matrix sent to GL. The size of the render target affects the GL matrix because we must
92      * convert from Skia device coords to GL's normalized coords. Also the origin of the render
93      * target may require us to perform a mirror-flip.
94      */
95     struct MatrixState {
96         SkMatrix        fViewMatrix;
97         SkISize         fRenderTargetSize;
98         GrSurfaceOrigin fRenderTargetOrigin;
99
100         MatrixState() { this->invalidate(); }
101         void invalidate() {
102             fViewMatrix = SkMatrix::InvalidMatrix();
103             fRenderTargetSize.fWidth = -1;
104             fRenderTargetSize.fHeight = -1;
105             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
106         }
107
108         /**
109          * Gets a matrix that goes from local coords to Skia's device coordinates.
110          */
111         template<int Size> void getGLMatrix(GrGLfloat* destMatrix) {
112             GrGLGetMatrix<Size>(destMatrix, fViewMatrix);
113         }
114
115         /**
116          * Gets a matrix that goes from local coordinates to GL normalized device coords.
117          */
118         template<int Size> void getRTAdjustedGLMatrix(GrGLfloat* destMatrix) {
119             SkMatrix combined;
120             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
121                 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
122                                 0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1,
123                                 0, 0, 1);
124             } else {
125                 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
126                                 0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1,
127                                 0, 0, 1);
128             }
129             combined.preConcat(fViewMatrix);
130             GrGLGetMatrix<Size>(destMatrix, combined);
131         }
132
133         /**
134          * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device
135          * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
136          * applied as such:
137          * pos.x = dot(v.xy, pos.xz)
138          * pos.y = dot(v.zq, pos.yz)
139          */
140         void getRTAdjustmentVec(GrGLfloat* destVec) {
141             destVec[0] = 2.f / fRenderTargetSize.fWidth;
142             destVec[1] = -1.f;
143             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
144                 destVec[2] = -2.f / fRenderTargetSize.fHeight;
145                 destVec[3] = 1.f;
146             } else {
147                 destVec[2] = 2.f / fRenderTargetSize.fHeight;
148                 destVec[3] = -1.f;
149             }
150         }
151     };
152
153     /**
154      * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a
155      * draw occurs using the program after the program has already been bound. It also uses the
156      * GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage
157      * stages come from GrGLProgramDesc::Build().
158      */
159     void setData(GrDrawState::BlendOptFlags,
160                  const GrEffectStage* colorStages[],
161                  const GrEffectStage* coverageStages[],
162                  const GrDeviceCoordTexture* dstCopy, // can be NULL
163                  SharedGLState*);
164
165 private:
166     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
167
168     GrGLProgram(GrGpuGL*,
169                 const GrGLProgramDesc&,
170                 const GrGLShaderBuilder&);
171
172     // Sets the texture units for samplers.
173     void initSamplerUniforms();
174
175     // Helper for setData(). Makes GL calls to specify the initial color when there is not
176     // per-vertex colors.
177     void setColor(const GrDrawState&, GrColor color, SharedGLState*);
178
179     // Helper for setData(). Makes GL calls to specify the initial coverage when there is not
180     // per-vertex coverages.
181     void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*);
182
183     // Helper for setData() that sets the view matrix and loads the render target height uniform
184     void setMatrixAndRenderTargetHeight(const GrDrawState&);
185
186     // these reflect the current values of uniforms (GL uniform values travel with program)
187     MatrixState                         fMatrixState;
188     GrColor                             fColor;
189     GrColor                             fCoverage;
190     int                                 fDstCopyTexUnit;
191
192     BuiltinUniformHandles               fBuiltinUniformHandles;
193     SkAutoTUnref<GrGLProgramEffects>    fColorEffects;
194     SkAutoTUnref<GrGLProgramEffects>    fCoverageEffects;
195     GrGLuint                            fProgramID;
196     bool                                fHasVertexShader;
197     int                                 fTexCoordSetCnt;
198
199     GrGLProgramDesc                     fDesc;
200     GrGpuGL*                            fGpu;
201
202     GrGLProgramDataManager              fProgramDataManager;
203
204     typedef SkRefCnt INHERITED;
205 };
206
207 #endif