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

Side by Side Diff: src/core/SkLinearBitmapPipeline_sample.h

Issue 1971863002: Make PixelGetters much smaller, move more common code to PixelAccessor. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Sync Created 4 years, 7 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 | « src/core/SkLinearBitmapPipeline.cpp ('k') | 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 #ifndef SkLinearBitmapPipeline_sampler_DEFINED 8 #ifndef SkLinearBitmapPipeline_sampler_DEFINED
9 #define SkLinearBitmapPipeline_sampler_DEFINED 9 #define SkLinearBitmapPipeline_sampler_DEFINED
10 10
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 Sk4s fxs = xs - xs.floor(); 42 Sk4s fxs = xs - xs.floor();
43 Sk4s fys = ys - ys.floor(); 43 Sk4s fys = ys - ys.floor();
44 Sk4s fxys{fxs * fys}; 44 Sk4s fxys{fxs * fys};
45 Sk4f sum = px11 * fxys; 45 Sk4f sum = px11 * fxys;
46 sum = sum + px01 * (fys - fxys); 46 sum = sum + px01 * (fys - fxys);
47 sum = sum + px10 * (fxs - fxys); 47 sum = sum + px10 * (fxs - fxys);
48 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys); 48 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys);
49 return sum; 49 return sum;
50 } 50 }
51 51
52 template<typename SourceStrategy, typename Next> 52 //////////////////////////////////////////////////////////////////////////////// ////////////////////
53 // PixelGetter is the lowest level interface to the source data. There is a Pixe lGetter for each
54 // of the different SkColorTypes.
55 template <SkColorType colorType, SkColorProfileType colorProfile> class PixelGet ter;
56
57 template <SkColorProfileType colorProfile>
58 class PixelGetter<kRGBA_8888_SkColorType, colorProfile> {
59 public:
60 using Element = uint32_t;
61 PixelGetter(const SkPixmap& srcPixmap) { }
62
63 Sk4f getPixelAt(const uint32_t* src) {
64 return colorProfile == kSRGB_SkColorProfileType
65 ? Sk4f_fromS32(*src)
66 : Sk4f_fromL32(*src);
67 }
68 };
69
70 template <SkColorProfileType colorProfile>
71 class PixelGetter<kBGRA_8888_SkColorType, colorProfile> {
72 public:
73 using Element = uint32_t;
74 PixelGetter(const SkPixmap& srcPixmap) { }
75
76 Sk4f getPixelAt(const uint32_t* src) {
77 Sk4f pixel = colorProfile == kSRGB_SkColorProfileType
78 ? Sk4f_fromS32(*src)
79 : Sk4f_fromL32(*src);
80 return SkNx_shuffle<2, 1, 0, 3>(pixel);
81 }
82 };
83
84 template <SkColorProfileType colorProfile>
85 class PixelGetter<kIndex_8_SkColorType, colorProfile> {
86 public:
87 using Element = uint8_t;
88 PixelGetter(const SkPixmap& srcPixmap) {
89 SkColorTable* skColorTable = srcPixmap.ctable();
90 SkASSERT(skColorTable != nullptr);
91
92 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
93 for (int i = 0; i < skColorTable->count(); i++) {
94 fColorTable[i] = this->convertPixel((*skColorTable)[i]);
95 }
96 }
97
98 PixelGetter(const PixelGetter& strategy) {
99 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
100 // TODO: figure out the count.
101 for (int i = 0; i < 256; i++) {
102 fColorTable[i] = strategy.fColorTable[i];
103 }
104 }
105
106 Sk4f getPixelAt(const uint8_t* src) {
107 return fColorTable[*src];
108 }
109
110 private:
111 static const size_t kColorTableSize = sizeof(Sk4f[256]) + 12;
112 Sk4f convertPixel(SkPMColor pmColor) {
113 Sk4f pixel = to_4f(pmColor);
114 float alpha = get_alpha(pixel);
115 if (alpha != 0.0f) {
116 float invAlpha = 1.0f / alpha;
117 Sk4f normalize = {invAlpha, invAlpha, invAlpha, 1.0f / 255.0f};
118 pixel = pixel * normalize;
119 if (colorProfile == kSRGB_SkColorProfileType) {
120 pixel = linear_to_srgb(pixel);
121 }
122 return pixel;
123 } else {
124 return Sk4f{0.0f};
125 }
126 }
127 SkAutoMalloc fColorTableStorage{kColorTableSize};
128 Sk4f* fColorTable;
129 };
130
131 template <>
132 class PixelGetter<kRGBA_F16_SkColorType, kLinear_SkColorProfileType> {
133 public:
134 using Element = uint64_t;
135 PixelGetter(const SkPixmap& srcPixmap) { }
136
137 Sk4f getPixelAt(const uint64_t* src) {
138 return SkHalfToFloat_01(*src);
139 }
140 };
141
142 //////////////////////////////////////////////////////////////////////////////// ////////////////////
143 // PixelAccessor handles all the same plumbing for all the PixelGetters.
144 template <SkColorType colorType, SkColorProfileType colorProfile>
145 class PixelAccessor {
146 using Element = typename PixelGetter<colorType, colorProfile>::Element;
147 public:
148 PixelAccessor(const SkPixmap& srcPixmap)
149 : fSrc{static_cast<const Element*>(srcPixmap.addr())}
150 , fWidth{srcPixmap.rowBytesAsPixels()}
151 , fGetter{srcPixmap} { }
152
153 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) {
154 Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
155 Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
156 Sk4i bufferLoc = YIs * fWidth + XIs;
157 switch (n) {
158 case 3:
159 *px2 = this->getPixelAt(bufferLoc[2]);
160 case 2:
161 *px1 = this->getPixelAt(bufferLoc[1]);
162 case 1:
163 *px0 = this->getPixelAt(bufferLoc[0]);
164 default:
165 break;
166 }
167 }
168
169 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2 , Sk4f* px3) {
170 Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
171 Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
172 Sk4i bufferLoc = YIs * fWidth + XIs;
173 *px0 = this->getPixelAt(bufferLoc[0]);
174 *px1 = this->getPixelAt(bufferLoc[1]);
175 *px2 = this->getPixelAt(bufferLoc[2]);
176 *px3 = this->getPixelAt(bufferLoc[3]);
177 }
178
179 void get4Pixels(const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) {
180 *px0 = this->getPixelFromRow(src, index + 0);
181 *px1 = this->getPixelFromRow(src, index + 1);
182 *px2 = this->getPixelFromRow(src, index + 2);
183 *px3 = this->getPixelFromRow(src, index + 3);
184 }
185
186 Sk4f getPixelFromRow(const void* row, int index) {
187 const Element* src = static_cast<const Element*>(row);
188 return fGetter.getPixelAt(src + index);
189 }
190
191 Sk4f getPixelAt(int index) {
192 return this->getPixelFromRow(fSrc, index);
193 }
194
195 const void* row(int y) const { return fSrc + y * fWidth[0]; }
196
197 private:
198 const Element* const fSrc;
199 const Sk4i fWidth;
200 PixelGetter<colorType, colorProfile> fGetter;
201 };
202
203 //////////////////////////////////////////////////////////////////////////////// ////////////////////
204 // GeneralSampler handles all the different sampling scenarios. It makes runtime decisions to
205 // choose the fastest stratagy given a particular job. It ultimately uses PixelG etters to access
206 // the pixels.
207 template<SkColorType colorType, SkColorProfileType colorProfile, typename Next>
53 class GeneralSampler { 208 class GeneralSampler {
54 public: 209 public:
55 template<typename... Args> 210 template<typename... Args>
56 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&& ... args) 211 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&& ... args)
57 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } 212 : fNext{next}, fStrategy{std::forward<Args>(args)...} { }
58 213
59 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, 214 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next,
60 const GeneralSampler& sampler) 215 const GeneralSampler& sampler)
61 : fNext{next}, fStrategy{sampler.fStrategy} { } 216 : fNext{next}, fStrategy{sampler.fStrategy} { }
62 217
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 while (count > 0) { 705 while (count > 0) {
551 Sk4f xs = Sk4f{-0.5f, 0.5f, -0.5f, 0.5f} + Sk4f{x}; 706 Sk4f xs = Sk4f{-0.5f, 0.5f, -0.5f, 0.5f} + Sk4f{x};
552 this->bilerpEdge(xs, ys); 707 this->bilerpEdge(xs, ys);
553 x += dx; 708 x += dx;
554 count -= 1; 709 count -= 1;
555 } 710 }
556 } 711 }
557 } 712 }
558 713
559 Next* const fNext; 714 Next* const fNext;
560 SourceStrategy fStrategy; 715 PixelAccessor<colorType, colorProfile> fStrategy;
561 }; 716 };
562 717
563 template <typename PixelGetter>
564 class PixelAccessor {
565 public:
566 PixelAccessor(const SkPixmap& srcPixmap)
567 : fWidth{srcPixmap.rowBytesAsPixels()}
568 , fGetter{srcPixmap} { }
569
570 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) {
571 Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
572 Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
573 Sk4i bufferLoc = YIs * fWidth + XIs;
574 switch (n) {
575 case 3:
576 *px2 = fGetter.getPixelAt(bufferLoc[2]);
577 case 2:
578 *px1 = fGetter.getPixelAt(bufferLoc[1]);
579 case 1:
580 *px0 = fGetter.getPixelAt(bufferLoc[0]);
581 default:
582 break;
583 }
584 }
585
586 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2 , Sk4f* px3) {
587 Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
588 Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
589 Sk4i bufferLoc = YIs * fWidth + XIs;
590 *px0 = fGetter.getPixelAt(bufferLoc[0]);
591 *px1 = fGetter.getPixelAt(bufferLoc[1]);
592 *px2 = fGetter.getPixelAt(bufferLoc[2]);
593 *px3 = fGetter.getPixelAt(bufferLoc[3]);
594 }
595
596 void get4Pixels(const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) {
597 *px0 = fGetter.getPixelFromRow(src, index + 0);
598 *px1 = fGetter.getPixelFromRow(src, index + 1);
599 *px2 = fGetter.getPixelFromRow(src, index + 2);
600 *px3 = fGetter.getPixelFromRow(src, index + 3);
601 }
602
603 Sk4f getPixelFromRow(const void* row, int index) {
604 return fGetter.getPixelFromRow(row, index);
605 }
606
607 const void* row(int y) { return fGetter.row(y); }
608
609 private:
610 const Sk4i fWidth;
611 PixelGetter fGetter;
612 };
613
614 template <SkColorType colorType, SkColorProfileType colorProfile> class PixelGet ter;
615
616 template <SkColorProfileType colorProfile>
617 class PixelGetter<kRGBA_8888_SkColorType, colorProfile> {
618 public:
619 PixelGetter(const SkPixmap& srcPixmap)
620 : fSrc{srcPixmap.addr32()}
621 , fWidth{srcPixmap.rowBytesAsPixels()} { }
622
623 Sk4f getPixelFromRow(const void* row, int index) {
624 const uint32_t* src = static_cast<const uint32_t*>(row) + index;
625 return colorProfile == kSRGB_SkColorProfileType
626 ? Sk4f_fromS32(*src)
627 : Sk4f_fromL32(*src);
628 }
629
630 Sk4f getPixelAt(int index) {
631 return this->getPixelFromRow(fSrc, index);
632 }
633
634 const void* row(int y) { return fSrc + y * fWidth; }
635
636 private:
637 const uint32_t* const fSrc;
638 const int fWidth;
639 };
640
641 using Pixel8888SRGB = PixelAccessor<PixelGetter<kRGBA_8888_SkColorType, kSRGB_Sk ColorProfileType>>;
642 using Pixel8888LRGB = PixelAccessor<PixelGetter<kRGBA_8888_SkColorType, kLinear_ SkColorProfileType>>;
643
644 template <SkColorProfileType colorProfile>
645 class PixelGetter<kBGRA_8888_SkColorType, colorProfile> {
646 public:
647 PixelGetter(const SkPixmap& srcPixmap)
648 : fSrc{srcPixmap.addr32()}
649 , fWidth{srcPixmap.rowBytesAsPixels()} { }
650
651 Sk4f getPixelFromRow(const void* row, int index) {
652 const uint32_t* src = static_cast<const uint32_t*>(row) + index;
653 Sk4f pixel = colorProfile == kSRGB_SkColorProfileType
654 ? Sk4f_fromS32(*src)
655 : Sk4f_fromL32(*src);
656 return SkNx_shuffle<2, 1, 0, 3>(pixel);
657 }
658
659 Sk4f getPixelAt(int index) {
660 return this->getPixelFromRow(fSrc, index);
661 }
662
663 const void* row(int y) { return fSrc + y * fWidth; }
664
665 private:
666 const uint32_t* const fSrc;
667 const int fWidth;
668 };
669
670 using Pixel8888SBGR = PixelAccessor<PixelGetter<kBGRA_8888_SkColorType, kSRGB_Sk ColorProfileType>>;
671 using Pixel8888LBGR = PixelAccessor<PixelGetter<kBGRA_8888_SkColorType, kLinear_ SkColorProfileType>>;
672
673 template <SkColorProfileType colorProfile>
674 class PixelGetter<kIndex_8_SkColorType, colorProfile> {
675 public:
676 PixelGetter(const SkPixmap& srcPixmap)
677 : fSrc{srcPixmap.addr8()}, fWidth{static_cast<int>(srcPixmap.rowBytes()) } {
678 SkASSERT(srcPixmap.colorType() == kIndex_8_SkColorType);
679 SkColorTable* skColorTable = srcPixmap.ctable();
680 SkASSERT(skColorTable != nullptr);
681
682 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
683 for (int i = 0; i < skColorTable->count(); i++) {
684 fColorTable[i] = this->convertPixel((*skColorTable)[i]);
685 }
686 }
687
688 PixelGetter(const PixelGetter& strategy)
689 : fSrc{strategy.fSrc}, fWidth{strategy.fWidth} {
690 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
691 // TODO: figure out the count.
692 for (int i = 0; i < 256; i++) {
693 fColorTable[i] = strategy.fColorTable[i];
694 }
695 }
696
697 Sk4f getPixelFromRow(const void* row, int index) {
698 const uint8_t* src = static_cast<const uint8_t*>(row) + index;
699 Sk4f pixel = fColorTable[*src];
700 return pixel;
701 }
702
703 Sk4f getPixelAt(int index) {
704 return this->getPixelFromRow(fSrc, index);
705 }
706
707 const void* row(int y) { return fSrc + y * fWidth; }
708
709 private:
710 static const size_t kColorTableSize = sizeof(Sk4f[256]) + 12;
711 Sk4f convertPixel(SkPMColor pmColor) {
712 Sk4f pixel = to_4f(pmColor);
713 float alpha = get_alpha(pixel);
714 if (alpha != 0.0f) {
715 float invAlpha = 1.0f / alpha;
716 Sk4f normalize = {invAlpha, invAlpha, invAlpha, 1.0f / 255.0f};
717 pixel = pixel * normalize;
718 if (colorProfile == kSRGB_SkColorProfileType) {
719 pixel = linear_to_srgb(pixel);
720 }
721 return pixel;
722 } else {
723 return Sk4f{0.0f};
724 }
725 }
726 const uint8_t* const fSrc;
727 const int fWidth;
728 SkAutoMalloc fColorTableStorage{kColorTableSize};
729 Sk4f* fColorTable;
730 };
731
732 using PixelIndex8SRGB = PixelAccessor<PixelGetter<kIndex_8_SkColorType, kSRGB_Sk ColorProfileType>>;
733 using PixelIndex8LRGB = PixelAccessor<PixelGetter<kIndex_8_SkColorType, kLinear_ SkColorProfileType>>;
734
735 template <>
736 class PixelGetter<kRGBA_F16_SkColorType, kLinear_SkColorProfileType> {
737 public:
738 PixelGetter(const SkPixmap& srcPixmap)
739 : fSrc{srcPixmap.addr64()}
740 , fWidth{static_cast<int>(srcPixmap.rowBytesAsPixels())} { }
741
742 Sk4f getPixelFromRow(const void* row, int index) {
743 const uint64_t* src = static_cast<const uint64_t*>(row) + index;
744 return SkHalfToFloat_01(*src);
745 }
746
747 Sk4f getPixelAt(int index) {
748 return this->getPixelFromRow(fSrc, index);
749 }
750
751 const void* row(int y) { return fSrc + y * fWidth; }
752
753 private:
754 const uint64_t* const fSrc;
755 const int fWidth;
756 };
757
758 using PixelHalfLinear = PixelAccessor<PixelGetter<kRGBA_F16_SkColorType, kLinear _SkColorProfileType>>;
759 718
760 } // namespace 719 } // namespace
761 720
762 #endif // SkLinearBitmapPipeline_sampler_DEFINED 721 #endif // SkLinearBitmapPipeline_sampler_DEFINED
OLDNEW
« no previous file with comments | « src/core/SkLinearBitmapPipeline.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698