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

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

Powered by Google App Engine
This is Rietveld 408576698