OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
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 "SkBitmapCache.h" | 8 #include "SkBitmapCache.h" |
9 #include "SkBitmapController.h" | 9 #include "SkBitmapController.h" |
10 #include "SkBitmapProcState.h" | 10 #include "SkBitmapProcState.h" |
(...skipping 18 matching lines...) Expand all Loading... | |
29 extern void SI8_opaque_D32_filter_DX_shaderproc_neon(const void *, int, int, ui nt32_t*, int); | 29 extern void SI8_opaque_D32_filter_DX_shaderproc_neon(const void *, int, int, ui nt32_t*, int); |
30 extern void Clamp_SI8_opaque_D32_filter_DX_shaderproc_neon(const void*, int, in t, uint32_t*, int); | 30 extern void Clamp_SI8_opaque_D32_filter_DX_shaderproc_neon(const void*, int, in t, uint32_t*, int); |
31 #endif | 31 #endif |
32 | 32 |
33 extern void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const void*, int, int, u int32_t*, int); | 33 extern void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const void*, int, int, u int32_t*, int); |
34 | 34 |
35 #define NAME_WRAP(x) x | 35 #define NAME_WRAP(x) x |
36 #include "SkBitmapProcState_filter.h" | 36 #include "SkBitmapProcState_filter.h" |
37 #include "SkBitmapProcState_procs.h" | 37 #include "SkBitmapProcState_procs.h" |
38 | 38 |
39 SkBitmapProcState::SkBitmapProcState(const SkBitmapProvider& provider, | 39 SkBitmapProcInfo::SkBitmapProcInfo(const SkBitmapProvider& provider, |
herb_g
2016/03/02 16:00:18
Line up params and below.
reed1
2016/03/02 16:28:27
Done.
| |
40 SkShader::TileMode tmx, SkShader::TileMode tmy) | 40 SkShader::TileMode tmx, SkShader::TileMode tmy) |
41 : fProvider(provider) | 41 : fProvider(provider) |
42 , fBMState(nullptr) | 42 , fBMState(nullptr) |
43 { | 43 { |
44 fTileModeX = tmx; | 44 fTileModeX = tmx; |
45 fTileModeY = tmy; | 45 fTileModeY = tmy; |
46 } | 46 } |
47 | 47 |
48 SkBitmapProcState::SkBitmapProcState(const SkBitmap& bm, | 48 SkBitmapProcInfo::SkBitmapProcInfo(const SkBitmap& bm, |
49 SkShader::TileMode tmx, SkShader::TileMode tmy) | 49 SkShader::TileMode tmx, SkShader::TileMode tmy) |
50 : fProvider(SkBitmapProvider(bm)) | 50 : fProvider(SkBitmapProvider(bm)) |
51 , fBMState(nullptr) | 51 , fBMState(nullptr) |
52 { | 52 { |
53 fTileModeX = tmx; | 53 fTileModeX = tmx; |
54 fTileModeY = tmy; | 54 fTileModeY = tmy; |
55 } | 55 } |
56 | 56 |
57 SkBitmapProcState::~SkBitmapProcState() { | 57 SkBitmapProcInfo::~SkBitmapProcInfo() { |
58 SkInPlaceDeleteCheck(fBMState, fBMStateStorage.get()); | 58 SkInPlaceDeleteCheck(fBMState, fBMStateStorage.get()); |
59 } | 59 } |
60 | 60 |
61 /////////////////////////////////////////////////////////////////////////////// | 61 /////////////////////////////////////////////////////////////////////////////// |
62 | 62 |
63 // true iff the matrix contains, at most, scale and translate elements | 63 // true iff the matrix contains, at most, scale and translate elements |
64 static bool matrix_only_scale_translate(const SkMatrix& m) { | 64 static bool matrix_only_scale_translate(const SkMatrix& m) { |
65 return m.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask); | 65 return m.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask); |
66 } | 66 } |
67 | 67 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
111 // if we got here, treat us as either kTranslate_Mask or identity | 111 // if we got here, treat us as either kTranslate_Mask or identity |
112 return true; | 112 return true; |
113 } | 113 } |
114 | 114 |
115 static bool valid_for_filtering(unsigned dimension) { | 115 static bool valid_for_filtering(unsigned dimension) { |
116 // for filtering, width and height must fit in 14bits, since we use steal | 116 // for filtering, width and height must fit in 14bits, since we use steal |
117 // 2 bits from each to store our 4bit subpixel data | 117 // 2 bits from each to store our 4bit subpixel data |
118 return (dimension & ~0x3FFF) == 0; | 118 return (dimension & ~0x3FFF) == 0; |
119 } | 119 } |
120 | 120 |
121 /* | 121 bool SkBitmapProcInfo::init(const SkMatrix& inv, const SkPaint& paint) { |
122 * Analyze filter-quality and matrix, and decide how to implement that. | 122 const int origW = fProvider.info().width(); |
123 * | 123 const int origH = fProvider.info().height(); |
124 * In general, we cascade down the request level [ High ... None ] | 124 |
125 * - for a given level, if we can fulfill it, fine, else | |
126 * - else we downgrade to the next lower level and try again. | |
127 * We can always fulfill requests for Low and None | |
128 * - sometimes we will "ignore" Low and give None, but this is likely a legacy perf hack | |
129 * and may be removed. | |
130 */ | |
131 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { | |
132 fPixmap.reset(); | 125 fPixmap.reset(); |
133 fInvMatrix = inv; | 126 fInvMatrix = inv; |
134 fFilterLevel = paint.getFilterQuality(); | 127 fFilterLevel = paint.getFilterQuality(); |
135 | 128 |
136 const int origW = fProvider.info().width(); | |
137 const int origH = fProvider.info().height(); | |
138 bool allow_ignore_fractional_translate = true; // historical default | 129 bool allow_ignore_fractional_translate = true; // historical default |
139 if (kMedium_SkFilterQuality == fFilterLevel) { | 130 if (kMedium_SkFilterQuality == fFilterLevel) { |
140 allow_ignore_fractional_translate = false; | 131 allow_ignore_fractional_translate = false; |
141 } | 132 } |
142 | 133 |
143 SkDefaultBitmapController controller; | 134 SkDefaultBitmapController controller; |
144 fBMState = controller.requestBitmap(fProvider, inv, paint.getFilterQuality() , | 135 fBMState = controller.requestBitmap(fProvider, inv, paint.getFilterQuality() , |
145 fBMStateStorage.get(), fBMStateStorage.s ize()); | 136 fBMStateStorage.get(), fBMStateStorage.s ize()); |
146 // Note : we allow the controller to return an empty (zero-dimension) result . Should we? | 137 // Note : we allow the controller to return an empty (zero-dimension) result . Should we? |
147 if (nullptr == fBMState || fBMState->pixmap().info().isEmpty()) { | 138 if (nullptr == fBMState || fBMState->pixmap().info().isEmpty()) { |
148 return false; | 139 return false; |
149 } | 140 } |
150 fPixmap = fBMState->pixmap(); | 141 fPixmap = fBMState->pixmap(); |
151 fInvMatrix = fBMState->invMatrix(); | 142 fInvMatrix = fBMState->invMatrix(); |
143 fPaintColor = paint.getColor(); | |
152 fFilterLevel = fBMState->quality(); | 144 fFilterLevel = fBMState->quality(); |
153 SkASSERT(fPixmap.addr()); | 145 SkASSERT(fPixmap.addr()); |
154 | 146 |
155 bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; | 147 bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; |
156 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && | 148 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && |
157 SkShader::kClamp_TileMode == fTileModeY; | 149 SkShader::kClamp_TileMode == fTileModeY; |
158 | 150 |
159 // Most of the scanline procs deal with "unit" texture coordinates, as this | 151 // Most of the scanline procs deal with "unit" texture coordinates, as this |
160 // makes it easy to perform tiling modes (repeat = (x & 0xFFFF)). To generat e | 152 // makes it easy to perform tiling modes (repeat = (x & 0xFFFF)). To generat e |
161 // those, we divide the matrix by its dimensions here. | 153 // those, we divide the matrix by its dimensions here. |
162 // | 154 // |
163 // We don't do this if we're either trivial (can ignore the matrix) or clamp ing | 155 // We don't do this if we're either trivial (can ignore the matrix) or clamp ing |
164 // in both X and Y since clamping to width,height is just as easy as to 0xFF FF. | 156 // in both X and Y since clamping to width,height is just as easy as to 0xFF FF. |
165 | 157 |
166 if (!(clampClamp || trivialMatrix)) { | 158 if (!(clampClamp || trivialMatrix)) { |
167 fInvMatrix.postIDiv(fPixmap.width(), fPixmap.height()); | 159 fInvMatrix.postIDiv(fPixmap.width(), fPixmap.height()); |
168 } | 160 } |
169 | 161 |
170 // Now that all possible changes to the matrix have taken place, check | 162 // Now that all possible changes to the matrix have taken place, check |
171 // to see if we're really close to a no-scale matrix. If so, explicitly | 163 // to see if we're really close to a no-scale matrix. If so, explicitly |
172 // set it to be so. Subsequent code may inspect this matrix to choose | 164 // set it to be so. Subsequent code may inspect this matrix to choose |
173 // a faster path in this case. | 165 // a faster path in this case. |
174 | 166 |
175 // This code will only execute if the matrix has some scale component; | 167 // This code will only execute if the matrix has some scale component; |
176 // if it's already pure translate then we won't do this inversion. | 168 // if it's already pure translate then we won't do this inversion. |
177 | 169 |
178 if (matrix_only_scale_translate(fInvMatrix)) { | 170 if (matrix_only_scale_translate(fInvMatrix)) { |
179 SkMatrix forward; | 171 SkMatrix forward; |
180 if (fInvMatrix.invert(&forward)) { | 172 if (fInvMatrix.invert(&forward)) { |
181 if ((clampClamp && allow_ignore_fractional_translate) | 173 if ((clampClamp && allow_ignore_fractional_translate) |
182 ? just_trans_clamp(forward, fPixmap) | 174 ? just_trans_clamp(forward, fPixmap) |
183 : just_trans_general(forward)) { | 175 : just_trans_general(forward)) { |
184 fInvMatrix.setTranslate(-forward.getTranslateX(), -forward.getTr anslateY()); | 176 fInvMatrix.setTranslate(-forward.getTranslateX(), -forward.getTr anslateY()); |
185 } | 177 } |
186 } | 178 } |
187 } | 179 } |
188 | 180 |
189 fInvProc = fInvMatrix.getMapXYProc(); | 181 fInvType = fInvMatrix.getType(); |
190 fInvType = fInvMatrix.getType(); | |
191 fInvSx = SkScalarToFixed(fInvMatrix.getScaleX()); | |
192 fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix.getScaleX()); | |
193 fInvKy = SkScalarToFixed(fInvMatrix.getSkewY()); | |
194 fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix.getSkewY()); | |
195 | |
196 fAlphaScale = SkAlpha255To256(paint.getAlpha()); | |
197 | |
198 fShaderProc32 = nullptr; | |
199 fShaderProc16 = nullptr; | |
200 fSampleProc32 = nullptr; | |
201 | |
202 // recompute the triviality of the matrix here because we may have | |
203 // changed it! | |
204 | |
205 trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; | |
206 | 182 |
207 // If our target pixmap is the same as the original, then we revert back to legacy behavior | 183 // If our target pixmap is the same as the original, then we revert back to legacy behavior |
208 // and allow the code to ignore fractional translate. | 184 // and allow the code to ignore fractional translate. |
209 // | 185 // |
210 // The width/height check allows allow_ignore_fractional_translate to stay f alse if we | 186 // The width/height check allows allow_ignore_fractional_translate to stay f alse if we |
211 // previously set it that way (e.g. we started in kMedium). | 187 // previously set it that way (e.g. we started in kMedium). |
212 // | 188 // |
213 if (fPixmap.width() == origW && fPixmap.height() == origH) { | 189 if (fPixmap.width() == origW && fPixmap.height() == origH) { |
214 allow_ignore_fractional_translate = true; | 190 allow_ignore_fractional_translate = true; |
215 } | 191 } |
216 | 192 |
217 if (kLow_SkFilterQuality == fFilterLevel && allow_ignore_fractional_translat e) { | 193 if (kLow_SkFilterQuality == fFilterLevel && allow_ignore_fractional_translat e) { |
218 // Only try bilerp if the matrix is "interesting" and | 194 // Only try bilerp if the matrix is "interesting" and |
219 // the image has a suitable size. | 195 // the image has a suitable size. |
220 | 196 |
221 if (fInvType <= SkMatrix::kTranslate_Mask || | 197 if (fInvType <= SkMatrix::kTranslate_Mask || |
222 !valid_for_filtering(fPixmap.width() | fPixmap.height())) | 198 !valid_for_filtering(fPixmap.width() | fPixmap.height())) |
223 { | 199 { |
224 fFilterLevel = kNone_SkFilterQuality; | 200 fFilterLevel = kNone_SkFilterQuality; |
225 } | 201 } |
226 } | 202 } |
227 | 203 |
228 return this->chooseScanlineProcs(trivialMatrix, clampClamp, paint); | 204 return true; |
229 } | 205 } |
230 | 206 |
231 bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, | 207 /* |
232 const SkPaint& paint) { | 208 * Analyze filter-quality and matrix, and decide how to implement that. |
209 * | |
210 * In general, we cascade down the request level [ High ... None ] | |
211 * - for a given level, if we can fulfill it, fine, else | |
212 * - else we downgrade to the next lower level and try again. | |
213 * We can always fulfill requests for Low and None | |
214 * - sometimes we will "ignore" Low and give None, but this is likely a legacy perf hack | |
215 * and may be removed. | |
216 */ | |
217 bool SkBitmapProcState::chooseProcs() { | |
218 fInvProc = fInvMatrix.getMapXYProc(); | |
219 fInvSx = SkScalarToFixed(fInvMatrix.getScaleX()); | |
herb_g
2016/03/02 16:00:18
Align =?
reed1
2016/03/02 16:28:27
Done.
| |
220 fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix.getScaleX()); | |
221 fInvKy = SkScalarToFixed(fInvMatrix.getSkewY()); | |
222 fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix.getSkewY()); | |
223 | |
224 fAlphaScale = SkAlpha255To256(SkColorGetA(fPaintColor)); | |
225 | |
226 fShaderProc32 = nullptr; | |
227 fShaderProc16 = nullptr; | |
228 fSampleProc32 = nullptr; | |
229 | |
230 const bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mas k) == 0; | |
231 const bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && | |
232 SkShader::kClamp_TileMode == fTileModeY; | |
233 | |
234 return this->chooseScanlineProcs(trivialMatrix, clampClamp); | |
235 } | |
236 | |
237 bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp) { | |
233 fMatrixProc = this->chooseMatrixProc(trivialMatrix); | 238 fMatrixProc = this->chooseMatrixProc(trivialMatrix); |
234 // TODO(dominikg): SkASSERT(fMatrixProc) instead? chooseMatrixProc never ret urns nullptr. | 239 // TODO(dominikg): SkASSERT(fMatrixProc) instead? chooseMatrixProc never ret urns nullptr. |
235 if (nullptr == fMatrixProc) { | 240 if (nullptr == fMatrixProc) { |
236 return false; | 241 return false; |
237 } | 242 } |
238 | 243 |
239 /////////////////////////////////////////////////////////////////////// | 244 /////////////////////////////////////////////////////////////////////// |
240 | 245 |
241 const SkAlphaType at = fPixmap.alphaType(); | 246 const SkAlphaType at = fPixmap.alphaType(); |
242 | 247 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
274 index |= 16; | 279 index |= 16; |
275 break; | 280 break; |
276 case kARGB_4444_SkColorType: | 281 case kARGB_4444_SkColorType: |
277 if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) { | 282 if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) { |
278 return false; | 283 return false; |
279 } | 284 } |
280 index |= 24; | 285 index |= 24; |
281 break; | 286 break; |
282 case kAlpha_8_SkColorType: | 287 case kAlpha_8_SkColorType: |
283 index |= 32; | 288 index |= 32; |
284 fPaintPMColor = SkPreMultiplyColor(paint.getColor()); | 289 fPaintPMColor = SkPreMultiplyColor(fPaintColor); |
285 break; | 290 break; |
286 case kGray_8_SkColorType: | 291 case kGray_8_SkColorType: |
287 index |= 40; | 292 index |= 40; |
288 fPaintPMColor = SkPreMultiplyColor(paint.getColor()); | 293 fPaintPMColor = SkPreMultiplyColor(fPaintColor); |
289 break; | 294 break; |
290 default: | 295 default: |
291 // TODO(dominikg): Should we ever get here? SkASSERT(false) inst ead? | 296 // TODO(dominikg): Should we ever get here? SkASSERT(false) inst ead? |
292 return false; | 297 return false; |
293 } | 298 } |
294 | 299 |
295 #if !SK_ARM_NEON_IS_ALWAYS | 300 #if !SK_ARM_NEON_IS_ALWAYS |
296 static const SampleProc32 gSkBitmapProcStateSample32[] = { | 301 static const SampleProc32 gSkBitmapProcStateSample32[] = { |
297 S32_opaque_D32_nofilter_DXDY, | 302 S32_opaque_D32_nofilter_DXDY, |
298 S32_alpha_D32_nofilter_DXDY, | 303 S32_alpha_D32_nofilter_DXDY, |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
812 fx += dx; | 817 fx += dx; |
813 } | 818 } |
814 } else { | 819 } else { |
815 for (int i = 0; i < count; ++i) { | 820 for (int i = 0; i < count; ++i) { |
816 dst[i] = src[SkClampMax(SkFractionalIntToInt(fx), maxX)]; | 821 dst[i] = src[SkClampMax(SkFractionalIntToInt(fx), maxX)]; |
817 fx += dx; | 822 fx += dx; |
818 } | 823 } |
819 } | 824 } |
820 } | 825 } |
821 | 826 |
OLD | NEW |