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

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: reorganization of chooseProcs to be more readable and correct 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() {
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 fOrigBitmap.width() / fUnitInvMatrix.getScaleX() ,
reed1 2013/07/11 20:26:18 This / produces a float (SkScalar). We should use
112 fOrigBitmap.height() / fUnitInvMatrix.getScaleY( ));
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;
reed1 2013/07/11 20:26:18 Perhaps we should return now, since everything bel
125 } else if (!fOrigBitmap.hasMipMap()) {
126
127 // STEP 2: DOWNSAMPLE
128
129 // Check to see if the transformation matrix is scaling *down*.
130 // If so, automatically build mipmaps.
131
132 SkPoint v1, v2;
133
134 // conservatively estimate if the matrix is scaling down by seeing
135 // what its upper left 2x2 portion does to two unit vectors.
136
137 v1.fX = fUnitInvMatrix.getScaleX();
138 v1.fY = fUnitInvMatrix.getSkewY();
139
140 v2.fX = fUnitInvMatrix.getSkewX();
141 v2.fY = fUnitInvMatrix.getScaleY();
142
143 if (v1.fX * v1.fX + v1.fY * v1.fY > 1 ||
144 v2.fX * v2.fX + v2.fY * v2.fY > 1) {
145 fOrigBitmap.buildMipMap();
146 }
147
148 // Now that we've built the mipmaps and we know we're downsampling,
149 // downgrade to bilinear interpolation for the mip level.
150
151 fFilterQuality = kBilerp_BitmapFilter;
152 }
153
154 if (fOrigBitmap.hasMipMap() && fBitmap == &fOrigBitmap) {
155
156 // STEP 3: We've got mipmaps, let's choose the closest level as our rend er
157 // source and adjust the matrix accordingly.
158
159 int shift = fOrigBitmap.extractMipLevel(&fScaledBitmap,
160 SkScalarToFixed(fUnitInvMatrix.g etScaleX()),
161 SkScalarToFixed(fUnitInvMatrix.g etSkewY()));
162
163 if (shift > 0) {
164 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift);
165 fUnitInvMatrix.postScale(scale, scale);
166 fBitmap = &fScaledBitmap;
167 }
168 }
169 }
170
171 void SkBitmapProcState::endContext() {
172 SkDELETE(fBitmapFilter);
173 }
174
93 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { 175 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
94 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) { 176 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) {
95 return false; 177 return false;
96 } 178 }
97 179
98 const SkMatrix* m;
99 bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0; 180 bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0;
100 bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX && 181 bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX &&
101 SkShader::kClamp_TileMode == fTileModeY; 182 SkShader::kClamp_TileMode == fTileModeY;
102 183
103 if (clamp_clamp || trivial_matrix) { 184 fUnitInvMatrix = inv;
104 m = &inv; 185 if (!(clamp_clamp || trivial_matrix)) {
105 } else {
106 fUnitInvMatrix = inv;
107 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); 186 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height());
108 m = &fUnitInvMatrix;
109 } 187 }
110 188
111 fBitmap = &fOrigBitmap; 189 fBitmap = &fOrigBitmap;
112 if (fOrigBitmap.hasMipMap()) { 190
113 int shift = fOrigBitmap.extractMipLevel(&fMipBitmap, 191 // initialize our filter quality to the one requested by the caller.
114 SkScalarToFixed(m->getScaleX()), 192 // We may downgrade it later if we determine that we either don't need
115 SkScalarToFixed(m->getSkewY())); 193 // or can't provide as high a quality filtering as the user requested.
116 194
117 if (shift > 0) { 195 fFilterQuality = kNone_BitmapFilter;
118 if (m != &fUnitInvMatrix) { 196 if (paint.isFilterBitmap()) {
119 fUnitInvMatrix = *m; 197 if (paint.getFlags() & SkPaint::kHighQualityFilterBitmap_Flag) {
120 m = &fUnitInvMatrix; 198 fFilterQuality = kHQ_BitmapFilter;
121 } 199 } else {
122 200 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 } 201 }
129 } 202 }
130 203
131 // wack our matrix to exactly no-scale, if we're really close to begin with 204 // possiblyScaleImage will look to see if it can rescale the image as a
132 if (matrix_only_scale_translate(*m)) { 205 // preprocess; either by scaling up to the target size, or by selecting
206 // a nearby mipmap level. If it does, it will adjust the working
207 // matrix as well as the working bitmap. It may also adjust the filter
208 // quality to avoid re-filtering an already perfectly scaled image.
209
210 possiblyScaleImage();
211
212 // Now that all possible changes to the matrix have taken place, check
213 // to see if we're really close to a no-scale matrix. If so, explicitly
214 // set it to be so. Subsequent code may inspect this matrix to choose
215 // a faster path in this case.
216
217 if (matrix_only_scale_translate(fUnitInvMatrix)) {
133 SkMatrix forward; 218 SkMatrix forward;
134 if (m->invert(&forward)) { 219 if (fUnitInvMatrix.invert(&forward)) {
135 if (clamp_clamp ? just_trans_clamp(forward, *fBitmap) 220 if (clamp_clamp ? just_trans_clamp(forward, *fBitmap)
136 : just_trans_general(forward)) { 221 : just_trans_general(forward)) {
137 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX()); 222 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX());
138 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY()); 223 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY());
139 fUnitInvMatrix.setTranslate(tx, ty); 224 fUnitInvMatrix.setTranslate(tx, ty);
140 m = &fUnitInvMatrix; 225
141 // now the following code will sniff m, and decide to take the
142 // fast case (since m is purely translate).
143 } 226 }
144 } 227 }
145 } 228 }
146 229
147 // Below this point, we should never refer to the inv parameter, since we 230 // Below this point, we should never refer to the inv parameter, since we
148 // may be using a munged version for "our" inverse. 231 // may be using a munged version for "our" inverse.
149 232
150 fInvMatrix = m; 233 fInvMatrix = &fUnitInvMatrix;
151 fInvProc = m->getMapXYProc(); 234 fInvProc = fInvMatrix->getMapXYProc();
152 fInvType = m->getType(); 235 fInvType = fInvMatrix->getType();
153 fInvSx = SkScalarToFixed(m->getScaleX()); 236 fInvSx = SkScalarToFixed(fInvMatrix->getScaleX());
154 fInvSxFractionalInt = SkScalarToFractionalInt(m->getScaleX()); 237 fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix->getScaleX());
155 fInvKy = SkScalarToFixed(m->getSkewY()); 238 fInvKy = SkScalarToFixed(fInvMatrix->getSkewY());
156 fInvKyFractionalInt = SkScalarToFractionalInt(m->getSkewY()); 239 fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix->getSkewY());
157 240
158 fAlphaScale = SkAlpha255To256(paint.getAlpha()); 241 fAlphaScale = SkAlpha255To256(paint.getAlpha());
159 242
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; 243 fShaderProc32 = NULL;
170 fShaderProc16 = NULL; 244 fShaderProc16 = NULL;
171 fSampleProc32 = NULL; 245 fSampleProc32 = NULL;
172 fSampleProc16 = NULL; 246 fSampleProc16 = NULL;
173 247
248 if (fFilterQuality == kHQ_BitmapFilter) {
reed1 2013/07/11 20:26:18 nit: reverse the sides of the ==
249 // If this is still set, that means we wanted HQ sampling
250 // but couldn't do it as a preprocess. Let's try to install
251 // the scanline version of the HQ sampler. If that process fails,
252 // downgrade to bilerp.
253
254 fShaderProc32 = this->chooseBitmapFilterProc();
reed1 2013/07/11 20:26:18 A little tricky (in the future) here, as we will w
255 if (!fShaderProc32) {
256 fFilterQuality = kBilerp_BitmapFilter;
257 }
258 }
259
260 if (fFilterQuality == kBilerp_BitmapFilter) {
261 // Only try bilerp if the matrix is "interesting" and
262 // the image has a suitable size.
263
264 if (fInvType < SkMatrix::kTranslate_Mask ||
265 !valid_for_filtering(fBitmap->width() | fBitmap->height())) {
266 fFilterQuality = kNone_BitmapFilter;
267 }
268 }
269
270 // At this point, we know exactly what kind of sampling the per-scanline
271 // shader will perform.
272
174 fMatrixProc = this->chooseMatrixProc(trivial_matrix); 273 fMatrixProc = this->chooseMatrixProc(trivial_matrix);
175 if (NULL == fMatrixProc) { 274 if (NULL == fMatrixProc) {
176 return false; 275 return false;
177 } 276 }
178 277
179 /////////////////////////////////////////////////////////////////////// 278 ///////////////////////////////////////////////////////////////////////
180 279
181 int index = 0; 280 // 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 281 // still set to HQ by the time we get here, then we must have installed
183 index |= 1; 282 // 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 283
213 #if !SK_ARM_NEON_IS_ALWAYS 284 if (fFilterQuality < kHQ_BitmapFilter) {
214 static const SampleProc32 gSkBitmapProcStateSample32[] = { 285
215 S32_opaque_D32_nofilter_DXDY, 286 int index = 0;
216 S32_alpha_D32_nofilter_DXDY, 287 if (fAlphaScale < 256) { // note: this distinction is not used for D16
217 S32_opaque_D32_nofilter_DX, 288 index |= 1;
218 S32_alpha_D32_nofilter_DX, 289 }
219 S32_opaque_D32_filter_DXDY, 290 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
220 S32_alpha_D32_filter_DXDY, 291 index |= 2;
221 S32_opaque_D32_filter_DX, 292 }
222 S32_alpha_D32_filter_DX, 293 if (fFilterQuality != kNone_BitmapFilter) {
294 index |= 4;
295 }
296 // bits 3,4,5 encoding the source bitmap format
297 switch (fBitmap->config()) {
298 case SkBitmap::kARGB_8888_Config:
299 index |= 0;
300 break;
301 case SkBitmap::kRGB_565_Config:
302 index |= 8;
303 break;
304 case SkBitmap::kIndex8_Config:
305 index |= 16;
306 break;
307 case SkBitmap::kARGB_4444_Config:
308 index |= 24;
309 break;
310 case SkBitmap::kA8_Config:
311 index |= 32;
312 fPaintPMColor = SkPreMultiplyColor(paint.getColor());
313 break;
314 default:
315 return false;
316 }
223 317
224 S16_opaque_D32_nofilter_DXDY, 318 #if !SK_ARM_NEON_IS_ALWAYS
225 S16_alpha_D32_nofilter_DXDY, 319 static const SampleProc32 gSkBitmapProcStateSample32[] = {
226 S16_opaque_D32_nofilter_DX, 320 S32_opaque_D32_nofilter_DXDY,
227 S16_alpha_D32_nofilter_DX, 321 S32_alpha_D32_nofilter_DXDY,
228 S16_opaque_D32_filter_DXDY, 322 S32_opaque_D32_nofilter_DX,
229 S16_alpha_D32_filter_DXDY, 323 S32_alpha_D32_nofilter_DX,
230 S16_opaque_D32_filter_DX, 324 S32_opaque_D32_filter_DXDY,
231 S16_alpha_D32_filter_DX, 325 S32_alpha_D32_filter_DXDY,
326 S32_opaque_D32_filter_DX,
327 S32_alpha_D32_filter_DX,
232 328
233 SI8_opaque_D32_nofilter_DXDY, 329 S16_opaque_D32_nofilter_DXDY,
234 SI8_alpha_D32_nofilter_DXDY, 330 S16_alpha_D32_nofilter_DXDY,
235 SI8_opaque_D32_nofilter_DX, 331 S16_opaque_D32_nofilter_DX,
236 SI8_alpha_D32_nofilter_DX, 332 S16_alpha_D32_nofilter_DX,
237 SI8_opaque_D32_filter_DXDY, 333 S16_opaque_D32_filter_DXDY,
238 SI8_alpha_D32_filter_DXDY, 334 S16_alpha_D32_filter_DXDY,
239 SI8_opaque_D32_filter_DX, 335 S16_opaque_D32_filter_DX,
240 SI8_alpha_D32_filter_DX, 336 S16_alpha_D32_filter_DX,
241 337
242 S4444_opaque_D32_nofilter_DXDY, 338 SI8_opaque_D32_nofilter_DXDY,
243 S4444_alpha_D32_nofilter_DXDY, 339 SI8_alpha_D32_nofilter_DXDY,
244 S4444_opaque_D32_nofilter_DX, 340 SI8_opaque_D32_nofilter_DX,
245 S4444_alpha_D32_nofilter_DX, 341 SI8_alpha_D32_nofilter_DX,
246 S4444_opaque_D32_filter_DXDY, 342 SI8_opaque_D32_filter_DXDY,
247 S4444_alpha_D32_filter_DXDY, 343 SI8_alpha_D32_filter_DXDY,
248 S4444_opaque_D32_filter_DX, 344 SI8_opaque_D32_filter_DX,
249 S4444_alpha_D32_filter_DX, 345 SI8_alpha_D32_filter_DX,
250 346
251 // A8 treats alpha/opaque the same (equally efficient) 347 S4444_opaque_D32_nofilter_DXDY,
252 SA8_alpha_D32_nofilter_DXDY, 348 S4444_alpha_D32_nofilter_DXDY,
253 SA8_alpha_D32_nofilter_DXDY, 349 S4444_opaque_D32_nofilter_DX,
254 SA8_alpha_D32_nofilter_DX, 350 S4444_alpha_D32_nofilter_DX,
255 SA8_alpha_D32_nofilter_DX, 351 S4444_opaque_D32_filter_DXDY,
256 SA8_alpha_D32_filter_DXDY, 352 S4444_alpha_D32_filter_DXDY,
257 SA8_alpha_D32_filter_DXDY, 353 S4444_opaque_D32_filter_DX,
258 SA8_alpha_D32_filter_DX, 354 S4444_alpha_D32_filter_DX,
259 SA8_alpha_D32_filter_DX
260 };
261 355
262 static const SampleProc16 gSkBitmapProcStateSample16[] = { 356 // A8 treats alpha/opaque the same (equally efficient)
263 S32_D16_nofilter_DXDY, 357 SA8_alpha_D32_nofilter_DXDY,
264 S32_D16_nofilter_DX, 358 SA8_alpha_D32_nofilter_DXDY,
265 S32_D16_filter_DXDY, 359 SA8_alpha_D32_nofilter_DX,
266 S32_D16_filter_DX, 360 SA8_alpha_D32_nofilter_DX,
361 SA8_alpha_D32_filter_DXDY,
362 SA8_alpha_D32_filter_DXDY,
363 SA8_alpha_D32_filter_DX,
364 SA8_alpha_D32_filter_DX
365 };
267 366
268 S16_D16_nofilter_DXDY, 367 static const SampleProc16 gSkBitmapProcStateSample16[] = {
269 S16_D16_nofilter_DX, 368 S32_D16_nofilter_DXDY,
270 S16_D16_filter_DXDY, 369 S32_D16_nofilter_DX,
271 S16_D16_filter_DX, 370 S32_D16_filter_DXDY,
371 S32_D16_filter_DX,
272 372
273 SI8_D16_nofilter_DXDY, 373 S16_D16_nofilter_DXDY,
274 SI8_D16_nofilter_DX, 374 S16_D16_nofilter_DX,
275 SI8_D16_filter_DXDY, 375 S16_D16_filter_DXDY,
276 SI8_D16_filter_DX, 376 S16_D16_filter_DX,
277 377
278 // Don't support 4444 -> 565 378 SI8_D16_nofilter_DXDY,
279 NULL, NULL, NULL, NULL, 379 SI8_D16_nofilter_DX,
280 // Don't support A8 -> 565 380 SI8_D16_filter_DXDY,
281 NULL, NULL, NULL, NULL 381 SI8_D16_filter_DX,
282 };
283 #endif
284 382
285 fSampleProc32 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample32)[index]; 383 // Don't support 4444 -> 565
286 index >>= 1; // shift away any opaque/alpha distinction 384 NULL, NULL, NULL, NULL,
287 fSampleProc16 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample16)[index]; 385 // Don't support A8 -> 565
386 NULL, NULL, NULL, NULL
387 };
388 #endif
288 389
289 // our special-case shaderprocs 390 fSampleProc32 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample32)[index];
290 if (SK_ARM_NEON_WRAP(S16_D16_filter_DX) == fSampleProc16) { 391 index >>= 1; // shift away any opaque/alpha distinction
291 if (clamp_clamp) { 392 fSampleProc16 = SK_ARM_NEON_WRAP(gSkBitmapProcStateSample16)[index];
292 fShaderProc16 = SK_ARM_NEON_WRAP(Clamp_S16_D16_filter_DX_shaderproc) ; 393
293 } else if (SkShader::kRepeat_TileMode == fTileModeX && 394 // our special-case shaderprocs
294 SkShader::kRepeat_TileMode == fTileModeY) { 395 if (SK_ARM_NEON_WRAP(S16_D16_filter_DX) == fSampleProc16) {
295 fShaderProc16 = SK_ARM_NEON_WRAP(Repeat_S16_D16_filter_DX_shaderproc ); 396 if (clamp_clamp) {
397 fShaderProc16 = SK_ARM_NEON_WRAP(Clamp_S16_D16_filter_DX_shaderp roc);
398 } else if (SkShader::kRepeat_TileMode == fTileModeX &&
399 SkShader::kRepeat_TileMode == fTileModeY) {
400 fShaderProc16 = SK_ARM_NEON_WRAP(Repeat_S16_D16_filter_DX_shader proc);
401 }
402 } else if (SK_ARM_NEON_WRAP(SI8_opaque_D32_filter_DX) == fSampleProc32 & & clamp_clamp) {
403 fShaderProc32 = SK_ARM_NEON_WRAP(Clamp_SI8_opaque_D32_filter_DX_shad erproc);
296 } 404 }
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 405
301 if (NULL == fShaderProc32) { 406 if (NULL == fShaderProc32) {
302 fShaderProc32 = this->chooseShaderProc32(); 407 fShaderProc32 = this->chooseShaderProc32();
303 } 408 }
304
305 if (NULL == fShaderProc32) {
306 fShaderProc32 = this->chooseBitmapFilterProc(paint);
307 } 409 }
308 410
309 // see if our platform has any accelerated overrides 411 // see if our platform has any accelerated overrides
310 this->platformProcs(); 412 this->platformProcs();
311 413
312 return true; 414 return true;
313 } 415 }
314 416
315 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, 417 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s,
316 int x, int y, 418 int x, int y,
317 SkPMColor* SK_RESTRICT color s, 419 SkPMColor* SK_RESTRICT color s,
318 int count) { 420 int count) {
319 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); 421 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0);
320 SkASSERT(s.fInvKy == 0); 422 SkASSERT(s.fInvKy == 0);
321 SkASSERT(count > 0 && colors != NULL); 423 SkASSERT(count > 0 && colors != NULL);
322 SkASSERT(!s.fDoFilter); 424 SkASSERT(s.fFilterQuality == SkBitmapProcState::kNone_BitmapFilter);
reed1 2013/07/11 20:26:18 nit: reverse the sides of the ==
323 425
324 const int maxX = s.fBitmap->width() - 1; 426 const int maxX = s.fBitmap->width() - 1;
325 const int maxY = s.fBitmap->height() - 1; 427 const int maxY = s.fBitmap->height() - 1;
326 int ix = s.fFilterOneX + x; 428 int ix = s.fFilterOneX + x;
327 int iy = SkClampMax(s.fFilterOneY + y, maxY); 429 int iy = SkClampMax(s.fFilterOneY + y, maxY);
328 #ifdef SK_DEBUG 430 #ifdef SK_DEBUG
329 { 431 {
330 SkPoint pt; 432 SkPoint pt;
331 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 433 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
332 SkIntToScalar(y) + SK_ScalarHalf, &pt); 434 SkIntToScalar(y) + SK_ScalarHalf, &pt);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 return x; 488 return x;
387 } 489 }
388 490
389 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, 491 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s,
390 int x, int y, 492 int x, int y,
391 SkPMColor* SK_RESTRICT colo rs, 493 SkPMColor* SK_RESTRICT colo rs,
392 int count) { 494 int count) {
393 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); 495 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0);
394 SkASSERT(s.fInvKy == 0); 496 SkASSERT(s.fInvKy == 0);
395 SkASSERT(count > 0 && colors != NULL); 497 SkASSERT(count > 0 && colors != NULL);
396 SkASSERT(!s.fDoFilter); 498 SkASSERT(s.fFilterQuality == SkBitmapProcState::kNone_BitmapFilter);
reed1 2013/07/11 20:26:18 nit: reverse
397 499
398 const int stopX = s.fBitmap->width(); 500 const int stopX = s.fBitmap->width();
399 const int stopY = s.fBitmap->height(); 501 const int stopY = s.fBitmap->height();
400 int ix = s.fFilterOneX + x; 502 int ix = s.fFilterOneX + x;
401 int iy = sk_int_mod(s.fFilterOneY + y, stopY); 503 int iy = sk_int_mod(s.fFilterOneY + y, stopY);
402 #ifdef SK_DEBUG 504 #ifdef SK_DEBUG
403 { 505 {
404 SkPoint pt; 506 SkPoint pt;
405 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 507 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
406 SkIntToScalar(y) + SK_ScalarHalf, &pt); 508 SkIntToScalar(y) + SK_ScalarHalf, &pt);
(...skipping 25 matching lines...) Expand all
432 int count) { 534 int count) {
433 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0); 535 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0);
434 SkASSERT(s.fInvKy == 0); 536 SkASSERT(s.fInvKy == 0);
435 SkASSERT(count > 0 && colors != NULL); 537 SkASSERT(count > 0 && colors != NULL);
436 SkASSERT(1 == s.fBitmap->width()); 538 SkASSERT(1 == s.fBitmap->width());
437 539
438 int iY0; 540 int iY0;
439 int iY1 SK_INIT_TO_AVOID_WARNING; 541 int iY1 SK_INIT_TO_AVOID_WARNING;
440 int iSubY SK_INIT_TO_AVOID_WARNING; 542 int iSubY SK_INIT_TO_AVOID_WARNING;
441 543
442 if (s.fDoFilter) { 544 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) {
443 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); 545 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc();
444 uint32_t xy[2]; 546 uint32_t xy[2];
445 547
446 mproc(s, xy, 1, x, y); 548 mproc(s, xy, 1, x, y);
447 549
448 iY0 = xy[0] >> 18; 550 iY0 = xy[0] >> 18;
449 iY1 = xy[0] & 0x3FFF; 551 iY1 = xy[0] & 0x3FFF;
450 iSubY = (xy[0] >> 14) & 0xF; 552 iSubY = (xy[0] >> 14) & 0xF;
451 } else { 553 } else {
452 int yTemp; 554 int yTemp;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 } 615 }
514 616
515 SkASSERT(iY0 == iY2); 617 SkASSERT(iY0 == iY2);
516 } 618 }
517 #endif 619 #endif
518 } 620 }
519 621
520 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0); 622 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0);
521 SkPMColor color; 623 SkPMColor color;
522 624
523 if (s.fDoFilter) { 625 if (s.fFilterQuality != SkBitmapProcState::kNone_BitmapFilter) {
524 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1); 626 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1);
525 627
526 if (s.fAlphaScale < 256) { 628 if (s.fAlphaScale < 256) {
527 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale); 629 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale);
528 } else { 630 } else {
529 Filter_32_opaque(iSubY, *row0, *row1, &color); 631 Filter_32_opaque(iSubY, *row0, *row1, &color);
530 } 632 }
531 } else { 633 } else {
532 if (s.fAlphaScale < 256) { 634 if (s.fAlphaScale < 256) {
533 color = SkAlphaMulQ(*row0, s.fAlphaScale); 635 color = SkAlphaMulQ(*row0, s.fAlphaScale);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 671
570 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { 672 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() {
571 673
572 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) { 674 if (SkBitmap::kARGB_8888_Config != fBitmap->config()) {
573 return NULL; 675 return NULL;
574 } 676 }
575 677
576 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask; 678 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask;
577 679
578 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) { 680 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) {
579 if (!fDoFilter && fInvType <= SkMatrix::kTranslate_Mask && !this->setupF orTranslate()) { 681 if (fFilterQuality == kNone_BitmapFilter &&
682 fInvType <= SkMatrix::kTranslate_Mask &&
683 !this->setupForTranslate()) {
580 return DoNothing_shaderproc; 684 return DoNothing_shaderproc;
581 } 685 }
582 return S32_D32_constX_shaderproc; 686 return S32_D32_constX_shaderproc;
583 } 687 }
584 688
585 if (fAlphaScale < 256) { 689 if (fAlphaScale < 256) {
586 return NULL; 690 return NULL;
587 } 691 }
588 if (fInvType > SkMatrix::kTranslate_Mask) { 692 if (fInvType > SkMatrix::kTranslate_Mask) {
589 return NULL; 693 return NULL;
590 } 694 }
591 if (fDoFilter) { 695 if (fFilterQuality != kNone_BitmapFilter) {
592 return NULL; 696 return NULL;
593 } 697 }
594 698
595 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX; 699 SkShader::TileMode tx = (SkShader::TileMode)fTileModeX;
596 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY; 700 SkShader::TileMode ty = (SkShader::TileMode)fTileModeY;
597 701
598 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) { 702 if (SkShader::kClamp_TileMode == tx && SkShader::kClamp_TileMode == ty) {
599 if (this->setupForTranslate()) { 703 if (this->setupForTranslate()) {
600 return Clamp_S32_D32_nofilter_trans_shaderproc; 704 return Clamp_S32_D32_nofilter_trans_shaderproc;
601 } 705 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 SkASSERT(count > 0); 781 SkASSERT(count > 0);
678 782
679 state.fMatrixProc(state, bitmapXY, count, x, y); 783 state.fMatrixProc(state, bitmapXY, count, x, y);
680 784
681 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my); 785 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my);
682 786
683 // There are four formats possible: 787 // There are four formats possible:
684 // scale -vs- affine 788 // scale -vs- affine
685 // filter -vs- nofilter 789 // filter -vs- nofilter
686 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { 790 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
687 proc = state.fDoFilter ? check_scale_filter : check_scale_nofilter; 791 proc = state.fFilterQuality != kNone_BitmapFilter ? check_scale_filter : check_scale_nofilter;
688 } else { 792 } else {
689 proc = state.fDoFilter ? check_affine_filter : check_affine_nofilter; 793 proc = state.fFilterQuality != kNone_BitmapFilter ? check_affine_filter : check_affine_nofilter;
690 } 794 }
691 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height()); 795 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height());
692 } 796 }
693 797
694 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const { 798 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const {
695 return DebugMatrixProc; 799 return DebugMatrixProc;
696 } 800 }
697 801
698 #endif 802 #endif
699 803
(...skipping 14 matching lines...) Expand all
714 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { 818 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
715 size -= 4; // the shared Y (or YY) coordinate 819 size -= 4; // the shared Y (or YY) coordinate
716 if (size < 0) { 820 if (size < 0) {
717 size = 0; 821 size = 0;
718 } 822 }
719 size >>= 1; 823 size >>= 1;
720 } else { 824 } else {
721 size >>= 2; 825 size >>= 2;
722 } 826 }
723 827
724 if (fDoFilter) { 828 if (fFilterQuality != kNone_BitmapFilter) {
725 size >>= 1; 829 size >>= 1;
726 } 830 }
727 831
728 return size; 832 return size;
729 } 833 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698