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

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

Issue 1719333002: tile spans (Closed) Base URL: https://skia.googlesource.com/skia.git@code-organization-speed
Patch Set: After sync Created 4 years, 10 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 | « no previous file | 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 #include "SkLinearBitmapPipeline.h" 8 #include "SkLinearBitmapPipeline.h"
9 #include "SkPM4f.h" 9 #include "SkPM4f.h"
10 10
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 , fXMax{X(max) - 1.0f} 367 , fXMax{X(max) - 1.0f}
368 , fYMax{Y(max) - 1.0f} { } 368 , fYMax{Y(max) - 1.0f} { }
369 369
370 void processPoints(Sk4f* xs, Sk4f* ys) { 370 void processPoints(Sk4f* xs, Sk4f* ys) {
371 *xs = Sk4f::Min(Sk4f::Max(*xs, fXMin), fXMax); 371 *xs = Sk4f::Min(Sk4f::Max(*xs, fXMin), fXMax);
372 *ys = Sk4f::Min(Sk4f::Max(*ys, fYMin), fYMax); 372 *ys = Sk4f::Min(Sk4f::Max(*ys, fYMin), fYMax);
373 } 373 }
374 374
375 template <typename Next> 375 template <typename Next>
376 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { 376 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) {
377 return false; 377 SkScalar xMin = fXMin[0];
mtklein 2016/02/23 15:51:56 It's occurred to me that we should probably be usi
herb_g 2016/02/23 21:10:23 Done.
378 SkScalar xMax = fXMax[0];
379 SkScalar yMin = fYMin[0];
380 SkScalar yMax = fYMax[0];
381 SkScalar x = X(start);
382 SkScalar y = std::min(std::max(yMin, start.fY), yMax);
mtklein 2016/02/23 15:51:56 Weird to write X(start) and start.fY...
herb_g 2016/02/23 21:10:23 Done.
383
mtklein 2016/02/23 15:51:56 Some ideas: - invert the logic so the easy case
herb_g 2016/02/23 21:10:23 I did this a totally different way. Please re-revi
384 int beforeCount = 0;
385 int middleCount = count;
386 int afterCount = 0;
387 if (x < xMin || x + length > xMax) {
388 SkScalar dx = length / (count - 1);
f(malita) 2016/02/23 20:53:48 'count' is the span/pixel count, right - why (coun
f(malita) 2016/02/23 21:04:08 A more general comment re. dx and dst->src mapping
389
390 if (x < xMin) {
391 SkScalar overLength = xMin - x;
392 beforeCount = SkScalarFloorToInt(overLength / dx) + 1;
393 middleCount -= beforeCount;
394 length = length - dx * beforeCount;
395 x = xMin;
396 }
397
398 if (x + length > xMax) {
399 SkScalar overLength = (x + length) - xMax;
400 afterCount = SkScalarFloorToInt(overLength / dx) + 1;
401 middleCount -= afterCount;
402 length = length - dx * afterCount;
403 }
404 auto SendSpan = [&](SkPoint start, SkScalar length, int count) {
f(malita) 2016/02/23 20:53:48 Looks like we only need to capture 'next' here.
herb_g 2016/02/23 21:30:35 This is gone. I made Span handle count == 1.
405 if (count > 0) {
406 if (count == 1) {
407 next->pointListFew(1, Sk4f{X(start)}, Sk4f{Y(start)});
mtklein 2016/02/23 15:51:56 Why can't pointSpan handle count == 1?
herb_g 2016/02/23 21:30:35 There was a NaN problem with the division in a dee
408 } else {
409 next->pointSpan(start, length, count);
410 }
411 }
412 };
413 SendSpan(SkPoint{xMin, y}, 0.0f, beforeCount);
414 SendSpan(SkPoint{x, y}, length, middleCount);
415 SendSpan(SkPoint{xMax - 1, y}, 0.0f, afterCount);
416 } else {
417 next->pointSpan(start, length, count);
418 }
419
420 return true;
378 } 421 }
379 422
380 private: 423 private:
381 const Sk4f fXMin{SK_FloatNegativeInfinity}; 424 const Sk4f fXMin{SK_FloatNegativeInfinity};
382 const Sk4f fYMin{SK_FloatNegativeInfinity}; 425 const Sk4f fYMin{SK_FloatNegativeInfinity};
383 const Sk4f fXMax{SK_FloatInfinity}; 426 const Sk4f fXMax{SK_FloatInfinity};
384 const Sk4f fYMax{SK_FloatInfinity}; 427 const Sk4f fYMax{SK_FloatInfinity};
385 }; 428 };
386 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface> 429 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface>
387 using Clamp = BilerpProcessor<ClampStrategy, Next>; 430 using Clamp = BilerpProcessor<ClampStrategy, Next>;
388 431
432 // It would be nice to use fmod, but it uses trunc based rounding where floor ro unding is needed.
433 static float tile_mod(float l, float base) {
mtklein 2016/02/23 15:51:56 I think you might want to pick a different letter-
herb_g 2016/02/23 21:10:23 Done.
434 return l - std::floor(l / base) * base;
mtklein 2016/02/23 15:51:56 We're getting a little loosey-goosey about SkScala
herb_g 2016/02/23 21:10:23 Done.
435 }
436
389 class RepeatStrategy { 437 class RepeatStrategy {
390 public: 438 public:
391 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { } 439 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { }
392 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { } 440 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { }
393 RepeatStrategy(SkSize max) 441 RepeatStrategy(SkSize max)
394 : fXMax{X(max)} 442 : fXMax{X(max)}
395 , fXInvMax{1.0f / X(max)} 443 , fXInvMax{1.0f / X(max)}
396 , fYMax{Y(max)} 444 , fYMax{Y(max)}
397 , fYInvMax{1.0f / Y(max)} { } 445 , fYInvMax{1.0f / Y(max)} { }
398 446
399 void processPoints(Sk4f* xs, Sk4f* ys) { 447 void processPoints(Sk4f* xs, Sk4f* ys) {
400 Sk4f divX = (*xs * fXInvMax).floor(); 448 Sk4f divX = (*xs * fXInvMax).floor();
401 Sk4f divY = (*ys * fYInvMax).floor(); 449 Sk4f divY = (*ys * fYInvMax).floor();
402 Sk4f baseX = (divX * fXMax); 450 Sk4f baseX = (divX * fXMax);
403 Sk4f baseY = (divY * fYMax); 451 Sk4f baseY = (divY * fYMax);
404 *xs = *xs - baseX; 452 *xs = *xs - baseX;
405 *ys = *ys - baseY; 453 *ys = *ys - baseY;
406 } 454 }
407 455
408 template <typename Next> 456 template <typename Next>
409 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { 457 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) {
410 return false; 458 SkScalar x = tile_mod(X(start), fXMax[0]);
459 SkScalar y = tile_mod(Y(start), fYMax[0]);
460 SkScalar dx = length / (count - 1);
f(malita) 2016/02/23 20:53:48 Same question re count - 1.
herb_g 2016/02/23 21:30:35 Added much documentation. See if that answers the
461 auto SendSpan = [&](SkPoint start, SkScalar length, int count) {
462 if (count > 0) {
463 if (count == 1) {
464 next->pointListFew(1, Sk4f{X(start)}, Sk4f{Y(start)});
465 } else {
466 next->pointSpan(start, length, count);
467 }
468 }
469 };
470 while (x + length > fXMax[0]) {
mtklein 2016/02/23 15:51:56 Explain how this works?
herb_g 2016/02/23 21:10:23 Done.
471 SkScalar lengthForTile = std::min(fXMax[0] - x, length);
472 int countForTile = SkScalarFloorToInt(lengthForTile / dx);
f(malita) 2016/02/23 20:53:48 I noticed we always pad one to the count in the cl
herb_g 2016/02/23 21:30:35 If the source is 1 pixel wide, then this should ma
473 SkScalar lengthForDx = countForTile * dx;
474 SendSpan({x, y}, lengthForDx, countForTile);
475 length -= lengthForDx;
476 count -= countForTile;
f(malita) 2016/02/23 20:53:48 Looks like we only track count in order to handle
herb_g 2016/02/23 21:30:35 That would mean a bunch of calculation in the comm
477 x = 0;
478 }
479 SendSpan({x, y}, length, count);
480
481 return true;
411 } 482 }
412 483
413 private: 484 private:
414 const Sk4f fXMax{0.0f}; 485 const Sk4f fXMax{0.0f};
415 const Sk4f fXInvMax{0.0f}; 486 const Sk4f fXInvMax{0.0f};
416 const Sk4f fYMax{0.0f}; 487 const Sk4f fYMax{0.0f};
417 const Sk4f fYInvMax{0.0f}; 488 const Sk4f fYInvMax{0.0f};
418 }; 489 };
419 490
420 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface> 491 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface>
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 if (count == 1) { 772 if (count == 1) {
702 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f}); 773 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f});
703 } else { 774 } else {
704 // The count and length arguments start out in a precise relation in ord er to keep the 775 // The count and length arguments start out in a precise relation in ord er to keep the
705 // math correct through the different stages. Count is the number of pix el to produce. 776 // math correct through the different stages. Count is the number of pix el to produce.
706 // Since the code samples at pixel centers, length is the distance from the center of the 777 // Since the code samples at pixel centers, length is the distance from the center of the
707 // first pixel to the center of the last pixel. This implies that length is count-1. 778 // first pixel to the center of the last pixel. This implies that length is count-1.
708 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count); 779 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count);
709 } 780 }
710 } 781 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698