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

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

Issue 1158273007: switch bitmapshader internals over to pixmap (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix neon/mips to use pixmpas Created 5 years, 6 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
« no previous file with comments | « src/core/SkBitmapProcState.h ('k') | src/core/SkBitmapProcState_matrix.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 // true iff the matrix contains, at most, scale and translate elements 48 // true iff the matrix contains, at most, scale and translate elements
49 static bool matrix_only_scale_translate(const SkMatrix& m) { 49 static bool matrix_only_scale_translate(const SkMatrix& m) {
50 return m.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask); 50 return m.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask);
51 } 51 }
52 52
53 /** 53 /**
54 * For the purposes of drawing bitmaps, if a matrix is "almost" translate 54 * For the purposes of drawing bitmaps, if a matrix is "almost" translate
55 * go ahead and treat it as if it were, so that subsequent code can go fast. 55 * go ahead and treat it as if it were, so that subsequent code can go fast.
56 */ 56 */
57 static bool just_trans_clamp(const SkMatrix& matrix, const SkBitmap& bitmap) { 57 static bool just_trans_clamp(const SkMatrix& matrix, const SkPixmap& pixmap) {
58 SkASSERT(matrix_only_scale_translate(matrix)); 58 SkASSERT(matrix_only_scale_translate(matrix));
59 59
60 if (matrix.getType() & SkMatrix::kScale_Mask) { 60 if (matrix.getType() & SkMatrix::kScale_Mask) {
61 SkRect src, dst; 61 SkRect dst;
62 bitmap.getBounds(&src); 62 SkRect src = SkRect::Make(pixmap.bounds());
63 63
64 // Can't call mapRect(), since that will fix up inverted rectangles, 64 // Can't call mapRect(), since that will fix up inverted rectangles,
65 // e.g. when scale is negative, and we don't want to return true for 65 // e.g. when scale is negative, and we don't want to return true for
66 // those. 66 // those.
67 matrix.mapPoints(SkTCast<SkPoint*>(&dst), 67 matrix.mapPoints(SkTCast<SkPoint*>(&dst),
68 SkTCast<const SkPoint*>(&src), 68 SkTCast<const SkPoint*>(&src),
69 2); 69 2);
70 70
71 // Now round all 4 edges to device space, and then compare the device 71 // Now round all 4 edges to device space, and then compare the device
72 // width/height to the original. Note: we must map all 4 and subtract 72 // width/height to the original. Note: we must map all 4 and subtract
73 // rather than map the "width" and compare, since we care about the 73 // rather than map the "width" and compare, since we care about the
74 // phase (in pixel space) that any translate in the matrix might impart. 74 // phase (in pixel space) that any translate in the matrix might impart.
75 SkIRect idst; 75 SkIRect idst;
76 dst.round(&idst); 76 dst.round(&idst);
77 return idst.width() == bitmap.width() && idst.height() == bitmap.height( ); 77 return idst.width() == pixmap.width() && idst.height() == pixmap.height( );
78 } 78 }
79 // if we got here, we're either kTranslate_Mask or identity 79 // if we got here, we're either kTranslate_Mask or identity
80 return true; 80 return true;
81 } 81 }
82 82
83 static bool just_trans_general(const SkMatrix& matrix) { 83 static bool just_trans_general(const SkMatrix& matrix) {
84 SkASSERT(matrix_only_scale_translate(matrix)); 84 SkASSERT(matrix_only_scale_translate(matrix));
85 85
86 if (matrix.getType() & SkMatrix::kScale_Mask) { 86 if (matrix.getType() & SkMatrix::kScale_Mask) {
87 const SkScalar tol = SK_Scalar1 / 32768; 87 const SkScalar tol = SK_Scalar1 / 32768;
(...skipping 19 matching lines...) Expand all
107 * Analyze filter-quality and matrix, and decide how to implement that. 107 * Analyze filter-quality and matrix, and decide how to implement that.
108 * 108 *
109 * In general, we cascade down the request level [ High ... None ] 109 * In general, we cascade down the request level [ High ... None ]
110 * - for a given level, if we can fulfill it, fine, else 110 * - for a given level, if we can fulfill it, fine, else
111 * - else we downgrade to the next lower level and try again. 111 * - else we downgrade to the next lower level and try again.
112 * We can always fulfill requests for Low and None 112 * We can always fulfill requests for Low and None
113 * - sometimes we will "ignore" Low and give None, but this is likely a legacy perf hack 113 * - sometimes we will "ignore" Low and give None, but this is likely a legacy perf hack
114 * and may be removed. 114 * and may be removed.
115 */ 115 */
116 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { 116 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
117 fBitmap = NULL; 117 fPixmap.reset();
118 fInvMatrix = inv; 118 fInvMatrix = inv;
119 fFilterLevel = paint.getFilterQuality(); 119 fFilterLevel = paint.getFilterQuality();
120 120
121 SkDefaultBitmapController controller; 121 SkDefaultBitmapController controller;
122 fBMState = controller.requestBitmap(fOrigBitmap, inv, paint.getFilterQuality (), 122 fBMState = controller.requestBitmap(fOrigBitmap, inv, paint.getFilterQuality (),
123 fBMStateStorage.get(), fBMStateStorage.s ize()); 123 fBMStateStorage.get(), fBMStateStorage.s ize());
124 if (NULL == fBMState) { 124 // Note : we allow the controller to return an empty (zero-dimension) result . Should we?
125 if (NULL == fBMState || fBMState->pixmap().info().isEmpty()) {
125 return false; 126 return false;
126 } 127 }
127 fBitmap = &fBMState->lockedBitmap(); 128 fPixmap = fBMState->pixmap();
128 fInvMatrix = fBMState->invMatrix(); 129 fInvMatrix = fBMState->invMatrix();
129 fFilterLevel = fBMState->quality(); 130 fFilterLevel = fBMState->quality();
130 SkASSERT(fBitmap->getPixels()); 131 SkASSERT(fPixmap.addr());
131 132
132 bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; 133 bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0;
133 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && 134 bool clampClamp = SkShader::kClamp_TileMode == fTileModeX &&
134 SkShader::kClamp_TileMode == fTileModeY; 135 SkShader::kClamp_TileMode == fTileModeY;
135 136
136 // Most of the scanline procs deal with "unit" texture coordinates, as this 137 // Most of the scanline procs deal with "unit" texture coordinates, as this
137 // makes it easy to perform tiling modes (repeat = (x & 0xFFFF)). To generat e 138 // makes it easy to perform tiling modes (repeat = (x & 0xFFFF)). To generat e
138 // those, we divide the matrix by its dimensions here. 139 // those, we divide the matrix by its dimensions here.
139 // 140 //
140 // We don't do this if we're either trivial (can ignore the matrix) or clamp ing 141 // We don't do this if we're either trivial (can ignore the matrix) or clamp ing
141 // in both X and Y since clamping to width,height is just as easy as to 0xFF FF. 142 // in both X and Y since clamping to width,height is just as easy as to 0xFF FF.
142 143
143 if (!(clampClamp || trivialMatrix)) { 144 if (!(clampClamp || trivialMatrix)) {
144 fInvMatrix.postIDiv(fBitmap->width(), fBitmap->height()); 145 fInvMatrix.postIDiv(fPixmap.width(), fPixmap.height());
145 } 146 }
146 147
147 // Now that all possible changes to the matrix have taken place, check 148 // Now that all possible changes to the matrix have taken place, check
148 // to see if we're really close to a no-scale matrix. If so, explicitly 149 // to see if we're really close to a no-scale matrix. If so, explicitly
149 // set it to be so. Subsequent code may inspect this matrix to choose 150 // set it to be so. Subsequent code may inspect this matrix to choose
150 // a faster path in this case. 151 // a faster path in this case.
151 152
152 // This code will only execute if the matrix has some scale component; 153 // This code will only execute if the matrix has some scale component;
153 // if it's already pure translate then we won't do this inversion. 154 // if it's already pure translate then we won't do this inversion.
154 155
155 if (matrix_only_scale_translate(fInvMatrix)) { 156 if (matrix_only_scale_translate(fInvMatrix)) {
156 SkMatrix forward; 157 SkMatrix forward;
157 if (fInvMatrix.invert(&forward)) { 158 if (fInvMatrix.invert(&forward)) {
158 if (clampClamp ? just_trans_clamp(forward, *fBitmap) 159 if (clampClamp ? just_trans_clamp(forward, fPixmap)
159 : just_trans_general(forward)) { 160 : just_trans_general(forward)) {
160 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX()); 161 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX());
161 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY()); 162 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY());
162 fInvMatrix.setTranslate(tx, ty); 163 fInvMatrix.setTranslate(tx, ty);
163 } 164 }
164 } 165 }
165 } 166 }
166 167
167 fInvProc = fInvMatrix.getMapXYProc(); 168 fInvProc = fInvMatrix.getMapXYProc();
168 fInvType = fInvMatrix.getType(); 169 fInvType = fInvMatrix.getType();
(...skipping 12 matching lines...) Expand all
181 // recompute the triviality of the matrix here because we may have 182 // recompute the triviality of the matrix here because we may have
182 // changed it! 183 // changed it!
183 184
184 trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; 185 trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0;
185 186
186 if (kLow_SkFilterQuality == fFilterLevel) { 187 if (kLow_SkFilterQuality == fFilterLevel) {
187 // Only try bilerp if the matrix is "interesting" and 188 // Only try bilerp if the matrix is "interesting" and
188 // the image has a suitable size. 189 // the image has a suitable size.
189 190
190 if (fInvType <= SkMatrix::kTranslate_Mask || 191 if (fInvType <= SkMatrix::kTranslate_Mask ||
191 !valid_for_filtering(fBitmap->width() | fBitmap->height())) 192 !valid_for_filtering(fPixmap.width() | fPixmap.height()))
192 { 193 {
193 fFilterLevel = kNone_SkFilterQuality; 194 fFilterLevel = kNone_SkFilterQuality;
194 } 195 }
195 } 196 }
196 197
197 return this->chooseScanlineProcs(trivialMatrix, clampClamp, paint); 198 return this->chooseScanlineProcs(trivialMatrix, clampClamp, paint);
198 } 199 }
199 200
200 bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp, 201 bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp,
201 const SkPaint& paint) { 202 const SkPaint& paint) {
202 fMatrixProc = this->chooseMatrixProc(trivialMatrix); 203 fMatrixProc = this->chooseMatrixProc(trivialMatrix);
203 // TODO(dominikg): SkASSERT(fMatrixProc) instead? chooseMatrixProc never ret urns NULL. 204 // TODO(dominikg): SkASSERT(fMatrixProc) instead? chooseMatrixProc never ret urns NULL.
204 if (NULL == fMatrixProc) { 205 if (NULL == fMatrixProc) {
205 return false; 206 return false;
206 } 207 }
207 208
208 /////////////////////////////////////////////////////////////////////// 209 ///////////////////////////////////////////////////////////////////////
209 210
210 const SkAlphaType at = fBitmap->alphaType(); 211 const SkAlphaType at = fPixmap.alphaType();
211 212
212 // No need to do this if we're doing HQ sampling; if filter quality is 213 // No need to do this if we're doing HQ sampling; if filter quality is
213 // still set to HQ by the time we get here, then we must have installed 214 // still set to HQ by the time we get here, then we must have installed
214 // the shader procs above and can skip all this. 215 // the shader procs above and can skip all this.
215 216
216 if (fFilterLevel < kHigh_SkFilterQuality) { 217 if (fFilterLevel < kHigh_SkFilterQuality) {
217 218
218 int index = 0; 219 int index = 0;
219 if (fAlphaScale < 256) { // note: this distinction is not used for D16 220 if (fAlphaScale < 256) { // note: this distinction is not used for D16
220 index |= 1; 221 index |= 1;
221 } 222 }
222 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { 223 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
223 index |= 2; 224 index |= 2;
224 } 225 }
225 if (fFilterLevel > kNone_SkFilterQuality) { 226 if (fFilterLevel > kNone_SkFilterQuality) {
226 index |= 4; 227 index |= 4;
227 } 228 }
228 // bits 3,4,5 encoding the source bitmap format 229 // bits 3,4,5 encoding the source bitmap format
229 switch (fBitmap->colorType()) { 230 switch (fPixmap.colorType()) {
230 case kN32_SkColorType: 231 case kN32_SkColorType:
231 if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) { 232 if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) {
232 return false; 233 return false;
233 } 234 }
234 index |= 0; 235 index |= 0;
235 break; 236 break;
236 case kRGB_565_SkColorType: 237 case kRGB_565_SkColorType:
237 index |= 8; 238 index |= 8;
238 break; 239 break;
239 case kIndex_8_SkColorType: 240 case kIndex_8_SkColorType:
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 377
377 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, 378 static void Clamp_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s,
378 int x, int y, 379 int x, int y,
379 SkPMColor* SK_RESTRICT color s, 380 SkPMColor* SK_RESTRICT color s,
380 int count) { 381 int count) {
381 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); 382 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0);
382 SkASSERT(s.fInvKy == 0); 383 SkASSERT(s.fInvKy == 0);
383 SkASSERT(count > 0 && colors != NULL); 384 SkASSERT(count > 0 && colors != NULL);
384 SkASSERT(kNone_SkFilterQuality == s.fFilterLevel); 385 SkASSERT(kNone_SkFilterQuality == s.fFilterLevel);
385 386
386 const int maxX = s.fBitmap->width() - 1; 387 const int maxX = s.fPixmap.width() - 1;
387 const int maxY = s.fBitmap->height() - 1; 388 const int maxY = s.fPixmap.height() - 1;
388 int ix = s.fFilterOneX + x; 389 int ix = s.fFilterOneX + x;
389 int iy = SkClampMax(s.fFilterOneY + y, maxY); 390 int iy = SkClampMax(s.fFilterOneY + y, maxY);
390 #ifdef SK_DEBUG 391 #ifdef SK_DEBUG
391 { 392 {
392 SkPoint pt; 393 SkPoint pt;
393 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 394 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
394 SkIntToScalar(y) + SK_ScalarHalf, &pt); 395 SkIntToScalar(y) + SK_ScalarHalf, &pt);
395 int iy2 = SkClampMax(SkScalarFloorToInt(pt.fY), maxY); 396 int iy2 = SkClampMax(SkScalarFloorToInt(pt.fY), maxY);
396 int ix2 = SkScalarFloorToInt(pt.fX); 397 int ix2 = SkScalarFloorToInt(pt.fX);
397 398
398 SkASSERT(iy == iy2); 399 SkASSERT(iy == iy2);
399 SkASSERT(ix == ix2); 400 SkASSERT(ix == ix2);
400 } 401 }
401 #endif 402 #endif
402 const SkPMColor* row = s.fBitmap->getAddr32(0, iy); 403 const SkPMColor* row = s.fPixmap.addr32(0, iy);
403 404
404 // clamp to the left 405 // clamp to the left
405 if (ix < 0) { 406 if (ix < 0) {
406 int n = SkMin32(-ix, count); 407 int n = SkMin32(-ix, count);
407 sk_memset32(colors, row[0], n); 408 sk_memset32(colors, row[0], n);
408 count -= n; 409 count -= n;
409 if (0 == count) { 410 if (0 == count) {
410 return; 411 return;
411 } 412 }
412 colors += n; 413 colors += n;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 451
451 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s, 452 static void Repeat_S32_D32_nofilter_trans_shaderproc(const SkBitmapProcState& s,
452 int x, int y, 453 int x, int y,
453 SkPMColor* SK_RESTRICT colo rs, 454 SkPMColor* SK_RESTRICT colo rs,
454 int count) { 455 int count) {
455 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0); 456 SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0);
456 SkASSERT(s.fInvKy == 0); 457 SkASSERT(s.fInvKy == 0);
457 SkASSERT(count > 0 && colors != NULL); 458 SkASSERT(count > 0 && colors != NULL);
458 SkASSERT(kNone_SkFilterQuality == s.fFilterLevel); 459 SkASSERT(kNone_SkFilterQuality == s.fFilterLevel);
459 460
460 const int stopX = s.fBitmap->width(); 461 const int stopX = s.fPixmap.width();
461 const int stopY = s.fBitmap->height(); 462 const int stopY = s.fPixmap.height();
462 int ix = s.fFilterOneX + x; 463 int ix = s.fFilterOneX + x;
463 int iy = sk_int_mod(s.fFilterOneY + y, stopY); 464 int iy = sk_int_mod(s.fFilterOneY + y, stopY);
464 #ifdef SK_DEBUG 465 #ifdef SK_DEBUG
465 { 466 {
466 SkPoint pt; 467 SkPoint pt;
467 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 468 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
468 SkIntToScalar(y) + SK_ScalarHalf, &pt); 469 SkIntToScalar(y) + SK_ScalarHalf, &pt);
469 int iy2 = sk_int_mod(SkScalarFloorToInt(pt.fY), stopY); 470 int iy2 = sk_int_mod(SkScalarFloorToInt(pt.fY), stopY);
470 int ix2 = SkScalarFloorToInt(pt.fX); 471 int ix2 = SkScalarFloorToInt(pt.fX);
471 472
472 SkASSERT(iy == iy2); 473 SkASSERT(iy == iy2);
473 SkASSERT(ix == ix2); 474 SkASSERT(ix == ix2);
474 } 475 }
475 #endif 476 #endif
476 const SkPMColor* row = s.fBitmap->getAddr32(0, iy); 477 const SkPMColor* row = s.fPixmap.addr32(0, iy);
477 478
478 ix = sk_int_mod(ix, stopX); 479 ix = sk_int_mod(ix, stopX);
479 for (;;) { 480 for (;;) {
480 int n = SkMin32(stopX - ix, count); 481 int n = SkMin32(stopX - ix, count);
481 memcpy(colors, row + ix, n * sizeof(SkPMColor)); 482 memcpy(colors, row + ix, n * sizeof(SkPMColor));
482 count -= n; 483 count -= n;
483 if (0 == count) { 484 if (0 == count) {
484 return; 485 return;
485 } 486 }
486 colors += n; 487 colors += n;
487 ix = 0; 488 ix = 0;
488 } 489 }
489 } 490 }
490 491
491 static void S32_D32_constX_shaderproc(const SkBitmapProcState& s, 492 static void S32_D32_constX_shaderproc(const SkBitmapProcState& s,
492 int x, int y, 493 int x, int y,
493 SkPMColor* SK_RESTRICT colors, 494 SkPMColor* SK_RESTRICT colors,
494 int count) { 495 int count) {
495 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0); 496 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) == 0);
496 SkASSERT(s.fInvKy == 0); 497 SkASSERT(s.fInvKy == 0);
497 SkASSERT(count > 0 && colors != NULL); 498 SkASSERT(count > 0 && colors != NULL);
498 SkASSERT(1 == s.fBitmap->width()); 499 SkASSERT(1 == s.fPixmap.width());
499 500
500 int iY0; 501 int iY0;
501 int iY1 SK_INIT_TO_AVOID_WARNING; 502 int iY1 SK_INIT_TO_AVOID_WARNING;
502 int iSubY SK_INIT_TO_AVOID_WARNING; 503 int iSubY SK_INIT_TO_AVOID_WARNING;
503 504
504 if (kNone_SkFilterQuality != s.fFilterLevel) { 505 if (kNone_SkFilterQuality != s.fFilterLevel) {
505 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc(); 506 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc();
506 uint32_t xy[2]; 507 uint32_t xy[2];
507 508
508 mproc(s, xy, 1, x, y); 509 mproc(s, xy, 1, x, y);
509 510
510 iY0 = xy[0] >> 18; 511 iY0 = xy[0] >> 18;
511 iY1 = xy[0] & 0x3FFF; 512 iY1 = xy[0] & 0x3FFF;
512 iSubY = (xy[0] >> 14) & 0xF; 513 iSubY = (xy[0] >> 14) & 0xF;
513 } else { 514 } else {
514 int yTemp; 515 int yTemp;
515 516
516 if (s.fInvType > SkMatrix::kTranslate_Mask) { 517 if (s.fInvType > SkMatrix::kTranslate_Mask) {
517 SkPoint pt; 518 SkPoint pt;
518 s.fInvProc(s.fInvMatrix, 519 s.fInvProc(s.fInvMatrix,
519 SkIntToScalar(x) + SK_ScalarHalf, 520 SkIntToScalar(x) + SK_ScalarHalf,
520 SkIntToScalar(y) + SK_ScalarHalf, 521 SkIntToScalar(y) + SK_ScalarHalf,
521 &pt); 522 &pt);
522 // When the matrix has a scale component the setup code in 523 // When the matrix has a scale component the setup code in
523 // chooseProcs multiples the inverse matrix by the inverse of the 524 // chooseProcs multiples the inverse matrix by the inverse of the
524 // bitmap's width and height. Since this method is going to do 525 // bitmap's width and height. Since this method is going to do
525 // its own tiling and sampling we need to undo that here. 526 // its own tiling and sampling we need to undo that here.
526 if (SkShader::kClamp_TileMode != s.fTileModeX || 527 if (SkShader::kClamp_TileMode != s.fTileModeX ||
527 SkShader::kClamp_TileMode != s.fTileModeY) { 528 SkShader::kClamp_TileMode != s.fTileModeY) {
528 yTemp = SkScalarFloorToInt(pt.fY * s.fBitmap->height()); 529 yTemp = SkScalarFloorToInt(pt.fY * s.fPixmap.height());
529 } else { 530 } else {
530 yTemp = SkScalarFloorToInt(pt.fY); 531 yTemp = SkScalarFloorToInt(pt.fY);
531 } 532 }
532 } else { 533 } else {
533 yTemp = s.fFilterOneY + y; 534 yTemp = s.fFilterOneY + y;
534 } 535 }
535 536
536 const int stopY = s.fBitmap->height(); 537 const int stopY = s.fPixmap.height();
537 switch (s.fTileModeY) { 538 switch (s.fTileModeY) {
538 case SkShader::kClamp_TileMode: 539 case SkShader::kClamp_TileMode:
539 iY0 = SkClampMax(yTemp, stopY-1); 540 iY0 = SkClampMax(yTemp, stopY-1);
540 break; 541 break;
541 case SkShader::kRepeat_TileMode: 542 case SkShader::kRepeat_TileMode:
542 iY0 = sk_int_mod(yTemp, stopY); 543 iY0 = sk_int_mod(yTemp, stopY);
543 break; 544 break;
544 case SkShader::kMirror_TileMode: 545 case SkShader::kMirror_TileMode:
545 default: 546 default:
546 iY0 = sk_int_mirror(yTemp, stopY); 547 iY0 = sk_int_mirror(yTemp, stopY);
547 break; 548 break;
548 } 549 }
549 550
550 #ifdef SK_DEBUG 551 #ifdef SK_DEBUG
551 { 552 {
552 SkPoint pt; 553 SkPoint pt;
553 s.fInvProc(s.fInvMatrix, 554 s.fInvProc(s.fInvMatrix,
554 SkIntToScalar(x) + SK_ScalarHalf, 555 SkIntToScalar(x) + SK_ScalarHalf,
555 SkIntToScalar(y) + SK_ScalarHalf, 556 SkIntToScalar(y) + SK_ScalarHalf,
556 &pt); 557 &pt);
557 if (s.fInvType > SkMatrix::kTranslate_Mask && 558 if (s.fInvType > SkMatrix::kTranslate_Mask &&
558 (SkShader::kClamp_TileMode != s.fTileModeX || 559 (SkShader::kClamp_TileMode != s.fTileModeX ||
559 SkShader::kClamp_TileMode != s.fTileModeY)) { 560 SkShader::kClamp_TileMode != s.fTileModeY)) {
560 pt.fY *= s.fBitmap->height(); 561 pt.fY *= s.fPixmap.height();
561 } 562 }
562 int iY2; 563 int iY2;
563 564
564 switch (s.fTileModeY) { 565 switch (s.fTileModeY) {
565 case SkShader::kClamp_TileMode: 566 case SkShader::kClamp_TileMode:
566 iY2 = SkClampMax(SkScalarFloorToInt(pt.fY), stopY-1); 567 iY2 = SkClampMax(SkScalarFloorToInt(pt.fY), stopY-1);
567 break; 568 break;
568 case SkShader::kRepeat_TileMode: 569 case SkShader::kRepeat_TileMode:
569 iY2 = sk_int_mod(SkScalarFloorToInt(pt.fY), stopY); 570 iY2 = sk_int_mod(SkScalarFloorToInt(pt.fY), stopY);
570 break; 571 break;
571 case SkShader::kMirror_TileMode: 572 case SkShader::kMirror_TileMode:
572 default: 573 default:
573 iY2 = sk_int_mirror(SkScalarFloorToInt(pt.fY), stopY); 574 iY2 = sk_int_mirror(SkScalarFloorToInt(pt.fY), stopY);
574 break; 575 break;
575 } 576 }
576 577
577 SkASSERT(iY0 == iY2); 578 SkASSERT(iY0 == iY2);
578 } 579 }
579 #endif 580 #endif
580 } 581 }
581 582
582 const SkPMColor* row0 = s.fBitmap->getAddr32(0, iY0); 583 const SkPMColor* row0 = s.fPixmap.addr32(0, iY0);
583 SkPMColor color; 584 SkPMColor color;
584 585
585 if (kNone_SkFilterQuality != s.fFilterLevel) { 586 if (kNone_SkFilterQuality != s.fFilterLevel) {
586 const SkPMColor* row1 = s.fBitmap->getAddr32(0, iY1); 587 const SkPMColor* row1 = s.fPixmap.addr32(0, iY1);
587 588
588 if (s.fAlphaScale < 256) { 589 if (s.fAlphaScale < 256) {
589 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale); 590 Filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale);
590 } else { 591 } else {
591 Filter_32_opaque(iSubY, *row0, *row1, &color); 592 Filter_32_opaque(iSubY, *row0, *row1, &color);
592 } 593 }
593 } else { 594 } else {
594 if (s.fAlphaScale < 256) { 595 if (s.fAlphaScale < 256) {
595 color = SkAlphaMulQ(*row0, s.fAlphaScale); 596 color = SkAlphaMulQ(*row0, s.fAlphaScale);
596 } else { 597 } else {
(...skipping 27 matching lines...) Expand all
624 // Since we know we're not filtered, we re-purpose these fields allow 625 // Since we know we're not filtered, we re-purpose these fields allow
625 // us to go from device -> src coordinates w/ just an integer add, 626 // us to go from device -> src coordinates w/ just an integer add,
626 // rather than running through the inverse-matrix 627 // rather than running through the inverse-matrix
627 fFilterOneX = SkScalarFloorToInt(pt.fX); 628 fFilterOneX = SkScalarFloorToInt(pt.fX);
628 fFilterOneY = SkScalarFloorToInt(pt.fY); 629 fFilterOneY = SkScalarFloorToInt(pt.fY);
629 return true; 630 return true;
630 } 631 }
631 632
632 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() { 633 SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() {
633 634
634 if (kN32_SkColorType != fBitmap->colorType()) { 635 if (kN32_SkColorType != fPixmap.colorType()) {
635 return NULL; 636 return NULL;
636 } 637 }
637 638
638 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask; 639 static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_M ask;
639 640
640 if (1 == fBitmap->width() && 0 == (fInvType & ~kMask)) { 641 if (1 == fPixmap.width() && 0 == (fInvType & ~kMask)) {
641 if (kNone_SkFilterQuality == fFilterLevel && 642 if (kNone_SkFilterQuality == fFilterLevel &&
642 fInvType <= SkMatrix::kTranslate_Mask && 643 fInvType <= SkMatrix::kTranslate_Mask &&
643 !this->setupForTranslate()) { 644 !this->setupForTranslate()) {
644 return DoNothing_shaderproc; 645 return DoNothing_shaderproc;
645 } 646 }
646 return S32_D32_constX_shaderproc; 647 return S32_D32_constX_shaderproc;
647 } 648 }
648 649
649 if (fAlphaScale < 256) { 650 if (fAlphaScale < 256) {
650 return NULL; 651 return NULL;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my); 746 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my);
746 747
747 // There are four formats possible: 748 // There are four formats possible:
748 // scale -vs- affine 749 // scale -vs- affine
749 // filter -vs- nofilter 750 // filter -vs- nofilter
750 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { 751 if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
751 proc = state.fFilterLevel != kNone_SkFilterQuality ? check_scale_filter : check_scale_nofilter; 752 proc = state.fFilterLevel != kNone_SkFilterQuality ? check_scale_filter : check_scale_nofilter;
752 } else { 753 } else {
753 proc = state.fFilterLevel != kNone_SkFilterQuality ? check_affine_filter : check_affine_nofilter; 754 proc = state.fFilterLevel != kNone_SkFilterQuality ? check_affine_filter : check_affine_nofilter;
754 } 755 }
755 proc(bitmapXY, count, state.fBitmap->width(), state.fBitmap->height()); 756 proc(bitmapXY, count, state.fPixmap.width(), state.fPixmap.height());
756 } 757 }
757 758
758 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const { 759 SkBitmapProcState::MatrixProc SkBitmapProcState::getMatrixProc() const {
759 return DebugMatrixProc; 760 return DebugMatrixProc;
760 } 761 }
761 762
762 #endif 763 #endif
763 764
764 /////////////////////////////////////////////////////////////////////////////// 765 ///////////////////////////////////////////////////////////////////////////////
765 /* 766 /*
(...skipping 26 matching lines...) Expand all
792 return size; 793 return size;
793 } 794 }
794 795
795 /////////////////////// 796 ///////////////////////
796 797
797 void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const SkBitmapProcState& s, in t x, int y, 798 void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const SkBitmapProcState& s, in t x, int y,
798 SkPMColor* SK_RESTRICT dst, in t count) { 799 SkPMColor* SK_RESTRICT dst, in t count) {
799 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 800 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
800 SkMatrix::kScale_Mask)) == 0); 801 SkMatrix::kScale_Mask)) == 0);
801 802
802 const unsigned maxX = s.fBitmap->width() - 1; 803 const unsigned maxX = s.fPixmap.width() - 1;
803 SkFractionalInt fx; 804 SkFractionalInt fx;
804 int dstY; 805 int dstY;
805 { 806 {
806 SkPoint pt; 807 SkPoint pt;
807 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar (y) + SK_ScalarHalf, 808 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar (y) + SK_ScalarHalf,
808 &pt); 809 &pt);
809 fx = SkScalarToFractionalInt(pt.fY); 810 fx = SkScalarToFractionalInt(pt.fY);
810 const unsigned maxY = s.fBitmap->height() - 1; 811 const unsigned maxY = s.fPixmap.height() - 1;
811 dstY = SkClampMax(SkFractionalIntToInt(fx), maxY); 812 dstY = SkClampMax(SkFractionalIntToInt(fx), maxY);
812 fx = SkScalarToFractionalInt(pt.fX); 813 fx = SkScalarToFractionalInt(pt.fX);
813 } 814 }
814 815
815 const SkPMColor* SK_RESTRICT src = s.fBitmap->getAddr32(0, dstY); 816 const SkPMColor* SK_RESTRICT src = s.fPixmap.addr32(0, dstY);
816 const SkFractionalInt dx = s.fInvSxFractionalInt; 817 const SkFractionalInt dx = s.fInvSxFractionalInt;
817 818
818 // Check if we're safely inside [0...maxX] so no need to clamp each computed index. 819 // Check if we're safely inside [0...maxX] so no need to clamp each computed index.
819 // 820 //
820 if ((uint64_t)SkFractionalIntToInt(fx) <= maxX && 821 if ((uint64_t)SkFractionalIntToInt(fx) <= maxX &&
821 (uint64_t)SkFractionalIntToInt(fx + dx * (count - 1)) <= maxX) 822 (uint64_t)SkFractionalIntToInt(fx + dx * (count - 1)) <= maxX)
822 { 823 {
823 int count4 = count >> 2; 824 int count4 = count >> 2;
824 for (int i = 0; i < count4; ++i) { 825 for (int i = 0; i < count4; ++i) {
825 SkPMColor src0 = src[SkFractionalIntToInt(fx)]; fx += dx; 826 SkPMColor src0 = src[SkFractionalIntToInt(fx)]; fx += dx;
(...skipping 13 matching lines...) Expand all
839 fx += dx; 840 fx += dx;
840 } 841 }
841 } else { 842 } else {
842 for (int i = 0; i < count; ++i) { 843 for (int i = 0; i < count; ++i) {
843 dst[i] = src[SkClampMax(SkFractionalIntToInt(fx), maxX)]; 844 dst[i] = src[SkClampMax(SkFractionalIntToInt(fx), maxX)];
844 fx += dx; 845 fx += dx;
845 } 846 }
846 } 847 }
847 } 848 }
848 849
OLDNEW
« no previous file with comments | « src/core/SkBitmapProcState.h ('k') | src/core/SkBitmapProcState_matrix.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698