Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: src/core/SkBlitter.cpp

Issue 207683004: Extract most of the mutable state of SkShader into a separate Context object. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase & cleanup Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 = N ULL) const
582 if (!this->INHERITED::setContext(device, paint, matrix)) { 596 SK_OVERRIDE
597 {
598 if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
583 return false; 599 return false;
584 } 600 }
585 if (fProxy) { 601 if (fProxy) {
586 if (!fProxy->setContext(device, paint, matrix)) { 602 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 } 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 if (!this->validContext(device, paint, matrix)) {
613 return NULL;
614 }
615
616 SkShader::Context* proxyContext;
598 if (fProxy) { 617 if (fProxy) {
599 fProxy->endContext(); 618 char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderConte xt);
619 proxyContext = fProxy->createContext(device, paint, matrix, proxyCon textStorage);
620 SkASSERT(proxyContext);
621 } else {
622 proxyContext = NULL;
600 } 623 }
601 this->INHERITED::endContext(); 624 return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderContext, (*this, device, paint, matrix,
625 proxyContext));
602 } 626 }
603 627
604 virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRID E { 628 class Sk3DShaderContext : public SkShader::Context {
605 if (fProxy) { 629 public:
606 fProxy->shadeSpan(x, y, span, count); 630 // Takes ownership of proxyContext and calls its destructor.
scroggo 2014/04/03 15:35:54 Once again, I think this is not pure ownership.
Dominik Grewe 2014/04/04 10:59:41 Done.
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 }
607 } 640 }
608 641
609 if (fMask == NULL) { 642 virtual ~Sk3DShaderContext() {
610 if (fProxy == NULL) { 643 if (fProxyContext) {
611 sk_memset32(span, fPMColor, count); 644 fProxyContext->SkShader::Context::~Context();
612 } 645 }
613 return;
614 } 646 }
615 647
616 SkASSERT(fMask->fBounds.contains(x, y)); 648 void setMask(const SkMask* mask) { fMask = mask; }
617 SkASSERT(fMask->fBounds.contains(x + count - 1, y));
618 649
619 size_t size = fMask->computeImageSize(); 650 virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVE RRIDE {
620 const uint8_t* alpha = fMask->getAddr8(x, y); 651 if (fProxyContext) {
621 const uint8_t* mulp = alpha + size; 652 fProxyContext->shadeSpan(x, y, span, count);
622 const uint8_t* addp = mulp + size; 653 }
623 654
624 if (fProxy) { 655 if (fMask == NULL) {
625 for (int i = 0; i < count; i++) { 656 if (fProxyContext == NULL) {
626 if (alpha[i]) { 657 sk_memset32(span, fPMColor, count);
627 SkPMColor c = span[i]; 658 }
628 if (c) { 659 return;
629 unsigned a = SkGetPackedA32(c); 660 }
630 unsigned r = SkGetPackedR32(c);
631 unsigned g = SkGetPackedG32(c);
632 unsigned b = SkGetPackedB32(c);
633 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]) {
634 unsigned mul = SkAlpha255To256(mulp[i]); 700 unsigned mul = SkAlpha255To256(mulp[i]);
635 unsigned add = addp[i]; 701 unsigned add = addp[i];
636 702
637 r = SkFastMin32(SkAlphaMul(r, mul) + add, a); 703 span[i] = SkPackARGB32( a,
638 g = SkFastMin32(SkAlphaMul(g, mul) + add, a); 704 SkFastMin32(SkAlphaMul(r, mul) + add, a) ,
639 b = SkFastMin32(SkAlphaMul(b, mul) + add, a); 705 SkFastMin32(SkAlphaMul(g, mul) + add, a) ,
640 706 SkFastMin32(SkAlphaMul(b, mul) + add, a) );
641 span[i] = SkPackARGB32(a, r, g, b); 707 } else {
708 span[i] = 0;
642 } 709 }
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 } 710 }
664 } 711 }
665 } 712 }
666 } 713 private:
714 // Unowned.
715 const SkMask* fMask;
716 // Memory is unowned, but we need to call the destructor.
717 SkShader::Context* fProxyContext;
718 SkPMColor fPMColor;
719
720 typedef SkShader::Context INHERITED;
721 };
667 722
668 #ifndef SK_IGNORE_TO_STRING 723 #ifndef SK_IGNORE_TO_STRING
669 virtual void toString(SkString* str) const SK_OVERRIDE { 724 virtual void toString(SkString* str) const SK_OVERRIDE {
670 str->append("Sk3DShader: ("); 725 str->append("Sk3DShader: (");
671 726
672 if (NULL != fProxy) { 727 if (NULL != fProxy) {
673 str->append("Proxy: "); 728 str->append("Proxy: ");
674 fProxy->toString(str); 729 fProxy->toString(str);
675 } 730 }
676 731
677 this->INHERITED::toString(str); 732 this->INHERITED::toString(str);
678 733
679 str->append(")"); 734 str->append(")");
680 } 735 }
681 #endif 736 #endif
682 737
683 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader) 738 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader)
684 739
685 protected: 740 protected:
686 Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) { 741 Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) {
687 fProxy = buffer.readShader(); 742 fProxy = buffer.readShader();
688 fPMColor = buffer.readColor(); 743 // Leaving this here until we bump the picture version, though this
689 fMask = NULL; 744 // shader should never be recorded.
745 buffer.readColor();
690 } 746 }
691 747
692 virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE { 748 virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
693 this->INHERITED::flatten(buffer); 749 this->INHERITED::flatten(buffer);
694 buffer.writeFlattenable(fProxy); 750 buffer.writeFlattenable(fProxy);
695 buffer.writeColor(fPMColor); 751 // Leaving this here until we bump the picture version, though this
752 // shader should never be recorded.
753 buffer.writeColor(SkColor());
696 } 754 }
697 755
698 private: 756 private:
699 SkShader* fProxy; 757 SkShader* fProxy;
700 SkPMColor fPMColor;
701 const SkMask* fMask;
702 758
703 typedef SkShader INHERITED; 759 typedef SkShader INHERITED;
704 }; 760 };
705 761
706 class Sk3DBlitter : public SkBlitter { 762 class Sk3DBlitter : public SkBlitter {
707 public: 763 public:
708 Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader) 764 Sk3DBlitter(SkBlitter* proxy, Sk3DShader::Sk3DShaderContext* shaderContext)
709 : fProxy(proxy) 765 : fProxy(proxy)
710 , f3DShader(SkRef(shader)) 766 , f3DShaderContext(shaderContext)
711 {} 767 {}
712 768
713 virtual void blitH(int x, int y, int width) { 769 virtual void blitH(int x, int y, int width) {
714 fProxy->blitH(x, y, width); 770 fProxy->blitH(x, y, width);
715 } 771 }
716 772
717 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], 773 virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
718 const int16_t runs[]) { 774 const int16_t runs[]) {
719 fProxy->blitAntiH(x, y, antialias, runs); 775 fProxy->blitAntiH(x, y, antialias, runs);
720 } 776 }
721 777
722 virtual void blitV(int x, int y, int height, SkAlpha alpha) { 778 virtual void blitV(int x, int y, int height, SkAlpha alpha) {
723 fProxy->blitV(x, y, height, alpha); 779 fProxy->blitV(x, y, height, alpha);
724 } 780 }
725 781
726 virtual void blitRect(int x, int y, int width, int height) { 782 virtual void blitRect(int x, int y, int width, int height) {
727 fProxy->blitRect(x, y, width, height); 783 fProxy->blitRect(x, y, width, height);
728 } 784 }
729 785
730 virtual void blitMask(const SkMask& mask, const SkIRect& clip) { 786 virtual void blitMask(const SkMask& mask, const SkIRect& clip) {
731 if (mask.fFormat == SkMask::k3D_Format) { 787 if (mask.fFormat == SkMask::k3D_Format) {
732 f3DShader->setMask(&mask); 788 f3DShaderContext->setMask(&mask);
733 789
734 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; 790 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
735 fProxy->blitMask(mask, clip); 791 fProxy->blitMask(mask, clip);
736 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; 792 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
737 793
738 f3DShader->setMask(NULL); 794 f3DShaderContext->setMask(NULL);
739 } else { 795 } else {
740 fProxy->blitMask(mask, clip); 796 fProxy->blitMask(mask, clip);
741 } 797 }
742 } 798 }
743 799
744 private: 800 private:
745 // fProxy is unowned. It will be deleted by SkSmallAllocator. 801 // Both pointers are unowned. They will be deleted by SkSmallAllocator.
746 SkBlitter* fProxy; 802 SkBlitter* fProxy;
747 SkAutoTUnref<Sk3DShader> f3DShader; 803 Sk3DShader::Sk3DShaderContext* f3DShaderContext;
748 }; 804 };
749 805
750 /////////////////////////////////////////////////////////////////////////////// 806 ///////////////////////////////////////////////////////////////////////////////
751 807
752 #include "SkCoreBlitters.h" 808 #include "SkCoreBlitters.h"
753 809
754 static bool just_solid_color(const SkPaint& paint) { 810 static bool just_solid_color(const SkPaint& paint) {
755 if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) { 811 if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) {
756 SkShader* shader = paint.getShader(); 812 SkShader* shader = paint.getShader();
757 if (NULL == shader || 813 // FIXME: This is ONLY called BEFORE setContext, when the flags are not
758 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) { 814 // supposed to be meaningful. Do we need flags on the shader as well as
815 // the impl?
816 if (NULL == shader /*||
817 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)*/) {
scroggo 2014/04/03 15:35:54 Here are the shaders that potentially return kOpaq
Dominik Grewe 2014/04/04 10:59:41 That just shows that getFlags shouldn't be called
759 return true; 818 return true;
760 } 819 }
761 } 820 }
762 return false; 821 return false;
763 } 822 }
764 823
765 /** By analyzing the paint (with an xfermode), we may decide we can take 824 /** By analyzing the paint (with an xfermode), we may decide we can take
766 special action. This enum lists our possible actions 825 special action. This enum lists our possible actions
767 */ 826 */
768 enum XferInterp { 827 enum XferInterp {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 945
887 if (cf) { 946 if (cf) {
888 SkASSERT(shader); 947 SkASSERT(shader);
889 shader = SkNEW_ARGS(SkFilterShader, (shader, cf)); 948 shader = SkNEW_ARGS(SkFilterShader, (shader, cf));
890 paint.writable()->setShader(shader)->unref(); 949 paint.writable()->setShader(shader)->unref();
891 // blitters should ignore the presence/absence of a filter, since 950 // blitters should ignore the presence/absence of a filter, since
892 // if there is one, the shader will take care of it. 951 // if there is one, the shader will take care of it.
893 } 952 }
894 953
895 /* 954 /*
896 * We need to have balanced calls to the shader: 955 * 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 */ 956 */
903 if (shader && !shader->setContext(device, *paint, matrix)) { 957 SkShader::Context* shaderContext;
904 blitter = allocator->createT<SkNullBlitter>(); 958 if (shader) {
905 return blitter; 959 // Try to create the ShaderContext
960 void* storage = allocator->reserveT<SkShader::Context>(shader->contextSi ze());
961 shaderContext = shader->createContext(device, *paint, matrix, storage);
962 if (!shaderContext) {
963 allocator->freeLast();
964 blitter = allocator->createT<SkNullBlitter>();
965 return blitter;
966 }
967 SkASSERT(shaderContext);
968 SkASSERT((void*) shaderContext == storage);
969 } else {
970 shaderContext = NULL;
906 } 971 }
907 972
908 973
909 switch (device.colorType()) { 974 switch (device.colorType()) {
910 case kAlpha_8_SkColorType: 975 case kAlpha_8_SkColorType:
911 if (drawCoverage) { 976 if (drawCoverage) {
912 SkASSERT(NULL == shader); 977 SkASSERT(NULL == shader);
913 SkASSERT(NULL == paint->getXfermode()); 978 SkASSERT(NULL == paint->getXfermode());
914 blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *pai nt); 979 blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *pai nt);
915 } else if (shader) { 980 } else if (shader) {
916 blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint ); 981 blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint , shaderContext);
917 } else { 982 } else {
918 blitter = allocator->createT<SkA8_Blitter>(device, *paint); 983 blitter = allocator->createT<SkA8_Blitter>(device, *paint);
919 } 984 }
920 break; 985 break;
921 986
922 case kRGB_565_SkColorType: 987 case kRGB_565_SkColorType:
923 blitter = SkBlitter_ChooseD565(device, *paint, allocator); 988 blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, alloca tor);
924 break; 989 break;
925 990
926 case kPMColor_SkColorType: 991 case kPMColor_SkColorType:
927 if (shader) { 992 if (shader) {
928 blitter = allocator->createT<SkARGB32_Shader_Blitter>(device, *p aint); 993 blitter = allocator->createT<SkARGB32_Shader_Blitter>(device, *p aint, shaderContext);
scroggo 2014/04/03 15:35:54 nit: 100 chars.
Dominik Grewe 2014/04/04 10:59:41 Done.
929 } else if (paint->getColor() == SK_ColorBLACK) { 994 } else if (paint->getColor() == SK_ColorBLACK) {
930 blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *pa int); 995 blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *pa int);
931 } else if (paint->getAlpha() == 0xFF) { 996 } else if (paint->getAlpha() == 0xFF) {
932 blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *p aint); 997 blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *p aint);
933 } else { 998 } else {
934 blitter = allocator->createT<SkARGB32_Blitter>(device, *paint); 999 blitter = allocator->createT<SkARGB32_Blitter>(device, *paint);
935 } 1000 }
936 break; 1001 break;
937 1002
938 default: 1003 default:
939 SkDEBUGFAIL("unsupported device config"); 1004 SkDEBUGFAIL("unsupported device config");
940 blitter = allocator->createT<SkNullBlitter>(); 1005 blitter = allocator->createT<SkNullBlitter>();
941 break; 1006 break;
942 } 1007 }
943 1008
944 if (shader3D) { 1009 if (shader3D) {
945 SkBlitter* innerBlitter = blitter; 1010 SkBlitter* innerBlitter = blitter;
946 // innerBlitter was allocated by allocator, which will delete it. 1011 // innerBlitter was allocated by allocator, which will delete it.
947 blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shader3D); 1012 // We know shaderContext is of type Sk3DShaderContext because it belongs to shader3D.
1013 blitter = allocator->createT<Sk3DBlitter>(innerBlitter,
1014 static_cast<Sk3DShader::Sk3DShaderContext*>(shaderContext));
948 } 1015 }
949 return blitter; 1016 return blitter;
950 } 1017 }
951 1018
952 /////////////////////////////////////////////////////////////////////////////// 1019 ///////////////////////////////////////////////////////////////////////////////
953 1020
954 const uint16_t gMask_0F0F = 0xF0F; 1021 const uint16_t gMask_0F0F = 0xF0F;
955 const uint32_t gMask_00FF00FF = 0xFF00FF; 1022 const uint32_t gMask_00FF00FF = 0xFF00FF;
956 1023
957 /////////////////////////////////////////////////////////////////////////////// 1024 ///////////////////////////////////////////////////////////////////////////////
958 1025
959 SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint) 1026 SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint,
960 : INHERITED(device) { 1027 SkShader::Context* shaderContext)
961 fShader = paint.getShader(); 1028 : INHERITED(device), fShader(paint.getShader()), fShaderContext(shaderCo ntext) {
scroggo 2014/04/03 15:35:54 nit: fShader and fShaderContext should be on their
Dominik Grewe 2014/04/04 10:59:41 Done.
962 SkASSERT(fShader); 1029 SkASSERT(fShader);
963 SkASSERT(fShader->setContextHasBeenCalled()); 1030 SkASSERT(fShaderContext);
964 1031
965 fShader->ref(); 1032 fShader->ref();
966 fShaderFlags = fShader->getFlags(); 1033 fShaderFlags = fShaderContext->getFlags();
967 } 1034 }
968 1035
969 SkShaderBlitter::~SkShaderBlitter() { 1036 SkShaderBlitter::~SkShaderBlitter() {
970 SkASSERT(fShader->setContextHasBeenCalled());
971 fShader->endContext();
972 fShader->unref(); 1037 fShader->unref();
973 } 1038 }
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 is 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->SkShader::Context::~Context();
1052 fShaderContext = fShader->createContext(device, paint, matrix, (void*)fShade rContext);
1053 SkASSERT(fShaderContext);
1054
1055 return true;
1056 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698