OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrGLProgram.h" | 8 #include "GrGLProgram.h" |
9 | 9 |
10 #include "GrAllocator.h" | 10 #include "GrAllocator.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 program = NULL; | 32 program = NULL; |
33 } | 33 } |
34 return program; | 34 return program; |
35 } | 35 } |
36 | 36 |
37 GrGLProgram::GrGLProgram(GrGpuGL* gpu, | 37 GrGLProgram::GrGLProgram(GrGpuGL* gpu, |
38 const GrGLProgramDesc& desc, | 38 const GrGLProgramDesc& desc, |
39 const GrEffectStage* colorStages[], | 39 const GrEffectStage* colorStages[], |
40 const GrEffectStage* coverageStages[]) | 40 const GrEffectStage* coverageStages[]) |
41 : fGpu(gpu) | 41 : fGpu(gpu) |
42 , fUniformManager(gpu) { | 42 , fUniformManager(gpu) |
| 43 , fHasVertexShader(false) |
| 44 , fNumTexCoordSets(0) { |
43 fDesc = desc; | 45 fDesc = desc; |
44 fProgramID = 0; | 46 fProgramID = 0; |
45 | 47 |
46 fDstCopyTexUnit = -1; | 48 fDstCopyTexUnit = -1; |
47 | 49 |
48 fColor = GrColor_ILLEGAL; | 50 fColor = GrColor_ILLEGAL; |
49 fColorFilterColor = GrColor_ILLEGAL; | 51 fColorFilterColor = GrColor_ILLEGAL; |
50 | 52 |
51 this->genProgram(colorStages, coverageStages); | 53 if (fDesc.getHeader().fHasVertexCode || |
| 54 !fGpu->glCaps().fixedFunctionSupport() || |
| 55 !fGpu->glCaps().pathStencilingSupport()) { |
| 56 |
| 57 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); |
| 58 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { |
| 59 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); |
| 60 fHasVertexShader = true; |
| 61 } |
| 62 } else { |
| 63 GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(fGpu, fUniformManager,
fDesc); |
| 64 if (this->genProgram(&fragmentOnlyBuilder, colorStages, coverageStages))
{ |
| 65 fNumTexCoordSets = fragmentOnlyBuilder.getNumTexCoordSets(); |
| 66 } |
| 67 } |
52 } | 68 } |
53 | 69 |
54 GrGLProgram::~GrGLProgram() { | 70 GrGLProgram::~GrGLProgram() { |
55 if (fProgramID) { | 71 if (fProgramID) { |
56 GL_CALL(DeleteProgram(fProgramID)); | 72 GL_CALL(DeleteProgram(fProgramID)); |
57 } | 73 } |
58 } | 74 } |
59 | 75 |
60 void GrGLProgram::abandon() { | 76 void GrGLProgram::abandon() { |
61 fProgramID = 0; | 77 fProgramID = 0; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 *string = GrGLSLZerosVecf(4); | 214 *string = GrGLSLZerosVecf(4); |
199 break; | 215 break; |
200 case kOnes_GrSLConstantVec: | 216 case kOnes_GrSLConstantVec: |
201 *string = GrGLSLOnesVecf(4); | 217 *string = GrGLSLOnesVecf(4); |
202 break; | 218 break; |
203 } | 219 } |
204 } | 220 } |
205 | 221 |
206 } | 222 } |
207 | 223 |
208 bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], | 224 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, |
| 225 const GrEffectStage* colorStages[], |
209 const GrEffectStage* coverageStages[]) { | 226 const GrEffectStage* coverageStages[]) { |
210 SkASSERT(0 == fProgramID); | 227 SkASSERT(0 == fProgramID); |
211 | 228 |
212 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 229 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
213 | 230 |
214 GrGLFullShaderBuilder builder(fGpu, fUniformManager, fDesc); | |
215 fUniformHandles.fViewMatrixUni = builder.getViewMatrixUniform(); | |
216 | |
217 // incoming color to current stage being processed. | 231 // incoming color to current stage being processed. |
218 SkString inColor = builder.getInputColor(); | 232 SkString inColor = builder->getInputColor(); |
219 GrSLConstantVec knownColorValue = builder.getKnownColorValue(); | 233 GrSLConstantVec knownColorValue = builder->getKnownColorValue(); |
220 | 234 |
221 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. | 235 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. |
222 SkXfermode::Coeff colorCoeff; | 236 SkXfermode::Coeff colorCoeff; |
223 SkXfermode::Coeff filterColorCoeff; | 237 SkXfermode::Coeff filterColorCoeff; |
224 SkAssertResult( | 238 SkAssertResult( |
225 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, | 239 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, |
226 &filterColorCoeff, | 240 &filterColorCoeff, |
227 &colorCoeff)); | 241 &colorCoeff)); |
228 bool needColor, needFilterColor; | 242 bool needColor, needFilterColor; |
229 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); | 243 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); |
230 | 244 |
231 fColorEffects.reset( | 245 fColorEffects.reset( |
232 builder.createAndEmitEffects(colorStages, | 246 builder->createAndEmitEffects(colorStages, |
233 fDesc.effectKeys(), | 247 fDesc.effectKeys(), |
234 needColor ? fDesc.numColorEffects() : 0, | 248 needColor ? fDesc.numColorEffects() : 0, |
235 &inColor, | 249 &inColor, |
236 &knownColorValue)); | 250 &knownColorValue)); |
237 | 251 |
238 // Insert the color filter. This will soon be replaced by a color effect. | 252 // Insert the color filter. This will soon be replaced by a color effect. |
239 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { | 253 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { |
240 const char* colorFilterColorUniName = NULL; | 254 const char* colorFilterColorUniName = NULL; |
241 fUniformHandles.fColorFilterUni = builder.addUniform(GrGLShaderBuilder::
kFragment_Visibility, | 255 fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder:
:kFragment_Visibility, |
242 kVec4f_GrSLType, "F
ilterColor", | 256 kVec4f_GrSLType, "
FilterColor", |
243 &colorFilterColorUn
iName); | 257 &colorFilterColorU
niName); |
244 | 258 |
245 builder.fsCodeAppend("\tvec4 filteredColor;\n"); | 259 builder->fsCodeAppend("\tvec4 filteredColor;\n"); |
246 const char* color; | 260 const char* color; |
247 // add_color_filter requires a real input string. | 261 // add_color_filter requires a real input string. |
248 if (knownColorValue == kOnes_GrSLConstantVec) { | 262 if (knownColorValue == kOnes_GrSLConstantVec) { |
249 color = GrGLSLOnesVecf(4); | 263 color = GrGLSLOnesVecf(4); |
250 } else if (knownColorValue == kZeros_GrSLConstantVec) { | 264 } else if (knownColorValue == kZeros_GrSLConstantVec) { |
251 color = GrGLSLZerosVecf(4); | 265 color = GrGLSLZerosVecf(4); |
252 } else { | 266 } else { |
253 color = inColor.c_str(); | 267 color = inColor.c_str(); |
254 } | 268 } |
255 add_color_filter(&builder, "filteredColor", filterColorCoeff, | 269 add_color_filter(builder, "filteredColor", filterColorCoeff, |
256 colorCoeff, colorFilterColorUniName, color); | 270 colorCoeff, colorFilterColorUniName, color); |
257 inColor = "filteredColor"; | 271 inColor = "filteredColor"; |
258 } | 272 } |
259 | 273 |
260 /////////////////////////////////////////////////////////////////////////// | 274 /////////////////////////////////////////////////////////////////////////// |
261 // compute the partial coverage | 275 // compute the partial coverage |
262 SkString inCoverage = builder.getInputCoverage(); | 276 SkString inCoverage = builder->getInputCoverage(); |
263 GrSLConstantVec knownCoverageValue = builder.getKnownCoverageValue(); | 277 GrSLConstantVec knownCoverageValue = builder->getKnownCoverageValue(); |
264 | 278 |
265 fCoverageEffects.reset( | 279 fCoverageEffects.reset( |
266 builder.createAndEmitEffects(coverageStages, | 280 builder->createAndEmitEffects(coverageStages, |
267 fDesc.getEffectKeys() + fDesc.numColorEffec
ts(), | 281 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), |
268 fDesc.numCoverageEffects(), | 282 fDesc.numCoverageEffects(), |
269 &inCoverage, | 283 &inCoverage, |
270 &knownCoverageValue)); | 284 &knownCoverageValue)); |
271 | 285 |
272 // discard if coverage is zero | 286 // discard if coverage is zero |
273 if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageV
alue) { | 287 if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageV
alue) { |
274 if (kZeros_GrSLConstantVec == knownCoverageValue) { | 288 if (kZeros_GrSLConstantVec == knownCoverageValue) { |
275 // This is unfortunate. | 289 // This is unfortunate. |
276 builder.fsCodeAppend("\tdiscard;\n"); | 290 builder->fsCodeAppend("\tdiscard;\n"); |
277 } else { | 291 } else { |
278 builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\
t\tdiscard;\n\t}\n", | 292 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n
\t\tdiscard;\n\t}\n", |
279 inCoverage.c_str()); | 293 inCoverage.c_str()); |
280 } | 294 } |
281 } | 295 } |
282 | 296 |
283 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { | 297 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { |
284 const char* secondaryOutputName = builder.enableSecondaryOutput(); | 298 const char* secondaryOutputName = builder->enableSecondaryOutput(); |
285 | 299 |
286 // default coeff to ones for kCoverage_DualSrcOutput | 300 // default coeff to ones for kCoverage_DualSrcOutput |
287 SkString coeff; | 301 SkString coeff; |
288 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; | 302 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; |
289 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { | 303 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { |
290 // Get (1-A) into coeff | 304 // Get (1-A) into coeff |
291 SkString inColorAlpha; | 305 SkString inColorAlpha; |
292 GrGLSLGetComponent4f(&inColorAlpha, | 306 GrGLSLGetComponent4f(&inColorAlpha, |
293 inColor.c_str(), | 307 inColor.c_str(), |
294 kA_GrColorComponentFlag, | 308 kA_GrColorComponentFlag, |
(...skipping 15 matching lines...) Expand all Loading... |
310 true); | 324 true); |
311 } | 325 } |
312 // Get coeff * coverage into modulate and then write that to the dual so
urce output. | 326 // Get coeff * coverage into modulate and then write that to the dual so
urce output. |
313 SkString modulate; | 327 SkString modulate; |
314 GrGLSLModulatef<4>(&modulate, | 328 GrGLSLModulatef<4>(&modulate, |
315 coeff.c_str(), | 329 coeff.c_str(), |
316 inCoverage.c_str(), | 330 inCoverage.c_str(), |
317 knownCoeffValue, | 331 knownCoeffValue, |
318 knownCoverageValue, | 332 knownCoverageValue, |
319 false); | 333 false); |
320 builder.fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_st
r()); | 334 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_s
tr()); |
321 } | 335 } |
322 | 336 |
323 /////////////////////////////////////////////////////////////////////////// | 337 /////////////////////////////////////////////////////////////////////////// |
324 // combine color and coverage as frag color | 338 // combine color and coverage as frag color |
325 | 339 |
326 // Get "color * coverage" into fragColor | 340 // Get "color * coverage" into fragColor |
327 SkString fragColor; | 341 SkString fragColor; |
328 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, | 342 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, |
329 inColor.c_str(), | 343 inColor.c_str(), |
330 inCoverage.c_str(), | 344 inCoverage.c_str(), |
331 knownColorValue, | 345 knownColorValue, |
332 knownCoverageValue, | 346 knownCoverageValue, |
333 true); | 347 true); |
334 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do
so. | 348 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do
so. |
335 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu
t) { | 349 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu
t) { |
336 SkString dstCoeff; | 350 SkString dstCoeff; |
337 GrSLConstantVec knownDstCoeffValue = GrGLSLSubtractf<4>(&dstCoeff, | 351 GrSLConstantVec knownDstCoeffValue = GrGLSLSubtractf<4>(&dstCoeff, |
338 NULL, | 352 NULL, |
339 inCoverage.c_str
(), | 353 inCoverage.c_str
(), |
340 kOnes_GrSLConsta
ntVec, | 354 kOnes_GrSLConsta
ntVec, |
341 knownCoverageVal
ue, | 355 knownCoverageVal
ue, |
342 true); | 356 true); |
343 SkString dstContribution; | 357 SkString dstContribution; |
344 GrSLConstantVec knownDstContributionValue = GrGLSLModulatef<4>(&dstContr
ibution, | 358 GrSLConstantVec knownDstContributionValue = GrGLSLModulatef<4>(&dstContr
ibution, |
345 dstCoeff.
c_str(), | 359 dstCoeff.
c_str(), |
346 builder.d
stColor(), | 360 builder->
dstColor(), |
347 knownDstC
oeffValue, | 361 knownDstC
oeffValue, |
348 kNone_GrS
LConstantVec, | 362 kNone_GrS
LConstantVec, |
349 true); | 363 true); |
350 SkString oldFragColor = fragColor; | 364 SkString oldFragColor = fragColor; |
351 fragColor.reset(); | 365 fragColor.reset(); |
352 GrGLSLAddf<4>(&fragColor, | 366 GrGLSLAddf<4>(&fragColor, |
353 oldFragColor.c_str(), | 367 oldFragColor.c_str(), |
354 dstContribution.c_str(), | 368 dstContribution.c_str(), |
355 knownFragColorValue, | 369 knownFragColorValue, |
356 knownDstContributionValue, | 370 knownDstContributionValue, |
357 false); | 371 false); |
358 } else { | 372 } else { |
359 expand_known_value4f(&fragColor, knownFragColorValue); | 373 expand_known_value4f(&fragColor, knownFragColorValue); |
360 } | 374 } |
361 builder.fsCodeAppendf("\t%s = %s;\n", builder.getColorOutputName(), fragColo
r.c_str()); | 375 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragCo
lor.c_str()); |
362 | 376 |
363 if (!builder.finish(&fProgramID)) { | 377 if (!builder->finish(&fProgramID)) { |
364 return false; | 378 return false; |
365 } | 379 } |
366 | 380 |
367 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); | 381 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform(); |
368 fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform(); | 382 fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform(); |
369 fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform(); | 383 fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform(); |
370 fUniformHandles.fColorUni = builder.getColorUniform(); | 384 fUniformHandles.fColorUni = builder->getColorUniform(); |
371 fUniformHandles.fCoverageUni = builder.getCoverageUniform(); | 385 fUniformHandles.fCoverageUni = builder->getCoverageUniform(); |
372 fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform(); | 386 fUniformHandles.fDstCopySamplerUni = builder->getDstCopySamplerUniform(); |
373 // This must be called after we set fDstCopySamplerUni above. | 387 // This must be called after we set fDstCopySamplerUni above. |
374 this->initSamplerUniforms(); | 388 this->initSamplerUniforms(); |
375 | 389 |
376 return true; | 390 return true; |
377 } | 391 } |
378 | 392 |
379 void GrGLProgram::initSamplerUniforms() { | 393 void GrGLProgram::initSamplerUniforms() { |
380 GL_CALL(UseProgram(fProgramID)); | 394 GL_CALL(UseProgram(fProgramID)); |
381 GrGLint texUnitIdx = 0; | 395 GrGLint texUnitIdx = 0; |
382 if (fUniformHandles.fDstCopySamplerUni.isValid()) { | 396 if (fUniformHandles.fDstCopySamplerUni.isValid()) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); | 452 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); |
439 } | 453 } |
440 } else { | 454 } else { |
441 SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid()); | 455 SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid()); |
442 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid()); | 456 SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid()); |
443 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); | 457 SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid()); |
444 } | 458 } |
445 | 459 |
446 fColorEffects->setData(fGpu, fUniformManager, colorStages); | 460 fColorEffects->setData(fGpu, fUniformManager, colorStages); |
447 fCoverageEffects->setData(fGpu, fUniformManager, coverageStages); | 461 fCoverageEffects->setData(fGpu, fUniformManager, coverageStages); |
| 462 |
| 463 if (!fHasVertexShader) { |
| 464 fGpu->disableUnusedTexGen(fNumTexCoordSets); |
| 465 } |
448 } | 466 } |
449 | 467 |
450 void GrGLProgram::setColor(const GrDrawState& drawState, | 468 void GrGLProgram::setColor(const GrDrawState& drawState, |
451 GrColor color, | 469 GrColor color, |
452 SharedGLState* sharedState) { | 470 SharedGLState* sharedState) { |
453 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 471 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
454 if (!drawState.hasColorVertexAttribute()) { | 472 if (!drawState.hasColorVertexAttribute()) { |
455 switch (header.fColorInput) { | 473 switch (header.fColorInput) { |
456 case GrGLProgramDesc::kAttribute_ColorInput: | 474 case GrGLProgramDesc::kAttribute_ColorInput: |
457 SkASSERT(-1 != header.fColorAttributeIndex); | 475 SkASSERT(-1 != header.fColorAttributeIndex); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 const GrRenderTarget* rt = drawState.getRenderTarget(); | 548 const GrRenderTarget* rt = drawState.getRenderTarget(); |
531 SkISize size; | 549 SkISize size; |
532 size.set(rt->width(), rt->height()); | 550 size.set(rt->width(), rt->height()); |
533 | 551 |
534 // Load the RT height uniform if it is needed to y-flip gl_FragCoord. | 552 // Load the RT height uniform if it is needed to y-flip gl_FragCoord. |
535 if (fUniformHandles.fRTHeightUni.isValid() && | 553 if (fUniformHandles.fRTHeightUni.isValid() && |
536 fMatrixState.fRenderTargetSize.fHeight != size.fHeight) { | 554 fMatrixState.fRenderTargetSize.fHeight != size.fHeight) { |
537 fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.f
Height)); | 555 fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.f
Height)); |
538 } | 556 } |
539 | 557 |
540 if (fMatrixState.fRenderTargetOrigin != rt->origin() || | 558 if (!fHasVertexShader) { |
541 !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) || | 559 SkASSERT(!fUniformHandles.fViewMatrixUni.isValid()); |
542 fMatrixState.fRenderTargetSize != size) { | 560 fGpu->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin())
; |
| 561 } else if (fMatrixState.fRenderTargetOrigin != rt->origin() || |
| 562 fMatrixState.fRenderTargetSize != size || |
| 563 !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix())
) { |
| 564 SkASSERT(fUniformHandles.fViewMatrixUni.isValid()); |
543 | 565 |
544 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 566 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
545 fMatrixState.fRenderTargetSize = size; | 567 fMatrixState.fRenderTargetSize = size; |
546 fMatrixState.fRenderTargetOrigin = rt->origin(); | 568 fMatrixState.fRenderTargetOrigin = rt->origin(); |
547 | 569 |
548 GrGLfloat viewMatrix[3 * 3]; | 570 GrGLfloat viewMatrix[3 * 3]; |
549 fMatrixState.getGLMatrix<3>(viewMatrix); | 571 fMatrixState.getGLMatrix<3>(viewMatrix); |
550 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); | 572 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); |
551 } | 573 } |
552 } | 574 } |
OLD | NEW |