Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrGLProgramBuilder.h" | 8 #include "GrGLProgramBuilder.h" |
| 9 #include "gl/GrGLGeometryProcessor.h" | 9 #include "gl/GrGLGeometryProcessor.h" |
| 10 #include "gl/GrGLProgram.h" | 10 #include "gl/GrGLProgram.h" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 // ES2 FS only guarantees mediump and lowp support | 25 // ES2 FS only guarantees mediump and lowp support |
| 26 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar: :kMedium_Precision; | 26 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar: :kMedium_Precision; |
| 27 | 27 |
| 28 ////////////////////////////////////////////////////////////////////////////// | 28 ////////////////////////////////////////////////////////////////////////////// |
| 29 | 29 |
| 30 const int GrGLProgramBuilder::kVarsPerBlock = 8; | 30 const int GrGLProgramBuilder::kVarsPerBlock = 8; |
| 31 | 31 |
| 32 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState, | 32 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState, |
| 33 const GrGLProgramDesc& desc, | 33 const GrGLProgramDesc& desc, |
| 34 GrGpu::DrawType drawType, | 34 GrGpu::DrawType drawType, |
| 35 const GrGeometryStage* geometryPr ocessor, | |
| 36 const GrFragmentStage* colorStage s[], | |
| 37 const GrFragmentStage* coverageSt ages[], | |
| 38 GrGpuGL* gpu) { | 35 GrGpuGL* gpu) { |
| 39 // create a builder. This will be handed off to effects so they can use it to add | 36 // create a builder. This will be handed off to effects so they can use it to add |
| 40 // uniforms, varyings, textures, etc | 37 // uniforms, varyings, textures, etc |
| 41 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc, | 38 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc, |
| 42 optState, | 39 optState, |
| 43 drawType, | 40 drawType, |
| 44 SkToBool(geom etryProcessor), | 41 optState.hasG eometryProcessor(), |
| 45 gpu)); | 42 gpu)); |
| 46 | 43 |
| 47 GrGLProgramBuilder* pb = builder.get(); | 44 GrGLProgramBuilder* pb = builder.get(); |
| 48 const GrGLProgramDesc::KeyHeader& header = pb->header(); | 45 const GrGLProgramDesc::KeyHeader& header = pb->header(); |
| 49 | 46 |
| 50 // emit code to read the dst copy texture, if necessary | 47 // emit code to read the dst copy texture, if necessary |
| 51 if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey | 48 if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey |
| 52 && !gpu->glCaps().fbFetchSupport()) { | 49 && !gpu->glCaps().fbFetchSupport()) { |
| 53 pb->fFS.emitCodeToReadDstTexture(); | 50 pb->fFS.emitCodeToReadDstTexture(); |
| 54 } | 51 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 67 pb->fVS.codeAppend("gl_PointSize = 1.0;"); | 64 pb->fVS.codeAppend("gl_PointSize = 1.0;"); |
| 68 } | 65 } |
| 69 if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) { | 66 if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) { |
| 70 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); | 67 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); |
| 71 } | 68 } |
| 72 if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { | 69 if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { |
| 73 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); | 70 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); |
| 74 } | 71 } |
| 75 } | 72 } |
| 76 | 73 |
| 77 pb->createAndEmitProcessors(geometryProcessor, colorStages, coverageStages, &inputColor, | 74 pb->createAndEmitProcessors(optState, &inputColor, &inputCoverage); |
| 78 &inputCoverage); | |
| 79 | 75 |
| 80 if (hasVertexShader) { | 76 if (hasVertexShader) { |
| 81 pb->fVS.transformSkiaToGLCoords(); | 77 pb->fVS.transformSkiaToGLCoords(); |
| 82 } | 78 } |
| 83 | 79 |
| 84 // write the secondary color output if necessary | 80 // write the secondary color output if necessary |
| 85 if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType ) { | 81 if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType ) { |
| 86 pb->fFS.enableSecondaryOutput(inputColor, inputCoverage); | 82 pb->fFS.enableSecondaryOutput(inputColor, inputCoverage); |
| 87 } | 83 } |
| 88 | 84 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 109 GrGLPathRendering::SeparableShaders_TexturingMode); | 105 GrGLPathRendering::SeparableShaders_TexturingMode); |
| 110 SkASSERT(!hasGeometryProcessor); | 106 SkASSERT(!hasGeometryProcessor); |
| 111 return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState, desc)); | 107 return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState, desc)); |
| 112 } else { | 108 } else { |
| 113 return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState, desc)); | 109 return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState, desc)); |
| 114 } | 110 } |
| 115 } | 111 } |
| 116 | 112 |
| 117 ///////////////////////////////////////////////////////////////////////////// | 113 ///////////////////////////////////////////////////////////////////////////// |
| 118 | 114 |
| 119 GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optSt ate, | 115 GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, |
| 116 const GrOptDrawState& optState, | |
| 120 const GrGLProgramDesc& desc) | 117 const GrGLProgramDesc& desc) |
| 121 : fVS(this) | 118 : fVS(this) |
| 122 , fGS(this) | 119 , fGS(this) |
| 123 , fFS(this, desc) | 120 , fFS(this, desc) |
| 124 , fOutOfStage(true) | 121 , fOutOfStage(true) |
| 125 , fStageIndex(-1) | 122 , fStageIndex(-1) |
| 123 , fGeometryProcessor(NULL) | |
| 126 , fOptState(optState) | 124 , fOptState(optState) |
| 127 , fDesc(desc) | 125 , fDesc(desc) |
| 128 , fGpu(gpu) | 126 , fGpu(gpu) |
| 129 , fUniforms(kVarsPerBlock) { | 127 , fUniforms(kVarsPerBlock) { |
| 130 } | 128 } |
| 131 | 129 |
| 132 void GrGLProgramBuilder::addVarying(GrSLType type, | 130 void GrGLProgramBuilder::addVarying(GrSLType type, |
| 133 const char* name, | 131 const char* name, |
| 134 const char** vsOutName, | 132 const char** vsOutName, |
| 135 const char** fsInName, | 133 const char** fsInName, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 216 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 219 kVec4f_GrSLType, | 217 kVec4f_GrSLType, |
| 220 "Coverage", | 218 "Coverage", |
| 221 &name); | 219 &name); |
| 222 *inputCoverage = GrGLSLExpr4(name); | 220 *inputCoverage = GrGLSLExpr4(name); |
| 223 } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { | 221 } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { |
| 224 *inputCoverage = GrGLSLExpr4(1); | 222 *inputCoverage = GrGLSLExpr4(1); |
| 225 } | 223 } |
| 226 } | 224 } |
| 227 | 225 |
| 228 void GrGLProgramBuilder::createAndEmitProcessors(const GrGeometryStage* geometry Processor, | 226 void GrGLProgramBuilder::createAndEmitProcessors(const GrOptDrawState& optState, |
|
bsalomon
2014/10/10 15:25:50
Should we be using the word "install" rather than
| |
| 229 const GrFragmentStage* colorSta ges[], | |
| 230 const GrFragmentStage* coverage Stages[], | |
| 231 GrGLSLExpr4* inputColor, | 227 GrGLSLExpr4* inputColor, |
| 232 GrGLSLExpr4* inputCoverage) { | 228 GrGLSLExpr4* inputCoverage) { |
| 233 bool useLocalCoords = fVS.hasExplicitLocalCoords(); | 229 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); |
| 234 | 230 int numProcs = optState.numFragmentStages(); |
| 235 EffectKeyProvider colorKeyProvider(&fDesc, EffectKeyProvider::kColor_EffectT ype); | 231 this->emitFragmentProcessors(0, optState.numColorStages(), inputColor); |
| 236 int numColorEffects = fDesc.numColorEffects(); | 232 if (optState.hasGeometryProcessor()) { |
| 237 GrGLInstalledProcessors* ip = SkNEW_ARGS(GrGLInstalledProcessors, (numColorE ffects, | 233 const GrGeometryProcessor& gp = *optState.getGeometryProcessor(); |
| 238 useLocalC oords)); | 234 fVS.emitAttributes(gp); |
| 239 this->createAndEmitProcessors<GrFragmentStage>(colorStages, numColorEffects, colorKeyProvider, | 235 EffectKeyProvider keyProvider(&fDesc, EffectKeyProvider::kGeometryProces sor_EffectType); |
| 240 inputColor, ip); | 236 GrGLSLExpr4 output; |
| 241 fColorEffects.reset(ip); | 237 this->emit<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &out put); |
| 242 | 238 *inputCoverage = output; |
| 243 if (geometryProcessor) { | |
| 244 fVS.emitAttributes(*geometryProcessor->getProcessor()); | |
| 245 EffectKeyProvider gpKeyProvider(&fDesc, EffectKeyProvider::kGeometryProc essor_EffectType); | |
| 246 ip = SkNEW_ARGS(GrGLInstalledProcessors, (1, useLocalCoords)); | |
| 247 this->createAndEmitProcessors<GrGeometryStage>(&geometryProcessor, 1, gp KeyProvider, | |
| 248 inputCoverage, ip); | |
| 249 fGeometryProcessor.reset(ip); | |
| 250 } | 239 } |
| 251 | 240 this->emitFragmentProcessors(optState.numColorStages(), numProcs, inputCove rage); |
| 252 EffectKeyProvider coverageKeyProvider(&fDesc, EffectKeyProvider::kCoverage_E ffectType); | |
| 253 int numCoverageEffects = fDesc.numCoverageEffects(); | |
| 254 ip = SkNEW_ARGS(GrGLInstalledProcessors, (numCoverageEffects, useLocalCoords )); | |
| 255 this->createAndEmitProcessors<GrFragmentStage>(coverageStages, numCoverageEf fects, | |
| 256 coverageKeyProvider, inputCov erage, ip); | |
| 257 fCoverageEffects.reset(ip); | |
| 258 } | 241 } |
| 259 | 242 |
| 260 template <class ProcessorStage> | 243 void GrGLProgramBuilder::emitFragmentProcessors(int procOffset, int numProcs, Gr GLSLExpr4* inOut) { |
| 261 void GrGLProgramBuilder::createAndEmitProcessors(const ProcessorStage* processSt ages[], | 244 EffectKeyProvider keyProvider(&fDesc, EffectKeyProvider::kColor_EffectType); |
| 262 int effectCnt, | 245 for (int e = procOffset; e < numProcs; ++e) { |
| 263 const EffectKeyProvider& keyPro vider, | 246 GrGLSLExpr4 output; |
| 264 GrGLSLExpr4* fsInOutColor, | 247 const GrFragmentStage& stage = fOptState.getFragmentStage(e); |
| 265 GrGLInstalledProcessors* instal ledProcessors) { | 248 this->emit<GrFragmentStage>(stage, e, keyProvider, *inOut, &output); |
| 266 bool effectEmitted = false; | 249 *inOut = output; |
| 267 | |
| 268 GrGLSLExpr4 inColor = *fsInOutColor; | |
| 269 GrGLSLExpr4 outColor; | |
| 270 | |
| 271 for (int e = 0; e < effectCnt; ++e) { | |
| 272 // Program builders have a bit of state we need to clear with each effec t | |
| 273 AutoStageAdvance adv(this); | |
| 274 const ProcessorStage& stage = *processStages[e]; | |
| 275 SkASSERT(stage.getProcessor()); | |
| 276 | |
| 277 if (inColor.isZeros()) { | |
| 278 SkString inColorName; | |
| 279 | |
| 280 // Effects have no way to communicate zeros, they treat an empty str ing as ones. | |
| 281 this->nameVariable(&inColorName, '\0', "input"); | |
| 282 fFS.codeAppendf("vec4 %s = %s;", inColorName.c_str(), inColor.c_str( )); | |
| 283 inColor = inColorName; | |
| 284 } | |
| 285 | |
| 286 // create var to hold stage result | |
| 287 SkString outColorName; | |
| 288 this->nameVariable(&outColorName, '\0', "output"); | |
| 289 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); | |
| 290 outColor = outColorName; | |
| 291 | |
| 292 SkASSERT(installedProcessors); | |
| 293 const typename ProcessorStage::Processor& processor = *stage.getProcesso r(); | |
| 294 SkSTArray<2, GrGLProcessor::TransformedCoords> coords(processor.numTrans forms()); | |
| 295 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(processor.numTextur es()); | |
| 296 | |
| 297 this->emitTransforms(stage, &coords, installedProcessors); | |
| 298 this->emitSamplers(processor, &samplers, installedProcessors); | |
| 299 | |
| 300 typename ProcessorStage::GLProcessor* glEffect = | |
| 301 processor.getFactory().createGLInstance(processor); | |
| 302 installedProcessors->addEffect(glEffect); | |
| 303 | |
| 304 // Enclose custom code in a block to avoid namespace conflicts | |
| 305 SkString openBrace; | |
| 306 openBrace.printf("{ // Stage %d: %s\n", fStageIndex, glEffect->name()); | |
| 307 fFS.codeAppend(openBrace.c_str()); | |
| 308 fVS.codeAppend(openBrace.c_str()); | |
| 309 | |
| 310 glEffect->emitCode(this, processor, keyProvider.get(e), outColor.c_str() , | |
| 311 inColor.isOnes() ? NULL : inColor.c_str(), coords, sa mplers); | |
| 312 | |
| 313 // We have to check that effects and the code they emit are consistent, ie if an effect | |
| 314 // asks for dst color, then the emit code needs to follow suit | |
| 315 verify(processor); | |
| 316 fFS.codeAppend("}"); | |
| 317 fVS.codeAppend("}"); | |
| 318 | |
| 319 inColor = outColor; | |
| 320 effectEmitted = true; | |
| 321 } | |
| 322 | |
| 323 if (effectEmitted) { | |
| 324 *fsInOutColor = outColor; | |
| 325 } | 250 } |
| 326 } | 251 } |
| 327 | 252 |
| 253 // TODO effects cannot zeros, the fix is to allow effects to take the GrGLSLExpr 4 directly | |
|
joshua.litt
2014/10/10 13:44:58
I'll fix this comment before submit
| |
| 254 template <class Proc> | |
| 255 void GrGLProgramBuilder::emit(const Proc& proc, | |
| 256 int index, | |
| 257 const EffectKeyProvider keyProvider, | |
| 258 const GrGLSLExpr4& input, | |
| 259 GrGLSLExpr4* output) { | |
| 260 // Program builders have a bit of state we need to clear with each effect | |
| 261 AutoStageAdvance adv(this); | |
| 262 | |
| 263 // create var to hold stage result | |
| 264 SkString outColorName; | |
| 265 this->nameVariable(&outColorName, '\0', "output"); | |
| 266 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); | |
| 267 *output = outColorName; | |
| 268 | |
| 269 // Enclose custom code in a block to avoid namespace conflicts | |
| 270 SkString openBrace; | |
| 271 openBrace.printf("{ // Stage %d\n", fStageIndex); | |
| 272 fFS.codeAppend(openBrace.c_str()); | |
| 273 | |
| 274 this->emit(proc, keyProvider.get(index), output->c_str(), input.c_str()); | |
| 275 | |
| 276 fFS.codeAppend("}"); | |
| 277 } | |
| 278 | |
| 279 void GrGLProgramBuilder::emit(const GrFragmentStage& fs, | |
| 280 const GrProcessorKey& key, | |
| 281 const char* outColor, | |
| 282 const char* inColor) { | |
| 283 GrGLInstalledFragProc* ifp = SkNEW_ARGS(GrGLInstalledFragProc, (fVS.hasLocal Coords())); | |
| 284 | |
| 285 const GrFragmentProcessor& fp = *fs.getProcessor(); | |
| 286 ifp->fGLProc = fp.getFactory().createGLInstance(fp); | |
| 287 | |
| 288 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures()); | |
| 289 this->emitSamplers(fp, &samplers, ifp); | |
| 290 | |
| 291 // Fragment processors can have coord transforms | |
| 292 SkSTArray<2, GrGLProcessor::TransformedCoords> coords(fp.numTransforms()); | |
| 293 this->emitTransforms(fs, &coords, ifp); | |
| 294 | |
| 295 ifp->fGLProc->emitCode(this, fp, key, outColor, inColor, coords, samplers); | |
| 296 | |
| 297 // We have to check that effects and the code they emit are consistent, ie i f an effect | |
| 298 // asks for dst color, then the emit code needs to follow suit | |
| 299 verify(fp); | |
| 300 fFragmentProcessors->fProcs.push_back(ifp); | |
| 301 } | |
| 302 | |
| 303 void GrGLProgramBuilder::emit(const GrGeometryProcessor& gp, | |
| 304 const GrProcessorKey& key, | |
| 305 const char* outColor, | |
| 306 const char* inColor) { | |
| 307 SkASSERT(!fGeometryProcessor); | |
| 308 fGeometryProcessor = SkNEW(GrGLInstalledGeoProc); | |
| 309 | |
| 310 fGeometryProcessor->fGLProc = gp.getFactory().createGLInstance(gp); | |
| 311 | |
| 312 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures()); | |
| 313 this->emitSamplers(gp, &samplers, fGeometryProcessor); | |
| 314 | |
| 315 SkSTArray<2, GrGLProcessor::TransformedCoords> coords; | |
| 316 | |
| 317 // TODO remove coords from emit code signature, probably best to use a struc t here so these | |
| 318 // updates are less painful | |
| 319 fGeometryProcessor->fGLProc->emitCode(this, gp, key, outColor, inColor, coor ds, samplers); | |
| 320 | |
| 321 // We have to check that effects and the code they emit are consistent, ie i f an effect | |
| 322 // asks for dst color, then the emit code needs to follow suit | |
| 323 verify(gp); | |
| 324 } | |
| 325 | |
| 328 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) { | 326 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) { |
| 329 SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition()); | 327 SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition()); |
| 330 } | 328 } |
| 331 | 329 |
| 332 void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) { | 330 void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) { |
| 333 SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition()); | 331 SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition()); |
| 334 SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor()); | 332 SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor()); |
| 335 } | 333 } |
| 336 | 334 |
| 337 void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage, | 335 void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage, |
| 338 GrGLProcessor::TransformedCoordsArray* o utCoords, | 336 GrGLProcessor::TransformedCoordsArray* o utCoords, |
| 339 GrGLInstalledProcessors* installedProces sors) { | 337 GrGLInstalledFragProc* ifp) { |
| 340 SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = | 338 const GrFragmentProcessor* effect = effectStage.getProcessor(); |
| 341 installedProcessors->addTransforms(); | |
| 342 const GrProcessor* effect = effectStage.getProcessor(); | |
| 343 int numTransforms = effect->numTransforms(); | 339 int numTransforms = effect->numTransforms(); |
| 344 transforms.push_back_n(numTransforms); | 340 ifp->fTransforms.push_back_n(numTransforms); |
| 345 | 341 |
| 346 for (int t = 0; t < numTransforms; t++) { | 342 for (int t = 0; t < numTransforms; t++) { |
| 347 const char* uniName = "StageMatrix"; | 343 const char* uniName = "StageMatrix"; |
| 348 GrSLType varyingType = | 344 GrSLType varyingType = |
| 349 effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalC oords()) ? | 345 effectStage.isPerspectiveCoordTransform(t, fVS.hasLocalCoords()) ? |
| 350 kVec3f_GrSLType : | 346 kVec3f_GrSLType : |
| 351 kVec2f_GrSLType; | 347 kVec2f_GrSLType; |
| 352 | 348 |
| 353 SkString suffixedUniName; | 349 SkString suffixedUniName; |
| 354 if (0 != t) { | 350 if (0 != t) { |
| 355 suffixedUniName.append(uniName); | 351 suffixedUniName.append(uniName); |
| 356 suffixedUniName.appendf("_%i", t); | 352 suffixedUniName.appendf("_%i", t); |
| 357 uniName = suffixedUniName.c_str(); | 353 uniName = suffixedUniName.c_str(); |
| 358 } | 354 } |
| 359 transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Vis ibility, | 355 ifp->fTransforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVert ex_Visibility, |
| 360 kMat33f_GrSLType, | 356 kMat33f_GrSLType, |
| 361 uniName, | 357 uniName, |
| 362 &uniName).toShaderBuilderIndex( ); | 358 &uniName).toShaderBuilder Index(); |
| 363 | 359 |
| 364 const char* varyingName = "MatrixCoord"; | 360 const char* varyingName = "MatrixCoord"; |
| 365 SkString suffixedVaryingName; | 361 SkString suffixedVaryingName; |
| 366 if (0 != t) { | 362 if (0 != t) { |
| 367 suffixedVaryingName.append(varyingName); | 363 suffixedVaryingName.append(varyingName); |
| 368 suffixedVaryingName.appendf("_%i", t); | 364 suffixedVaryingName.appendf("_%i", t); |
| 369 varyingName = suffixedVaryingName.c_str(); | 365 varyingName = suffixedVaryingName.c_str(); |
| 370 } | 366 } |
| 371 const char* vsVaryingName; | 367 const char* vsVaryingName; |
| 372 const char* fsVaryingName; | 368 const char* fsVaryingName; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 386 fVS.codeAppendf("%s = %s * vec3(%s, 1);", | 382 fVS.codeAppendf("%s = %s * vec3(%s, 1);", |
| 387 vsVaryingName, uniName, coords.c_str()); | 383 vsVaryingName, uniName, coords.c_str()); |
| 388 } | 384 } |
| 389 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, | 385 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, |
| 390 (SkString(fsVaryingName), varyingType)); | 386 (SkString(fsVaryingName), varyingType)); |
| 391 } | 387 } |
| 392 } | 388 } |
| 393 | 389 |
| 394 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, | 390 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, |
| 395 GrGLProcessor::TextureSamplerArray* outSam plers, | 391 GrGLProcessor::TextureSamplerArray* outSam plers, |
| 396 GrGLInstalledProcessors* installedProcesso rs) { | 392 GrGLInstalledProc* ip) { |
| 397 SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = installedProces sors->addSamplers(); | |
| 398 int numTextures = processor.numTextures(); | 393 int numTextures = processor.numTextures(); |
| 399 samplers.push_back_n(numTextures); | 394 ip->fSamplers.push_back_n(numTextures); |
| 400 SkString name; | 395 SkString name; |
| 401 for (int t = 0; t < numTextures; ++t) { | 396 for (int t = 0; t < numTextures; ++t) { |
| 402 name.printf("Sampler%d", t); | 397 name.printf("Sampler%d", t); |
| 403 samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Vi sibility, | 398 ip->fSamplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragme nt_Visibility, |
| 404 kSampler2D_GrSLType, | 399 kSampler2D_GrSLType, |
| 405 name.c_str()); | 400 name.c_str()); |
| 406 SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler, | 401 SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler, |
| 407 (samplers[t].fUniform, processor.textureAccess(t) )); | 402 (ip->fSamplers[t].fUniform, processor.textureAcce ss(t))); |
| 408 } | 403 } |
| 409 } | 404 } |
| 410 | 405 |
| 411 GrGLProgram* GrGLProgramBuilder::finalize() { | 406 GrGLProgram* GrGLProgramBuilder::finalize() { |
| 412 // verify we can get a program id | 407 // verify we can get a program id |
| 413 GrGLuint programID; | 408 GrGLuint programID; |
| 414 GL_CALL_RET(programID, CreateProgram()); | 409 GL_CALL_RET(programID, CreateProgram()); |
| 415 if (0 == programID) { | 410 if (0 == programID) { |
| 416 return NULL; | 411 return NULL; |
| 417 } | 412 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 cleanupShaders(shaderIDs); | 494 cleanupShaders(shaderIDs); |
| 500 } | 495 } |
| 501 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { | 496 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { |
| 502 for (int i = 0; i < shaderIDs.count(); ++i) { | 497 for (int i = 0; i < shaderIDs.count(); ++i) { |
| 503 GL_CALL(DeleteShader(shaderIDs[i])); | 498 GL_CALL(DeleteShader(shaderIDs[i])); |
| 504 } | 499 } |
| 505 } | 500 } |
| 506 | 501 |
| 507 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { | 502 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { |
| 508 return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUn iforms, | 503 return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUn iforms, |
| 509 fGeometryProcessor, fColorEffects, fCoverage Effects)); | 504 fGeometryProcessor, fFragmentProcessors.get( ))); |
| 510 } | 505 } |
| 511 | 506 |
| 512 //////////////////////////////////////////////////////////////////////////////// | 507 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 513 | 508 |
| 514 GrGLInstalledProcessors::~GrGLInstalledProcessors() { | 509 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
| 515 int numEffects = fGLProcessors.count(); | 510 int numProcs = fProcs.count(); |
| 516 for (int e = 0; e < numEffects; ++e) { | 511 for (int e = 0; e < numProcs; ++e) { |
| 517 SkDELETE(fGLProcessors[e]); | 512 SkDELETE(fProcs[e]->fGLProc); |
| 518 } | 513 } |
| 519 } | 514 } |
| OLD | NEW |