aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkLinearBitmapPipeline_sample.h
diff options
context:
space:
mode:
authorGravatar herb <herb@google.com>2016-05-12 11:37:00 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-05-12 11:37:00 -0700
commit15332a841d7b65774bc5dbcdfeec3a954a655895 (patch)
tree1ce97fa54f86341f3570fe4aa25855cee5a8b129 /src/core/SkLinearBitmapPipeline_sample.h
parentdd4fcd450016648c1d8f298cea762e9b1308fbb5 (diff)
Make PixelGetters much smaller, move more common code to PixelAccessor.
Diffstat (limited to 'src/core/SkLinearBitmapPipeline_sample.h')
-rw-r--r--src/core/SkLinearBitmapPipeline_sample.h355
1 files changed, 157 insertions, 198 deletions
diff --git a/src/core/SkLinearBitmapPipeline_sample.h b/src/core/SkLinearBitmapPipeline_sample.h
index 566ed84ffe..78af038660 100644
--- a/src/core/SkLinearBitmapPipeline_sample.h
+++ b/src/core/SkLinearBitmapPipeline_sample.h
@@ -49,7 +49,162 @@ static Sk4s VECTORCALL bilerp4(Sk4s xs, Sk4s ys, Sk4f px00, Sk4f px10,
return sum;
}
-template<typename SourceStrategy, typename Next>
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// PixelGetter is the lowest level interface to the source data. There is a PixelGetter for each
+// of the different SkColorTypes.
+template <SkColorType colorType, SkColorProfileType colorProfile> class PixelGetter;
+
+template <SkColorProfileType colorProfile>
+class PixelGetter<kRGBA_8888_SkColorType, colorProfile> {
+public:
+ using Element = uint32_t;
+ PixelGetter(const SkPixmap& srcPixmap) { }
+
+ Sk4f getPixelAt(const uint32_t* src) {
+ return colorProfile == kSRGB_SkColorProfileType
+ ? Sk4f_fromS32(*src)
+ : Sk4f_fromL32(*src);
+ }
+};
+
+template <SkColorProfileType colorProfile>
+class PixelGetter<kBGRA_8888_SkColorType, colorProfile> {
+public:
+ using Element = uint32_t;
+ PixelGetter(const SkPixmap& srcPixmap) { }
+
+ Sk4f getPixelAt(const uint32_t* src) {
+ Sk4f pixel = colorProfile == kSRGB_SkColorProfileType
+ ? Sk4f_fromS32(*src)
+ : Sk4f_fromL32(*src);
+ return SkNx_shuffle<2, 1, 0, 3>(pixel);
+ }
+};
+
+template <SkColorProfileType colorProfile>
+class PixelGetter<kIndex_8_SkColorType, colorProfile> {
+public:
+ using Element = uint8_t;
+ PixelGetter(const SkPixmap& srcPixmap) {
+ SkColorTable* skColorTable = srcPixmap.ctable();
+ SkASSERT(skColorTable != nullptr);
+
+ fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
+ for (int i = 0; i < skColorTable->count(); i++) {
+ fColorTable[i] = this->convertPixel((*skColorTable)[i]);
+ }
+ }
+
+ PixelGetter(const PixelGetter& strategy) {
+ fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
+ // TODO: figure out the count.
+ for (int i = 0; i < 256; i++) {
+ fColorTable[i] = strategy.fColorTable[i];
+ }
+ }
+
+ Sk4f getPixelAt(const uint8_t* src) {
+ return fColorTable[*src];
+ }
+
+private:
+ static const size_t kColorTableSize = sizeof(Sk4f[256]) + 12;
+ Sk4f convertPixel(SkPMColor pmColor) {
+ Sk4f pixel = to_4f(pmColor);
+ float alpha = get_alpha(pixel);
+ if (alpha != 0.0f) {
+ float invAlpha = 1.0f / alpha;
+ Sk4f normalize = {invAlpha, invAlpha, invAlpha, 1.0f / 255.0f};
+ pixel = pixel * normalize;
+ if (colorProfile == kSRGB_SkColorProfileType) {
+ pixel = linear_to_srgb(pixel);
+ }
+ return pixel;
+ } else {
+ return Sk4f{0.0f};
+ }
+ }
+ SkAutoMalloc fColorTableStorage{kColorTableSize};
+ Sk4f* fColorTable;
+};
+
+template <>
+class PixelGetter<kRGBA_F16_SkColorType, kLinear_SkColorProfileType> {
+public:
+ using Element = uint64_t;
+ PixelGetter(const SkPixmap& srcPixmap) { }
+
+ Sk4f getPixelAt(const uint64_t* src) {
+ return SkHalfToFloat_01(*src);
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// PixelAccessor handles all the same plumbing for all the PixelGetters.
+template <SkColorType colorType, SkColorProfileType colorProfile>
+class PixelAccessor {
+ using Element = typename PixelGetter<colorType, colorProfile>::Element;
+public:
+ PixelAccessor(const SkPixmap& srcPixmap)
+ : fSrc{static_cast<const Element*>(srcPixmap.addr())}
+ , fWidth{srcPixmap.rowBytesAsPixels()}
+ , fGetter{srcPixmap} { }
+
+ void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) {
+ Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
+ Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
+ Sk4i bufferLoc = YIs * fWidth + XIs;
+ switch (n) {
+ case 3:
+ *px2 = this->getPixelAt(bufferLoc[2]);
+ case 2:
+ *px1 = this->getPixelAt(bufferLoc[1]);
+ case 1:
+ *px0 = this->getPixelAt(bufferLoc[0]);
+ default:
+ break;
+ }
+ }
+
+ void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) {
+ Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
+ Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
+ Sk4i bufferLoc = YIs * fWidth + XIs;
+ *px0 = this->getPixelAt(bufferLoc[0]);
+ *px1 = this->getPixelAt(bufferLoc[1]);
+ *px2 = this->getPixelAt(bufferLoc[2]);
+ *px3 = this->getPixelAt(bufferLoc[3]);
+ }
+
+ void get4Pixels(const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) {
+ *px0 = this->getPixelFromRow(src, index + 0);
+ *px1 = this->getPixelFromRow(src, index + 1);
+ *px2 = this->getPixelFromRow(src, index + 2);
+ *px3 = this->getPixelFromRow(src, index + 3);
+ }
+
+ Sk4f getPixelFromRow(const void* row, int index) {
+ const Element* src = static_cast<const Element*>(row);
+ return fGetter.getPixelAt(src + index);
+ }
+
+ Sk4f getPixelAt(int index) {
+ return this->getPixelFromRow(fSrc, index);
+ }
+
+ const void* row(int y) const { return fSrc + y * fWidth[0]; }
+
+private:
+ const Element* const fSrc;
+ const Sk4i fWidth;
+ PixelGetter<colorType, colorProfile> fGetter;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// GeneralSampler handles all the different sampling scenarios. It makes runtime decisions to
+// choose the fastest stratagy given a particular job. It ultimately uses PixelGetters to access
+// the pixels.
+template<SkColorType colorType, SkColorProfileType colorProfile, typename Next>
class GeneralSampler {
public:
template<typename... Args>
@@ -557,205 +712,9 @@ private:
}
Next* const fNext;
- SourceStrategy fStrategy;
-};
-
-template <typename PixelGetter>
-class PixelAccessor {
-public:
- PixelAccessor(const SkPixmap& srcPixmap)
- : fWidth{srcPixmap.rowBytesAsPixels()}
- , fGetter{srcPixmap} { }
-
- void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) {
- Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
- Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
- Sk4i bufferLoc = YIs * fWidth + XIs;
- switch (n) {
- case 3:
- *px2 = fGetter.getPixelAt(bufferLoc[2]);
- case 2:
- *px1 = fGetter.getPixelAt(bufferLoc[1]);
- case 1:
- *px0 = fGetter.getPixelAt(bufferLoc[0]);
- default:
- break;
- }
- }
-
- void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) {
- Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
- Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
- Sk4i bufferLoc = YIs * fWidth + XIs;
- *px0 = fGetter.getPixelAt(bufferLoc[0]);
- *px1 = fGetter.getPixelAt(bufferLoc[1]);
- *px2 = fGetter.getPixelAt(bufferLoc[2]);
- *px3 = fGetter.getPixelAt(bufferLoc[3]);
- }
-
- void get4Pixels(const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* px3) {
- *px0 = fGetter.getPixelFromRow(src, index + 0);
- *px1 = fGetter.getPixelFromRow(src, index + 1);
- *px2 = fGetter.getPixelFromRow(src, index + 2);
- *px3 = fGetter.getPixelFromRow(src, index + 3);
- }
-
- Sk4f getPixelFromRow(const void* row, int index) {
- return fGetter.getPixelFromRow(row, index);
- }
-
- const void* row(int y) { return fGetter.row(y); }
-
-private:
- const Sk4i fWidth;
- PixelGetter fGetter;
-};
-
-template <SkColorType colorType, SkColorProfileType colorProfile> class PixelGetter;
-
-template <SkColorProfileType colorProfile>
-class PixelGetter<kRGBA_8888_SkColorType, colorProfile> {
-public:
- PixelGetter(const SkPixmap& srcPixmap)
- : fSrc{srcPixmap.addr32()}
- , fWidth{srcPixmap.rowBytesAsPixels()} { }
-
- Sk4f getPixelFromRow(const void* row, int index) {
- const uint32_t* src = static_cast<const uint32_t*>(row) + index;
- return colorProfile == kSRGB_SkColorProfileType
- ? Sk4f_fromS32(*src)
- : Sk4f_fromL32(*src);
- }
-
- Sk4f getPixelAt(int index) {
- return this->getPixelFromRow(fSrc, index);
- }
-
- const void* row(int y) { return fSrc + y * fWidth; }
-
-private:
- const uint32_t* const fSrc;
- const int fWidth;
-};
-
-using Pixel8888SRGB = PixelAccessor<PixelGetter<kRGBA_8888_SkColorType, kSRGB_SkColorProfileType>>;
-using Pixel8888LRGB = PixelAccessor<PixelGetter<kRGBA_8888_SkColorType, kLinear_SkColorProfileType>>;
-
-template <SkColorProfileType colorProfile>
-class PixelGetter<kBGRA_8888_SkColorType, colorProfile> {
-public:
- PixelGetter(const SkPixmap& srcPixmap)
- : fSrc{srcPixmap.addr32()}
- , fWidth{srcPixmap.rowBytesAsPixels()} { }
-
- Sk4f getPixelFromRow(const void* row, int index) {
- const uint32_t* src = static_cast<const uint32_t*>(row) + index;
- Sk4f pixel = colorProfile == kSRGB_SkColorProfileType
- ? Sk4f_fromS32(*src)
- : Sk4f_fromL32(*src);
- return SkNx_shuffle<2, 1, 0, 3>(pixel);
- }
-
- Sk4f getPixelAt(int index) {
- return this->getPixelFromRow(fSrc, index);
- }
-
- const void* row(int y) { return fSrc + y * fWidth; }
-
-private:
- const uint32_t* const fSrc;
- const int fWidth;
-};
-
-using Pixel8888SBGR = PixelAccessor<PixelGetter<kBGRA_8888_SkColorType, kSRGB_SkColorProfileType>>;
-using Pixel8888LBGR = PixelAccessor<PixelGetter<kBGRA_8888_SkColorType, kLinear_SkColorProfileType>>;
-
-template <SkColorProfileType colorProfile>
-class PixelGetter<kIndex_8_SkColorType, colorProfile> {
-public:
- PixelGetter(const SkPixmap& srcPixmap)
- : fSrc{srcPixmap.addr8()}, fWidth{static_cast<int>(srcPixmap.rowBytes())} {
- SkASSERT(srcPixmap.colorType() == kIndex_8_SkColorType);
- SkColorTable* skColorTable = srcPixmap.ctable();
- SkASSERT(skColorTable != nullptr);
-
- fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
- for (int i = 0; i < skColorTable->count(); i++) {
- fColorTable[i] = this->convertPixel((*skColorTable)[i]);
- }
- }
-
- PixelGetter(const PixelGetter& strategy)
- : fSrc{strategy.fSrc}, fWidth{strategy.fWidth} {
- fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get());
- // TODO: figure out the count.
- for (int i = 0; i < 256; i++) {
- fColorTable[i] = strategy.fColorTable[i];
- }
- }
-
- Sk4f getPixelFromRow(const void* row, int index) {
- const uint8_t* src = static_cast<const uint8_t*>(row) + index;
- Sk4f pixel = fColorTable[*src];
- return pixel;
- }
-
- Sk4f getPixelAt(int index) {
- return this->getPixelFromRow(fSrc, index);
- }
-
- const void* row(int y) { return fSrc + y * fWidth; }
-
-private:
- static const size_t kColorTableSize = sizeof(Sk4f[256]) + 12;
- Sk4f convertPixel(SkPMColor pmColor) {
- Sk4f pixel = to_4f(pmColor);
- float alpha = get_alpha(pixel);
- if (alpha != 0.0f) {
- float invAlpha = 1.0f / alpha;
- Sk4f normalize = {invAlpha, invAlpha, invAlpha, 1.0f / 255.0f};
- pixel = pixel * normalize;
- if (colorProfile == kSRGB_SkColorProfileType) {
- pixel = linear_to_srgb(pixel);
- }
- return pixel;
- } else {
- return Sk4f{0.0f};
- }
- }
- const uint8_t* const fSrc;
- const int fWidth;
- SkAutoMalloc fColorTableStorage{kColorTableSize};
- Sk4f* fColorTable;
-};
-
-using PixelIndex8SRGB = PixelAccessor<PixelGetter<kIndex_8_SkColorType, kSRGB_SkColorProfileType>>;
-using PixelIndex8LRGB = PixelAccessor<PixelGetter<kIndex_8_SkColorType, kLinear_SkColorProfileType>>;
-
-template <>
-class PixelGetter<kRGBA_F16_SkColorType, kLinear_SkColorProfileType> {
-public:
- PixelGetter(const SkPixmap& srcPixmap)
- : fSrc{srcPixmap.addr64()}
- , fWidth{static_cast<int>(srcPixmap.rowBytesAsPixels())} { }
-
- Sk4f getPixelFromRow(const void* row, int index) {
- const uint64_t* src = static_cast<const uint64_t*>(row) + index;
- return SkHalfToFloat_01(*src);
- }
-
- Sk4f getPixelAt(int index) {
- return this->getPixelFromRow(fSrc, index);
- }
-
- const void* row(int y) { return fSrc + y * fWidth; }
-
-private:
- const uint64_t* const fSrc;
- const int fWidth;
+ PixelAccessor<colorType, colorProfile> fStrategy;
};
-using PixelHalfLinear = PixelAccessor<PixelGetter<kRGBA_F16_SkColorType, kLinear_SkColorProfileType>>;
} // namespace