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

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

Issue 18978014: Working plumb of image scaling: (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: No need to special case scale=1 Created 7 years, 5 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 | Annotate | Revision Log
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "SkBitmapProcState.h" 8 #include "SkBitmapProcState.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10 #include "SkFilterProc.h" 10 #include "SkFilterProc.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 } 83 }
84 84
85 /////////////////////////////////////////////////////////////////////////////// 85 ///////////////////////////////////////////////////////////////////////////////
86 86
87 static bool valid_for_filtering(unsigned dimension) { 87 static bool valid_for_filtering(unsigned dimension) {
88 // for filtering, width and height must fit in 14bits, since we use steal 88 // for filtering, width and height must fit in 14bits, since we use steal
89 // 2 bits from each to store our 4bit subpixel data 89 // 2 bits from each to store our 4bit subpixel data
90 return (dimension & ~0x3FFF) == 0; 90 return (dimension & ~0x3FFF) == 0;
91 } 91 }
92 92
93 void SkBitmapProcState::possiblyScaleImage() {
reed1 2013/07/12 14:01:06 I think we may need to pass in the clip-bounds, so
humper 2013/07/12 17:18:01 Is it OK to leave this as a TODO comment for now a
94
95 if (fFilterQuality != kHQ_BitmapFilter) {
96 return;
97 }
98
99 // STEP 1: UPSAMPLE?
100
101 // Check to see if the transformation matrix is scaling up, and if
102 // the matrix is simple, and if we're doing high quality scaling.
103 // If so, do the bitmap scale here and remove the scaling component from the matrix.
104
105 if (fUnitInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslat e_Mask) &&
106 (fUnitInvMatrix.getScaleX() < 1 || fUnitInvMatrix.getScaleY() < 1) &&
107 fOrigBitmap.config() == SkBitmap::kARGB_8888_Config) {
108
109 // All the criteria are met; let's make a new bitmap.
110 fScaledBitmap.setConfig(SkBitmap::kARGB_8888_Config,
111 (int)(fOrigBitmap.width() / fUnitInvMatrix.getSc aleX()),
112 (int)(fOrigBitmap.height() / fUnitInvMatrix.getS caleY()));
113 fScaledBitmap.allocPixels();
114 fOrigBitmap.scale(&fScaledBitmap);
115 fBitmap = &fScaledBitmap;
116
117 // set the inv matrix type to translate-only;
118
119 fUnitInvMatrix.setTranslate( 1/fUnitInvMatrix.getScaleX() * fUnitInvMatr ix.getTranslateX(),
120 1/fUnitInvMatrix.getScaleY() * fUnitInvMatr ix.getTranslateY() );
121
122 // no need for any further filtering; we just did it!
123
124 fFilterQuality = kNone_BitmapFilter;
125
126 return;
127 }
128
129 if (!fOrigBitmap.hasMipMap()) {
130
131 // STEP 2: DOWNSAMPLE
132
133 // Check to see if the transformation matrix is scaling *down*.
134 // If so, automatically build mipmaps.
135
136 SkPoint v1, v2;
137
138 // conservatively estimate if the matrix is scaling down by seeing
139 // what its upper left 2x2 portion does to two unit vectors.
140
141 v1.fX = fUnitInvMatrix.getScaleX();
142 v1.fY = fUnitInvMatrix.getSkewY();
143
144 v2.fX = fUnitInvMatrix.getSkewX();
145 v2.fY = fUnitInvMatrix.getScaleY();
146
147 if (v1.fX * v1.fX + v1.fY * v1.fY > 1 ||
148 v2.fX * v2.fX + v2.fY * v2.fY > 1) {
149 fOrigBitmap.buildMipMap();
150
151 // Now that we've built the mipmaps and we know we're downsampling,
152 // downgrade to bilinear interpolation for the mip level.
153
154 fFilterQuality = kBilerp_BitmapFilter;
155 }
156 }
157
158 if (fOrigBitmap.hasMipMap()) {
159
160 // STEP 3: We've got mipmaps, let's choose the closest level as our rend er
161 // source and adjust the matrix accordingly.
162
163 int shift = fOrigBitmap.extractMipLevel(&fScaledBitmap,
164 SkScalarToFixed(fUnitInvMatrix.g etScaleX()),
165 SkScalarToFixed(fUnitInvMatrix.g etSkewY()));
166
167 if (shift > 0) {
168 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift);
169 fUnitInvMatrix.postScale(scale, scale);
170 fBitmap = &fScaledBitmap;
171 }
172 }
173 }
174
175 void SkBitmapProcState::endContext() {
176 SkDELETE(fBitmapFilter);
177 }
178
93 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { 179 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
94 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) { 180 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) {
95 return false; 181 return false;
96 } 182 }
97 183
98 const SkMatrix* m;
99 bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0; 184 bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0;
reed1 2013/07/12 14:01:06 This is probably too soon to be computing "trivial
humper 2013/07/12 17:18:01 trivial_matrix is used immediately (so we need it
reed1 2013/07/12 18:33:24 Yes, lets recompute it, either when we know we've
100 bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX && 185 bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX &&
101 SkShader::kClamp_TileMode == fTileModeY; 186 SkShader::kClamp_TileMode == fTileModeY;
102 187
103 if (clamp_clamp || trivial_matrix) { 188 fUnitInvMatrix = inv;
reed1 2013/07/12 14:01:06 I see now that your change meas we *always* use fU
humper 2013/07/12 17:18:01 Done.
104 m = &inv; 189 if (!(clamp_clamp || trivial_matrix)) {
105 } else {
106 fUnitInvMatrix = inv;
107 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); 190 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height());
108 m = &fUnitInvMatrix;
109 } 191 }
110 192
111 fBitmap = &fOrigBitmap; 193 fBitmap = &fOrigBitmap;
112 if (fOrigBitmap.hasMipMap()) { 194
113 int shift = fOrigBitmap.extractMipLevel(&fMipBitmap, 195 // initialize our filter quality to the one requested by the caller.
114 SkScalarToFixed(m->getScaleX()), 196 // We may downgrade it later if we determine that we either don't need
115 SkScalarToFixed(m->getSkewY())); 197 // or can't provide as high a quality filtering as the user requested.
116 198
117 if (shift > 0) { 199 fFilterQuality = kNone_BitmapFilter;
118 if (m != &fUnitInvMatrix) { 200 if (paint.isFilterBitmap()) {
119 fUnitInvMatrix = *m; 201 if (paint.getFlags() & SkPaint::kHighQualityFilterBitmap_Flag) {
120 m = &fUnitInvMatrix; 202 fFilterQuality = kHQ_BitmapFilter;
121 } 203 } else {
122 204 fFilterQuality = kBilerp_BitmapFilter;
123 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift);
124 fUnitInvMatrix.postScale(scale, scale);
125
126 // now point here instead of fOrigBitmap
127 fBitmap = &fMipBitmap;
128 } 205 }
129 } 206 }
130 207
131 // wack our matrix to exactly no-scale, if we're really close to begin with 208 // possiblyScaleImage will look to see if it can rescale the image as a
132 if (matrix_only_scale_translate(*m)) { 209 // preprocess; either by scaling up to the target size, or by selecting
210 // a nearby mipmap level. If it does, it will adjust the working
211 // matrix as well as the working bitmap. It may also adjust the filter
212 // quality to avoid re-filtering an already perfectly scaled image.
213
214 possiblyScaleImage();
reed1 2013/07/12 14:01:06 nit: this->possiblyScaleImage();
humper 2013/07/12 17:18:01 Done.
215
216 // Now that all possible changes to the matrix have taken place, check
217 // to see if we're really close to a no-scale matrix. If so, explicitly
218 // set it to be so. Subsequent code may inspect this matrix to choose
219 // a faster path in this case.
220
221 if (matrix_only_scale_translate(fUnitInvMatrix)) {
reed1 2013/07/12 14:01:06 unrelated to this CL, but this guy should probably
humper 2013/07/12 17:18:01 Done.
133 SkMatrix forward; 222 SkMatrix forward;
134 if (m->invert(&forward)) { 223 if (fUnitInvMatrix.invert(&forward)) {
135 if (clamp_clamp ? just_trans_clamp(forward, *fBitmap) 224 if (clamp_clamp ? just_trans_clamp(forward, *fBitmap)
136 : just_trans_general(forward)) { 225 : just_trans_general(forward)) {
137 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX()); 226 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX());
138 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY()); 227 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY());
139 fUnitInvMatrix.setTranslate(tx, ty); 228 fUnitInvMatrix.setTranslate(tx, ty);
140 m = &fUnitInvMatrix; 229
141 // now the following code will sniff m, and decide to take the
142 // fast case (since m is purely translate).
143 } 230 }
144 } 231 }
145 } 232 }
146 233
147 // Below this point, we should never refer to the inv parameter, since we 234 // Below this point, we should never refer to the inv parameter, since we
148 // may be using a munged version for "our" inverse. 235 // may be using a munged version for "our" inverse.
149 236
150 fInvMatrix = m; 237 fInvMatrix = &fUnitInvMatrix;
151 fInvProc = m->getMapXYProc(); 238 fInvProc = fInvMatrix->getMapXYProc();
reed1 2013/07/12 14:01:06 Maybe we no longer need fInvMatrix as a pointer an
humper 2013/07/12 17:18:01 Done.
152 fInvType = m->getType(); 239 fInvType = fInvMatrix->getType();
153 fInvSx = SkScalarToFixed(m->getScaleX()); 240 fInvSx = SkScalarToFixed(fInvMatrix->getScaleX());
154 fInvSxFractionalInt = SkScalarToFractionalInt(m->getScaleX()); 241 fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix->getScaleX());
155 fInvKy = SkScalarToFixed(m->getSkewY()); 242 fInvKy = SkScalarToFixed(fInvMatrix->getSkewY());
156 fInvKyFractionalInt = SkScalarToFractionalInt(m->getSkewY()); 243 fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix->getSkewY());
157 244
158 fAlphaScale = SkAlpha255To256(paint.getAlpha()); 245 fAlphaScale = SkAlpha255To256(paint.getAlpha());
159 246
160 // pick-up filtering from the paint, but only if the matrix is
161 // more complex than identity/translate (i.e. no need to pay the cost
162 // of filtering if we're not scaled etc.).
163 // note: we explicitly check inv, since m might be scaled due to unitinv
164 // trickery, but we don't want to see that for this test
165 fDoFilter = paint.isFilterBitmap() &&
166 (fInvType > SkMatrix::kTranslate_Mask &&
167 valid_for_filtering(fBitmap->width() | fBitmap->height()));
168
169 fShaderProc32 = NULL; 247 fShaderProc32 = NULL;
170 fShaderProc16 = NULL; 248 fShaderProc16 = NULL;
171 fSampleProc32 = NULL; 249 fSampleProc32 = NULL;
172 fSampleProc16 = NULL; 250 fSampleProc16 = NULL;
173 251
252 if (kHQ_BitmapFilter == fFilterQuality) {
reed1 2013/07/12 14:01:06 *maybe* we can add an ASSERT here that claims that
humper 2013/07/12 17:18:01 Done.
253 // If this is still set, that means we wanted HQ sampling
254 // but couldn't do it as a preprocess. Let's try to install
255 // the scanline version of the HQ sampler. If that process fails,
256 // downgrade to bilerp.
257
258 // NOTE: Might need to be careful here in the future when we want
259 // to have the platform proc have a shot at this; it's possible that
260 // the chooseBitmapFilterProc will fail to install a shader but a
261 // platform-specific one might succeed, so it might be premature here
262 // to fall back to bilerp. This needs thought.
263
264 fShaderProc32 = this->chooseBitmapFilterProc();
265 if (!fShaderProc32) {
266 fFilterQuality = kBilerp_BitmapFilter;
267 }
268 }
269
270 if (kBilerp_BitmapFilter == fFilterQuality) {
271 // Only try bilerp if the matrix is "interesting" and
272 // the image has a suitable size.
273
274 if (fInvType < SkMatrix::kTranslate_Mask ||
275 !valid_for_filtering(fBitmap->width() | fBitmap->height())) {
276 fFilterQuality = kNone_BitmapFilter;
277 }
278 }
279
280 // At this point, we know exactly what kind of sampling the per-scanline
281 // shader will perform.
282
174 fMatrixProc = this->chooseMatrixProc(trivial_matrix); 283 fMatrixProc = this->chooseMatrixProc(trivial_matrix);
175 if (NULL == fMatrixProc) { 284 if (NULL == fMatrixProc) {
176 return false; 285 return false;
177 } 286 }
178 287
179 /////////////////////////////////////////////////////////////////////// 288 ///////////////////////////////////////////////////////////////////////
180 289
181 int index = 0; 290 // No need to do this if we're doing HQ sampling; if filter quality is
182 if (fAlphaScale < 256) { // note: this distinction is not used for D16 291 // still set to HQ by the time we get here, then we must have installed
183 index |= 1; 292 // the shader proc above and can skip all this.
184 }
185 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
186 index |= 2;
187 }
188 if (fDoFilter) {
189 index |= 4;
190 }
191 // bits 3,4,5 encoding the source bitmap format
192 switch (fBitmap->config()) {
193 case SkBitmap::kARGB_8888_Config:
194 index |= 0;
195 break;
196 case SkBitmap::kRGB_565_Config:
197 index |= 8;
198 break;
199 case SkBitmap::kIndex8_Config:
200 index |= 16;
201 break;
202 case SkBitmap::kARGB_4444_Config:
203 index |= 24;
204 break;
205 case SkBitmap::kA8_Config:
206 index |= 32;
207 fPaintPMColor = SkPreMultiplyColor(paint.getColor());
208 break;
209 default:
210 return false;
211 }
212 293
213 #if !SK_ARM_NEON_IS_ALWAYS 294 if (fFilterQuality < kHQ_BitmapFilter) {
214 static const SampleProc32 gSkBitmapProcStateSample32[] = { 295
215 S32_opaque_D32_nofilter_DXDY, 296 int index = 0;
216 S32_alpha_D32_nofilter_DXDY, 297 if (fAlphaScale < 256) { // note: this distinction is not used for D16
217 S32_opaque_D32_nofilter_DX, 298 index |= 1;
218 S32_alpha_D32_nofilter_DX, 299 }
219 S32_opaque_D32_filter_DXDY, 300 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
220 S32_alpha_D32_filter_DXDY, 301 index |= 2;
221 S32_opaque_D32_filter_DX, 302 }
222 S32_alpha_D32_filter_DX, 303 if (fFilterQuality != kNone_BitmapFilter) {
304 index |= 4;
305 }
306 // bits 3,4,5 encoding the source bitmap format
307 switch (fBitmap->config()) {
308 case SkBitmap::kARGB_8888_Config:
309 index |= 0;
310 break;
311 case SkBitmap::kRGB_565_Config:
312 index |= 8;
313 break;
314 case SkBitmap::kIndex8_Config:
315 index |= 16;
316 break;
317 case SkBitmap::kARGB_4444_Config:
318 index |= 24;
319 break;
320 case SkBitmap::kA8_Config:
321 index |= 32;
322 fPaintPMColor = SkPreMultiplyColor(paint.getColor());
323 break;
324 default:
325 return false;
326 }
223 327
224 S16_opaque_D32_nofilter_DXDY, 328 #if !SK_ARM_NEON_IS_ALWAYS
225 S16_alpha_D32_nofilter_DXDY, 329 static const SampleProc32 gSkBitmapProcStateSample32[] = {
226 S16_opaque_D32_nofilter_DX, 330 S32_opaque_D32_nofilter_DXDY,
227 S16_alpha_D32_nofilter_DX, 331 S32_alpha_D32_nofilter_DXDY,
228 S16_opaque_D32_filter_DXDY, 332 S32_opaque_D32_nofilter_DX,
229 S16_alpha_D32_filter_DXDY, 333 S32_alpha_D32_nofilter_DX,
230 S16_opaque_D32_filter_DX, 334 S32_opaque_D32_filter_DXDY,
231 S16_alpha_D32_filter_DX, 335 S32_alpha_D32_filter_DXDY,
336 S32_opaque_D32_filter_DX,
337 S32_alpha_D32_filter_DX,
232 338
233 SI8_opaque_D32_nofilter_DXDY, 339 S16_opaque_D32_nofilter_DXDY,
234 SI8_alpha_D32_nofilter_DXDY, 340 S16_alpha_D32_nofilter_DXDY,
235 SI8_opaque_D32_nofilter_DX, 341 S16_opaque_D32_nofilter_DX,
236 SI8_alpha_D32_nofilter_DX, 342 S16_alpha_D32_nofilter_DX,
237 SI8_opaque_D32_filter_DXDY, 343 S16_opaque_D32_filter_DXDY,
238 SI8_alpha_D32_filter_DXDY, 344 S16_alpha_D32_filter_DXDY,
239 SI8_opaque_D32_filter_DX, 345 S16_opaque_D32_filter_DX,
240 SI8_alpha_D32_filter_DX, 346 S16_alpha_D32_filter_DX,
241 347
242 S4444_opaque_D32_nofilter_DXDY, 348 SI8_opaque_D32_nofilter_DXDY,
243 S4444_alpha_D32_nofilter_DXDY, 349 SI8_alpha_D32_nofilter_DXDY,
244 S4444_opaque_D32_nofilter_DX, 350 SI8_opaque_D32_nofilter_DX,
245 S4444_alpha_D32_nofilter_DX, 351 SI8_alpha_D32_nofilter_DX,
246 S4444_opaque_D32_filter_DXDY, 352 SI8_opaque_D32_filter_DXDY,
247 S4444_alpha_D32_filter_DXDY, 353 SI8_alpha_D32_filter_DXDY,
248 S4444_opaque_D32_filter_DX, 354 SI8_opaque_D32_filter_DX,
249 S4444_alpha_D32_filter_DX, 355 SI8_alpha_D32_filter_DX,
250 356
251 // A8 treats alpha/opaque the same (equally efficient) 357 S4444_opaque_D32_nofilter_DXDY,
252 SA8_alpha_D32_nofilter_DXDY, 358 S4444_alpha_D32_nofilter_DXDY,
253 SA8_alpha_D32_nofilter_DXDY, 359 S4444_opaque_D32_nofilter_DX,
254 SA8_alpha_D32_nofilter_DX, 360 S4444_alpha_D32_nofilter_DX,
255 SA8_alpha_D32_nofilter_DX, 361 S4444_opaque_D32_filter_DXDY,
256 SA8_alpha_D32_filter_DXDY, 362 S4444_alpha_D32_filter_DXDY,
257 SA8_alpha_D32_filter_DXDY, 363 S4444_opaque_D32_filter_DX,
258 SA8_alpha_D32_filter_DX, 364 S4444_alpha_D32_filter_DX,
259 SA8_alpha_D32_filter_DX
260 };
261 365
262 static const SampleProc16 gSkBitmapProcStateSample16[] = { 366 // A8 treats alpha/opaque the same (equally efficient)
263 S32_D16_nofilter_DXDY, 367 SA8_alpha_D32_nofilter_DXDY,
264 S32_D16_nofilter_DX, 368 SA8_alpha_D32_nofilter_DXDY,
265 S32_D16_filter_DXDY, 369 SA8_alpha_D32_nofilter_DX,
266 S32_D16_filter_DX, 370 SA8_alpha_D32_nofilter_DX,
371 SA8_alpha_D32_filter_DXDY,
372 SA8_alpha_D32_filter_DXDY,
373 SA8_alpha_D32_filter_DX,
374 SA8_alpha_D32_filter_DX
375 };
267 376
268 S16_D16_nofilter_DXDY, 377 static const SampleProc16 gSkBitmapProcStateSample16[] = {
269 S16_D16_nofilter_DX, 378 S32_D16_nofilter_DXDY,
270 S16_D16_filter_DXDY, 379 S32_D16_nofilter_DX,
271 S16_D16_filter_DX, 380 S32_D16_filter_DXDY,
381 S32_D16_filter_DX,
272 382
273 SI8_D16_nofilter_DXDY, 383 S16_D16_nofilter_DXDY,
274 SI8_D16_nofilter_DX, 384 S16_D16_nofilter_DX,
275 SI8_D16_filter_DXDY, 385 S16_D16_filter_DXDY,
276 SI8_D16_filter_DX, 386 S16_D16_filter_DX,
277 387
278 // Don't support 4444 -> 565 388 SI8_D16_nofilter_DXDY,
279 NULL, NULL, NULL, NULL, 389 SI8_D16_nofilter_DX,
280 // Don't support A8 -> 565 390 SI8_D16_filter_DXDY,
281 NULL, NULL, NULL, NULL 391 SI8_D16_filter_DX,
282 };
283 #endif
284 392
285 fSampleProc32 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample32)[index]; 393 // Don't support 4444 -> 565
286 index >>= 1; // shift away any opaque/alpha distinction 394 NULL, NULL, NULL, NULL,
287 fSampleProc16 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample16)[index]; 395 // Don't support A8 -> 565
396 NULL, NULL, NULL, NULL
397 };
398 #endif
288 399
289 // our special-case shaderprocs 400 fSampleProc32 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample32)[index];
290 if (SK_ARM_NEON_WRAP(S16_D16_filter_DX) == fSampleProc16) { 401 index >>= 1; // shift away any opaque/alpha distinction
291 if (clamp_clamp) { 402 fSampleProc16 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample16)[index];
292 fShaderProc16 = SK_ARM_NEON_WRAP(Clamp_S16_D16_filter_DX_shaderproc) ; 403
293 } else if (SkShader::kRepeat_TileMode == fTileModeX && 404 // our special-case shaderprocs
294 SkShader::kRepeat_TileMode == fTileModeY) { 405 if (SK_ARM_NEON_WRAP(S16_D16_filter_DX) == fSampleProc16) {
295 fShaderProc16 = SK_ARM_NEON_WRAP(Repeat_S16_D16_filter_DX_shaderproc ); 406 if (clamp_clamp) {
407 fShaderProc16 = SK_ARM_NEON_WRAP(Clamp_S16_D16_filter_DX_shaderp roc);
408 } else if (SkShader::kRepeat_TileMode == fTileModeX &&
409 SkShader::kRepeat_TileMode == fTileModeY) {
410 fShaderProc16 = SK_ARM_NEON_WRAP(Repeat_S16_D16_filter_DX_shader proc);
411 }
412 } else if (SK_ARM_NEON_WRAP(SI8_opaque_D32_filter_DX) == fSampleProc32 & & clamp_clamp) {
413 fShaderProc32 = SK_ARM_NEON_WRAP(Clamp_SI8_opaque_D32_filter_DX_shad erproc);
296 } 414 }
297 } else if (SK_ARM_NEON_WRAP(SI8_opaque_D32_filter_DX) == fSampleProc32 && cl amp_clamp) {
298 fShaderProc32 = SK_ARM_NEON_WRAP(Clamp_SI8_opaque_D32_filter_DX_shaderpr oc);
299 }
300 415
301 if (NULL == fShaderProc32) { 416 if (NULL == fShaderProc32) {
302 fShaderProc32 = this->chooseShaderProc32(); 417 fShaderProc32 = this->chooseShaderProc32();
303 } 418 }
304
305 if (NULL == fShaderProc32) {
306 fShaderProc32 = this->chooseBitmapFilterProc(paint);
307 } 419 }
308 420
309 // see if our platform has any accelerated overrides 421 // see if our platform has any accelerated overrides
310 this->platformProcs(); 422 this->platformProcs();
311 423
312 return true; 424 return true;
313 } 425 }
314 426
315 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, 427 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s,
316 int x, int y, 428 int x, int y,
317 SkPMColor* SK_RESTRICT color s, 429 SkPMColor* SK_RESTRICT color s,
318 int count) { 430 int count) {
319 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); 431 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0);
320 SkASSERT(s.fInvKy == 0); 432 SkASSERT(s.fInvKy == 0);
321 SkASSERT(count > 0 && colors != NULL); 433 SkASSERT(count > 0 && colors != NULL);
322 SkASSERT(!s.fDoFilter); 434 SkASSERT(SkBitmapProcState::kNone_BitmapFilter == s.fFilterQuality);
323 435
324 const int maxX = s.fBitmap->width() - 1; 436 const int maxX = s.fBitmap->width() - 1;
325 const int maxY = s.fBitmap->height() - 1; 437 const int maxY = s.fBitmap->height() - 1;
326 int ix = s.fFilterOneX + x; 438 int ix = s.fFilterOneX + x;
327 int iy = SkClampMax(s.fFilterOneY + y, maxY); 439 int iy = SkClampMax(s.fFilterOneY + y, maxY);
328 #ifdef SK_DEBUG 440 #ifdef SK_DEBUG
329 { 441 {
330 SkPoint pt; 442 SkPoint pt;
331 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 443 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
332 SkIntToScalar(y) + SK_ScalarHalf, &pt); 444 SkIntToScalar(y) + SK_ScalarHalf, &pt);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 return x; 498 return x;
387 } 499 }
388 500
389 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, 501 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s,
390 int x, int y, 502 int x, int y,
391 SkPMColor* SK_RESTRICT colo rs, 503 SkPMColor* SK_RESTRICT colo rs,
392 int count) { 504 int count) {
393 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); 505 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0);
394 SkASSERT(s.fInvKy == 0); 506 SkASSERT(s.fInvKy == 0);
395 SkASSERT(count > 0 && colors != NULL); 507 SkASSERT(count > 0 && colors != NULL);
396 SkASSERT(!s.fDoFilter); 508 SkASSERT(SkBitmapProcState::kNone_BitmapFilter == s.fFilterQuality);
397 509
398 const int stopX = s.fBitmap->width(); 510 const int stopX = s.fBitmap->width();
399 const int stopY = s.fBitmap->height(); 511 const int stopY = s.fBitmap->height();
400 int ix = s.fFilterOneX + x; 512 int ix = s.fFilterOneX + x;
401 int iy = sk_int_mod(s.fFilterOneY + y, stopY); 513 int iy = sk_int_mod(s.fFilterOneY + y, stopY);
402 #ifdef SK_DEBUG 514 #ifdef SK_DEBUG
403 { 515 {
404 SkPoint pt; 516 SkPoint pt;
405 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 517 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
406 SkIntToScalar(y) + SK_ScalarHalf, &pt); 518 SkIntToScalar(y) + SK_ScalarHalf, &pt);
(...skipping 25 matching lines...) Expand all
432 int count) { 544 int count) {
433 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0); 545 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0);
434 SkASSERT(s.fInvKy == 0); 546 SkASSERT(s.fInvKy == 0);
435 SkASSERT(count > 0 && colors != NULL); 547 SkASSERT(count > 0 && colors != NULL);
436 SkASSERT(1 == s.fBitmap->width()); 548 SkASSERT(1 == s.fBitmap->width());
437 549
438 int iY0; 550 int iY0;
439 int iY1 SK_INIT_TO_AVOID_WARNING; 551 int iY1 SK_INIT_TO_AVOID_WARNING;
440 int iSubY SK_INIT_TO_AVOID_WARNING; 552 int iSubY SK_INIT_TO_AVOID_WARNING;
441 553
442 if (s.fDoFilter) { 554 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) {
443 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); 555 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc();
444 uint32_t xy[2]; 556 uint32_t xy[2];
445 557
446 mproc(s, xy, 1, x, y); 558 mproc(s, xy, 1, x, y);
447 559
448 iY0 = xy[0] >> 18; 560 iY0 = xy[0] >> 18;
449 iY1 = xy[0] & 0x3FFF; 561 iY1 = xy[0] & 0x3FFF;
450 iSubY = (xy[0] >> 14) & 0xF; 562 iSubY = (xy[0] >> 14) & 0xF;
451 } else { 563 } else {
452 int yTemp; 564 int yTemp;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 } 625 }
514 626
515 SkASSERT(iY0 == iY2); 627 SkASSERT(iY0 == iY2);
516 } 628 }
517 #endif 629 #endif
518 } 630 }
519 631
520 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0); 632 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0);
521 SkPMColor color; 633 SkPMColor color;
522 634
523 if (s.fDoFilter) { 635 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) {
524 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1); 636 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1);
525 637
526 if (s.fAlphaScale < 256) { 638 if (s.fAlphaScale < 256) {
527 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale); 639 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale);
528 } else { 640 } else {
529 Filter_32_opaque(iSubY, *row0, *row1, &color); 641 Filter_32_opaque(iSubY, *row0, *row1, &color);
530 } 642 }
531 } else { 643 } else {
532 if (s.fAlphaScale < 256) { 644 if (s.fAlphaScale < 256) {
533 color = SkAlphaMulQ(*row0, s.fAlphaScale); 645 color = SkAlphaMulQ(*row0, s.fAlphaScale);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 681
570 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { 682 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() {
571 683
572 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) { 684 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) {
573 return NULL; 685 return NULL;
574 } 686 }
575 687
576 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask; 688 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask;
577 689
578 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) { 690 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) {
579 if (!fDoFilter && fInvType <= SkMatrix::kTranslate_Mask && !this->setupF orTranslate()) { 691 if (kNone_BitmapFilter == fFilterQuality &&
692 fInvType <= SkMatrix::kTranslate_Mask &&
693 !this->setupForTranslate()) {
580 return DoNothing_shaderproc; 694 return DoNothing_shaderproc;
581 } 695 }
582 return S32_D32_constX_shaderproc; 696 return S32_D32_constX_shaderproc;
583 } 697 }
584 698
585 if (fAlphaScale < 256) { 699 if (fAlphaScale < 256) {
586 return NULL; 700 return NULL;
587 } 701 }
588 if (fInvType > SkMatrix::kTranslate_Mask) { 702 if (fInvType > SkMatrix::kTranslate_Mask) {
589 return NULL; 703 return NULL;
590 } 704 }
591 if (fDoFilter) { 705 if (fFilterQuality != kNone_BitmapFilter) {
592 return NULL; 706 return NULL;
593 } 707 }
594 708
595 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX; 709 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX;
596 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY; 710 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY;
597 711
598 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) { 712 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) {
599 if (this->setupForTranslate()) { 713 if (this->setupForTranslate()) {
600 return Clamp_S32_D32_nofilter_trans_shaderproc; 714 return Clamp_S32_D32_nofilter_trans_shaderproc;
601 } 715 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 SkASSERT(count > 0); 791 SkASSERT(count > 0);
678 792
679 state.fMatrixProc(state, bitmapXY, count, x, y); 793 state.fMatrixProc(state, bitmapXY, count, x, y);
680 794
681 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my); 795 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my);
682 796
683 // There are four formats possible: 797 // There are four formats possible:
684 // scale -vs- affine 798 // scale -vs- affine
685 // filter -vs- nofilter 799 // filter -vs- nofilter
686 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { 800 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
687 proc = state.fDoFilter ? check_scale_filter : check_scale_nofilter; 801 proc = state.fFilterQuality != kNone_BitmapFilter ? check_scale_filter : check_scale_nofilter;
688 } else { 802 } else {
689 proc = state.fDoFilter ? check_affine_filter : check_affine_nofilter; 803 proc = state.fFilterQuality != kNone_BitmapFilter ? check_affine_filter : check_affine_nofilter;
690 } 804 }
691 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height()); 805 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height());
692 } 806 }
693 807
694 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const { 808 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const {
695 return DebugMatrixProc; 809 return DebugMatrixProc;
696 } 810 }
697 811
698 #endif 812 #endif
699 813
(...skipping 14 matching lines...) Expand all
714 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { 828 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
715 size -= 4; // the shared Y (or YY) coordinate 829 size -= 4; // the shared Y (or YY) coordinate
716 if (size < 0) { 830 if (size < 0) {
717 size = 0; 831 size = 0;
718 } 832 }
719 size >>= 1; 833 size >>= 1;
720 } else { 834 } else {
721 size >>= 2; 835 size >>= 2;
722 } 836 }
723 837
724 if (fDoFilter) { 838 if (fFilterQuality != kNone_BitmapFilter) {
725 size >>= 1; 839 size >>= 1;
726 } 840 }
727 841
728 return size; 842 return size;
729 } 843 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698