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

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

Issue 1743123004: Handle spans in sampling. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments. Created 4 years, 9 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 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2 , Sk4f* px3) { 738 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2 , Sk4f* px3) {
739 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); 739 Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
740 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); 740 Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
741 Sk4i bufferLoc = YIs * fWidth + XIs; 741 Sk4i bufferLoc = YIs * fWidth + XIs;
742 *px0 = this->getPixel(fSrc, bufferLoc[0]); 742 *px0 = this->getPixel(fSrc, bufferLoc[0]);
743 *px1 = this->getPixel(fSrc, bufferLoc[1]); 743 *px1 = this->getPixel(fSrc, bufferLoc[1]);
744 *px2 = this->getPixel(fSrc, bufferLoc[2]); 744 *px2 = this->getPixel(fSrc, bufferLoc[2]);
745 *px3 = this->getPixel(fSrc, bufferLoc[3]); 745 *px3 = this->getPixel(fSrc, bufferLoc[3]);
746 } 746 }
747 747
748 Sk4f getPixel(const uint32_t* src, int index) { 748 void get4Pixels(const void* vsrc, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2 , Sk4f* px3) {
749 const uint32_t* src = static_cast<const uint32_t*>(vsrc);
750 *px0 = this->getPixel(src, index + 0);
751 *px1 = this->getPixel(src, index + 1);
752 *px2 = this->getPixel(src, index + 2);
753 *px3 = this->getPixel(src, index + 3);
754 }
755
756 Sk4f getPixel(const void* vsrc, int index) {
757 const uint32_t* src = static_cast<const uint32_t*>(vsrc);
749 Sk4b bytePixel = Sk4b::Load((uint8_t *)(&src[index])); 758 Sk4b bytePixel = Sk4b::Load((uint8_t *)(&src[index]));
750 Sk4f pixel = SkNx_cast<float, uint8_t>(bytePixel); 759 Sk4f pixel = SkNx_cast<float, uint8_t>(bytePixel);
751 if (colorOrder == ColorOrder::kBGRA) { 760 if (colorOrder == ColorOrder::kBGRA) {
752 pixel = SkNx_shuffle<2, 1, 0, 3>(pixel); 761 pixel = SkNx_shuffle<2, 1, 0, 3>(pixel);
753 } 762 }
754 pixel = pixel * Sk4f{1.0f/255.0f}; 763 pixel = pixel * Sk4f{1.0f/255.0f};
755 if (colorProfile == kSRGB_SkColorProfileType) { 764 if (colorProfile == kSRGB_SkColorProfileType) {
756 pixel = sRGBFast::sRGBToLinear(pixel); 765 pixel = sRGBFast::sRGBToLinear(pixel);
757 } 766 }
758 return pixel; 767 return pixel;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 } 831 }
823 832
824 void VECTORCALL bilerpList(Sk4s xs, Sk4s ys) override { 833 void VECTORCALL bilerpList(Sk4s xs, Sk4s ys) override {
825 Sk4f px00, px10, px01, px11; 834 Sk4f px00, px10, px01, px11;
826 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11); 835 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11);
827 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); 836 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11);
828 fNext->placePixel(pixel); 837 fNext->placePixel(pixel);
829 } 838 }
830 839
831 void pointSpan(Span span) override { 840 void pointSpan(Span span) override {
841 SkASSERT(!span.isEmpty());
842 SkPoint start; SkScalar length; int count;
843 std::tie(start, length, count) = span;
844 if (length < (count - 1)) {
845 this->pointSpanSlowRate(span);
846 } else if (length == (count - 1)) {
847 this->pointSpanUnitRate(span);
848 } else {
849 this->pointSpanFastRate(span);
850 }
851 }
852
853 private:
854 // When moving through source space more slowly than dst space (zoomed in),
855 // we'll be sampling from the same source pixel more than once.
856 void pointSpanSlowRate(Span span) {
857 SkPoint start; SkScalar length; int count;
858 std::tie(start, length, count) = span;
859 SkScalar x = X(start);
860 SkFixed fx = SkScalarToFixed(x);
861 SkScalar dx = length / (count - 1);
862 SkFixed fdx = SkScalarToFixed(dx);
863
864 const void* row = fStrategy.row((int)std::floor(Y(start)));
865 SkLinearBitmapPipeline::PixelPlacerInterface* next = fNext;
866
867 int ix = SkFixedFloorToInt(fx);
868 int prevIX = ix;
869 Sk4f fpixel = fStrategy.getPixel(row, ix);
870
871 // When dx is less than one, each pixel is used more than once. Using th e fixed point fx
872 // allows the code to quickly check that the same pixel is being used. T he code uses this
873 // same pixel check to do the sRGB and normalization only once.
874 auto getNextPixel = [&]() {
875 if (ix != prevIX) {
876 fpixel = fStrategy.getPixel(row, ix);
877 prevIX = ix;
878 }
879 fx += fdx;
880 ix = SkFixedFloorToInt(fx);
881 return fpixel;
882 };
883
884 while (count >= 4) {
885 Sk4f px0 = getNextPixel();
886 Sk4f px1 = getNextPixel();
887 Sk4f px2 = getNextPixel();
888 Sk4f px3 = getNextPixel();
889 next->place4Pixels(px0, px1, px2, px3);
890 count -= 4;
891 }
892 while (count > 0) {
893 next->placePixel(getNextPixel());
894 count -= 1;
895 }
896 }
897
898 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel.
899 // We'll never re-use pixels, but we can at least load contiguous pixels.
900 void pointSpanUnitRate(Span span) {
901 SkPoint start; SkScalar length; int count;
902 std::tie(start, length, count) = span;
903 int ix = SkScalarFloorToInt(X(start));
904 const void* row = fStrategy.row((int)std::floor(Y(start)));
905 SkLinearBitmapPipeline::PixelPlacerInterface* next = fNext;
906 while (count >= 4) {
907 Sk4f px0, px1, px2, px3;
908 fStrategy.get4Pixels(row, ix, &px0, &px1, &px2, &px3);
909 next->place4Pixels(px0, px1, px2, px3);
910 ix += 4;
911 count -= 4;
912 }
913
914 while (count > 0) {
915 next->placePixel(fStrategy.getPixel(row, ix));
916 ix += 1;
917 count -= 1;
918 }
919 }
920
921 // We're moving through source space faster than dst (zoomed out),
922 // so we'll never reuse a source pixel or be able to do contiguous loads.
923 void pointSpanFastRate(Span span) {
832 span_fallback(span, this); 924 span_fallback(span, this);
833 } 925 }
834 926
835 private: 927 private:
836 SkLinearBitmapPipeline::PixelPlacerInterface* const fNext; 928 SkLinearBitmapPipeline::PixelPlacerInterface* const fNext;
837 SourceStrategy fStrategy; 929 SourceStrategy fStrategy;
838 }; 930 };
839 931
840 using Pixel8888SRGB = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kRGBA>; 932 using Pixel8888SRGB = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kRGBA>;
841 using Pixel8888LRGB = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kRGBA>; 933 using Pixel8888LRGB = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kRGBA>;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 1033
942 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { 1034 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) {
943 SkASSERT(count > 0); 1035 SkASSERT(count > 0);
944 fPixelStage->setDestination(dst); 1036 fPixelStage->setDestination(dst);
945 // The count and length arguments start out in a precise relation in order t o keep the 1037 // The count and length arguments start out in a precise relation in order t o keep the
946 // math correct through the different stages. Count is the number of pixel t o produce. 1038 // math correct through the different stages. Count is the number of pixel t o produce.
947 // Since the code samples at pixel centers, length is the distance from the center of the 1039 // Since the code samples at pixel centers, length is the distance from the center of the
948 // first pixel to the center of the last pixel. This implies that length is count-1. 1040 // first pixel to the center of the last pixel. This implies that length is count-1.
949 fFirstStage->pointSpan(Span{SkPoint{x + 0.5f, y + 0.5f}, count - 1.0f, count }); 1041 fFirstStage->pointSpan(Span{SkPoint{x + 0.5f, y + 0.5f}, count - 1.0f, count });
950 } 1042 }
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