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

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: freeLast reduces fStorageUsed; TriColorShaderContext::setup; totalInverse param to validContext Created 6 years, 9 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) 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
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 }
OLDNEW
« no previous file with comments | « src/core/SkBlitter.h ('k') | src/core/SkBlitter_A8.cpp » ('j') | src/core/SkDraw.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698