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