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 } 205