| 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 |