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 |