Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / GrGLProgram.cpp
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 #include "GrGLProgram.h"
9
10 #include "builders/GrGLFullProgramBuilder.h"
11 #include "builders/GrGLFragmentOnlyProgramBuilder.h"
12 #include "GrAllocator.h"
13 #include "GrProcessor.h"
14 #include "GrCoordTransform.h"
15 #include "GrGLProcessor.h"
16 #include "GrGpuGL.h"
17 #include "GrGLPathRendering.h"
18 #include "GrGLShaderVar.h"
19 #include "GrGLSL.h"
20 #include "GrOptDrawState.h"
21 #include "SkXfermode.h"
22
23 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
24 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X)
25
26 GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
27                                  const GrGLProgramDesc& desc,
28                                  const GrGeometryStage* geometryProcessor,
29                                  const GrFragmentStage* colorStages[],
30                                  const GrFragmentStage* coverageStages[]) {
31     SkAutoTDelete<GrGLProgramBuilder> builder;
32     if (desc.getHeader().fUseFragShaderOnly) {
33         SkASSERT(gpu->glCaps().pathRenderingSupport());
34         SkASSERT(gpu->glPathRendering()->texturingMode() ==
35                  GrGLPathRendering::FixedFunction_TexturingMode);
36         SkASSERT(NULL == geometryProcessor);
37         builder.reset(SkNEW_ARGS(GrGLFragmentOnlyProgramBuilder, (gpu, desc)));
38     } else {
39         builder.reset(SkNEW_ARGS(GrGLFullProgramBuilder, (gpu, desc)));
40     }
41     if (builder->genProgram(geometryProcessor, colorStages, coverageStages)) {
42         SkASSERT(0 != builder->getProgramID());
43         return SkNEW_ARGS(GrGLProgram, (gpu, desc, *builder));
44     }
45     return NULL;
46 }
47
48 GrGLProgram::GrGLProgram(GrGpuGL* gpu,
49                          const GrGLProgramDesc& desc,
50                          const GrGLProgramBuilder& builder)
51     : fColor(GrColor_ILLEGAL)
52     , fCoverage(GrColor_ILLEGAL)
53     , fDstCopyTexUnit(-1)
54     , fBuiltinUniformHandles(builder.getBuiltinUniformHandles())
55     , fGeometryProcessor(SkSafeRef(builder.getGeometryProcessor()))
56     , fColorEffects(SkRef(builder.getColorEffects()))
57     , fCoverageEffects(SkRef(builder.getCoverageEffects()))
58     , fProgramID(builder.getProgramID())
59     , fHasVertexShader(builder.hasVertexShader())
60     , fTexCoordSetCnt(builder.getTexCoordSetCount())
61     , fDesc(desc)
62     , fGpu(gpu)
63     , fProgramDataManager(gpu, this, builder) {
64     this->initSamplerUniforms();
65 }
66
67 GrGLProgram::~GrGLProgram() {
68     if (fProgramID) {
69         GL_CALL(DeleteProgram(fProgramID));
70     }
71 }
72
73 void GrGLProgram::abandon() {
74     fProgramID = 0;
75 }
76
77 void GrGLProgram::initSamplerUniforms() {
78     GL_CALL(UseProgram(fProgramID));
79     GrGLint texUnitIdx = 0;
80     if (fBuiltinUniformHandles.fDstCopySamplerUni.isValid()) {
81         fProgramDataManager.setSampler(fBuiltinUniformHandles.fDstCopySamplerUni, texUnitIdx);
82         fDstCopyTexUnit = texUnitIdx++;
83     }
84     if (fGeometryProcessor.get()) {
85         fGeometryProcessor->initSamplers(fProgramDataManager, &texUnitIdx);
86     }
87     fColorEffects->initSamplers(fProgramDataManager, &texUnitIdx);
88     fCoverageEffects->initSamplers(fProgramDataManager, &texUnitIdx);
89 }
90
91 ///////////////////////////////////////////////////////////////////////////////
92
93 void GrGLProgram::setData(const GrOptDrawState& optState,
94                           GrGpu::DrawType drawType,
95                           const GrGeometryStage* geometryProcessor,
96                           const GrFragmentStage* colorStages[],
97                           const GrFragmentStage* coverageStages[],
98                           const GrDeviceCoordTexture* dstCopy,
99                           SharedGLState* sharedState) {
100     GrColor color = optState.getColor();
101     GrColor coverage = optState.getCoverageColor();
102
103     this->setColor(optState, color, sharedState);
104     this->setCoverage(optState, coverage, sharedState);
105     this->setMatrixAndRenderTargetHeight(drawType, optState);
106
107     if (dstCopy) {
108         if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) {
109             fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyTopLeftUni,
110                                        static_cast<GrGLfloat>(dstCopy->offset().fX),
111                                        static_cast<GrGLfloat>(dstCopy->offset().fY));
112             fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyScaleUni,
113                                        1.f / dstCopy->texture()->width(),
114                                        1.f / dstCopy->texture()->height());
115             GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture());
116             static GrTextureParams kParams; // the default is clamp, nearest filtering.
117             fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
118         } else {
119             SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
120             SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
121         }
122     } else {
123         SkASSERT(!fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid());
124         SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
125         SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
126     }
127
128     if (fGeometryProcessor.get()) {
129         SkASSERT(geometryProcessor);
130         fGeometryProcessor->setData(fGpu, drawType, fProgramDataManager, geometryProcessor);
131     }
132     fColorEffects->setData(fGpu, drawType, fProgramDataManager, colorStages);
133     fCoverageEffects->setData(fGpu, drawType, fProgramDataManager, coverageStages);
134
135     // PathTexGen state applies to the the fixed function vertex shader. For
136     // custom shaders, it's ignored, so we don't need to change the texgen
137     // settings in that case.
138     if (!fHasVertexShader) {
139         fGpu->glPathRendering()->flushPathTexGenSettings(fTexCoordSetCnt);
140     }
141 }
142
143 void GrGLProgram::setColor(const GrOptDrawState& optState,
144                            GrColor color,
145                            SharedGLState* sharedState) {
146     const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
147     if (!optState.hasColorVertexAttribute()) {
148         switch (header.fColorInput) {
149             case GrGLProgramDesc::kAttribute_ColorInput:
150                 SkASSERT(-1 != header.fColorAttributeIndex);
151                 if (sharedState->fConstAttribColor != color ||
152                     sharedState->fConstAttribColorIndex != header.fColorAttributeIndex) {
153                     // OpenGL ES only supports the float varieties of glVertexAttrib
154                     GrGLfloat c[4];
155                     GrColorToRGBAFloat(color, c);
156                     GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c));
157                     sharedState->fConstAttribColor = color;
158                     sharedState->fConstAttribColorIndex = header.fColorAttributeIndex;
159                 }
160                 break;
161             case GrGLProgramDesc::kUniform_ColorInput:
162                 if (fColor != color && fBuiltinUniformHandles.fColorUni.isValid()) {
163                     // OpenGL ES doesn't support unsigned byte varieties of glUniform
164                     GrGLfloat c[4];
165                     GrColorToRGBAFloat(color, c);
166                     fProgramDataManager.set4fv(fBuiltinUniformHandles.fColorUni, 1, c);
167                     fColor = color;
168                 }
169                 sharedState->fConstAttribColorIndex = -1;
170                 break;
171             case GrGLProgramDesc::kAllOnes_ColorInput:
172                 sharedState->fConstAttribColorIndex = -1;
173                 break;
174             default:
175                 SkFAIL("Unexpected color type.");
176         }
177     } else {
178         sharedState->fConstAttribColorIndex = -1;
179     }
180 }
181
182 void GrGLProgram::setCoverage(const GrOptDrawState& optState,
183                               GrColor coverage,
184                               SharedGLState* sharedState) {
185     const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
186     if (!optState.hasCoverageVertexAttribute()) {
187         switch (header.fCoverageInput) {
188             case GrGLProgramDesc::kAttribute_ColorInput:
189                 if (sharedState->fConstAttribCoverage != coverage ||
190                     sharedState->fConstAttribCoverageIndex != header.fCoverageAttributeIndex) {
191                     // OpenGL ES only supports the float varieties of  glVertexAttrib
192                     GrGLfloat c[4];
193                     GrColorToRGBAFloat(coverage, c);
194                     GL_CALL(VertexAttrib4fv(header.fCoverageAttributeIndex, c));
195                     sharedState->fConstAttribCoverage = coverage;
196                     sharedState->fConstAttribCoverageIndex = header.fCoverageAttributeIndex;
197                 }
198                 break;
199             case GrGLProgramDesc::kUniform_ColorInput:
200                 if (fCoverage != coverage) {
201                     // OpenGL ES doesn't support unsigned byte varieties of glUniform
202                     GrGLfloat c[4];
203                     GrColorToRGBAFloat(coverage, c);
204                     fProgramDataManager.set4fv(fBuiltinUniformHandles.fCoverageUni, 1, c);
205                     fCoverage = coverage;
206                 }
207                 sharedState->fConstAttribCoverageIndex = -1;
208                 break;
209             case GrGLProgramDesc::kAllOnes_ColorInput:
210                 sharedState->fConstAttribCoverageIndex = -1;
211                 break;
212             default:
213                 SkFAIL("Unexpected coverage type.");
214         }
215     } else {
216         sharedState->fConstAttribCoverageIndex = -1;
217     }
218 }
219
220 void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
221                                                  const GrOptDrawState& optState) {
222     const GrRenderTarget* rt = optState.getRenderTarget();
223     SkISize size;
224     size.set(rt->width(), rt->height());
225
226     // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
227     if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
228         fMatrixState.fRenderTargetSize.fHeight != size.fHeight) {
229         fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni,
230                                    SkIntToScalar(size.fHeight));
231     }
232
233     if (GrGpu::IsPathRenderingDrawType(drawType)) {
234         fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin());
235     } else if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
236                fMatrixState.fRenderTargetSize != size ||
237                !fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) {
238         SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid());
239
240         fMatrixState.fViewMatrix = optState.getViewMatrix();
241         fMatrixState.fRenderTargetSize = size;
242         fMatrixState.fRenderTargetOrigin = rt->origin();
243
244         GrGLfloat viewMatrix[3 * 3];
245         fMatrixState.getGLMatrix<3>(viewMatrix);
246         fProgramDataManager.setMatrix3f(fBuiltinUniformHandles.fViewMatrixUni, viewMatrix);
247
248         GrGLfloat rtAdjustmentVec[4];
249         fMatrixState.getRTAdjustmentVec(rtAdjustmentVec);
250         fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
251     }
252 }