OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "effects/GrCustomXfermode.h" | 8 #include "effects/GrCustomXfermode.h" |
9 #include "effects/GrCustomXfermodePriv.h" | 9 #include "effects/GrCustomXfermodePriv.h" |
10 | 10 |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 GLCustomXferFP(const GrFragmentProcessor&) {} | 409 GLCustomXferFP(const GrFragmentProcessor&) {} |
410 ~GLCustomXferFP() SK_OVERRIDE {}; | 410 ~GLCustomXferFP() SK_OVERRIDE {}; |
411 | 411 |
412 void emitCode(GrGLFPBuilder* builder, | 412 void emitCode(GrGLFPBuilder* builder, |
413 const GrFragmentProcessor& fp, | 413 const GrFragmentProcessor& fp, |
414 const char* outputColor, | 414 const char* outputColor, |
415 const char* inputColor, | 415 const char* inputColor, |
416 const TransformedCoordsArray& coords, | 416 const TransformedCoordsArray& coords, |
417 const TextureSamplerArray& samplers) SK_OVERRIDE { | 417 const TextureSamplerArray& samplers) SK_OVERRIDE { |
418 SkXfermode::Mode mode = fp.cast<GrCustomXferFP>().mode(); | 418 SkXfermode::Mode mode = fp.cast<GrCustomXferFP>().mode(); |
419 const GrTexture* backgroundTex = | |
420 fp.cast<GrCustomXferFP>().backgroundAccess().getTexture(); | |
421 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 419 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
422 const char* dstColor; | 420 const char* dstColor = "bgColor"; |
423 if (backgroundTex) { | 421 fsBuilder->codeAppendf("vec4 %s = ", dstColor); |
424 dstColor = "bgColor"; | 422 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0]
.getType()); |
425 fsBuilder->codeAppendf("vec4 %s = ", dstColor); | 423 fsBuilder->codeAppendf(";"); |
426 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coord
s[0].getType()); | |
427 fsBuilder->codeAppendf(";"); | |
428 } else { | |
429 dstColor = fsBuilder->dstColor(); | |
430 } | |
431 SkASSERT(dstColor); | |
432 | 424 |
433 emit_custom_xfermode_code(mode, fsBuilder, outputColor, inputColor, dstC
olor); | 425 emit_custom_xfermode_code(mode, fsBuilder, outputColor, inputColor, dstC
olor); |
434 } | 426 } |
435 | 427 |
436 void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE
{} | 428 void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE
{} |
437 | 429 |
438 static void GenKey(const GrFragmentProcessor& proc, const GrGLCaps&, GrProce
ssorKeyBuilder* b) { | 430 static void GenKey(const GrFragmentProcessor& proc, const GrGLCaps&, GrProce
ssorKeyBuilder* b) { |
439 // The background may come from the dst or from a texture. | 431 // The background may come from the dst or from a texture. |
440 uint32_t key = proc.numTextures(); | 432 uint32_t key = proc.numTextures(); |
441 SkASSERT(key <= 1); | 433 SkASSERT(key <= 1); |
442 key |= proc.cast<GrCustomXferFP>().mode() << 1; | 434 key |= proc.cast<GrCustomXferFP>().mode() << 1; |
443 b->add32(key); | 435 b->add32(key); |
444 } | 436 } |
445 | 437 |
446 private: | 438 private: |
447 typedef GrGLFragmentProcessor INHERITED; | 439 typedef GrGLFragmentProcessor INHERITED; |
448 }; | 440 }; |
449 | 441 |
450 /////////////////////////////////////////////////////////////////////////////// | 442 /////////////////////////////////////////////////////////////////////////////// |
451 | 443 |
452 GrCustomXferFP::GrCustomXferFP(SkXfermode::Mode mode, GrTexture* background) | 444 GrCustomXferFP::GrCustomXferFP(SkXfermode::Mode mode, GrTexture* background) |
453 : fMode(mode) { | 445 : fMode(mode) { |
454 this->initClassID<GrCustomXferFP>(); | 446 this->initClassID<GrCustomXferFP>(); |
455 if (background) { | 447 |
456 fBackgroundTransform.reset(kLocal_GrCoordSet, background, | 448 SkASSERT(background); |
457 GrTextureParams::kNone_FilterMode); | 449 fBackgroundTransform.reset(kLocal_GrCoordSet, background, |
458 this->addCoordTransform(&fBackgroundTransform); | 450 GrTextureParams::kNone_FilterMode); |
459 fBackgroundAccess.reset(background); | 451 this->addCoordTransform(&fBackgroundTransform); |
460 this->addTextureAccess(&fBackgroundAccess); | 452 fBackgroundAccess.reset(background); |
461 } else { | 453 this->addTextureAccess(&fBackgroundAccess); |
462 this->setWillReadDstColor(); | |
463 } | |
464 } | 454 } |
465 | 455 |
466 void GrCustomXferFP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuild
er* b) const { | 456 void GrCustomXferFP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuild
er* b) const { |
467 GLCustomXferFP::GenKey(*this, caps, b); | 457 GLCustomXferFP::GenKey(*this, caps, b); |
468 } | 458 } |
469 | 459 |
470 GrGLFragmentProcessor* GrCustomXferFP::createGLInstance() const { | 460 GrGLFragmentProcessor* GrCustomXferFP::createGLInstance() const { |
471 return SkNEW_ARGS(GLCustomXferFP, (*this)); | 461 return SkNEW_ARGS(GLCustomXferFP, (*this)); |
472 } | 462 } |
473 | 463 |
474 bool GrCustomXferFP::onIsEqual(const GrFragmentProcessor& other) const { | 464 bool GrCustomXferFP::onIsEqual(const GrFragmentProcessor& other) const { |
475 const GrCustomXferFP& s = other.cast<GrCustomXferFP>(); | 465 const GrCustomXferFP& s = other.cast<GrCustomXferFP>(); |
476 return fMode == s.fMode; | 466 return fMode == s.fMode; |
477 } | 467 } |
478 | 468 |
479 void GrCustomXferFP::onComputeInvariantOutput(GrInvariantOutput* inout) const { | 469 void GrCustomXferFP::onComputeInvariantOutput(GrInvariantOutput* inout) const { |
480 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); | 470 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); |
481 } | 471 } |
482 | 472 |
483 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCustomXferFP); | 473 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCustomXferFP); |
484 GrFragmentProcessor* GrCustomXferFP::TestCreate(SkRandom* rand, | 474 GrFragmentProcessor* GrCustomXferFP::TestCreate(SkRandom* rand, |
485 GrContext*, | 475 GrContext*, |
486 const GrDrawTargetCaps&, | 476 const GrDrawTargetCaps&, |
487 GrTexture*[]) { | 477 GrTexture* textures[]) { |
488 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas
tSeparableMode); | 478 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas
tSeparableMode); |
489 | 479 |
490 return SkNEW_ARGS(GrCustomXferFP, (static_cast<SkXfermode::Mode>(mode), NULL
)); | 480 return SkNEW_ARGS(GrCustomXferFP, (static_cast<SkXfermode::Mode>(mode), text
ures[0])); |
491 } | 481 } |
492 | 482 |
| 483 /////////////////////////////////////////////////////////////////////////////// |
| 484 // Xfer Processor |
| 485 /////////////////////////////////////////////////////////////////////////////// |
| 486 |
| 487 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) { |
| 488 if (!GrCustomXfermode::IsSupportedMode(mode)) { |
| 489 return NULL; |
| 490 } else { |
| 491 return SkNEW_ARGS(GrCustomXPFactory, (mode)); |
| 492 } |
| 493 } |
| 494 |
| 495 /////////////////////////////////////////////////////////////////////////////// |
| 496 |
| 497 class GLCustomXP : public GrGLXferProcessor { |
| 498 public: |
| 499 GLCustomXP(const GrXferProcessor&) {} |
| 500 ~GLCustomXP() SK_OVERRIDE {} |
| 501 |
| 502 void emitCode(const EmitArgs& args) SK_OVERRIDE { |
| 503 SkXfermode::Mode mode = args.fXP.cast<GrCustomXP>().mode(); |
| 504 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 505 const char* dstColor = fsBuilder->dstColor(); |
| 506 |
| 507 emit_custom_xfermode_code(mode, fsBuilder, args.fOutputPrimary, args.fIn
putColor, dstColor); |
| 508 |
| 509 fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;", |
| 510 args.fOutputPrimary, args.fOutputPrimary, args.fI
nputCoverage, |
| 511 args.fInputCoverage, dstColor); |
| 512 } |
| 513 |
| 514 void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERR
IDE {} |
| 515 |
| 516 static void GenKey(const GrXferProcessor& proc, const GrGLCaps&, GrProcessor
KeyBuilder* b) { |
| 517 uint32_t key = proc.numTextures(); |
| 518 SkASSERT(key <= 1); |
| 519 key |= proc.cast<GrCustomXP>().mode() << 1; |
| 520 b->add32(key); |
| 521 } |
| 522 |
| 523 private: |
| 524 typedef GrGLFragmentProcessor INHERITED; |
| 525 }; |
| 526 |
| 527 /////////////////////////////////////////////////////////////////////////////// |
| 528 |
| 529 GrCustomXP::GrCustomXP(SkXfermode::Mode mode) |
| 530 : fMode(mode) { |
| 531 this->initClassID<GrCustomXP>(); |
| 532 this->setWillReadDstColor(); |
| 533 } |
| 534 |
| 535 void GrCustomXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder*
b) const { |
| 536 GLCustomXP::GenKey(*this, caps, b); |
| 537 } |
| 538 |
| 539 GrGLXferProcessor* GrCustomXP::createGLInstance() const { |
| 540 return SkNEW_ARGS(GLCustomXP, (*this)); |
| 541 } |
| 542 |
| 543 bool GrCustomXP::onIsEqual(const GrXferProcessor& other) const { |
| 544 const GrCustomXP& s = other.cast<GrCustomXP>(); |
| 545 return fMode == s.fMode; |
| 546 } |
| 547 |
| 548 GrXferProcessor::OptFlags GrCustomXP::getOptimizations(const GrProcOptInfo& colo
rPOI, |
| 549 const GrProcOptInfo& cove
ragePOI, |
| 550 bool doesStencilWrite, |
| 551 GrColor* overrideColor, |
| 552 const GrDrawTargetCaps& c
aps) { |
| 553 return GrXferProcessor::kNone_Opt; |
| 554 } |
| 555 |
| 556 /////////////////////////////////////////////////////////////////////////////// |
| 557 |
| 558 GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode) |
| 559 : fMode(mode) { |
| 560 this->initClassID<GrCustomXPFactory>(); |
| 561 } |
| 562 |
| 563 void GrCustomXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, |
| 564 const GrProcOptInfo& coveragePOI, |
| 565 GrXPFactory::InvariantOutput* out
put) const { |
| 566 output->fWillBlendWithDst = true; |
| 567 output->fBlendedColorFlags = 0; |
| 568 } |
| 569 |
| 570 GR_DEFINE_XP_FACTORY_TEST(GrCustomXPFactory); |
| 571 GrXPFactory* GrCustomXPFactory::TestCreate(SkRandom* rand, |
| 572 GrContext*, |
| 573 const GrDrawTargetCaps&, |
| 574 GrTexture*[]) { |
| 575 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas
tSeparableMode); |
| 576 |
| 577 return SkNEW_ARGS(GrCustomXPFactory, (static_cast<SkXfermode::Mode>(mode))); |
| 578 } |
| 579 |
OLD | NEW |