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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 }; | 701 }; |
702 | 702 |
703 const uint32_t* const fSrc; | 703 const uint32_t* const fSrc; |
704 const int32_t fWidth; | 704 const int32_t fWidth; |
705 uint32_t* fDest; | 705 uint32_t* fDest; |
706 uint32_t* fEnd; | 706 uint32_t* fEnd; |
707 }; | 707 }; |
708 | 708 |
709 using Blender = SkLinearBitmapPipeline::BlendProcessorInterface; | 709 using Blender = SkLinearBitmapPipeline::BlendProcessorInterface; |
710 | 710 |
| 711 template <SkColorType colorType, template <SkColorType, SkColorProfileType, type
name> class Sampler> |
| 712 static void choose_specific_sampler( |
| 713 Blender* next, |
| 714 const SkPixmap& srcPixmap, |
| 715 SkLinearBitmapPipeline::SampleStage* sampleStage) |
| 716 { |
| 717 if (srcPixmap.info().profileType() == kSRGB_SkColorProfileType) { |
| 718 using S = Sampler<colorType, kSRGB_SkColorProfileType, Blender>; |
| 719 sampleStage->initStage<S>(next, srcPixmap); |
| 720 } else { |
| 721 using S = Sampler<colorType, kLinear_SkColorProfileType, Blender>; |
| 722 sampleStage->initStage<S>(next, srcPixmap); |
| 723 } |
| 724 } |
| 725 |
711 template<template <SkColorType, SkColorProfileType, typename> class Sampler> | 726 template<template <SkColorType, SkColorProfileType, typename> class Sampler> |
712 static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_ba
se( | 727 static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_ba
se( |
713 Blender* next, | 728 Blender* next, |
714 const SkPixmap& srcPixmap, | 729 const SkPixmap& srcPixmap, |
715 SkLinearBitmapPipeline::SampleStage* sampleStage) { | 730 const SkColor A8TintColor, |
| 731 SkLinearBitmapPipeline::SampleStage* sampleStage) |
| 732 { |
716 const SkImageInfo& imageInfo = srcPixmap.info(); | 733 const SkImageInfo& imageInfo = srcPixmap.info(); |
717 switch (imageInfo.colorType()) { | 734 switch (imageInfo.colorType()) { |
718 case kRGBA_8888_SkColorType: | 735 case kAlpha_8_SkColorType: { |
719 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { | 736 using S = Sampler<kAlpha_8_SkColorType, kLinear_SkColorProfileTy
pe, Blender>; |
720 using S = Sampler<kRGBA_8888_SkColorType, kSRGB_SkColorProfileTy
pe, Blender>; | 737 sampleStage->initStage<S>(next, srcPixmap, A8TintColor); |
721 sampleStage->initStage<S>(next, srcPixmap); | |
722 } else { | |
723 using S = Sampler<kRGBA_8888_SkColorType, kLinear_SkColorProfile
Type, Blender>; | |
724 sampleStage->initStage<S>(next, srcPixmap); | |
725 } | 738 } |
726 break; | 739 break; |
| 740 case kARGB_4444_SkColorType: |
| 741 choose_specific_sampler<kARGB_4444_SkColorType, Sampler>(next, srcPi
xmap, sampleStage); |
| 742 break; |
| 743 case kRGB_565_SkColorType: |
| 744 choose_specific_sampler<kRGB_565_SkColorType, Sampler>(next, srcPixm
ap, sampleStage); |
| 745 break; |
| 746 case kRGBA_8888_SkColorType: |
| 747 choose_specific_sampler<kRGBA_8888_SkColorType, Sampler>(next, srcPi
xmap, sampleStage); |
| 748 break; |
727 case kBGRA_8888_SkColorType: | 749 case kBGRA_8888_SkColorType: |
728 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { | 750 choose_specific_sampler<kBGRA_8888_SkColorType, Sampler>(next, srcPi
xmap, sampleStage); |
729 using S = Sampler<kBGRA_8888_SkColorType, kSRGB_SkColorProfileTy
pe, Blender>; | |
730 sampleStage->initStage<S>(next, srcPixmap); | |
731 } else { | |
732 using S = Sampler<kBGRA_8888_SkColorType, kLinear_SkColorProfile
Type, Blender>; | |
733 sampleStage->initStage<S>(next, srcPixmap); | |
734 } | |
735 break; | 751 break; |
736 case kIndex_8_SkColorType: | 752 case kIndex_8_SkColorType: |
737 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { | 753 choose_specific_sampler<kIndex_8_SkColorType, Sampler>(next, srcPixm
ap, sampleStage); |
738 using S = Sampler<kIndex_8_SkColorType, kSRGB_SkColorProfileType
, Blender>; | 754 break; |
739 sampleStage->initStage<S>(next, srcPixmap); | 755 case kGray_8_SkColorType: |
740 } else { | 756 choose_specific_sampler<kGray_8_SkColorType, Sampler>(next, srcPixma
p, sampleStage); |
741 using S = Sampler<kIndex_8_SkColorType, kLinear_SkColorProfileTy
pe, Blender>; | |
742 sampleStage->initStage<S>(next, srcPixmap); | |
743 } | |
744 break; | 757 break; |
745 case kRGBA_F16_SkColorType: { | 758 case kRGBA_F16_SkColorType: { |
746 using S = Sampler<kRGBA_F16_SkColorType, kLinear_SkColorProfileT
ype, Blender>; | 759 using S = Sampler<kRGBA_F16_SkColorType, kLinear_SkColorProfileT
ype, Blender>; |
747 sampleStage->initStage<S>(next, srcPixmap); | 760 sampleStage->initStage<S>(next, srcPixmap); |
748 } | 761 } |
749 break; | 762 break; |
750 default: | 763 default: |
751 SkFAIL("Not implemented. Unsupported src"); | 764 SkFAIL("Not implemented. Unsupported src"); |
752 break; | 765 break; |
753 } | 766 } |
754 return sampleStage->get(); | 767 return sampleStage->get(); |
755 } | 768 } |
756 | 769 |
757 SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler( | 770 SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler( |
758 Blender* next, | 771 Blender* next, |
759 SkFilterQuality filterQuality, | 772 SkFilterQuality filterQuality, |
760 const SkPixmap& srcPixmap, | 773 const SkPixmap& srcPixmap, |
| 774 const SkColor A8TintColor, |
761 SkLinearBitmapPipeline::SampleStage* sampleStage) | 775 SkLinearBitmapPipeline::SampleStage* sampleStage) |
762 { | 776 { |
763 if (filterQuality == kNone_SkFilterQuality) { | 777 if (filterQuality == kNone_SkFilterQuality) { |
764 return choose_pixel_sampler_base<NearestNeighborSampler>(next, srcPixmap
, sampleStage); | 778 return choose_pixel_sampler_base<NearestNeighborSampler>( |
| 779 next, srcPixmap, A8TintColor, sampleStage); |
765 } else { | 780 } else { |
766 return choose_pixel_sampler_base<BilerpSampler>(next, srcPixmap, sampleS
tage); | 781 return choose_pixel_sampler_base<BilerpSampler>(next, srcPixmap, A8TintC
olor, sampleStage); |
767 } | 782 } |
768 } | 783 } |
769 | 784 |
770 ////////////////////////////////////////////////////////////////////////////////
//////////////////// | 785 ////////////////////////////////////////////////////////////////////////////////
//////////////////// |
771 // Pixel Blender Stage | 786 // Pixel Blender Stage |
772 template <SkAlphaType alphaType> | 787 template <SkAlphaType alphaType> |
773 class SrcFPPixel final : public SkLinearBitmapPipeline::BlendProcessorInterface
{ | 788 class SrcFPPixel final : public SkLinearBitmapPipeline::BlendProcessorInterface
{ |
774 public: | 789 public: |
775 SrcFPPixel(float postAlpha) : fPostAlpha{postAlpha} { } | 790 SrcFPPixel(float postAlpha) : fPostAlpha{postAlpha} { } |
776 SrcFPPixel(const SrcFPPixel& Blender) : fPostAlpha(Blender.fPostAlpha) {} | 791 SrcFPPixel(const SrcFPPixel& Blender) : fPostAlpha(Blender.fPostAlpha) {} |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 } // namespace | 845 } // namespace |
831 | 846 |
832 ////////////////////////////////////////////////////////////////////////////////
//////////////////// | 847 ////////////////////////////////////////////////////////////////////////////////
//////////////////// |
833 // SkLinearBitmapPipeline | 848 // SkLinearBitmapPipeline |
834 SkLinearBitmapPipeline::~SkLinearBitmapPipeline() {} | 849 SkLinearBitmapPipeline::~SkLinearBitmapPipeline() {} |
835 | 850 |
836 SkLinearBitmapPipeline::SkLinearBitmapPipeline( | 851 SkLinearBitmapPipeline::SkLinearBitmapPipeline( |
837 const SkMatrix& inverse, | 852 const SkMatrix& inverse, |
838 SkFilterQuality filterQuality, | 853 SkFilterQuality filterQuality, |
839 SkShader::TileMode xTile, SkShader::TileMode yTile, | 854 SkShader::TileMode xTile, SkShader::TileMode yTile, |
840 float postAlpha, | 855 SkColor paintColor, |
841 const SkPixmap& srcPixmap) | 856 const SkPixmap& srcPixmap) |
842 { | 857 { |
843 SkISize dimensions = srcPixmap.info().dimensions(); | 858 SkISize dimensions = srcPixmap.info().dimensions(); |
844 const SkImageInfo& srcImageInfo = srcPixmap.info(); | 859 const SkImageInfo& srcImageInfo = srcPixmap.info(); |
845 | 860 |
846 SkMatrix adjustedInverse = inverse; | 861 SkMatrix adjustedInverse = inverse; |
847 if (filterQuality == kNone_SkFilterQuality) { | 862 if (filterQuality == kNone_SkFilterQuality) { |
848 if (inverse.getScaleX() >= 0.0f) { | 863 if (inverse.getScaleX() >= 0.0f) { |
849 adjustedInverse.setTranslateX( | 864 adjustedInverse.setTranslateX( |
850 nextafterf(inverse.getTranslateX(), std::floor(inverse.getTransl
ateX()))); | 865 nextafterf(inverse.getTranslateX(), std::floor(inverse.getTransl
ateX()))); |
851 } | 866 } |
852 if (inverse.getScaleY() >= 0.0f) { | 867 if (inverse.getScaleY() >= 0.0f) { |
853 adjustedInverse.setTranslateY( | 868 adjustedInverse.setTranslateY( |
854 nextafterf(inverse.getTranslateY(), std::floor(inverse.getTransl
ateY()))); | 869 nextafterf(inverse.getTranslateY(), std::floor(inverse.getTransl
ateY()))); |
855 } | 870 } |
856 } | 871 } |
857 | 872 |
858 SkScalar dx = adjustedInverse.getScaleX(); | 873 SkScalar dx = adjustedInverse.getScaleX(); |
859 | 874 |
860 // If it is an index 8 color type, the sampler converts to unpremul for bett
er fidelity. | 875 // If it is an index 8 color type, the sampler converts to unpremul for bett
er fidelity. |
861 SkAlphaType alphaType = srcImageInfo.alphaType(); | 876 SkAlphaType alphaType = srcImageInfo.alphaType(); |
862 if (srcPixmap.colorType() == kIndex_8_SkColorType) { | 877 if (srcPixmap.colorType() == kIndex_8_SkColorType) { |
863 alphaType = kUnpremul_SkAlphaType; | 878 alphaType = kUnpremul_SkAlphaType; |
864 } | 879 } |
865 | 880 |
| 881 float postAlpha = SkColorGetA(paintColor) * (1.0f / 255.0f); |
866 // As the stages are built, the chooser function may skip a stage. For examp
le, with the | 882 // As the stages are built, the chooser function may skip a stage. For examp
le, with the |
867 // identity matrix, the matrix stage is skipped, and the tilerStage is the f
irst stage. | 883 // identity matrix, the matrix stage is skipped, and the tilerStage is the f
irst stage. |
868 auto blenderStage = choose_blender_for_shading(alphaType, postAlpha, &fBlend
erStage); | 884 auto blenderStage = choose_blender_for_shading(alphaType, postAlpha, &fBlend
erStage); |
869 auto samplerStage = choose_pixel_sampler(blenderStage, filterQuality, srcPix
map, &fSampleStage); | 885 auto samplerStage = choose_pixel_sampler( |
| 886 blenderStage, filterQuality, srcPixmap, paintColor, &fSampleStage); |
870 auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile, | 887 auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile, |
871 filterQuality, dx, &fTileStage); | 888 filterQuality, dx, &fTileStage); |
872 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage
); | 889 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage
); |
873 fLastStage = blenderStage; | 890 fLastStage = blenderStage; |
874 } | 891 } |
875 | 892 |
876 bool SkLinearBitmapPipeline::ClonePipelineForBlitting( | 893 bool SkLinearBitmapPipeline::ClonePipelineForBlitting( |
877 void* blitterStorage, | 894 void* blitterStorage, |
878 const SkLinearBitmapPipeline& pipeline, | 895 const SkLinearBitmapPipeline& pipeline, |
879 SkMatrix::TypeMask matrixMask, | 896 SkMatrix::TypeMask matrixMask, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 void SkLinearBitmapPipeline::blitSpan(int x, int y, void* dst, int count) { | 961 void SkLinearBitmapPipeline::blitSpan(int x, int y, void* dst, int count) { |
945 SkASSERT(count > 0); | 962 SkASSERT(count > 0); |
946 fLastStage->setDestination(dst, count); | 963 fLastStage->setDestination(dst, count); |
947 | 964 |
948 // The count and length arguments start out in a precise relation in order t
o keep the | 965 // The count and length arguments start out in a precise relation in order t
o keep the |
949 // math correct through the different stages. Count is the number of pixel t
o produce. | 966 // math correct through the different stages. Count is the number of pixel t
o produce. |
950 // Since the code samples at pixel centers, length is the distance from the
center of the | 967 // Since the code samples at pixel centers, length is the distance from the
center of the |
951 // first pixel to the center of the last pixel. This implies that length is
count-1. | 968 // first pixel to the center of the last pixel. This implies that length is
count-1. |
952 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); | 969 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); |
953 } | 970 } |
OLD | NEW |