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

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

Issue 1159763004: SkPDF: with opaque draws, treat SRC mode as SRC_OVER (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: unify with blitter code Created 5 years, 7 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 * 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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698