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 "SkSmallAllocator.h" | 9 #include "SkSmallAllocator.h" |
9 #include "SkSpriteBlitter.h" | 10 #include "SkSpriteBlitter.h" |
10 | 11 |
11 SkSpriteBlitter::SkSpriteBlitter(const SkPixmap& source) : fSource(source) {} | 12 SkSpriteBlitter::SkSpriteBlitter(const SkPixmap& source) : fSource(source) {} |
12 | 13 |
13 void SkSpriteBlitter::setup(const SkPixmap& dst, int left, int top, const SkPain
t& paint) { | 14 void SkSpriteBlitter::setup(const SkPixmap& dst, int left, int top, const SkPain
t& paint) { |
14 fDst = dst; | 15 fDst = dst; |
15 fLeft = left; | 16 fLeft = left; |
16 fTop = top; | 17 fTop = top; |
17 fPaint = &paint; | 18 fPaint = &paint; |
(...skipping 18 matching lines...) Expand all Loading... |
36 } | 37 } |
37 #endif | 38 #endif |
38 | 39 |
39 /////////////////////////////////////////////////////////////////////////////// | 40 /////////////////////////////////////////////////////////////////////////////// |
40 | 41 |
41 // Only valid if... | 42 // Only valid if... |
42 // 1. src == dst format | 43 // 1. src == dst format |
43 // 2. paint has no modifiers (i.e. alpha, colorfilter, etc.) | 44 // 2. paint has no modifiers (i.e. alpha, colorfilter, etc.) |
44 // 3. xfermode needs no blending: e.g. kSrc_Mode or kSrcOver_Mode + opaque
src | 45 // 3. xfermode needs no blending: e.g. kSrc_Mode or kSrcOver_Mode + opaque
src |
45 // | 46 // |
46 class SkSpriteBlitter_memcpy : public SkSpriteBlitter { | 47 class SkSpriteBlitter_Src_SrcOver : public SkSpriteBlitter { |
47 public: | 48 public: |
48 static bool Supports(const SkPixmap& dst, const SkPixmap& src, const SkPaint
& paint) { | 49 static bool Supports(const SkPixmap& dst, const SkPixmap& src, const SkPaint
& paint) { |
49 if (dst.colorType() != src.colorType()) { | 50 if (dst.colorType() != src.colorType()) { |
50 return false; | 51 return false; |
51 } | 52 } |
52 if (dst.info().profileType() != src.info().profileType()) { | 53 if (dst.info().profileType() != src.info().profileType()) { |
53 return false; | 54 return false; |
54 } | 55 } |
55 if (paint.getMaskFilter() || paint.getColorFilter() || paint.getImageFil
ter()) { | 56 if (paint.getMaskFilter() || paint.getColorFilter() || paint.getImageFil
ter()) { |
56 return false; | 57 return false; |
57 } | 58 } |
58 if (0xFF != paint.getAlpha()) { | 59 if (0xFF != paint.getAlpha()) { |
59 return false; | 60 return false; |
60 } | 61 } |
61 SkXfermode::Mode mode; | 62 SkXfermode::Mode mode; |
62 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { | 63 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { |
63 return false; | 64 return false; |
64 } | 65 } |
65 if (SkXfermode::kSrc_Mode == mode) { | 66 if (SkXfermode::kSrc_Mode == mode) { |
66 return true; | 67 return true; |
67 } | 68 } |
68 if (SkXfermode::kSrcOver_Mode == mode && src.isOpaque()) { | 69 if (SkXfermode::kSrcOver_Mode == mode && src.isOpaque()) { |
69 return true; | 70 return true; |
70 } | 71 } |
71 return false; | 72 |
| 73 // At this point memcpy can't be used. The following check for using Src
Over. |
| 74 |
| 75 if (dst.colorType() != kN32_SkColorType |
| 76 || dst.info().profileType() != kSRGB_SkColorProfileType) { |
| 77 return false; |
| 78 } |
| 79 |
| 80 return SkXfermode::kSrcOver_Mode == mode; |
72 } | 81 } |
73 | 82 |
74 SkSpriteBlitter_memcpy(const SkPixmap& src) : INHERITED(src) {} | 83 SkSpriteBlitter_Src_SrcOver(const SkPixmap& src) : INHERITED(src) {} |
75 | 84 |
76 void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) ove
rride { | 85 void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) ove
rride { |
77 SkASSERT(Supports(dst, fSource, paint)); | 86 SkASSERT(Supports(dst, fSource, paint)); |
78 this->INHERITED::setup(dst, left, top, paint); | 87 this->INHERITED::setup(dst, left, top, paint); |
| 88 SkXfermode::Mode mode; |
| 89 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { |
| 90 SkFAIL("Should never happen."); |
| 91 } |
| 92 |
| 93 SkASSERT(mode == SkXfermode::kSrcOver_Mode || mode == SkXfermode::kSrc_M
ode); |
| 94 |
| 95 if (mode == SkXfermode::kSrcOver_Mode && !fSource.isOpaque()) { |
| 96 fUseMemcpy = false; |
| 97 } |
79 } | 98 } |
80 | 99 |
81 void blitRect(int x, int y, int width, int height) override { | 100 void blitRect(int x, int y, int width, int height) override { |
82 SkASSERT(fDst.colorType() == fSource.colorType()); | 101 SkASSERT(fDst.colorType() == fSource.colorType()); |
83 SkASSERT(fDst.info().profileType() == fSource.info().profileType()); | 102 SkASSERT(fDst.info().profileType() == fSource.info().profileType()); |
84 SkASSERT(width > 0 && height > 0); | 103 SkASSERT(width > 0 && height > 0); |
85 | 104 |
86 char* dst = (char*)fDst.writable_addr(x, y); | 105 if (fUseMemcpy) { |
87 const char* src = (const char*)fSource.addr(x - fLeft, y - fTop); | 106 char* dst = (char*)fDst.writable_addr(x, y); |
88 const size_t dstRB = fDst.rowBytes(); | 107 const char* src = (const char*)fSource.addr(x - fLeft, y - fTop); |
89 const size_t srcRB = fSource.rowBytes(); | 108 const size_t dstRB = fDst.rowBytes(); |
90 const size_t bytesToCopy = width << fSource.shiftPerPixel(); | 109 const size_t srcRB = fSource.rowBytes(); |
| 110 const size_t bytesToCopy = width << fSource.shiftPerPixel(); |
91 | 111 |
92 while (--height >= 0) { | 112 while (height --> 0) { |
93 memcpy(dst, src, bytesToCopy); | 113 memcpy(dst, src, bytesToCopy); |
94 dst += dstRB; | 114 dst += dstRB; |
95 src += srcRB; | 115 src += srcRB; |
| 116 } |
| 117 } else { |
| 118 uint32_t* dst = fDst.writable_addr32(x, y); |
| 119 const uint32_t* src = fSource.addr32(x - fLeft, y - fTop); |
| 120 const int dstStride = fDst.rowBytesAsPixels(); |
| 121 const int srcStride = fSource.rowBytesAsPixels(); |
| 122 |
| 123 while (height --> 0) { |
| 124 SkOpts::srcover_srgb_srgb(dst, src, width, width); |
| 125 dst += dstStride; |
| 126 src += srcStride; |
| 127 } |
96 } | 128 } |
97 } | 129 } |
98 | 130 |
| 131 private: |
99 typedef SkSpriteBlitter INHERITED; | 132 typedef SkSpriteBlitter INHERITED; |
| 133 |
| 134 bool fUseMemcpy {true}; |
100 }; | 135 }; |
101 | 136 |
102 | |
103 // returning null means the caller will call SkBlitter::Choose() and | 137 // returning null means the caller will call SkBlitter::Choose() and |
104 // have wrapped the source bitmap inside a shader | 138 // have wrapped the source bitmap inside a shader |
105 SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint, | 139 SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint, |
106 const SkPixmap& source, int left, int top, SkTBlitterAllocator* allocato
r) { | 140 const SkPixmap& source, int left, int top, SkTBlitterAllocator* allocato
r) { |
107 /* We currently ignore antialiasing and filtertype, meaning we will take ou
r | 141 /* We currently ignore antialiasing and filtertype, meaning we will take ou
r |
108 special blitters regardless of these settings. Ignoring filtertype seems
fine | 142 special blitters regardless of these settings. Ignoring filtertype seems
fine |
109 since by definition there is no scale in the matrix. Ignoring antialiasi
ng is | 143 since by definition there is no scale in the matrix. Ignoring antialiasi
ng is |
110 a bit of a hack, since we "could" pass in the fractional left/top for th
e bitmap, | 144 a bit of a hack, since we "could" pass in the fractional left/top for th
e bitmap, |
111 and respect that by blending the edges of the bitmap against the device.
To support | 145 and respect that by blending the edges of the bitmap against the device.
To support |
112 this we could either add more special blitters here, or detect antialias
ing in the | 146 this we could either add more special blitters here, or detect antialias
ing in the |
113 paint and return null if it is set, forcing the client to take the slow
shader case | 147 paint and return null if it is set, forcing the client to take the slow
shader case |
114 (which does respect soft edges). | 148 (which does respect soft edges). |
115 */ | 149 */ |
116 SkASSERT(allocator != nullptr); | 150 SkASSERT(allocator != nullptr); |
117 | 151 |
118 SkSpriteBlitter* blitter; | 152 SkSpriteBlitter* blitter = nullptr; |
119 | 153 |
120 if (SkSpriteBlitter_memcpy::Supports(dst, source, paint)) { | 154 if (SkSpriteBlitter_Src_SrcOver::Supports(dst, source, paint)) { |
121 blitter = allocator->createT<SkSpriteBlitter_memcpy>(source); | 155 blitter = allocator->createT<SkSpriteBlitter_Src_SrcOver>(source); |
122 } else { | 156 } else { |
123 switch (dst.colorType()) { | 157 switch (dst.colorType()) { |
124 case kRGB_565_SkColorType: | 158 case kRGB_565_SkColorType: |
125 blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator); | 159 blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator); |
126 break; | 160 break; |
127 case kN32_SkColorType: | 161 case kN32_SkColorType: |
128 if (dst.info().isSRGB()) { | 162 if (dst.info().isSRGB()) { |
129 blitter = SkSpriteBlitter::ChooseS32(source, paint, allocato
r); | 163 blitter = SkSpriteBlitter::ChooseS32(source, paint, allocato
r); |
130 } else { | 164 } else { |
131 blitter = SkSpriteBlitter::ChooseL32(source, paint, allocato
r); | 165 blitter = SkSpriteBlitter::ChooseL32(source, paint, allocato
r); |
132 } | 166 } |
133 break; | 167 break; |
134 case kRGBA_F16_SkColorType: | 168 case kRGBA_F16_SkColorType: |
135 blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator); | 169 blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator); |
136 break; | 170 break; |
137 default: | 171 default: |
138 blitter = nullptr; | |
139 break; | 172 break; |
140 } | 173 } |
141 } | 174 } |
142 | 175 |
143 if (blitter) { | 176 if (blitter) { |
144 blitter->setup(dst, left, top, paint); | 177 blitter->setup(dst, left, top, paint); |
145 } | 178 } |
146 return blitter; | 179 return blitter; |
147 } | 180 } |
OLD | NEW |