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

Side by Side Diff: src/core/SkLinearBitmapPipeline_sample.h

Issue 2055513003: Simplify code by breaking general sampler into Nearest and Bilerp. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: sync Created 4 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/SkLinearBitmapPipeline_core.h ('k') | no next file » | 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 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
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 } 259 }
260 260
261 const void* row(int y) const { return fSrc + y * fWidth[0]; } 261 const void* row(int y) const { return fSrc + y * fWidth[0]; }
262 262
263 private: 263 private:
264 const Element* const fSrc; 264 const Element* const fSrc;
265 const Sk4i fWidth; 265 const Sk4i fWidth;
266 PixelGetter<colorType, colorProfile> fGetter; 266 PixelGetter<colorType, colorProfile> fGetter;
267 }; 267 };
268 268
269 //////////////////////////////////////////////////////////////////////////////// //////////////////// 269 // We're moving through source space at a rate of 1 source pixel per 1 dst pixel .
270 // GeneralSampler handles all the different sampling scenarios. It makes runtime decisions to 270 // We'll never re-use pixels, but we can at least load contiguous pixels.
271 // choose the fastest strategy given a particular job. It ultimately uses PixelG etters to access 271 template <typename Next, typename Strategy>
272 // the pixels. 272 static void src_strategy_blend(Span span, Next* next, Strategy* strategy) {
273 SkPoint start;
274 SkScalar length;
275 int count;
276 std::tie(start, length, count) = span;
277 int ix = SkScalarFloorToInt(X(start));
278 const void* row = strategy->row((int)std::floor(Y(start)));
279 if (length > 0) {
280 while (count >= 4) {
281 Sk4f px0, px1, px2, px3;
282 strategy->get4Pixels(row, ix, &px0, &px1, &px2, &px3);
283 next->blend4Pixels(px0, px1, px2, px3);
284 ix += 4;
285 count -= 4;
286 }
287
288 while (count > 0) {
289 next->blendPixel(strategy->getPixelFromRow(row, ix));
290 ix += 1;
291 count -= 1;
292 }
293 } else {
294 while (count >= 4) {
295 Sk4f px0, px1, px2, px3;
296 strategy->get4Pixels(row, ix - 3, &px3, &px2, &px1, &px0);
297 next->blend4Pixels(px0, px1, px2, px3);
298 ix -= 4;
299 count -= 4;
300 }
301
302 while (count > 0) {
303 next->blendPixel(strategy->getPixelFromRow(row, ix));
304 ix -= 1;
305 count -= 1;
306 }
307 }
308 }
309
310 // NearestNeighborSampler - use nearest neighbor filtering to create runs of des tination pixels.
273 template<SkColorType colorType, SkColorProfileType colorProfile, typename Next> 311 template<SkColorType colorType, SkColorProfileType colorProfile, typename Next>
274 class GeneralSampler { 312 class NearestNeighborSampler : public SkLinearBitmapPipeline::SampleProcessorInt erface {
275 public: 313 public:
276 template<typename... Args> 314 template<typename... Args>
277 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&& ... args) 315 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next , Args&& ... args)
278 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } 316 : fNext{next}, fStrategy{std::forward<Args>(args)...} { }
279 317
280 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, 318 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next ,
281 const GeneralSampler& sampler) 319 const NearestNeighborSampler& sampler)
282 : fNext{next}, fStrategy{sampler.fStrategy} { } 320 : fNext{next}, fStrategy{sampler.fStrategy} { }
283 321
284 void VECTORCALL nearestListFew(int n, Sk4s xs, Sk4s ys) { 322 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
285 SkASSERT(0 < n && n < 4); 323 SkASSERT(0 < n && n < 4);
286 Sk4f px0, px1, px2; 324 Sk4f px0, px1, px2;
287 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); 325 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2);
288 if (n >= 1) fNext->blendPixel(px0); 326 if (n >= 1) fNext->blendPixel(px0);
289 if (n >= 2) fNext->blendPixel(px1); 327 if (n >= 2) fNext->blendPixel(px1);
290 if (n >= 3) fNext->blendPixel(px2); 328 if (n >= 3) fNext->blendPixel(px2);
291 } 329 }
292 330
293 void VECTORCALL nearestList4(Sk4s xs, Sk4s ys) { 331 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
294 Sk4f px0, px1, px2, px3; 332 Sk4f px0, px1, px2, px3;
295 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); 333 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3);
296 fNext->blend4Pixels(px0, px1, px2, px3); 334 fNext->blend4Pixels(px0, px1, px2, px3);
297 } 335 }
298 336
299 void nearestSpan(Span span) { 337 void pointSpan(Span span) override {
300 SkASSERT(!span.isEmpty()); 338 SkASSERT(!span.isEmpty());
301 SkPoint start; 339 SkPoint start;
302 SkScalar length; 340 SkScalar length;
303 int count; 341 int count;
304 std::tie(start, length, count) = span; 342 std::tie(start, length, count) = span;
305 SkScalar absLength = SkScalarAbs(length); 343 SkScalar absLength = SkScalarAbs(length);
306 if (absLength < (count - 1)) { 344 if (absLength < (count - 1)) {
307 this->nearestSpanSlowRate(span); 345 this->spanSlowRate(span);
308 } else if (absLength == (count - 1)) { 346 } else if (absLength == (count - 1)) {
309 this->nearestSpanUnitRate(span); 347 src_strategy_blend(span, fNext, &fStrategy);
310 } else { 348 } else {
311 this->nearestSpanFastRate(span); 349 this->spanFastRate(span);
312 } 350 }
313 } 351 }
314 352
315 Sk4f bilerpNonEdgePixel(SkScalar x, SkScalar y) { 353 void repeatSpan(Span span, int32_t repeatCount) override {
316 Sk4f px00, px10, px01, px11; 354 while (repeatCount > 0) {
317 // bilerp4() expects xs, ys are the top-lefts of the 2x2 kernel. 355 this->pointSpan(span);
318 Sk4f xs = Sk4f{x} - 0.5f; 356 repeatCount--;
319 Sk4f ys = Sk4f{y} - 0.5f; 357 }
320 Sk4f sampleXs = xs + Sk4f{0.0f, 1.0f, 0.0f, 1.0f};
321 Sk4f sampleYs = ys + Sk4f{0.0f, 0.0f, 1.0f, 1.0f};
322 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11);
323 return bilerp4(xs, ys, px00, px10, px01, px11);
324 } 358 }
325 359
326 void VECTORCALL bilerpListFew(int n, Sk4s xs, Sk4s ys) { 360 void VECTORCALL bilerpEdge(Sk4s xs, Sk4s ys) override {
327 SkASSERT(0 < n && n < 4); 361 SkFAIL("Using nearest neighbor sampler, but calling a bilerpEdge.");
328 auto bilerpPixel = [&](int index) {
329 return this->bilerpNonEdgePixel(xs[index], ys[index]);
330 };
331
332 if (n >= 1) fNext->blendPixel(bilerpPixel(0));
333 if (n >= 2) fNext->blendPixel(bilerpPixel(1));
334 if (n >= 3) fNext->blendPixel(bilerpPixel(2));
335 } 362 }
336 363
337 void VECTORCALL bilerpList4(Sk4s xs, Sk4s ys) { 364 void bilerpSpan(Span span, SkScalar y) override {
338 auto bilerpPixel = [&](int index) { 365 SkFAIL("Using nearest neighbor sampler, but calling a bilerpSpan.");
339 return this->bilerpNonEdgePixel(xs[index], ys[index]);
340 };
341 fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile rpPixel(3));
342 }
343
344 void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) {
345 Sk4f px00, px10, px01, px11;
346 Sk4f xs = Sk4f{sampleXs[0]};
347 Sk4f ys = Sk4f{sampleYs[0]};
348 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11);
349 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11);
350 fNext->blendPixel(pixel);
351 }
352
353 void bilerpSpan(Span span) {
354 this->bilerpSpanWithY(span, span.startY());
355 }
356
357 void bilerpSpanWithY(Span span, SkScalar y) {
358 SkASSERT(!span.isEmpty());
359 SkPoint start;
360 SkScalar length;
361 int count;
362 std::tie(start, length, count) = span;
363 SkScalar absLength = SkScalarAbs(length);
364 if (absLength == 0.0f) {
365 this->bilerpSpanZeroRate(span, y);
366 } else if (absLength < (count - 1)) {
367 this->bilerpSpanSlowRate(span, y);
368 } else if (absLength == (count - 1)) {
369 if (std::fmod(span.startX() - 0.5f, 1.0f) == 0.0f) {
370 if (std::fmod(span.startY() - 0.5f, 1.0f) == 0.0f) {
371 this->nearestSpanUnitRate(span);
372 } else {
373 this->bilerpSpanUnitRateAlignedX(span, y);
374 }
375 } else {
376 this->bilerpSpanUnitRate(span, y);
377 }
378 } else {
379 this->bilerpSpanFastRate(span, y);
380 }
381 } 366 }
382 367
383 private: 368 private:
384 // When moving through source space more slowly than dst space (zoomed in), 369 // When moving through source space more slowly than dst space (zoomed in),
385 // we'll be sampling from the same source pixel more than once. 370 // we'll be sampling from the same source pixel more than once.
386 void nearestSpanSlowRate(Span span) { 371 void spanSlowRate(Span span) {
387 SkPoint start; 372 SkPoint start;
388 SkScalar length; 373 SkScalar length;
389 int count; 374 int count;
390 std::tie(start, length, count) = span; 375 std::tie(start, length, count) = span;
391 SkScalar x = X(start); 376 SkScalar x = X(start);
392 SkFixed fx = SkScalarToFixed(x); 377 SkFixed fx = SkScalarToFixed(x);
393 SkScalar dx = length / (count - 1); 378 SkScalar dx = length / (count - 1);
394 SkFixed fdx = SkScalarToFixed(dx); 379 SkFixed fdx = SkScalarToFixed(dx);
395 380
396 const void* row = fStrategy.row((int)std::floor(Y(start))); 381 const void* row = fStrategy.row((int)std::floor(Y(start)));
(...skipping 25 matching lines...) Expand all
422 count -= 4; 407 count -= 4;
423 } 408 }
424 while (count > 0) { 409 while (count > 0) {
425 next->blendPixel(getNextPixel()); 410 next->blendPixel(getNextPixel());
426 count -= 1; 411 count -= 1;
427 } 412 }
428 } 413 }
429 414
430 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel. 415 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel.
431 // We'll never re-use pixels, but we can at least load contiguous pixels. 416 // We'll never re-use pixels, but we can at least load contiguous pixels.
432 void nearestSpanUnitRate(Span span) { 417 void spanUnitRate(Span span) {
418 src_strategy_blend(span, fNext, &fStrategy);
419 }
420
421 // We're moving through source space faster than dst (zoomed out),
422 // so we'll never reuse a source pixel or be able to do contiguous loads.
423 void spanFastRate(Span span) {
424 span_fallback(span, this);
425 }
426
427 Next* const fNext;
428 PixelAccessor<colorType, colorProfile> fStrategy;
429 };
430
431 // BilerpSampler - use a bilerp filter to create runs of destination pixels.
432 template<SkColorType colorType, SkColorProfileType colorProfile, typename Next>
433 class BilerpSampler : public SkLinearBitmapPipeline::SampleProcessorInterface {
434 public:
435 template<typename... Args>
436 BilerpSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&& ... args)
437 : fNext{next}, fStrategy{std::forward<Args>(args)...} { }
438
439 BilerpSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next,
440 const BilerpSampler& sampler)
441 : fNext{next}, fStrategy{sampler.fStrategy} { }
442
443 Sk4f bilerpNonEdgePixel(SkScalar x, SkScalar y) {
444 Sk4f px00, px10, px01, px11;
445
446 // bilerp4() expects xs, ys are the top-lefts of the 2x2 kernel.
447 Sk4f xs = Sk4f{x} - 0.5f;
448 Sk4f ys = Sk4f{y} - 0.5f;
449 Sk4f sampleXs = xs + Sk4f{0.0f, 1.0f, 0.0f, 1.0f};
450 Sk4f sampleYs = ys + Sk4f{0.0f, 0.0f, 1.0f, 1.0f};
451 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11);
452 return bilerp4(xs, ys, px00, px10, px01, px11);
453 }
454
455 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
456 SkASSERT(0 < n && n < 4);
457 auto bilerpPixel = [&](int index) {
458 return this->bilerpNonEdgePixel(xs[index], ys[index]);
459 };
460
461 if (n >= 1) fNext->blendPixel(bilerpPixel(0));
462 if (n >= 2) fNext->blendPixel(bilerpPixel(1));
463 if (n >= 3) fNext->blendPixel(bilerpPixel(2));
464 }
465
466 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
467 auto bilerpPixel = [&](int index) {
468 return this->bilerpNonEdgePixel(xs[index], ys[index]);
469 };
470 fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile rpPixel(3));
471 }
472
473 void pointSpan(Span span) override {
474 this->bilerpSpan(span, span.startY());
475 }
476
477 void repeatSpan(Span span, int32_t repeatCount) override {
478 while (repeatCount > 0) {
479 this->pointSpan(span);
480 repeatCount--;
481 }
482 }
483
484 void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) override {
485 Sk4f px00, px10, px01, px11;
486 Sk4f xs = Sk4f{sampleXs[0]};
487 Sk4f ys = Sk4f{sampleYs[0]};
488 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11);
489 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11);
490 fNext->blendPixel(pixel);
491 }
492
493 void bilerpSpan(Span span, SkScalar y) override {
494 SkASSERT(!span.isEmpty());
433 SkPoint start; 495 SkPoint start;
434 SkScalar length; 496 SkScalar length;
435 int count; 497 int count;
436 std::tie(start, length, count) = span; 498 std::tie(start, length, count) = span;
437 int ix = SkScalarFloorToInt(X(start)); 499 SkScalar absLength = SkScalarAbs(length);
438 const void* row = fStrategy.row((int)std::floor(Y(start))); 500 if (absLength == 0.0f) {
439 Next* next = fNext; 501 this->spanZeroRate(span, y);
440 if (length > 0) { 502 } else if (absLength < (count - 1)) {
441 while (count >= 4) { 503 this->spanSlowRate(span, y);
442 Sk4f px0, px1, px2, px3; 504 } else if (absLength == (count - 1)) {
443 fStrategy.get4Pixels(row, ix, &px0, &px1, &px2, &px3); 505 if (std::fmod(span.startX() - 0.5f, 1.0f) == 0.0f) {
444 next->blend4Pixels(px0, px1, px2, px3); 506 if (std::fmod(span.startY() - 0.5f, 1.0f) == 0.0f) {
445 ix += 4; 507 src_strategy_blend(span, fNext, &fStrategy);
446 count -= 4; 508 } else {
447 } 509 this->spanUnitRateAlignedX(span, y);
448 510 }
449 while (count > 0) { 511 } else {
450 next->blendPixel(fStrategy.getPixelFromRow(row, ix)); 512 this->spanUnitRate(span, y);
451 ix += 1;
452 count -= 1;
453 } 513 }
454 } else { 514 } else {
455 while (count >= 4) { 515 this->spanFastRate(span, y);
456 Sk4f px0, px1, px2, px3;
457 fStrategy.get4Pixels(row, ix - 3, &px3, &px2, &px1, &px0);
458 next->blend4Pixels(px0, px1, px2, px3);
459 ix -= 4;
460 count -= 4;
461 }
462
463 while (count > 0) {
464 next->blendPixel(fStrategy.getPixelFromRow(row, ix));
465 ix -= 1;
466 count -= 1;
467 }
468 } 516 }
469 } 517 }
470 518
471 // We're moving through source space faster than dst (zoomed out), 519 private:
472 // so we'll never reuse a source pixel or be able to do contiguous loads. 520 void spanZeroRate(Span span, SkScalar y1) {
473 void nearestSpanFastRate(Span span) {
474 struct NearestWrapper {
475 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) {
476 fSampler.nearestListFew(n, xs, ys);
477 }
478
479 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) {
480 fSampler.nearestList4(xs, ys);
481 }
482
483 GeneralSampler& fSampler;
484 };
485 NearestWrapper wrapper{*this};
486 span_fallback(span, &wrapper);
487 }
488
489 void bilerpSpanZeroRate(Span span, SkScalar y1) {
490 SkScalar y0 = span.startY() - 0.5f; 521 SkScalar y0 = span.startY() - 0.5f;
491 y1 += 0.5f; 522 y1 += 0.5f;
492 int iy0 = SkScalarFloorToInt(y0); 523 int iy0 = SkScalarFloorToInt(y0);
493 SkScalar filterY1 = y0 - iy0; 524 SkScalar filterY1 = y0 - iy0;
494 SkScalar filterY0 = 1.0f - filterY1; 525 SkScalar filterY0 = 1.0f - filterY1;
495 int iy1 = SkScalarFloorToInt(y1); 526 int iy1 = SkScalarFloorToInt(y1);
496 int ix = SkScalarFloorToInt(span.startX()); 527 int ix = SkScalarFloorToInt(span.startX());
497 Sk4f pixelY0 = fStrategy.getPixelFromRow(fStrategy.row(iy0), ix); 528 Sk4f pixelY0 = fStrategy.getPixelFromRow(fStrategy.row(iy0), ix);
498 Sk4f pixelY1 = fStrategy.getPixelFromRow(fStrategy.row(iy1), ix); 529 Sk4f pixelY1 = fStrategy.getPixelFromRow(fStrategy.row(iy1), ix);
499 Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1; 530 Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1;
500 int count = span.count(); 531 int count = span.count();
501 while (count >= 4) { 532 while (count >= 4) {
502 fNext->blend4Pixels(filterPixel, filterPixel, filterPixel, filterPix el); 533 fNext->blend4Pixels(filterPixel, filterPixel, filterPixel, filterPix el);
503 count -= 4; 534 count -= 4;
504 } 535 }
505 while (count > 0) { 536 while (count > 0) {
506 fNext->blendPixel(filterPixel); 537 fNext->blendPixel(filterPixel);
507 count -= 1; 538 count -= 1;
508 } 539 }
509 } 540 }
510 541
511 // When moving through source space more slowly than dst space (zoomed in), 542 // When moving through source space more slowly than dst space (zoomed in),
512 // we'll be sampling from the same source pixel more than once. 543 // we'll be sampling from the same source pixel more than once.
513 void bilerpSpanSlowRate(Span span, SkScalar ry1) { 544 void spanSlowRate(Span span, SkScalar ry1) {
514 SkPoint start; 545 SkPoint start;
515 SkScalar length; 546 SkScalar length;
516 int count; 547 int count;
517 std::tie(start, length, count) = span; 548 std::tie(start, length, count) = span;
518 SkFixed fx = SkScalarToFixed(X(start)-0.5f); 549 SkFixed fx = SkScalarToFixed(X(start)-0.5f);
519 550
520 SkFixed fdx = SkScalarToFixed(length / (count - 1)); 551 SkFixed fdx = SkScalarToFixed(length / (count - 1));
521 552
522 Sk4f xAdjust; 553 Sk4f xAdjust;
523 if (fdx >= 0) { 554 if (fdx >= 0) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 603
573 while (count > 0) { 604 while (count > 0) {
574 fNext->blendPixel(getNextPixel()); 605 fNext->blendPixel(getNextPixel());
575 606
576 count -= 1; 607 count -= 1;
577 } 608 }
578 } 609 }
579 610
580 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel. 611 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel.
581 // We'll never re-use pixels, but we can at least load contiguous pixels. 612 // We'll never re-use pixels, but we can at least load contiguous pixels.
582 void bilerpSpanUnitRate(Span span, SkScalar y1) { 613 void spanUnitRate(Span span, SkScalar y1) {
583 y1 += 0.5f; 614 y1 += 0.5f;
584 SkScalar y0 = span.startY() - 0.5f; 615 SkScalar y0 = span.startY() - 0.5f;
585 int iy0 = SkScalarFloorToInt(y0); 616 int iy0 = SkScalarFloorToInt(y0);
586 SkScalar filterY1 = y0 - iy0; 617 SkScalar filterY1 = y0 - iy0;
587 SkScalar filterY0 = 1.0f - filterY1; 618 SkScalar filterY0 = 1.0f - filterY1;
588 int iy1 = SkScalarFloorToInt(y1); 619 int iy1 = SkScalarFloorToInt(y1);
589 const void* rowY0 = fStrategy.row(iy0); 620 const void* rowY0 = fStrategy.row(iy0);
590 const void* rowY1 = fStrategy.row(iy1); 621 const void* rowY1 = fStrategy.row(iy1);
591 SkScalar x0 = span.startX() - 0.5f; 622 SkScalar x0 = span.startX() - 0.5f;
592 int ix0 = SkScalarFloorToInt(x0); 623 int ix0 = SkScalarFloorToInt(x0);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 Sk4f pixelY0 = fStrategy.getPixelFromRow(rowY0, ix0); 708 Sk4f pixelY0 = fStrategy.getPixelFromRow(rowY0, ix0);
678 Sk4f pixelY1 = fStrategy.getPixelFromRow(rowY1, ix0); 709 Sk4f pixelY1 = fStrategy.getPixelFromRow(rowY1, ix0);
679 710
680 fNext->blendPixel(lerp(pixelY0, pixelY1)); 711 fNext->blendPixel(lerp(pixelY0, pixelY1));
681 ix0 -= 1; 712 ix0 -= 1;
682 count -= 1; 713 count -= 1;
683 } 714 }
684 } 715 }
685 } 716 }
686 717
687 void bilerpSpanUnitRateAlignedX(Span span, SkScalar y1) { 718 void spanUnitRateAlignedX(Span span, SkScalar y1) {
688 SkScalar y0 = span.startY() - 0.5f; 719 SkScalar y0 = span.startY() - 0.5f;
689 y1 += 0.5f; 720 y1 += 0.5f;
690 int iy0 = SkScalarFloorToInt(y0); 721 int iy0 = SkScalarFloorToInt(y0);
691 SkScalar filterY1 = y0 - iy0; 722 SkScalar filterY1 = y0 - iy0;
692 SkScalar filterY0 = 1.0f - filterY1; 723 SkScalar filterY0 = 1.0f - filterY1;
693 int iy1 = SkScalarFloorToInt(y1); 724 int iy1 = SkScalarFloorToInt(y1);
694 int ix = SkScalarFloorToInt(span.startX()); 725 int ix = SkScalarFloorToInt(span.startX());
695 const void* rowY0 = fStrategy.row(iy0); 726 const void* rowY0 = fStrategy.row(iy0);
696 const void* rowY1 = fStrategy.row(iy1); 727 const void* rowY1 = fStrategy.row(iy1);
697 auto lerp = [&](Sk4f* pixelY0, Sk4f* pixelY1) { 728 auto lerp = [&](Sk4f* pixelY0, Sk4f* pixelY1) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 767
737 fNext->blendPixel(lerp(&pixelY0, &pixelY1)); 768 fNext->blendPixel(lerp(&pixelY0, &pixelY1));
738 ix -= 1; 769 ix -= 1;
739 count -= 1; 770 count -= 1;
740 } 771 }
741 } 772 }
742 } 773 }
743 774
744 // We're moving through source space faster than dst (zoomed out), 775 // We're moving through source space faster than dst (zoomed out),
745 // so we'll never reuse a source pixel or be able to do contiguous loads. 776 // so we'll never reuse a source pixel or be able to do contiguous loads.
746 void bilerpSpanFastRate(Span span, SkScalar y1) { 777 void spanFastRate(Span span, SkScalar y1) {
747 SkPoint start; 778 SkPoint start;
748 SkScalar length; 779 SkScalar length;
749 int count; 780 int count;
750 std::tie(start, length, count) = span; 781 std::tie(start, length, count) = span;
751 SkScalar x = X(start); 782 SkScalar x = X(start);
752 SkScalar y = Y(start); 783 SkScalar y = Y(start);
784
753 // In this sampler, it is assumed that if span.StartY() and y1 are the s ame then both 785 // In this sampler, it is assumed that if span.StartY() and y1 are the s ame then both
754 // y-lines are on the same tile. 786 // y-lines are on the same tile.
755 if (y == y1) { 787 if (y == y1) {
756 // Both y-lines are on the same tile. 788 // Both y-lines are on the same tile.
757 struct BilerpWrapper { 789 span_fallback(span, this);
758 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) {
759 fSampler.bilerpListFew(n, xs, ys);
760 }
761
762 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) {
763 fSampler.bilerpList4(xs, ys);
764 }
765
766 GeneralSampler& fSampler;
767 };
768 BilerpWrapper wrapper{*this};
769 span_fallback(span, &wrapper);
770 } else { 790 } else {
771 // The y-lines are on different tiles. 791 // The y-lines are on different tiles.
772 SkScalar dx = length / (count - 1); 792 SkScalar dx = length / (count - 1);
773 Sk4f ys = {y - 0.5f, y - 0.5f, y1 + 0.5f, y1 + 0.5f}; 793 Sk4f ys = {y - 0.5f, y - 0.5f, y1 + 0.5f, y1 + 0.5f};
774 while (count > 0) { 794 while (count > 0) {
775 Sk4f xs = Sk4f{-0.5f, 0.5f, -0.5f, 0.5f} + Sk4f{x}; 795 Sk4f xs = Sk4f{-0.5f, 0.5f, -0.5f, 0.5f} + Sk4f{x};
776 this->bilerpEdge(xs, ys); 796 this->bilerpEdge(xs, ys);
777 x += dx; 797 x += dx;
778 count -= 1; 798 count -= 1;
779 } 799 }
780 } 800 }
781 } 801 }
782 802
783 Next* const fNext; 803 Next* const fNext;
784 PixelAccessor<colorType, colorProfile> fStrategy; 804 PixelAccessor<colorType, colorProfile> fStrategy;
785 }; 805 };
786 806
787 } // namespace 807 } // namespace
788 808
789 #endif // SkLinearBitmapPipeline_sampler_DEFINED 809 #endif // SkLinearBitmapPipeline_sampler_DEFINED
OLDNEW
« no previous file with comments | « src/core/SkLinearBitmapPipeline_core.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698