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 |