OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBlitter.h" | 8 #include "SkBlitter.h" |
9 #include "SkAntiRun.h" | 9 #include "SkAntiRun.h" |
10 #include "SkColor.h" | 10 #include "SkColor.h" |
11 #include "SkColorFilter.h" | 11 #include "SkColorFilter.h" |
12 #include "SkCoreBlitters.h" | 12 #include "SkCoreBlitters.h" |
13 #include "SkFilterShader.h" | 13 #include "SkFilterShader.h" |
14 #include "SkReadBuffer.h" | 14 #include "SkReadBuffer.h" |
15 #include "SkWriteBuffer.h" | 15 #include "SkWriteBuffer.h" |
16 #include "SkMask.h" | 16 #include "SkMask.h" |
17 #include "SkMaskFilter.h" | 17 #include "SkMaskFilter.h" |
18 #include "SkString.h" | 18 #include "SkString.h" |
19 #include "SkTLazy.h" | 19 #include "SkTLazy.h" |
20 #include "SkUtils.h" | 20 #include "SkUtils.h" |
21 #include "SkXfermode.h" | 21 #include "SkXfermode.h" |
| 22 #include "SkXfermodeInterpretation.h" |
22 | 23 |
23 SkBlitter::~SkBlitter() {} | 24 SkBlitter::~SkBlitter() {} |
24 | 25 |
25 bool SkBlitter::isNullBlitter() const { return false; } | 26 bool SkBlitter::isNullBlitter() const { return false; } |
26 | 27 |
27 bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) { | 28 bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) { |
28 return true; | 29 return true; |
29 } | 30 } |
30 | 31 |
31 SkShader::Context* SkBlitter::getShaderContext() const { | 32 SkShader::Context* SkBlitter::getShaderContext() const { |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 private: | 771 private: |
771 // Both pointers are unowned. They will be deleted by SkSmallAllocator. | 772 // Both pointers are unowned. They will be deleted by SkSmallAllocator. |
772 SkBlitter* fProxy; | 773 SkBlitter* fProxy; |
773 SkShader::Context* fShaderContext; | 774 SkShader::Context* fShaderContext; |
774 }; | 775 }; |
775 | 776 |
776 /////////////////////////////////////////////////////////////////////////////// | 777 /////////////////////////////////////////////////////////////////////////////// |
777 | 778 |
778 #include "SkCoreBlitters.h" | 779 #include "SkCoreBlitters.h" |
779 | 780 |
780 static bool just_solid_color(const SkPaint& paint) { | |
781 if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) { | |
782 SkShader* shader = paint.getShader(); | |
783 if (NULL == shader) { | |
784 return true; | |
785 } | |
786 } | |
787 return false; | |
788 } | |
789 | |
790 /** By analyzing the paint (with an xfermode), we may decide we can take | |
791 special action. This enum lists our possible actions | |
792 */ | |
793 enum XferInterp { | |
794 kNormal_XferInterp, // no special interpretation, draw normally | |
795 kSrcOver_XferInterp, // draw as if in srcover mode | |
796 kSkipDrawing_XferInterp // draw nothing | |
797 }; | |
798 | |
799 static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer, | |
800 SkColorType deviceCT) { | |
801 SkXfermode::Mode mode; | |
802 | |
803 if (SkXfermode::AsMode(xfer, &mode)) { | |
804 switch (mode) { | |
805 case SkXfermode::kSrc_Mode: | |
806 if (just_solid_color(paint)) { | |
807 return kSrcOver_XferInterp; | |
808 } | |
809 break; | |
810 case SkXfermode::kDst_Mode: | |
811 return kSkipDrawing_XferInterp; | |
812 case SkXfermode::kSrcOver_Mode: | |
813 return kSrcOver_XferInterp; | |
814 case SkXfermode::kDstOver_Mode: | |
815 if (kRGB_565_SkColorType == deviceCT) { | |
816 return kSkipDrawing_XferInterp; | |
817 } | |
818 break; | |
819 case SkXfermode::kSrcIn_Mode: | |
820 if (kRGB_565_SkColorType == deviceCT && | |
821 just_solid_color(paint)) { | |
822 return kSrcOver_XferInterp; | |
823 } | |
824 break; | |
825 case SkXfermode::kDstIn_Mode: | |
826 if (just_solid_color(paint)) { | |
827 return kSkipDrawing_XferInterp; | |
828 } | |
829 break; | |
830 default: | |
831 break; | |
832 } | |
833 } | |
834 return kNormal_XferInterp; | |
835 } | |
836 | |
837 SkBlitter* SkBlitter::Choose(const SkBitmap& device, | 781 SkBlitter* SkBlitter::Choose(const SkBitmap& device, |
838 const SkMatrix& matrix, | 782 const SkMatrix& matrix, |
839 const SkPaint& origPaint, | 783 const SkPaint& origPaint, |
840 SkTBlitterAllocator* allocator, | 784 SkTBlitterAllocator* allocator, |
841 bool drawCoverage) { | 785 bool drawCoverage) { |
842 SkASSERT(allocator != NULL); | 786 SkASSERT(allocator != NULL); |
843 | 787 |
844 // which check, in case we're being called by a client with a dummy device | 788 // which check, in case we're being called by a client with a dummy device |
845 // (e.g. they have a bounder that always aborts the draw) | 789 // (e.g. they have a bounder that always aborts the draw) |
846 if (kUnknown_SkColorType == device.colorType() || | 790 if (kUnknown_SkColorType == device.colorType() || |
(...skipping 10 matching lines...) Expand all Loading... |
857 | 801 |
858 if (origPaint.getMaskFilter() != NULL && | 802 if (origPaint.getMaskFilter() != NULL && |
859 origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { | 803 origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { |
860 shader3D = SkNEW_ARGS(Sk3DShader, (shader)); | 804 shader3D = SkNEW_ARGS(Sk3DShader, (shader)); |
861 // we know we haven't initialized lazyPaint yet, so just do it | 805 // we know we haven't initialized lazyPaint yet, so just do it |
862 paint.writable()->setShader(shader3D)->unref(); | 806 paint.writable()->setShader(shader3D)->unref(); |
863 shader = shader3D; | 807 shader = shader3D; |
864 } | 808 } |
865 | 809 |
866 if (mode) { | 810 if (mode) { |
867 switch (interpret_xfermode(*paint, mode, device.colorType())) { | 811 bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType(); |
868 case kSrcOver_XferInterp: | 812 switch (SkInterpretXfermode(*paint, deviceIsOpaque)) { |
| 813 case kSrcOver_SkXfermodeInterpretation: |
869 mode = NULL; | 814 mode = NULL; |
870 paint.writable()->setXfermode(NULL); | 815 paint.writable()->setXfermode(NULL); |
871 break; | 816 break; |
872 case kSkipDrawing_XferInterp:{ | 817 case kSkipDrawing_SkXfermodeInterpretation:{ |
873 return allocator->createT<SkNullBlitter>(); | 818 return allocator->createT<SkNullBlitter>(); |
874 } | 819 } |
875 default: | 820 default: |
876 break; | 821 break; |
877 } | 822 } |
878 } | 823 } |
879 | 824 |
880 /* | 825 /* |
881 * If the xfermode is CLEAR, then we can completely ignore the installed | 826 * If the xfermode is CLEAR, then we can completely ignore the installed |
882 * color/shader/colorfilter, and just pretend we're SRC + color==0. This | 827 * color/shader/colorfilter, and just pretend we're SRC + color==0. This |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 fShaderContext->~Context(); | 969 fShaderContext->~Context(); |
1025 SkShader::Context* ctx = fShader->createContext(rec, (void*)fShaderContext); | 970 SkShader::Context* ctx = fShader->createContext(rec, (void*)fShaderContext); |
1026 if (NULL == ctx) { | 971 if (NULL == ctx) { |
1027 // Need a valid context in fShaderContext's storage, so we can later (or
our caller) call | 972 // Need a valid context in fShaderContext's storage, so we can later (or
our caller) call |
1028 // the in-place destructor. | 973 // the in-place destructor. |
1029 SkNEW_PLACEMENT_ARGS(fShaderContext, SkTransparentShaderContext, (*fShad
er, rec)); | 974 SkNEW_PLACEMENT_ARGS(fShaderContext, SkTransparentShaderContext, (*fShad
er, rec)); |
1030 return false; | 975 return false; |
1031 } | 976 } |
1032 return true; | 977 return true; |
1033 } | 978 } |
OLD | NEW |