Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkBlitter.h" | 10 #include "SkBlitter.h" |
| 11 #include "SkAntiRun.h" | 11 #include "SkAntiRun.h" |
| 12 #include "SkColor.h" | 12 #include "SkColor.h" |
| 13 #include "SkColorFilter.h" | 13 #include "SkColorFilter.h" |
| 14 #include "SkCoreBlitters.h" | 14 #include "SkCoreBlitters.h" |
| 15 #include "SkFilterShader.h" | 15 #include "SkFilterShader.h" |
| 16 #include "SkReadBuffer.h" | 16 #include "SkReadBuffer.h" |
| 17 #include "SkWriteBuffer.h" | 17 #include "SkWriteBuffer.h" |
| 18 #include "SkMask.h" | 18 #include "SkMask.h" |
| 19 #include "SkMaskFilter.h" | 19 #include "SkMaskFilter.h" |
| 20 #include "SkString.h" | 20 #include "SkString.h" |
| 21 #include "SkTLazy.h" | 21 #include "SkTLazy.h" |
| 22 #include "SkUtils.h" | 22 #include "SkUtils.h" |
| 23 #include "SkXfermode.h" | 23 #include "SkXfermode.h" |
| 24 | 24 |
| 25 SkBlitter::~SkBlitter() {} | 25 SkBlitter::~SkBlitter() {} |
| 26 | 26 |
| 27 bool SkBlitter::isNullBlitter() const { return false; } | 27 bool SkBlitter::isNullBlitter() const { return false; } |
| 28 | 28 |
| 29 bool SkBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint, | |
| 30 const SkMatrix& matrix) { | |
| 31 return true; | |
| 32 } | |
| 33 | |
| 29 const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { | 34 const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { |
| 30 return NULL; | 35 return NULL; |
| 31 } | 36 } |
| 32 | 37 |
| 33 void SkBlitter::blitH(int x, int y, int width) { | 38 void SkBlitter::blitH(int x, int y, int width) { |
| 34 SkDEBUGFAIL("unimplemented"); | 39 SkDEBUGFAIL("unimplemented"); |
| 35 } | 40 } |
| 36 | 41 |
| 37 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], | 42 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], |
| 38 const int16_t runs[]) { | 43 const int16_t runs[]) { |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 561 | 566 |
| 562 /////////////////////////////////////////////////////////////////////////////// | 567 /////////////////////////////////////////////////////////////////////////////// |
| 563 | 568 |
| 564 #include "SkColorShader.h" | 569 #include "SkColorShader.h" |
| 565 #include "SkColorPriv.h" | 570 #include "SkColorPriv.h" |
| 566 | 571 |
| 567 class Sk3DShader : public SkShader { | 572 class Sk3DShader : public SkShader { |
| 568 public: | 573 public: |
| 569 Sk3DShader(SkShader* proxy) : fProxy(proxy) { | 574 Sk3DShader(SkShader* proxy) : fProxy(proxy) { |
| 570 SkSafeRef(proxy); | 575 SkSafeRef(proxy); |
| 571 fMask = NULL; | |
| 572 } | 576 } |
| 573 | 577 |
| 574 virtual ~Sk3DShader() { | 578 virtual ~Sk3DShader() { |
| 575 SkSafeUnref(fProxy); | 579 SkSafeUnref(fProxy); |
| 576 } | 580 } |
| 577 | 581 |
| 578 void setMask(const SkMask* mask) { fMask = mask; } | 582 virtual size_t contextSize() const SK_OVERRIDE { |
| 583 size_t size = sizeof(SkShader::Context); | |
|
scroggo
2014/03/24 21:24:46
I think this should be sizeof(Sk3DShaderContext).
Dominik Grewe
2014/03/26 17:22:22
Yes.
scroggo
2014/03/26 23:13:09
I guess we could assert that the size of the retur
| |
| 584 if (fProxy) { | |
| 585 size += fProxy->contextSize(); | |
| 586 } | |
| 587 return size; | |
| 588 } | |
| 579 | 589 |
| 580 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, | 590 virtual bool validContext(const SkBitmap& device, const SkPaint& paint, |
| 581 const SkMatrix& matrix) SK_OVERRIDE { | 591 const SkMatrix& matrix) const SK_OVERRIDE |
| 582 if (!this->INHERITED::setContext(device, paint, matrix)) { | 592 { |
| 593 if (!this->INHERITED::validContext(device, paint, matrix)) { | |
| 583 return false; | 594 return false; |
| 584 } | 595 } |
| 585 if (fProxy) { | 596 if (fProxy) { |
| 586 if (!fProxy->setContext(device, paint, matrix)) { | 597 return fProxy->validContext(device, paint, matrix); |
| 587 // must keep our set/end context calls balanced | |
| 588 this->INHERITED::endContext(); | |
| 589 return false; | |
| 590 } | |
| 591 } else { | |
| 592 fPMColor = SkPreMultiplyColor(paint.getColor()); | |
| 593 } | 598 } |
| 594 return true; | 599 return true; |
| 595 } | 600 } |
| 596 | 601 |
| 597 virtual void endContext() SK_OVERRIDE { | 602 virtual SkShader::Context* createContext(const SkBitmap& device, |
| 603 const SkPaint& paint, | |
| 604 const SkMatrix& matrix, | |
| 605 void* storage) const SK_OVERRIDE | |
| 606 { | |
| 607 if (!this->validContext(device, paint, matrix)) { | |
| 608 return NULL; | |
| 609 } | |
| 610 | |
| 611 SkShader::Context* proxyContext; | |
| 598 if (fProxy) { | 612 if (fProxy) { |
| 599 fProxy->endContext(); | 613 char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderConte xt); |
| 614 proxyContext = fProxy->createContext(device, paint, matrix, proxyCon textStorage); | |
| 615 SkASSERT(proxyContext); | |
| 616 } else { | |
| 617 proxyContext = NULL; | |
| 600 } | 618 } |
| 601 this->INHERITED::endContext(); | 619 return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderContext, (*this, device, paint, matrix, |
| 620 proxyContext)); | |
| 602 } | 621 } |
| 603 | 622 |
| 604 virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRID E { | 623 class Sk3DShaderContext : public SkShader::Context { |
| 605 if (fProxy) { | 624 public: |
| 606 fProxy->shadeSpan(x, y, span, count); | 625 // Takes ownership of proxyContext and calls its destructor. |
| 626 Sk3DShaderContext(const Sk3DShader& shader, const SkBitmap& device, cons t SkPaint& paint, | |
| 627 const SkMatrix& matrix, SkShader::Context* proxyContex t) | |
| 628 : INHERITED(shader, device, paint, matrix) | |
| 629 , fMask(NULL) | |
| 630 , fProxyContext(proxyContext) | |
| 631 { | |
| 632 if (!fProxyContext) { | |
| 633 fPMColor = SkPreMultiplyColor(paint.getColor()); | |
| 634 } | |
| 607 } | 635 } |
| 608 | 636 |
| 609 if (fMask == NULL) { | 637 virtual ~Sk3DShaderContext() { |
| 610 if (fProxy == NULL) { | 638 if (fProxyContext) { |
| 611 sk_memset32(span, fPMColor, count); | 639 fProxyContext->SkShader::Context::~Context(); |
| 612 } | 640 } |
| 613 return; | |
| 614 } | 641 } |
| 615 | 642 |
| 616 SkASSERT(fMask->fBounds.contains(x, y)); | 643 void setMask(const SkMask* mask) { fMask = mask; } |
| 617 SkASSERT(fMask->fBounds.contains(x + count - 1, y)); | |
| 618 | 644 |
| 619 size_t size = fMask->computeImageSize(); | 645 virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVE RRIDE { |
| 620 const uint8_t* alpha = fMask->getAddr8(x, y); | 646 if (fProxyContext) { |
| 621 const uint8_t* mulp = alpha + size; | 647 fProxyContext->shadeSpan(x, y, span, count); |
| 622 const uint8_t* addp = mulp + size; | 648 } |
| 623 | 649 |
| 624 if (fProxy) { | 650 if (fMask == NULL) { |
| 625 for (int i = 0; i < count; i++) { | 651 if (fProxyContext == NULL) { |
| 626 if (alpha[i]) { | 652 sk_memset32(span, fPMColor, count); |
| 627 SkPMColor c = span[i]; | 653 } |
| 628 if (c) { | 654 return; |
| 629 unsigned a = SkGetPackedA32(c); | 655 } |
| 630 unsigned r = SkGetPackedR32(c); | |
| 631 unsigned g = SkGetPackedG32(c); | |
| 632 unsigned b = SkGetPackedB32(c); | |
| 633 | 656 |
| 657 SkASSERT(fMask->fBounds.contains(x, y)); | |
| 658 SkASSERT(fMask->fBounds.contains(x + count - 1, y)); | |
| 659 | |
| 660 size_t size = fMask->computeImageSize(); | |
| 661 const uint8_t* alpha = fMask->getAddr8(x, y); | |
| 662 const uint8_t* mulp = alpha + size; | |
| 663 const uint8_t* addp = mulp + size; | |
| 664 | |
| 665 if (fProxyContext) { | |
| 666 for (int i = 0; i < count; i++) { | |
| 667 if (alpha[i]) { | |
| 668 SkPMColor c = span[i]; | |
| 669 if (c) { | |
| 670 unsigned a = SkGetPackedA32(c); | |
| 671 unsigned r = SkGetPackedR32(c); | |
| 672 unsigned g = SkGetPackedG32(c); | |
| 673 unsigned b = SkGetPackedB32(c); | |
| 674 | |
| 675 unsigned mul = SkAlpha255To256(mulp[i]); | |
| 676 unsigned add = addp[i]; | |
| 677 | |
| 678 r = SkFastMin32(SkAlphaMul(r, mul) + add, a); | |
| 679 g = SkFastMin32(SkAlphaMul(g, mul) + add, a); | |
| 680 b = SkFastMin32(SkAlphaMul(b, mul) + add, a); | |
| 681 | |
| 682 span[i] = SkPackARGB32(a, r, g, b); | |
| 683 } | |
| 684 } else { | |
| 685 span[i] = 0; | |
| 686 } | |
| 687 } | |
| 688 } else { // color | |
| 689 unsigned a = SkGetPackedA32(fPMColor); | |
| 690 unsigned r = SkGetPackedR32(fPMColor); | |
| 691 unsigned g = SkGetPackedG32(fPMColor); | |
| 692 unsigned b = SkGetPackedB32(fPMColor); | |
| 693 for (int i = 0; i < count; i++) { | |
| 694 if (alpha[i]) { | |
| 634 unsigned mul = SkAlpha255To256(mulp[i]); | 695 unsigned mul = SkAlpha255To256(mulp[i]); |
| 635 unsigned add = addp[i]; | 696 unsigned add = addp[i]; |
| 636 | 697 |
| 637 r = SkFastMin32(SkAlphaMul(r, mul) + add, a); | 698 span[i] = SkPackARGB32( a, |
| 638 g = SkFastMin32(SkAlphaMul(g, mul) + add, a); | 699 SkFastMin32(SkAlphaMul(r, mul) + add, a) , |
| 639 b = SkFastMin32(SkAlphaMul(b, mul) + add, a); | 700 SkFastMin32(SkAlphaMul(g, mul) + add, a) , |
| 640 | 701 SkFastMin32(SkAlphaMul(b, mul) + add, a) ); |
| 641 span[i] = SkPackARGB32(a, r, g, b); | 702 } else { |
| 703 span[i] = 0; | |
| 642 } | 704 } |
| 643 } else { | |
| 644 span[i] = 0; | |
| 645 } | |
| 646 } | |
| 647 } else { // color | |
| 648 unsigned a = SkGetPackedA32(fPMColor); | |
| 649 unsigned r = SkGetPackedR32(fPMColor); | |
| 650 unsigned g = SkGetPackedG32(fPMColor); | |
| 651 unsigned b = SkGetPackedB32(fPMColor); | |
| 652 for (int i = 0; i < count; i++) { | |
| 653 if (alpha[i]) { | |
| 654 unsigned mul = SkAlpha255To256(mulp[i]); | |
| 655 unsigned add = addp[i]; | |
| 656 | |
| 657 span[i] = SkPackARGB32( a, | |
| 658 SkFastMin32(SkAlphaMul(r, mul) + add, a), | |
| 659 SkFastMin32(SkAlphaMul(g, mul) + add, a), | |
| 660 SkFastMin32(SkAlphaMul(b, mul) + add, a)); | |
| 661 } else { | |
| 662 span[i] = 0; | |
| 663 } | 705 } |
| 664 } | 706 } |
| 665 } | 707 } |
| 666 } | 708 private: |
| 709 // Unowned. | |
| 710 const SkMask* fMask; | |
| 711 // Memory is unowned, but we need to call the destructor. | |
| 712 SkShader::Context* fProxyContext; | |
|
scroggo
2014/03/24 21:24:46
nit: The variable names should align.
Dominik Grewe
2014/03/26 17:22:22
Done.
| |
| 713 SkPMColor fPMColor; | |
| 714 | |
| 715 typedef SkShader::Context INHERITED; | |
| 716 }; | |
| 667 | 717 |
| 668 #ifdef SK_DEVELOPER | 718 #ifdef SK_DEVELOPER |
| 669 virtual void toString(SkString* str) const SK_OVERRIDE { | 719 virtual void toString(SkString* str) const SK_OVERRIDE { |
| 670 str->append("Sk3DShader: ("); | 720 str->append("Sk3DShader: ("); |
| 671 | 721 |
| 672 if (NULL != fProxy) { | 722 if (NULL != fProxy) { |
| 673 str->append("Proxy: "); | 723 str->append("Proxy: "); |
| 674 fProxy->toString(str); | 724 fProxy->toString(str); |
| 675 } | 725 } |
| 676 | 726 |
| 677 this->INHERITED::toString(str); | 727 this->INHERITED::toString(str); |
| 678 | 728 |
| 679 str->append(")"); | 729 str->append(")"); |
| 680 } | 730 } |
| 681 #endif | 731 #endif |
| 682 | 732 |
| 683 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader) | 733 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader) |
| 684 | 734 |
| 685 protected: | 735 protected: |
| 686 Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) { | 736 Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) { |
| 687 fProxy = buffer.readShader(); | 737 fProxy = buffer.readShader(); |
| 688 fPMColor = buffer.readColor(); | 738 // Leaving this here until we bump the picture version, though this |
| 689 fMask = NULL; | 739 // shader should never be recorded. |
| 740 buffer.readColor(); | |
| 690 } | 741 } |
| 691 | 742 |
| 692 virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE { | 743 virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE { |
| 693 this->INHERITED::flatten(buffer); | 744 this->INHERITED::flatten(buffer); |
| 694 buffer.writeFlattenable(fProxy); | 745 buffer.writeFlattenable(fProxy); |
| 695 buffer.writeColor(fPMColor); | 746 // Leaving this here until we bump the picture version, though this |
| 747 // shader should never be recorded. | |
| 748 buffer.writeColor(SkColor()); | |
| 696 } | 749 } |
| 697 | 750 |
| 698 private: | 751 private: |
| 699 SkShader* fProxy; | 752 SkShader* fProxy; |
| 700 SkPMColor fPMColor; | |
| 701 const SkMask* fMask; | |
| 702 | 753 |
| 703 typedef SkShader INHERITED; | 754 typedef SkShader INHERITED; |
| 704 }; | 755 }; |
| 705 | 756 |
| 706 class Sk3DBlitter : public SkBlitter { | 757 class Sk3DBlitter : public SkBlitter { |
| 707 public: | 758 public: |
| 708 Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader) | 759 Sk3DBlitter(SkBlitter* proxy, Sk3DShader::Sk3DShaderContext* shaderContext) |
| 709 : fProxy(proxy) | 760 : fProxy(proxy) |
| 710 , f3DShader(SkRef(shader)) | 761 , f3DShaderContext(shaderContext) |
| 711 {} | 762 {} |
| 712 | 763 |
| 713 virtual void blitH(int x, int y, int width) { | 764 virtual void blitH(int x, int y, int width) { |
| 714 fProxy->blitH(x, y, width); | 765 fProxy->blitH(x, y, width); |
| 715 } | 766 } |
| 716 | 767 |
| 717 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], | 768 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], |
| 718 const int16_t runs[]) { | 769 const int16_t runs[]) { |
| 719 fProxy->blitAntiH(x, y, antialias, runs); | 770 fProxy->blitAntiH(x, y, antialias, runs); |
| 720 } | 771 } |
| 721 | 772 |
| 722 virtual void blitV(int x, int y, int height, SkAlpha alpha) { | 773 virtual void blitV(int x, int y, int height, SkAlpha alpha) { |
| 723 fProxy->blitV(x, y, height, alpha); | 774 fProxy->blitV(x, y, height, alpha); |
| 724 } | 775 } |
| 725 | 776 |
| 726 virtual void blitRect(int x, int y, int width, int height) { | 777 virtual void blitRect(int x, int y, int width, int height) { |
| 727 fProxy->blitRect(x, y, width, height); | 778 fProxy->blitRect(x, y, width, height); |
| 728 } | 779 } |
| 729 | 780 |
| 730 virtual void blitMask(const SkMask& mask, const SkIRect& clip) { | 781 virtual void blitMask(const SkMask& mask, const SkIRect& clip) { |
| 731 if (mask.fFormat == SkMask::k3D_Format) { | 782 if (mask.fFormat == SkMask::k3D_Format) { |
| 732 f3DShader->setMask(&mask); | 783 f3DShaderContext->setMask(&mask); |
| 733 | 784 |
| 734 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; | 785 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; |
| 735 fProxy->blitMask(mask, clip); | 786 fProxy->blitMask(mask, clip); |
| 736 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; | 787 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; |
| 737 | 788 |
| 738 f3DShader->setMask(NULL); | 789 f3DShaderContext->setMask(NULL); |
| 739 } else { | 790 } else { |
| 740 fProxy->blitMask(mask, clip); | 791 fProxy->blitMask(mask, clip); |
| 741 } | 792 } |
| 742 } | 793 } |
| 743 | 794 |
| 744 private: | 795 private: |
| 745 // fProxy is unowned. It will be deleted by SkSmallAllocator. | 796 // Both pointers are unowned. They will be deleted by SkSmallAllocator. |
| 746 SkBlitter* fProxy; | 797 SkBlitter* fProxy; |
| 747 SkAutoTUnref<Sk3DShader> f3DShader; | 798 Sk3DShader::Sk3DShaderContext* f3DShaderContext; |
| 748 }; | 799 }; |
| 749 | 800 |
| 750 /////////////////////////////////////////////////////////////////////////////// | 801 /////////////////////////////////////////////////////////////////////////////// |
| 751 | 802 |
| 752 #include "SkCoreBlitters.h" | 803 #include "SkCoreBlitters.h" |
| 753 | 804 |
| 754 static bool just_solid_color(const SkPaint& paint) { | 805 static bool just_solid_color(const SkPaint& paint) { |
| 755 if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) { | 806 if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) { |
| 756 SkShader* shader = paint.getShader(); | 807 SkShader* shader = paint.getShader(); |
| 757 if (NULL == shader || | 808 // FIXME: This is ONLY called BEFORE setContext, when the flags are not |
| 758 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) { | 809 // supposed to be meaningful. Do we need flags on the shader as well as |
| 810 // the impl? | |
| 811 if (NULL == shader /*|| | |
| 812 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)*/) { | |
| 759 return true; | 813 return true; |
| 760 } | 814 } |
| 761 } | 815 } |
| 762 return false; | 816 return false; |
| 763 } | 817 } |
| 764 | 818 |
| 765 /** By analyzing the paint (with an xfermode), we may decide we can take | 819 /** By analyzing the paint (with an xfermode), we may decide we can take |
| 766 special action. This enum lists our possible actions | 820 special action. This enum lists our possible actions |
| 767 */ | 821 */ |
| 768 enum XferInterp { | 822 enum XferInterp { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 886 | 940 |
| 887 if (cf) { | 941 if (cf) { |
| 888 SkASSERT(shader); | 942 SkASSERT(shader); |
| 889 shader = SkNEW_ARGS(SkFilterShader, (shader, cf)); | 943 shader = SkNEW_ARGS(SkFilterShader, (shader, cf)); |
| 890 paint.writable()->setShader(shader)->unref(); | 944 paint.writable()->setShader(shader)->unref(); |
| 891 // blitters should ignore the presence/absence of a filter, since | 945 // blitters should ignore the presence/absence of a filter, since |
| 892 // if there is one, the shader will take care of it. | 946 // if there is one, the shader will take care of it. |
| 893 } | 947 } |
| 894 | 948 |
| 895 /* | 949 /* |
| 896 * We need to have balanced calls to the shader: | 950 * We create a SkShader::Context object, and store it on the blitter. |
| 897 * setContext | |
| 898 * endContext | |
| 899 * We make the first call here, in case it fails we can abort the draw. | |
| 900 * The endContext() call is made by the blitter (assuming setContext did | |
| 901 * not fail) in its destructor. | |
| 902 */ | 951 */ |
| 903 if (shader && !shader->setContext(device, *paint, matrix)) { | 952 SkShader::Context* shaderContext; |
| 904 blitter = allocator->createT<SkNullBlitter>(); | 953 if (shader) { |
| 905 return blitter; | 954 // Try to create the ShaderContext |
| 955 void* storage = allocator->reserveT<SkShader::Context>(shader->contextSi ze()); | |
| 956 shaderContext = shader->createContext(device, *paint, matrix, storage); | |
| 957 if (!shaderContext) { | |
| 958 allocator->free(storage); | |
| 959 blitter = allocator->createT<SkNullBlitter>(); | |
| 960 return blitter; | |
| 961 } | |
| 962 SkASSERT(shaderContext); | |
| 963 SkASSERT((void*) shaderContext == storage); | |
| 964 } else { | |
| 965 shaderContext = NULL; | |
| 906 } | 966 } |
| 907 | 967 |
| 908 | 968 |
| 909 switch (device.colorType()) { | 969 switch (device.colorType()) { |
| 910 case kAlpha_8_SkColorType: | 970 case kAlpha_8_SkColorType: |
| 911 if (drawCoverage) { | 971 if (drawCoverage) { |
| 912 SkASSERT(NULL == shader); | 972 SkASSERT(NULL == shader); |
| 913 SkASSERT(NULL == paint->getXfermode()); | 973 SkASSERT(NULL == paint->getXfermode()); |
| 914 blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *pai nt); | 974 blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *pai nt); |
| 915 } else if (shader) { | 975 } else if (shader) { |
| 916 blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint ); | 976 blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint , shaderContext); |
| 917 } else { | 977 } else { |
| 918 blitter = allocator->createT<SkA8_Blitter>(device, *paint); | 978 blitter = allocator->createT<SkA8_Blitter>(device, *paint); |
| 919 } | 979 } |
| 920 break; | 980 break; |
| 921 | 981 |
| 922 case kRGB_565_SkColorType: | 982 case kRGB_565_SkColorType: |
| 923 blitter = SkBlitter_ChooseD565(device, *paint, allocator); | 983 blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, alloca tor); |
| 924 break; | 984 break; |
| 925 | 985 |
| 926 case kPMColor_SkColorType: | 986 case kPMColor_SkColorType: |
| 927 if (shader) { | 987 if (shader) { |
| 928 blitter = allocator->createT<SkARGB32_Shader_Blitter>(device, *p aint); | 988 blitter = allocator->createT<SkARGB32_Shader_Blitter>(device, *p aint, shaderContext); |
| 929 } else if (paint->getColor() == SK_ColorBLACK) { | 989 } else if (paint->getColor() == SK_ColorBLACK) { |
| 930 blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *pa int); | 990 blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *pa int); |
| 931 } else if (paint->getAlpha() == 0xFF) { | 991 } else if (paint->getAlpha() == 0xFF) { |
| 932 blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *p aint); | 992 blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *p aint); |
| 933 } else { | 993 } else { |
| 934 blitter = allocator->createT<SkARGB32_Blitter>(device, *paint); | 994 blitter = allocator->createT<SkARGB32_Blitter>(device, *paint); |
| 935 } | 995 } |
| 936 break; | 996 break; |
| 937 | 997 |
| 938 default: | 998 default: |
| 939 SkDEBUGFAIL("unsupported device config"); | 999 SkDEBUGFAIL("unsupported device config"); |
| 940 blitter = allocator->createT<SkNullBlitter>(); | 1000 blitter = allocator->createT<SkNullBlitter>(); |
| 941 break; | 1001 break; |
| 942 } | 1002 } |
| 943 | 1003 |
| 944 if (shader3D) { | 1004 if (shader3D) { |
| 945 SkBlitter* innerBlitter = blitter; | 1005 SkBlitter* innerBlitter = blitter; |
| 946 // innerBlitter was allocated by allocator, which will delete it. | 1006 // innerBlitter was allocated by allocator, which will delete it. |
| 947 blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shader3D); | 1007 blitter = allocator->createT<Sk3DBlitter>(innerBlitter, |
| 1008 static_cast<Sk3DShader::Sk3DShaderContext*>(shaderContext)); | |
|
scroggo
2014/03/24 21:24:46
Maybe add a comment here that we know shaderContex
Dominik Grewe
2014/03/26 17:22:22
Done.
| |
| 948 } | 1009 } |
| 949 return blitter; | 1010 return blitter; |
| 950 } | 1011 } |
| 951 | 1012 |
| 952 /////////////////////////////////////////////////////////////////////////////// | 1013 /////////////////////////////////////////////////////////////////////////////// |
| 953 | 1014 |
| 954 const uint16_t gMask_0F0F = 0xF0F; | 1015 const uint16_t gMask_0F0F = 0xF0F; |
| 955 const uint32_t gMask_00FF00FF = 0xFF00FF; | 1016 const uint32_t gMask_00FF00FF = 0xFF00FF; |
| 956 | 1017 |
| 957 /////////////////////////////////////////////////////////////////////////////// | 1018 /////////////////////////////////////////////////////////////////////////////// |
| 958 | 1019 |
| 959 SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint) | 1020 SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint, |
| 960 : INHERITED(device) { | 1021 SkShader::Context* shaderContext) |
| 961 fShader = paint.getShader(); | 1022 : INHERITED(device), fShader(paint.getShader()), fShaderContext(shaderCo ntext) { |
| 962 SkASSERT(fShader); | 1023 SkASSERT(fShader); |
| 963 SkASSERT(fShader->setContextHasBeenCalled()); | 1024 SkASSERT(fShaderContext); |
| 964 | 1025 |
| 965 fShader->ref(); | 1026 fShaderFlags = fShaderContext->getFlags(); |
| 966 fShaderFlags = fShader->getFlags(); | |
| 967 } | 1027 } |
| 968 | 1028 |
| 969 SkShaderBlitter::~SkShaderBlitter() { | 1029 SkShaderBlitter::~SkShaderBlitter() {} |
| 970 SkASSERT(fShader->setContextHasBeenCalled()); | 1030 |
| 971 fShader->endContext(); | 1031 bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint, |
| 972 fShader->unref(); | 1032 const SkMatrix& matrix) { |
| 1033 bool newContext = false; | |
|
scroggo
2014/03/24 21:24:46
Why do you need the variable newContext?
Why not
Dominik Grewe
2014/03/26 17:22:22
Good point. I rewrote this function a few times an
| |
| 1034 if (fShader->validContext(device, paint, matrix)) { | |
| 1035 // Only destroy the old context if we have a new one. We need to ensure to have a | |
| 1036 // live context in fShaderContext because the storage is owned by an SkS mallAllocator | |
| 1037 // outside of this class. | |
| 1038 fShaderContext->SkShader::Context::~Context(); | |
| 1039 fShaderContext = fShader->createContext(device, paint, matrix, (void*)fS haderContext); | |
| 1040 SkASSERT(fShaderContext); | |
|
scroggo
2014/03/24 21:24:46
This makes me nervous. It means we have to enforce
Dominik Grewe
2014/03/26 17:22:22
I agree. I was hoping we'd never have to call vali
scroggo
2014/03/26 23:13:09
Who else is calling validContext? (I was thinking
Dominik Grewe
2014/03/27 14:27:20
This is the only caller outside SkShader afaict.
scroggo
2014/03/27 18:05:33
I actually think it makes sense that blitter has t
Dominik Grewe
2014/03/28 18:16:31
The only problem is that the first SkShader::Conte
| |
| 1041 newContext = true; | |
| 1042 } | |
| 1043 | |
| 1044 return newContext; | |
| 973 } | 1045 } |
| OLD | NEW |