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 "SkOpts.h" | 8 #include "SkOpts.h" |
9 #include "SkSmallAllocator.h" | 9 #include "SkSmallAllocator.h" |
10 #include "SkSpriteBlitter.h" | 10 #include "SkSpriteBlitter.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 // 1. src == dst format | 52 // 1. src == dst format |
53 // 2. paint has no modifiers (i.e. alpha, colorfilter, etc.) | 53 // 2. paint has no modifiers (i.e. alpha, colorfilter, etc.) |
54 // 3. xfermode needs no blending: e.g. kSrc_Mode or kSrcOver_Mode + opaque
src | 54 // 3. xfermode needs no blending: e.g. kSrc_Mode or kSrcOver_Mode + opaque
src |
55 // | 55 // |
56 class SkSpriteBlitter_Src_SrcOver final : public SkSpriteBlitter { | 56 class SkSpriteBlitter_Src_SrcOver final : public SkSpriteBlitter { |
57 public: | 57 public: |
58 static bool Supports(const SkPixmap& dst, const SkPixmap& src, const SkPaint
& paint) { | 58 static bool Supports(const SkPixmap& dst, const SkPixmap& src, const SkPaint
& paint) { |
59 if (dst.colorType() != src.colorType()) { | 59 if (dst.colorType() != src.colorType()) { |
60 return false; | 60 return false; |
61 } | 61 } |
62 if (dst.info().profileType() != src.info().profileType()) { | 62 if (dst.info().gammaCloseToSRGB() != src.info().gammaCloseToSRGB()) { |
63 return false; | 63 return false; |
64 } | 64 } |
65 if (paint.getMaskFilter() || paint.getColorFilter() || paint.getImageFil
ter()) { | 65 if (paint.getMaskFilter() || paint.getColorFilter() || paint.getImageFil
ter()) { |
66 return false; | 66 return false; |
67 } | 67 } |
68 if (0xFF != paint.getAlpha()) { | 68 if (0xFF != paint.getAlpha()) { |
69 return false; | 69 return false; |
70 } | 70 } |
71 SkXfermode::Mode mode; | 71 SkXfermode::Mode mode; |
72 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { | 72 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { |
73 return false; | 73 return false; |
74 } | 74 } |
75 if (SkXfermode::kSrc_Mode == mode) { | 75 if (SkXfermode::kSrc_Mode == mode) { |
76 return true; | 76 return true; |
77 } | 77 } |
78 if (SkXfermode::kSrcOver_Mode == mode && src.isOpaque()) { | 78 if (SkXfermode::kSrcOver_Mode == mode && src.isOpaque()) { |
79 return true; | 79 return true; |
80 } | 80 } |
81 | 81 |
82 // At this point memcpy can't be used. The following check for using Src
Over. | 82 // At this point memcpy can't be used. The following check for using Src
Over. |
83 | 83 |
84 if (dst.colorType() != kN32_SkColorType | 84 if (dst.colorType() != kN32_SkColorType || !dst.info().gammaCloseToSRGB(
)) { |
85 || dst.info().profileType() != kSRGB_SkColorProfileType) { | |
86 return false; | 85 return false; |
87 } | 86 } |
88 | 87 |
89 return SkXfermode::kSrcOver_Mode == mode; | 88 return SkXfermode::kSrcOver_Mode == mode; |
90 } | 89 } |
91 | 90 |
92 SkSpriteBlitter_Src_SrcOver(const SkPixmap& src) | 91 SkSpriteBlitter_Src_SrcOver(const SkPixmap& src) |
93 : INHERITED(src) {} | 92 : INHERITED(src) {} |
94 | 93 |
95 void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) ove
rride { | 94 void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) ove
rride { |
96 SkASSERT(Supports(dst, fSource, paint)); | 95 SkASSERT(Supports(dst, fSource, paint)); |
97 this->INHERITED::setup(dst, left, top, paint); | 96 this->INHERITED::setup(dst, left, top, paint); |
98 SkXfermode::Mode mode; | 97 SkXfermode::Mode mode; |
99 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { | 98 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { |
100 SkFAIL("Should never happen."); | 99 SkFAIL("Should never happen."); |
101 } | 100 } |
102 | 101 |
103 SkASSERT(mode == SkXfermode::kSrcOver_Mode || mode == SkXfermode::kSrc_M
ode); | 102 SkASSERT(mode == SkXfermode::kSrcOver_Mode || mode == SkXfermode::kSrc_M
ode); |
104 | 103 |
105 if (mode == SkXfermode::kSrcOver_Mode && !fSource.isOpaque()) { | 104 if (mode == SkXfermode::kSrcOver_Mode && !fSource.isOpaque()) { |
106 fUseMemcpy = false; | 105 fUseMemcpy = false; |
107 } | 106 } |
108 } | 107 } |
109 | 108 |
110 void blitRect(int x, int y, int width, int height) override { | 109 void blitRect(int x, int y, int width, int height) override { |
111 SkASSERT(fDst.colorType() == fSource.colorType()); | 110 SkASSERT(fDst.colorType() == fSource.colorType()); |
112 SkASSERT(fDst.info().profileType() == fSource.info().profileType()); | 111 SkASSERT(fDst.info().gammaCloseToSRGB() == fSource.info().gammaCloseToSR
GB()); |
113 SkASSERT(width > 0 && height > 0); | 112 SkASSERT(width > 0 && height > 0); |
114 | 113 |
115 if (fUseMemcpy) { | 114 if (fUseMemcpy) { |
116 char* dst = (char*)fDst.writable_addr(x, y); | 115 char* dst = (char*)fDst.writable_addr(x, y); |
117 const char* src = (const char*)fSource.addr(x - fLeft, y - fTop); | 116 const char* src = (const char*)fSource.addr(x - fLeft, y - fTop); |
118 const size_t dstRB = fDst.rowBytes(); | 117 const size_t dstRB = fDst.rowBytes(); |
119 const size_t srcRB = fSource.rowBytes(); | 118 const size_t srcRB = fSource.rowBytes(); |
120 const size_t bytesToCopy = width << fSource.shiftPerPixel(); | 119 const size_t bytesToCopy = width << fSource.shiftPerPixel(); |
121 | 120 |
122 while (height --> 0) { | 121 while (height --> 0) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 SkSpriteBlitter* blitter = nullptr; | 167 SkSpriteBlitter* blitter = nullptr; |
169 | 168 |
170 if (SkSpriteBlitter_Src_SrcOver::Supports(dst, source, paint)) { | 169 if (SkSpriteBlitter_Src_SrcOver::Supports(dst, source, paint)) { |
171 blitter = allocator->createT<SkSpriteBlitter_Src_SrcOver>(source); | 170 blitter = allocator->createT<SkSpriteBlitter_Src_SrcOver>(source); |
172 } else { | 171 } else { |
173 switch (dst.colorType()) { | 172 switch (dst.colorType()) { |
174 case kRGB_565_SkColorType: | 173 case kRGB_565_SkColorType: |
175 blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator); | 174 blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator); |
176 break; | 175 break; |
177 case kN32_SkColorType: | 176 case kN32_SkColorType: |
178 if (dst.info().isSRGB()) { | 177 if (dst.info().gammaCloseToSRGB()) { |
179 blitter = SkSpriteBlitter::ChooseS32(source, paint, allocato
r); | 178 blitter = SkSpriteBlitter::ChooseS32(source, paint, allocato
r); |
180 } else { | 179 } else { |
181 blitter = SkSpriteBlitter::ChooseL32(source, paint, allocato
r); | 180 blitter = SkSpriteBlitter::ChooseL32(source, paint, allocato
r); |
182 } | 181 } |
183 break; | 182 break; |
184 case kRGBA_F16_SkColorType: | 183 case kRGBA_F16_SkColorType: |
185 blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator); | 184 blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator); |
186 break; | 185 break; |
187 default: | 186 default: |
188 break; | 187 break; |
189 } | 188 } |
190 } | 189 } |
191 | 190 |
192 if (blitter) { | 191 if (blitter) { |
193 blitter->setup(dst, left, top, paint); | 192 blitter->setup(dst, left, top, paint); |
194 } | 193 } |
195 return blitter; | 194 return blitter; |
196 } | 195 } |
OLD | NEW |