OLD | NEW |
| (Empty) |
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 coor
ds. | |
24 */ | |
25 SkMatrix get_transform_matrix(const GrProcessorStage& effectStage, | |
26 bool useExplicitLocalCoords, | |
27 int transformIdx) { | |
28 const GrCoordTransform& coordTransform = effectStage.getProcessor()->coordTr
ansform(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 chang
e. | |
33 const SkMatrix& ccm = | |
34 useExplicitLocalCoords ? SkMatrix::I() : effectStage.getCoordCha
ngeMatrix(); | |
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& programResou
rceManager, 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, i
nt 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& programData
Manager, | |
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& programData
Manager, | |
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& pro
gramDataManager, | |
116 const GrProcessorStage& effectSta
ge, | |
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& pd
man, | |
130 const GrProcessorStage& effectSt
age, | |
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, fHasExplicitL
ocalCoords, 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& effe
ctStage, | |
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, fHasExplic
itLocalCoords, 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& effectStag
e, | |
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, tr
ansform); | |
203 } | |
204 } | |
OLD | NEW |