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