Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / GrGLProgramEffects.cpp
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 #include "GrGLProgramEffects.h"
9 #include "gl/GrGLProcessor.h"
10 #include "gl/GrGLPathRendering.h"
11 #include "gl/builders/GrGLFullProgramBuilder.h"
12 #include "gl/builders/GrGLFragmentOnlyProgramBuilder.h"
13 #include "gl/GrGLGeometryProcessor.h"
14 #include "gl/GrGpuGL.h"
15
16 typedef GrGLProcessor::TransformedCoords TransformedCoords;
17 typedef GrGLProcessor::TransformedCoordsArray TransformedCoordsArray;
18 typedef GrGLProcessor::TextureSampler TextureSampler;
19 typedef GrGLProcessor::TextureSamplerArray TextureSamplerArray;
20
21 namespace {
22 /**
23  * Retrieves the final matrix that a transform needs to apply to its source coords.
24  */
25 SkMatrix get_transform_matrix(const GrProcessorStage& effectStage,
26                               bool useExplicitLocalCoords,
27                               int transformIdx) {
28     const GrCoordTransform& coordTransform = effectStage.getProcessor()->coordTransform(transformIdx);
29     SkMatrix combined;
30
31     if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
32         // If we have explicit local coords then we shouldn't need a coord change.
33         const SkMatrix& ccm =
34                 useExplicitLocalCoords ? SkMatrix::I() : effectStage.getCoordChangeMatrix();
35         combined.setConcat(coordTransform.getMatrix(), ccm);
36     } else {
37         combined = coordTransform.getMatrix();
38     }
39     if (coordTransform.reverseY()) {
40         // combined.postScale(1,-1);
41         // combined.postTranslate(0,1);
42         combined.set(SkMatrix::kMSkewY,
43             combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
44         combined.set(SkMatrix::kMScaleY,
45             combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
46         combined.set(SkMatrix::kMTransY,
47             combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
48     }
49     return combined;
50 }
51 }
52
53 ////////////////////////////////////////////////////////////////////////////////
54
55 GrGLProgramEffects::~GrGLProgramEffects() {
56     int numEffects = fGLProcessors.count();
57     for (int e = 0; e < numEffects; ++e) {
58         SkDELETE(fGLProcessors[e]);
59     }
60 }
61
62 void GrGLProgramEffects::initSamplers(const GrGLProgramDataManager& programResourceManager, int* texUnitIdx) {
63     int numEffects = fGLProcessors.count();
64     SkASSERT(numEffects == fSamplers.count());
65     for (int e = 0; e < numEffects; ++e) {
66         SkTArray<Sampler, true>& samplers = fSamplers[e];
67         int numSamplers = samplers.count();
68         for (int s = 0; s < numSamplers; ++s) {
69             SkASSERT(samplers[s].fUniform.isValid());
70             programResourceManager.setSampler(samplers[s].fUniform, *texUnitIdx);
71             samplers[s].fTextureUnit = (*texUnitIdx)++;
72         }
73     }
74 }
75
76 void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrProcessor& effect, int effectIdx) {
77     const SkTArray<Sampler, true>& samplers = fSamplers[effectIdx];
78     int numSamplers = samplers.count();
79     SkASSERT(numSamplers == effect.numTextures());
80     for (int s = 0; s < numSamplers; ++s) {
81         SkASSERT(samplers[s].fTextureUnit >= 0);
82         const GrTextureAccess& textureAccess = effect.textureAccess(s);
83         gpu->bindTexture(samplers[s].fTextureUnit,
84                          textureAccess.getParams(),
85                          static_cast<GrGLTexture*>(textureAccess.getTexture()));
86     }
87 }
88
89 ////////////////////////////////////////////////////////////////////////////////
90
91 void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
92                                        GrGpu::DrawType drawType,
93                                        const GrGLProgramDataManager& programDataManager,
94                                        const GrGeometryStage* effectStages) {
95     SkASSERT(1 == fGLProcessors.count());
96     SkASSERT(1 == fTransforms.count());
97     SkASSERT(1 == fSamplers.count());
98     this->setDataInternal(gpu, drawType, programDataManager, *effectStages, 0);
99 }
100
101 void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
102                                        GrGpu::DrawType drawType,
103                                        const GrGLProgramDataManager& programDataManager,
104                                        const GrFragmentStage* effectStages[]) {
105     int numEffects = fGLProcessors.count();
106     SkASSERT(numEffects == fTransforms.count());
107     SkASSERT(numEffects == fSamplers.count());
108     for (int e = 0; e < numEffects; ++e) {
109         this->setDataInternal(gpu, drawType, programDataManager, *effectStages[e], e);
110     }
111 }
112
113 void GrGLVertexProgramEffects::setDataInternal(GrGpuGL* gpu,
114                                                GrGpu::DrawType drawType,
115                                                const GrGLProgramDataManager& programDataManager,
116                                                const GrProcessorStage& effectStage,
117                                                int index) {
118     const GrProcessor& effect = *effectStage.getProcessor();
119     fGLProcessors[index]->setData(programDataManager, effect);
120     if (GrGpu::IsPathRenderingDrawType(drawType)) {
121         this->setPathTransformData(gpu, programDataManager, effectStage, index);
122     } else {
123         this->setTransformData(gpu, programDataManager, effectStage, index);
124     }
125     this->bindTextures(gpu, effect, index);
126 }
127
128 void GrGLVertexProgramEffects::setTransformData(GrGpuGL* gpu,
129                                                 const GrGLProgramDataManager& pdman,
130                                                 const GrProcessorStage& effectStage,
131                                                 int effectIdx) {
132     SkTArray<Transform, true>& transforms = fTransforms[effectIdx];
133     int numTransforms = transforms.count();
134     SkASSERT(numTransforms == effectStage.getProcessor()->numTransforms());
135     for (int t = 0; t < numTransforms; ++t) {
136         SkASSERT(transforms[t].fHandle.isValid());
137         const SkMatrix& matrix = get_transform_matrix(effectStage, fHasExplicitLocalCoords, t);
138         if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) {
139             pdman.setSkMatrix(transforms[t].fHandle, matrix);
140             transforms[t].fCurrentValue = matrix;
141         }
142     }
143 }
144
145 void GrGLVertexProgramEffects::setPathTransformData(GrGpuGL* gpu,
146                                                     const GrGLProgramDataManager& pdman,
147                                                     const GrProcessorStage& effectStage,
148                                                     int effectIdx) {
149     SkTArray<PathTransform, true>& transforms = fPathTransforms[effectIdx];
150     int numTransforms = transforms.count();
151     SkASSERT(numTransforms == effectStage.getProcessor()->numTransforms());
152     for (int t = 0; t < numTransforms; ++t) {
153         SkASSERT(transforms[t].fHandle.isValid());
154         const SkMatrix& transform = get_transform_matrix(effectStage, fHasExplicitLocalCoords, t);
155         if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
156             continue;
157         }
158         transforms[t].fCurrentValue = transform;
159         switch (transforms[t].fType) {
160             case kVec2f_GrSLType:
161                 pdman.setProgramPathFragmentInputTransform(transforms[t].fHandle, 2, transform);
162                 break;
163             case kVec3f_GrSLType:
164                 pdman.setProgramPathFragmentInputTransform(transforms[t].fHandle, 3, transform);
165                 break;
166             default:
167                 SkFAIL("Unexpected matrix type.");
168         }
169     }
170 }
171
172 ////////////////////////////////////////////////////////////////////////////////
173
174 void GrGLPathTexGenProgramEffects::setData(GrGpuGL* gpu,
175                                            GrGpu::DrawType,
176                                            const GrGLProgramDataManager& pdman,
177                                            const GrFragmentStage* effectStages[]) {
178     int numEffects = fGLProcessors.count();
179     SkASSERT(numEffects == fTransforms.count());
180     SkASSERT(numEffects == fSamplers.count());
181     for (int e = 0; e < numEffects; ++e) {
182         const GrProcessorStage& effectStage = *effectStages[e];
183         const GrProcessor& effect = *effectStage.getProcessor();
184         fGLProcessors[e]->setData(pdman, effect);
185         this->setPathTexGenState(gpu, effectStage, e);
186         this->bindTextures(gpu, effect, e);
187     }
188 }
189
190 void GrGLPathTexGenProgramEffects::setPathTexGenState(GrGpuGL* gpu,
191                                               const GrProcessorStage& effectStage,
192                                               int effectIdx) {
193     int texCoordIndex = fTransforms[effectIdx].fTexCoordIndex;
194     int numTransforms = effectStage.getProcessor()->numTransforms();
195     for (int t = 0; t < numTransforms; ++t) {
196         const SkMatrix& transform = get_transform_matrix(effectStage, false, t);
197         GrGLPathRendering::PathTexGenComponents components =
198                 GrGLPathRendering::kST_PathTexGenComponents;
199         if (effectStage.isPerspectiveCoordTransform(t, false)) {
200             components = GrGLPathRendering::kSTR_PathTexGenComponents;
201         }
202         gpu->glPathRendering()->enablePathTexGen(texCoordIndex++, components, transform);
203     }
204 }