OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 #ifndef SkLinearBitmapPipeline_sampler_DEFINED | 8 #ifndef SkLinearBitmapPipeline_sampler_DEFINED |
9 #define SkLinearBitmapPipeline_sampler_DEFINED | 9 #define SkLinearBitmapPipeline_sampler_DEFINED |
10 | 10 |
11 #include "SkLinearBitmapPipeline_core.h" | 11 #include "SkLinearBitmapPipeline_core.h" |
| 12 #include <array> |
12 #include <tuple> | 13 #include <tuple> |
13 | 14 |
14 namespace { | 15 namespace { |
15 // Explaination of the math: | 16 // Explaination of the math: |
16 // 1 - x x | 17 // 1 - x x |
17 // +--------+--------+ | 18 // +--------+--------+ |
18 // | | | | 19 // | | | |
19 // 1 - y | px00 | px10 | | 20 // 1 - y | px00 | px10 | |
20 // | | | | 21 // | | | |
21 // +--------+--------+ | 22 // +--------+--------+ |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 SkScalar x = X(start); | 163 SkScalar x = X(start); |
163 SkFixed fx = SkScalarToFixed(x); | 164 SkFixed fx = SkScalarToFixed(x); |
164 SkScalar dx = length / (count - 1); | 165 SkScalar dx = length / (count - 1); |
165 SkFixed fdx = SkScalarToFixed(dx); | 166 SkFixed fdx = SkScalarToFixed(dx); |
166 | 167 |
167 const void* row = fStrategy.row((int)std::floor(Y(start))); | 168 const void* row = fStrategy.row((int)std::floor(Y(start))); |
168 Next* next = fNext; | 169 Next* next = fNext; |
169 | 170 |
170 int ix = SkFixedFloorToInt(fx); | 171 int ix = SkFixedFloorToInt(fx); |
171 int prevIX = ix; | 172 int prevIX = ix; |
172 Sk4f fpixel = fStrategy.getPixel(row, ix); | 173 Sk4f fpixel = fStrategy.getPixelAt(row, ix); |
173 | 174 |
174 // When dx is less than one, each pixel is used more than once. Using th
e fixed point fx | 175 // When dx is less than one, each pixel is used more than once. Using th
e fixed point fx |
175 // allows the code to quickly check that the same pixel is being used. T
he code uses this | 176 // allows the code to quickly check that the same pixel is being used. T
he code uses this |
176 // same pixel check to do the sRGB and normalization only once. | 177 // same pixel check to do the sRGB and normalization only once. |
177 auto getNextPixel = [&]() { | 178 auto getNextPixel = [&]() { |
178 if (ix != prevIX) { | 179 if (ix != prevIX) { |
179 fpixel = fStrategy.getPixel(row, ix); | 180 fpixel = fStrategy.getPixelAt(row, ix); |
180 prevIX = ix; | 181 prevIX = ix; |
181 } | 182 } |
182 fx += fdx; | 183 fx += fdx; |
183 ix = SkFixedFloorToInt(fx); | 184 ix = SkFixedFloorToInt(fx); |
184 return fpixel; | 185 return fpixel; |
185 }; | 186 }; |
186 | 187 |
187 while (count >= 4) { | 188 while (count >= 4) { |
188 Sk4f px0 = getNextPixel(); | 189 Sk4f px0 = getNextPixel(); |
189 Sk4f px1 = getNextPixel(); | 190 Sk4f px1 = getNextPixel(); |
(...skipping 21 matching lines...) Expand all Loading... |
211 if (length > 0) { | 212 if (length > 0) { |
212 while (count >= 4) { | 213 while (count >= 4) { |
213 Sk4f px0, px1, px2, px3; | 214 Sk4f px0, px1, px2, px3; |
214 fStrategy.get4Pixels(row, ix, &px0, &px1, &px2, &px3); | 215 fStrategy.get4Pixels(row, ix, &px0, &px1, &px2, &px3); |
215 next->place4Pixels(px0, px1, px2, px3); | 216 next->place4Pixels(px0, px1, px2, px3); |
216 ix += 4; | 217 ix += 4; |
217 count -= 4; | 218 count -= 4; |
218 } | 219 } |
219 | 220 |
220 while (count > 0) { | 221 while (count > 0) { |
221 next->placePixel(fStrategy.getPixel(row, ix)); | 222 next->placePixel(fStrategy.getPixelAt(row, ix)); |
222 ix += 1; | 223 ix += 1; |
223 count -= 1; | 224 count -= 1; |
224 } | 225 } |
225 } else { | 226 } else { |
226 while (count >= 4) { | 227 while (count >= 4) { |
227 Sk4f px0, px1, px2, px3; | 228 Sk4f px0, px1, px2, px3; |
228 fStrategy.get4Pixels(row, ix - 3, &px3, &px2, &px1, &px0); | 229 fStrategy.get4Pixels(row, ix - 3, &px3, &px2, &px1, &px0); |
229 next->place4Pixels(px0, px1, px2, px3); | 230 next->place4Pixels(px0, px1, px2, px3); |
230 ix -= 4; | 231 ix -= 4; |
231 count -= 4; | 232 count -= 4; |
232 } | 233 } |
233 | 234 |
234 while (count > 0) { | 235 while (count > 0) { |
235 next->placePixel(fStrategy.getPixel(row, ix)); | 236 next->placePixel(fStrategy.getPixelAt(row, ix)); |
236 ix -= 1; | 237 ix -= 1; |
237 count -= 1; | 238 count -= 1; |
238 } | 239 } |
239 } | 240 } |
240 } | 241 } |
241 | 242 |
242 // We're moving through source space faster than dst (zoomed out), | 243 // We're moving through source space faster than dst (zoomed out), |
243 // so we'll never reuse a source pixel or be able to do contiguous loads. | 244 // so we'll never reuse a source pixel or be able to do contiguous loads. |
244 void nearestSpanFastRate(Span span) { | 245 void nearestSpanFastRate(Span span) { |
245 struct NearestWrapper { | 246 struct NearestWrapper { |
(...skipping 12 matching lines...) Expand all Loading... |
258 } | 259 } |
259 | 260 |
260 void bilerpSpanZeroRate(Span span, SkScalar y1) { | 261 void bilerpSpanZeroRate(Span span, SkScalar y1) { |
261 SkScalar y0 = span.startY() - 0.5f; | 262 SkScalar y0 = span.startY() - 0.5f; |
262 y1 += 0.5f; | 263 y1 += 0.5f; |
263 int iy0 = SkScalarFloorToInt(y0); | 264 int iy0 = SkScalarFloorToInt(y0); |
264 SkScalar filterY1 = y0 - iy0; | 265 SkScalar filterY1 = y0 - iy0; |
265 SkScalar filterY0 = 1.0f - filterY1; | 266 SkScalar filterY0 = 1.0f - filterY1; |
266 int iy1 = SkScalarFloorToInt(y1); | 267 int iy1 = SkScalarFloorToInt(y1); |
267 int ix = SkScalarFloorToInt(span.startX()); | 268 int ix = SkScalarFloorToInt(span.startX()); |
268 Sk4f pixelY0 = fStrategy.getPixel(fStrategy.row(iy0), ix); | 269 Sk4f pixelY0 = fStrategy.getPixelAt(fStrategy.row(iy0), ix); |
269 Sk4f pixelY1 = fStrategy.getPixel(fStrategy.row(iy1), ix); | 270 Sk4f pixelY1 = fStrategy.getPixelAt(fStrategy.row(iy1), ix); |
270 Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1; | 271 Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1; |
271 int count = span.count(); | 272 int count = span.count(); |
272 while (count >= 4) { | 273 while (count >= 4) { |
273 fNext->place4Pixels(filterPixel, filterPixel, filterPixel, filterPix
el); | 274 fNext->place4Pixels(filterPixel, filterPixel, filterPixel, filterPix
el); |
274 count -= 4; | 275 count -= 4; |
275 } | 276 } |
276 while (count > 0) { | 277 while (count > 0) { |
277 fNext->placePixel(filterPixel); | 278 fNext->placePixel(filterPixel); |
278 count -= 1; | 279 count -= 1; |
279 } | 280 } |
(...skipping 20 matching lines...) Expand all Loading... |
300 } | 301 } |
301 int ix = SkFixedFloorToInt(fx); | 302 int ix = SkFixedFloorToInt(fx); |
302 int ioldx = ix; | 303 int ioldx = ix; |
303 Sk4f x{SkFixedToScalar(fx) - ix}; | 304 Sk4f x{SkFixedToScalar(fx) - ix}; |
304 Sk4f dx{SkFixedToScalar(fdx)}; | 305 Sk4f dx{SkFixedToScalar(fdx)}; |
305 SkScalar ry0 = Y(start) - 0.5f; | 306 SkScalar ry0 = Y(start) - 0.5f; |
306 ry1 += 0.5f; | 307 ry1 += 0.5f; |
307 SkScalar yFloor = std::floor(ry0); | 308 SkScalar yFloor = std::floor(ry0); |
308 Sk4f y1 = Sk4f{ry0 - yFloor}; | 309 Sk4f y1 = Sk4f{ry0 - yFloor}; |
309 Sk4f y0 = Sk4f{1.0f} - y1; | 310 Sk4f y0 = Sk4f{1.0f} - y1; |
310 const uint32_t* const row0 = fStrategy.row(SkScalarFloorToInt(ry0)); | 311 const void* const row0 = fStrategy.row(SkScalarFloorToInt(ry0)); |
311 const uint32_t* const row1 = fStrategy.row(SkScalarFloorToInt(ry1)); | 312 const void* const row1 = fStrategy.row(SkScalarFloorToInt(ry1)); |
312 Sk4f fpixel00 = y0 * fStrategy.getPixel(row0, ix); | 313 Sk4f fpixel00 = y0 * fStrategy.getPixelAt(row0, ix); |
313 Sk4f fpixel01 = y1 * fStrategy.getPixel(row1, ix); | 314 Sk4f fpixel01 = y1 * fStrategy.getPixelAt(row1, ix); |
314 Sk4f fpixel10 = y0 * fStrategy.getPixel(row0, ix + 1); | 315 Sk4f fpixel10 = y0 * fStrategy.getPixelAt(row0, ix + 1); |
315 Sk4f fpixel11 = y1 * fStrategy.getPixel(row1, ix + 1); | 316 Sk4f fpixel11 = y1 * fStrategy.getPixelAt(row1, ix + 1); |
316 auto getNextPixel = [&]() { | 317 auto getNextPixel = [&]() { |
317 if (ix != ioldx) { | 318 if (ix != ioldx) { |
318 fpixel00 = fpixel10; | 319 fpixel00 = fpixel10; |
319 fpixel01 = fpixel11; | 320 fpixel01 = fpixel11; |
320 fpixel10 = y0 * fStrategy.getPixel(row0, ix + 1); | 321 fpixel10 = y0 * fStrategy.getPixelAt(row0, ix + 1); |
321 fpixel11 = y1 * fStrategy.getPixel(row1, ix + 1); | 322 fpixel11 = y1 * fStrategy.getPixelAt(row1, ix + 1); |
322 ioldx = ix; | 323 ioldx = ix; |
323 x = x + xAdjust; | 324 x = x + xAdjust; |
324 } | 325 } |
325 | 326 |
326 Sk4f x0, x1; | 327 Sk4f x0, x1; |
327 x0 = Sk4f{1.0f} - x; | 328 x0 = Sk4f{1.0f} - x; |
328 x1 = x; | 329 x1 = x; |
329 Sk4f fpixel = x0 * (fpixel00 + fpixel01) + x1 * (fpixel10 + fpixel11
); | 330 Sk4f fpixel = x0 * (fpixel00 + fpixel01) + x1 * (fpixel10 + fpixel11
); |
330 fx += fdx; | 331 fx += fdx; |
331 ix = SkFixedFloorToInt(fx); | 332 ix = SkFixedFloorToInt(fx); |
(...skipping 28 matching lines...) Expand all Loading... |
360 SkScalar filterY0 = 1.0f - filterY1; | 361 SkScalar filterY0 = 1.0f - filterY1; |
361 int iy1 = SkScalarFloorToInt(y1); | 362 int iy1 = SkScalarFloorToInt(y1); |
362 const void* rowY0 = fStrategy.row(iy0); | 363 const void* rowY0 = fStrategy.row(iy0); |
363 const void* rowY1 = fStrategy.row(iy1); | 364 const void* rowY1 = fStrategy.row(iy1); |
364 SkScalar x0 = span.startX() - 0.5f; | 365 SkScalar x0 = span.startX() - 0.5f; |
365 int ix0 = SkScalarFloorToInt(x0); | 366 int ix0 = SkScalarFloorToInt(x0); |
366 SkScalar filterX1 = x0 - ix0; | 367 SkScalar filterX1 = x0 - ix0; |
367 SkScalar filterX0 = 1.0f - filterX1; | 368 SkScalar filterX0 = 1.0f - filterX1; |
368 | 369 |
369 auto getPixelY0 = [&]() { | 370 auto getPixelY0 = [&]() { |
370 Sk4f px = fStrategy.getPixel(rowY0, ix0); | 371 Sk4f px = fStrategy.getPixelAt(rowY0, ix0); |
371 return px * filterY0; | 372 return px * filterY0; |
372 }; | 373 }; |
373 | 374 |
374 auto getPixelY1 = [&]() { | 375 auto getPixelY1 = [&]() { |
375 Sk4f px = fStrategy.getPixel(rowY1, ix0); | 376 Sk4f px = fStrategy.getPixelAt(rowY1, ix0); |
376 return px * filterY1; | 377 return px * filterY1; |
377 }; | 378 }; |
378 | 379 |
379 auto get4PixelsY0 = [&](int ix, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* p
x3) { | 380 auto get4PixelsY0 = [&](int ix, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* p
x3) { |
380 fStrategy.get4Pixels(rowY0, ix, px0, px1, px2, px3); | 381 fStrategy.get4Pixels(rowY0, ix, px0, px1, px2, px3); |
381 *px0 = *px0 * filterY0; | 382 *px0 = *px0 * filterY0; |
382 *px1 = *px1 * filterY0; | 383 *px1 = *px1 * filterY0; |
383 *px2 = *px2 * filterY0; | 384 *px2 = *px2 * filterY0; |
384 *px3 = *px3 * filterY0; | 385 *px3 = *px3 * filterY0; |
385 }; | 386 }; |
(...skipping 30 matching lines...) Expand all Loading... |
416 pxB = pxS3; | 417 pxB = pxS3; |
417 fNext->place4Pixels( | 418 fNext->place4Pixels( |
418 px0, | 419 px0, |
419 px1, | 420 px1, |
420 px2, | 421 px2, |
421 px3); | 422 px3); |
422 ix0 += 4; | 423 ix0 += 4; |
423 count -= 4; | 424 count -= 4; |
424 } | 425 } |
425 while (count > 0) { | 426 while (count > 0) { |
426 Sk4f pixelY0 = fStrategy.getPixel(rowY0, ix0); | 427 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix0); |
427 Sk4f pixelY1 = fStrategy.getPixel(rowY1, ix0); | 428 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix0); |
428 | 429 |
429 fNext->placePixel(lerp(pixelY0, pixelY1)); | 430 fNext->placePixel(lerp(pixelY0, pixelY1)); |
430 ix0 += 1; | 431 ix0 += 1; |
431 count -= 1; | 432 count -= 1; |
432 } | 433 } |
433 } else { | 434 } else { |
434 int count = span.count(); | 435 int count = span.count(); |
435 while (count >= 4) { | 436 while (count >= 4) { |
436 Sk4f px00, px10, px20, px30; | 437 Sk4f px00, px10, px20, px30; |
437 get4PixelsY0(ix0 - 3, &px00, &px10, &px20, &px30); | 438 get4PixelsY0(ix0 - 3, &px00, &px10, &px20, &px30); |
(...skipping 10 matching lines...) Expand all Loading... |
448 pxB = pxS0; | 449 pxB = pxS0; |
449 fNext->place4Pixels( | 450 fNext->place4Pixels( |
450 px0, | 451 px0, |
451 px1, | 452 px1, |
452 px2, | 453 px2, |
453 px3); | 454 px3); |
454 ix0 -= 4; | 455 ix0 -= 4; |
455 count -= 4; | 456 count -= 4; |
456 } | 457 } |
457 while (count > 0) { | 458 while (count > 0) { |
458 Sk4f pixelY0 = fStrategy.getPixel(rowY0, ix0); | 459 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix0); |
459 Sk4f pixelY1 = fStrategy.getPixel(rowY1, ix0); | 460 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix0); |
460 | 461 |
461 fNext->placePixel(lerp(pixelY0, pixelY1)); | 462 fNext->placePixel(lerp(pixelY0, pixelY1)); |
462 ix0 -= 1; | 463 ix0 -= 1; |
463 count -= 1; | 464 count -= 1; |
464 } | 465 } |
465 } | 466 } |
466 } | 467 } |
467 | 468 |
468 void bilerpSpanUnitRateAlignedX(Span span, SkScalar y1) { | 469 void bilerpSpanUnitRateAlignedX(Span span, SkScalar y1) { |
469 SkScalar y0 = span.startY() - 0.5f; | 470 SkScalar y0 = span.startY() - 0.5f; |
(...skipping 15 matching lines...) Expand all Loading... |
485 Sk4f px00, px10, px20, px30; | 486 Sk4f px00, px10, px20, px30; |
486 fStrategy.get4Pixels(rowY0, ix, &px00, &px10, &px20, &px30); | 487 fStrategy.get4Pixels(rowY0, ix, &px00, &px10, &px20, &px30); |
487 Sk4f px01, px11, px21, px31; | 488 Sk4f px01, px11, px21, px31; |
488 fStrategy.get4Pixels(rowY1, ix, &px01, &px11, &px21, &px31); | 489 fStrategy.get4Pixels(rowY1, ix, &px01, &px11, &px21, &px31); |
489 fNext->place4Pixels( | 490 fNext->place4Pixels( |
490 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21),
lerp(&px30, &px31)); | 491 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21),
lerp(&px30, &px31)); |
491 ix += 4; | 492 ix += 4; |
492 count -= 4; | 493 count -= 4; |
493 } | 494 } |
494 while (count > 0) { | 495 while (count > 0) { |
495 Sk4f pixelY0 = fStrategy.getPixel(rowY0, ix); | 496 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix); |
496 Sk4f pixelY1 = fStrategy.getPixel(rowY1, ix); | 497 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix); |
497 | 498 |
498 fNext->placePixel(lerp(&pixelY0, &pixelY1)); | 499 fNext->placePixel(lerp(&pixelY0, &pixelY1)); |
499 ix += 1; | 500 ix += 1; |
500 count -= 1; | 501 count -= 1; |
501 } | 502 } |
502 } else { | 503 } else { |
503 int count = span.count(); | 504 int count = span.count(); |
504 while (count >= 4) { | 505 while (count >= 4) { |
505 Sk4f px00, px10, px20, px30; | 506 Sk4f px00, px10, px20, px30; |
506 fStrategy.get4Pixels(rowY0, ix - 3, &px30, &px20, &px10, &px00); | 507 fStrategy.get4Pixels(rowY0, ix - 3, &px30, &px20, &px10, &px00); |
507 Sk4f px01, px11, px21, px31; | 508 Sk4f px01, px11, px21, px31; |
508 fStrategy.get4Pixels(rowY1, ix - 3, &px31, &px21, &px11, &px01); | 509 fStrategy.get4Pixels(rowY1, ix - 3, &px31, &px21, &px11, &px01); |
509 fNext->place4Pixels( | 510 fNext->place4Pixels( |
510 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21),
lerp(&px30, &px31)); | 511 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21),
lerp(&px30, &px31)); |
511 ix -= 4; | 512 ix -= 4; |
512 count -= 4; | 513 count -= 4; |
513 } | 514 } |
514 while (count > 0) { | 515 while (count > 0) { |
515 Sk4f pixelY0 = fStrategy.getPixel(rowY0, ix); | 516 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix); |
516 Sk4f pixelY1 = fStrategy.getPixel(rowY1, ix); | 517 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix); |
517 | 518 |
518 fNext->placePixel(lerp(&pixelY0, &pixelY1)); | 519 fNext->placePixel(lerp(&pixelY0, &pixelY1)); |
519 ix -= 1; | 520 ix -= 1; |
520 count -= 1; | 521 count -= 1; |
521 } | 522 } |
522 } | 523 } |
523 } | 524 } |
524 | 525 |
525 // We're moving through source space faster than dst (zoomed out), | 526 // We're moving through source space faster than dst (zoomed out), |
526 // so we'll never reuse a source pixel or be able to do contiguous loads. | 527 // so we'll never reuse a source pixel or be able to do contiguous loads. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 Pixel8888(const SkPixmap& srcPixmap) | 581 Pixel8888(const SkPixmap& srcPixmap) |
581 : fSrc{srcPixmap.addr32()} | 582 : fSrc{srcPixmap.addr32()} |
582 , fWidth{static_cast<int>(srcPixmap.rowBytes() / 4)} { } | 583 , fWidth{static_cast<int>(srcPixmap.rowBytes() / 4)} { } |
583 | 584 |
584 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1,
Sk4f* px2) { | 585 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1,
Sk4f* px2) { |
585 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); | 586 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); |
586 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); | 587 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); |
587 Sk4i bufferLoc = YIs * fWidth + XIs; | 588 Sk4i bufferLoc = YIs * fWidth + XIs; |
588 switch (n) { | 589 switch (n) { |
589 case 3: | 590 case 3: |
590 *px2 = this->getPixel(fSrc, bufferLoc[2]); | 591 *px2 = this->getPixelAt(fSrc, bufferLoc[2]); |
591 case 2: | 592 case 2: |
592 *px1 = this->getPixel(fSrc, bufferLoc[1]); | 593 *px1 = this->getPixelAt(fSrc, bufferLoc[1]); |
593 case 1: | 594 case 1: |
594 *px0 = this->getPixel(fSrc, bufferLoc[0]); | 595 *px0 = this->getPixelAt(fSrc, bufferLoc[0]); |
595 default: | 596 default: |
596 break; | 597 break; |
597 } | 598 } |
598 } | 599 } |
599 | 600 |
600 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2
, Sk4f* px3) { | 601 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2
, Sk4f* px3) { |
601 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); | 602 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); |
602 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); | 603 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); |
603 Sk4i bufferLoc = YIs * fWidth + XIs; | 604 Sk4i bufferLoc = YIs * fWidth + XIs; |
604 *px0 = this->getPixel(fSrc, bufferLoc[0]); | 605 *px0 = this->getPixelAt(fSrc, bufferLoc[0]); |
605 *px1 = this->getPixel(fSrc, bufferLoc[1]); | 606 *px1 = this->getPixelAt(fSrc, bufferLoc[1]); |
606 *px2 = this->getPixel(fSrc, bufferLoc[2]); | 607 *px2 = this->getPixelAt(fSrc, bufferLoc[2]); |
607 *px3 = this->getPixel(fSrc, bufferLoc[3]); | 608 *px3 = this->getPixelAt(fSrc, bufferLoc[3]); |
608 } | 609 } |
609 | 610 |
610 void get4Pixels(const void* vsrc, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2
, Sk4f* px3) { | 611 void get4Pixels(const void* vsrc, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2
, Sk4f* px3) { |
611 const uint32_t* src = static_cast<const uint32_t*>(vsrc); | 612 const uint32_t* src = static_cast<const uint32_t*>(vsrc); |
612 *px0 = this->getPixel(src, index + 0); | 613 *px0 = this->getPixelAt(src, index + 0); |
613 *px1 = this->getPixel(src, index + 1); | 614 *px1 = this->getPixelAt(src, index + 1); |
614 *px2 = this->getPixel(src, index + 2); | 615 *px2 = this->getPixelAt(src, index + 2); |
615 *px3 = this->getPixel(src, index + 3); | 616 *px3 = this->getPixelAt(src, index + 3); |
616 } | 617 } |
617 | 618 |
618 Sk4f getPixel(const void* vsrc, int index) { | 619 Sk4f getPixelAt(const void* vsrc, int index) { |
619 const uint32_t* src = static_cast<const uint32_t*>(vsrc); | 620 const uint32_t* src = static_cast<const uint32_t*>(vsrc); |
620 Sk4b bytePixel = Sk4b::Load((uint8_t *)(&src[index])); | 621 Sk4b bytePixel = Sk4b::Load((uint8_t *)(&src[index])); |
621 Sk4f pixel = SkNx_cast<float, uint8_t>(bytePixel); | 622 Sk4f pixel = SkNx_cast<float, uint8_t>(bytePixel); |
622 if (colorOrder == ColorOrder::kBGRA) { | 623 if (colorOrder == ColorOrder::kBGRA) { |
623 pixel = SkNx_shuffle<2, 1, 0, 3>(pixel); | 624 pixel = SkNx_shuffle<2, 1, 0, 3>(pixel); |
624 } | 625 } |
625 pixel = pixel * Sk4f{1.0f/255.0f}; | 626 pixel = pixel * Sk4f{1.0f/255.0f}; |
626 if (colorProfile == kSRGB_SkColorProfileType) { | 627 if (colorProfile == kSRGB_SkColorProfileType) { |
627 pixel = sRGBFast::sRGBToLinear(pixel); | 628 pixel = sRGBFast::sRGBToLinear(pixel); |
628 } | 629 } |
629 return pixel; | 630 return pixel; |
630 } | 631 } |
631 | 632 |
632 const uint32_t* row(int y) { return fSrc + y * fWidth[0]; } | 633 const void* row(int y) { return fSrc + y * fWidth[0]; } |
633 | 634 |
634 private: | 635 private: |
635 const uint32_t* const fSrc; | 636 const uint32_t* const fSrc; |
636 const Sk4i fWidth; | 637 const Sk4i fWidth; |
637 }; | 638 }; |
638 using Pixel8888SRGB = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kRGBA>; | 639 using Pixel8888SRGB = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kRGBA>; |
639 using Pixel8888LRGB = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kRGBA>; | 640 using Pixel8888LRGB = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kRGBA>; |
640 using Pixel8888SBGR = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kBGRA>; | 641 using Pixel8888SBGR = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kBGRA>; |
641 using Pixel8888LBGR = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kBGRA>; | 642 using Pixel8888LBGR = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kBGRA>; |
| 643 |
| 644 template <SkColorProfileType colorProfile> |
| 645 class PixelIndex8 { |
| 646 public: |
| 647 PixelIndex8(const SkPixmap& srcPixmap) |
| 648 : fSrc{srcPixmap.addr8()}, fWidth{static_cast<int>(srcPixmap.rowBytes())
} { |
| 649 SkASSERT(srcPixmap.colorType() == kIndex_8_SkColorType); |
| 650 SkColorTable* skColorTable = srcPixmap.ctable(); |
| 651 SkASSERT(skColorTable != nullptr); |
| 652 |
| 653 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get()); |
| 654 for (int i = 0; i < skColorTable->count(); i++) { |
| 655 fColorTable[i] = this->convertPixel((*skColorTable)[i]); |
| 656 } |
| 657 } |
| 658 |
| 659 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1,
Sk4f* px2) { |
| 660 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); |
| 661 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); |
| 662 Sk4i bufferLoc = YIs * fWidth + XIs; |
| 663 switch (n) { |
| 664 case 3: |
| 665 *px2 = this->getPixelAt(fSrc, bufferLoc[2]); |
| 666 case 2: |
| 667 *px1 = this->getPixelAt(fSrc, bufferLoc[1]); |
| 668 case 1: |
| 669 *px0 = this->getPixelAt(fSrc, bufferLoc[0]); |
| 670 default: |
| 671 break; |
| 672 } |
| 673 } |
| 674 |
| 675 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2
, Sk4f* px3) { |
| 676 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); |
| 677 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); |
| 678 Sk4i bufferLoc = YIs * fWidth + XIs; |
| 679 *px0 = this->getPixelAt(fSrc, bufferLoc[0]); |
| 680 *px1 = this->getPixelAt(fSrc, bufferLoc[1]); |
| 681 *px2 = this->getPixelAt(fSrc, bufferLoc[2]); |
| 682 *px3 = this->getPixelAt(fSrc, bufferLoc[3]); |
| 683 } |
| 684 |
| 685 void get4Pixels(const void* vsrc, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2
, Sk4f* px3) { |
| 686 *px0 = this->getPixelAt(vsrc, index + 0); |
| 687 *px1 = this->getPixelAt(vsrc, index + 1); |
| 688 *px2 = this->getPixelAt(vsrc, index + 2); |
| 689 *px3 = this->getPixelAt(vsrc, index + 3); |
| 690 } |
| 691 |
| 692 Sk4f getPixelAt(const void* vsrc, int index) { |
| 693 const uint8_t* src = static_cast<const uint8_t*>(vsrc); |
| 694 return getPixel(src + index); |
| 695 } |
| 696 |
| 697 Sk4f getPixel(const uint8_t* src) { |
| 698 Sk4f pixel = fColorTable[*src]; |
| 699 return pixel; |
| 700 } |
| 701 |
| 702 const void* row(int y) { return fSrc + y * fWidth[0]; } |
| 703 |
| 704 private: |
| 705 static const size_t kColorTableSize = sizeof(Sk4f[256]) + 12; |
| 706 Sk4f convertPixel(SkPMColor pmColor) { |
| 707 Sk4b bPixel = Sk4b::Load(&pmColor); |
| 708 Sk4f pixel = SkNx_cast<float, uint8_t>(bPixel); |
| 709 float alpha = pixel[3]; |
| 710 if (alpha != 0.0f) { |
| 711 float invAlpha = 1.0f / pixel[3]; |
| 712 Sk4f normalize = {invAlpha, invAlpha, invAlpha, 1.0f / 255.0f}; |
| 713 pixel = pixel * normalize; |
| 714 if (colorProfile == kSRGB_SkColorProfileType) { |
| 715 pixel = sRGBFast::sRGBToLinear(pixel); |
| 716 } |
| 717 return pixel; |
| 718 } else { |
| 719 return Sk4f{0.0f}; |
| 720 } |
| 721 } |
| 722 const uint8_t* const fSrc; |
| 723 const Sk4i fWidth; |
| 724 SkAutoMalloc fColorTableStorage{kColorTableSize}; |
| 725 Sk4f* fColorTable; |
| 726 }; |
| 727 |
| 728 using PixelIndex8SRGB = PixelIndex8<kSRGB_SkColorProfileType>; |
| 729 using PixelIndex8LRGB = PixelIndex8<kLinear_SkColorProfileType>; |
| 730 |
642 } // namespace | 731 } // namespace |
643 | 732 |
644 #endif // SkLinearBitmapPipeline_sampler_DEFINED | 733 #endif // SkLinearBitmapPipeline_sampler_DEFINED |
OLD | NEW |