| 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 #include "SkLinearBitmapPipeline.h" | 8 #include "SkLinearBitmapPipeline.h" |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 }; | 560 }; |
| 561 | 561 |
| 562 const uint32_t* const fSrc; | 562 const uint32_t* const fSrc; |
| 563 const int32_t fWidth; | 563 const int32_t fWidth; |
| 564 uint32_t* fDest; | 564 uint32_t* fDest; |
| 565 uint32_t* fEnd; | 565 uint32_t* fEnd; |
| 566 }; | 566 }; |
| 567 | 567 |
| 568 using Blender = SkLinearBitmapPipeline::BlendProcessorInterface; | 568 using Blender = SkLinearBitmapPipeline::BlendProcessorInterface; |
| 569 | 569 |
| 570 template <SkColorType colorType, template <SkColorType, SkGammaType, typename> c
lass Sampler> | 570 template <SkColorType colorType> |
| 571 static void choose_specific_sampler( | 571 static SkLinearBitmapPipeline::PixelAccessorInterface* choose_specific_accessor( |
| 572 Blender* next, | 572 const SkPixmap& srcPixmap, SkLinearBitmapPipeline::Accessor* accessor) |
| 573 const SkPixmap& srcPixmap, | |
| 574 SkLinearBitmapPipeline::SampleStage* sampleStage) | |
| 575 { | 573 { |
| 576 if (srcPixmap.info().gammaCloseToSRGB()) { | 574 if (srcPixmap.info().gammaCloseToSRGB()) { |
| 577 using S = Sampler<colorType, kSRGB_SkGammaType, Blender>; | 575 using PA = PixelAccessor<colorType, kSRGB_SkGammaType>; |
| 578 sampleStage->initStage<S>(next, srcPixmap); | 576 accessor->init<PA>(srcPixmap); |
| 577 return accessor->get(); |
| 579 } else { | 578 } else { |
| 580 using S = Sampler<colorType, kLinear_SkGammaType, Blender>; | 579 using PA = PixelAccessor<colorType, kLinear_SkGammaType>; |
| 581 sampleStage->initStage<S>(next, srcPixmap); | 580 accessor->init<PA>(srcPixmap); |
| 581 return accessor->get(); |
| 582 } | 582 } |
| 583 } | 583 } |
| 584 | 584 |
| 585 template<template <SkColorType, SkGammaType, typename> class Sampler> | 585 template<template <typename, typename> class Sampler> |
| 586 static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_ba
se( | 586 static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_ba
se( |
| 587 Blender* next, | 587 Blender* next, |
| 588 const SkPixmap& srcPixmap, | 588 const SkPixmap& srcPixmap, |
| 589 const SkColor A8TintColor, | 589 const SkColor A8TintColor, |
| 590 SkLinearBitmapPipeline::SampleStage* sampleStage) | 590 SkLinearBitmapPipeline::SampleStage* sampleStage, |
| 591 SkLinearBitmapPipeline::Accessor* accessor) |
| 591 { | 592 { |
| 592 const SkImageInfo& imageInfo = srcPixmap.info(); | 593 const SkImageInfo& imageInfo = srcPixmap.info(); |
| 594 |
| 595 SkLinearBitmapPipeline::PixelAccessorInterface* pixelAccessor = nullptr; |
| 593 switch (imageInfo.colorType()) { | 596 switch (imageInfo.colorType()) { |
| 594 case kAlpha_8_SkColorType: { | 597 case kAlpha_8_SkColorType: { |
| 595 using S = Sampler<kAlpha_8_SkColorType, kLinear_SkGammaType, Ble
nder>; | 598 using PA = PixelAccessor<kAlpha_8_SkColorType, kLinear_SkGammaTy
pe>; |
| 596 sampleStage->initStage<S>(next, srcPixmap, A8TintColor); | 599 accessor->init<PA>(srcPixmap, A8TintColor); |
| 600 pixelAccessor = accessor->get(); |
| 597 } | 601 } |
| 598 break; | 602 break; |
| 599 case kARGB_4444_SkColorType: | 603 case kARGB_4444_SkColorType: |
| 600 choose_specific_sampler<kARGB_4444_SkColorType, Sampler>(next, srcPi
xmap, sampleStage); | 604 pixelAccessor = choose_specific_accessor<kARGB_4444_SkColorType>(src
Pixmap, accessor); |
| 601 break; | 605 break; |
| 602 case kRGB_565_SkColorType: | 606 case kRGB_565_SkColorType: |
| 603 choose_specific_sampler<kRGB_565_SkColorType, Sampler>(next, srcPixm
ap, sampleStage); | 607 pixelAccessor = choose_specific_accessor<kRGB_565_SkColorType>(srcPi
xmap, accessor); |
| 604 break; | 608 break; |
| 605 case kRGBA_8888_SkColorType: | 609 case kRGBA_8888_SkColorType: |
| 606 choose_specific_sampler<kRGBA_8888_SkColorType, Sampler>(next, srcPi
xmap, sampleStage); | 610 pixelAccessor = choose_specific_accessor<kRGBA_8888_SkColorType>(src
Pixmap, accessor); |
| 607 break; | 611 break; |
| 608 case kBGRA_8888_SkColorType: | 612 case kBGRA_8888_SkColorType: |
| 609 choose_specific_sampler<kBGRA_8888_SkColorType, Sampler>(next, srcPi
xmap, sampleStage); | 613 pixelAccessor = choose_specific_accessor<kBGRA_8888_SkColorType>(src
Pixmap, accessor); |
| 610 break; | 614 break; |
| 611 case kIndex_8_SkColorType: | 615 case kIndex_8_SkColorType: |
| 612 choose_specific_sampler<kIndex_8_SkColorType, Sampler>(next, srcPixm
ap, sampleStage); | 616 pixelAccessor = choose_specific_accessor<kIndex_8_SkColorType>(srcPi
xmap, accessor); |
| 613 break; | 617 break; |
| 614 case kGray_8_SkColorType: | 618 case kGray_8_SkColorType: |
| 615 choose_specific_sampler<kGray_8_SkColorType, Sampler>(next, srcPixma
p, sampleStage); | 619 pixelAccessor = choose_specific_accessor<kGray_8_SkColorType>(srcPix
map, accessor); |
| 616 break; | 620 break; |
| 617 case kRGBA_F16_SkColorType: { | 621 case kRGBA_F16_SkColorType: { |
| 618 using S = Sampler<kRGBA_F16_SkColorType, kLinear_SkGammaType, Bl
ender>; | 622 using PA = PixelAccessor<kRGBA_F16_SkColorType, kLinear_SkGammaT
ype>; |
| 619 sampleStage->initStage<S>(next, srcPixmap); | 623 accessor->init<PA>(srcPixmap); |
| 624 pixelAccessor = accessor->get(); |
| 620 } | 625 } |
| 621 break; | 626 break; |
| 622 default: | 627 default: |
| 623 SkFAIL("Not implemented. Unsupported src"); | 628 SkFAIL("Not implemented. Unsupported src"); |
| 624 break; | 629 break; |
| 625 } | 630 } |
| 631 |
| 632 using S = Sampler<PixelAccessorShim, Blender>; |
| 633 sampleStage->initStage<S>(next, pixelAccessor); |
| 626 return sampleStage->get(); | 634 return sampleStage->get(); |
| 627 } | 635 } |
| 628 | 636 |
| 629 SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler( | 637 SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler( |
| 630 Blender* next, | 638 Blender* next, |
| 631 SkFilterQuality filterQuality, | 639 SkFilterQuality filterQuality, |
| 632 const SkPixmap& srcPixmap, | 640 const SkPixmap& srcPixmap, |
| 633 const SkColor A8TintColor, | 641 const SkColor A8TintColor, |
| 634 SkLinearBitmapPipeline::SampleStage* sampleStage) | 642 SkLinearBitmapPipeline::SampleStage* sampleStage, |
| 635 { | 643 SkLinearBitmapPipeline::Accessor* accessor) { |
| 644 const SkImageInfo& imageInfo = srcPixmap.info(); |
| 645 |
| 646 // Special case samplers with fully expanded templates |
| 647 if (imageInfo.gammaCloseToSRGB()) { |
| 648 if (filterQuality == kNone_SkFilterQuality) { |
| 649 switch (imageInfo.colorType()) { |
| 650 case kN32_SkColorType: { |
| 651 using S = |
| 652 NearestNeighborSampler< |
| 653 PixelAccessor<kN32_SkColorType, kSRGB_SkGammaType>, Blen
der>; |
| 654 sampleStage->initStage<S>(next, srcPixmap); |
| 655 return sampleStage->get(); |
| 656 } |
| 657 case kIndex_8_SkColorType: { |
| 658 using S = |
| 659 NearestNeighborSampler< |
| 660 PixelAccessor<kIndex_8_SkColorType, kSRGB_SkGammaType>,
Blender>; |
| 661 sampleStage->initStage<S>(next, srcPixmap); |
| 662 return sampleStage->get(); |
| 663 } |
| 664 default: |
| 665 break; |
| 666 } |
| 667 } else { |
| 668 switch (imageInfo.colorType()) { |
| 669 case kN32_SkColorType: { |
| 670 using S = |
| 671 BilerpSampler< |
| 672 PixelAccessor<kN32_SkColorType, kSRGB_SkGammaType>, Blen
der>; |
| 673 sampleStage->initStage<S>(next, srcPixmap); |
| 674 return sampleStage->get(); |
| 675 } |
| 676 case kIndex_8_SkColorType: { |
| 677 using S = |
| 678 BilerpSampler< |
| 679 PixelAccessor<kIndex_8_SkColorType, kSRGB_SkGammaType>,
Blender>; |
| 680 sampleStage->initStage<S>(next, srcPixmap); |
| 681 return sampleStage->get(); |
| 682 } |
| 683 default: |
| 684 break; |
| 685 } |
| 686 } |
| 687 } |
| 688 |
| 689 // General cases. |
| 636 if (filterQuality == kNone_SkFilterQuality) { | 690 if (filterQuality == kNone_SkFilterQuality) { |
| 637 return choose_pixel_sampler_base<NearestNeighborSampler>( | 691 return choose_pixel_sampler_base<NearestNeighborSampler>( |
| 638 next, srcPixmap, A8TintColor, sampleStage); | 692 next, srcPixmap, A8TintColor, sampleStage, accessor); |
| 639 } else { | 693 } else { |
| 640 return choose_pixel_sampler_base<BilerpSampler>(next, srcPixmap, A8TintC
olor, sampleStage); | 694 return choose_pixel_sampler_base<BilerpSampler>( |
| 695 next, srcPixmap, A8TintColor, sampleStage, accessor); |
| 641 } | 696 } |
| 642 } | 697 } |
| 643 | 698 |
| 644 ////////////////////////////////////////////////////////////////////////////////
//////////////////// | 699 ////////////////////////////////////////////////////////////////////////////////
//////////////////// |
| 645 // Pixel Blender Stage | 700 // Pixel Blender Stage |
| 646 template <SkAlphaType alphaType> | 701 template <SkAlphaType alphaType> |
| 647 class SrcFPPixel final : public SkLinearBitmapPipeline::BlendProcessorInterface
{ | 702 class SrcFPPixel final : public SkLinearBitmapPipeline::BlendProcessorInterface
{ |
| 648 public: | 703 public: |
| 649 SrcFPPixel(float postAlpha) : fPostAlpha{postAlpha} { } | 704 SrcFPPixel(float postAlpha) : fPostAlpha{postAlpha} { } |
| 650 SrcFPPixel(const SrcFPPixel& Blender) : fPostAlpha(Blender.fPostAlpha) {} | 705 SrcFPPixel(const SrcFPPixel& Blender) : fPostAlpha(Blender.fPostAlpha) {} |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 SkAlphaType alphaType = srcImageInfo.alphaType(); | 790 SkAlphaType alphaType = srcImageInfo.alphaType(); |
| 736 if (srcPixmap.colorType() == kIndex_8_SkColorType) { | 791 if (srcPixmap.colorType() == kIndex_8_SkColorType) { |
| 737 alphaType = kUnpremul_SkAlphaType; | 792 alphaType = kUnpremul_SkAlphaType; |
| 738 } | 793 } |
| 739 | 794 |
| 740 float postAlpha = SkColorGetA(paintColor) * (1.0f / 255.0f); | 795 float postAlpha = SkColorGetA(paintColor) * (1.0f / 255.0f); |
| 741 // As the stages are built, the chooser function may skip a stage. For examp
le, with the | 796 // As the stages are built, the chooser function may skip a stage. For examp
le, with the |
| 742 // identity matrix, the matrix stage is skipped, and the tilerStage is the f
irst stage. | 797 // identity matrix, the matrix stage is skipped, and the tilerStage is the f
irst stage. |
| 743 auto blenderStage = choose_blender_for_shading(alphaType, postAlpha, &fBlend
erStage); | 798 auto blenderStage = choose_blender_for_shading(alphaType, postAlpha, &fBlend
erStage); |
| 744 auto samplerStage = choose_pixel_sampler( | 799 auto samplerStage = choose_pixel_sampler( |
| 745 blenderStage, filterQuality, srcPixmap, paintColor, &fSampleStage); | 800 blenderStage, filterQuality, srcPixmap, paintColor, &fSampleStage, &fAcc
essor); |
| 746 auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile, | 801 auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile, |
| 747 filterQuality, dx, &fTileStage); | 802 filterQuality, dx, &fTileStage); |
| 748 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage
); | 803 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage
); |
| 749 fLastStage = blenderStage; | 804 fLastStage = blenderStage; |
| 750 } | 805 } |
| 751 | 806 |
| 752 bool SkLinearBitmapPipeline::ClonePipelineForBlitting( | 807 bool SkLinearBitmapPipeline::ClonePipelineForBlitting( |
| 753 SkEmbeddableLinearPipeline* pipelineStorage, | 808 SkEmbeddableLinearPipeline* pipelineStorage, |
| 754 const SkLinearBitmapPipeline& pipeline, | 809 const SkLinearBitmapPipeline& pipeline, |
| 755 SkMatrix::TypeMask matrixMask, | 810 SkMatrix::TypeMask matrixMask, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 void SkLinearBitmapPipeline::blitSpan(int x, int y, void* dst, int count) { | 876 void SkLinearBitmapPipeline::blitSpan(int x, int y, void* dst, int count) { |
| 822 SkASSERT(count > 0); | 877 SkASSERT(count > 0); |
| 823 fLastStage->setDestination(dst, count); | 878 fLastStage->setDestination(dst, count); |
| 824 | 879 |
| 825 // The count and length arguments start out in a precise relation in order t
o keep the | 880 // The count and length arguments start out in a precise relation in order t
o keep the |
| 826 // math correct through the different stages. Count is the number of pixel t
o produce. | 881 // math correct through the different stages. Count is the number of pixel t
o produce. |
| 827 // Since the code samples at pixel centers, length is the distance from the
center of the | 882 // Since the code samples at pixel centers, length is the distance from the
center of the |
| 828 // first pixel to the center of the last pixel. This implies that length is
count-1. | 883 // first pixel to the center of the last pixel. This implies that length is
count-1. |
| 829 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); | 884 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); |
| 830 } | 885 } |
| OLD | NEW |