aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkLinearBitmapPipeline.cpp34
-rw-r--r--src/core/SkLinearBitmapPipeline_sample.h355
2 files changed, 178 insertions, 211 deletions
diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp
index 562e3ecf6f..6bb88d1bf6 100644
--- a/src/core/SkLinearBitmapPipeline.cpp
+++ b/src/core/SkLinearBitmapPipeline.cpp
@@ -468,7 +468,7 @@ static SkLinearBitmapPipeline::PointProcessorInterface* choose_tiler(
////////////////////////////////////////////////////////////////////////////////////////////////////
// Source Sampling Stage
-template <typename SourceStrategy, typename Next>
+template <SkColorType colorType, SkColorProfileType colorProfile, typename Next>
class NearestNeighborSampler final : public SkLinearBitmapPipeline::SampleProcessorInterface {
public:
template <typename... Args>
@@ -506,10 +506,10 @@ public:
}
private:
- GeneralSampler<SourceStrategy, Next> fSampler;
+ GeneralSampler<colorType, colorProfile, Next> fSampler;
};
-template <typename SourceStrategy, typename Next>
+template <SkColorType colorType, SkColorProfileType colorProfile, typename Next>
class BilerpSampler final : public SkLinearBitmapPipeline::SampleProcessorInterface {
public:
template <typename... Args>
@@ -547,7 +547,7 @@ public:
}
private:
- GeneralSampler<SourceStrategy, Next> fSampler;
+ GeneralSampler<colorType, colorProfile, Next> fSampler;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -708,7 +708,7 @@ private:
using Blender = SkLinearBitmapPipeline::BlendProcessorInterface;
-template<template <typename, typename> class Sampler>
+template<template <SkColorType, SkColorProfileType, typename> class Sampler>
static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_base(
Blender* next,
const SkPixmap& srcPixmap,
@@ -717,27 +717,35 @@ static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_ba
switch (imageInfo.colorType()) {
case kRGBA_8888_SkColorType:
if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
- sampleStage->initStage<Sampler<Pixel8888SRGB, Blender>>(next, srcPixmap);
+ using S = Sampler<kRGBA_8888_SkColorType, kSRGB_SkColorProfileType, Blender>;
+ sampleStage->initStage<S>(next, srcPixmap);
} else {
- sampleStage->initStage<Sampler<Pixel8888LRGB, Blender>>(next, srcPixmap);
+ using S = Sampler<kRGBA_8888_SkColorType, kLinear_SkColorProfileType, Blender>;
+ sampleStage->initStage<S>(next, srcPixmap);
}
break;
case kBGRA_8888_SkColorType:
if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
- sampleStage->initStage<Sampler<Pixel8888SBGR, Blender>>(next, srcPixmap);
+ using S = Sampler<kBGRA_8888_SkColorType, kSRGB_SkColorProfileType, Blender>;
+ sampleStage->initStage<S>(next, srcPixmap);
} else {
- sampleStage->initStage<Sampler<Pixel8888LBGR, Blender>>(next, srcPixmap);
+ using S = Sampler<kBGRA_8888_SkColorType, kLinear_SkColorProfileType, Blender>;
+ sampleStage->initStage<S>(next, srcPixmap);
}
break;
case kIndex_8_SkColorType:
if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
- sampleStage->initStage<Sampler<PixelIndex8SRGB, Blender>>(next, srcPixmap);
+ using S = Sampler<kIndex_8_SkColorType, kSRGB_SkColorProfileType, Blender>;
+ sampleStage->initStage<S>(next, srcPixmap);
} else {
- sampleStage->initStage<Sampler<PixelIndex8LRGB, Blender>>(next, srcPixmap);
+ using S = Sampler<kIndex_8_SkColorType, kLinear_SkColorProfileType, Blender>;
+ sampleStage->initStage<S>(next, srcPixmap);
}
break;
- case kRGBA_F16_SkColorType:
- sampleStage->initStage<Sampler<PixelHalfLinear, Blender>>(next, srcPixmap);
+ case kRGBA_F16_SkColorType: {
+ using S = Sampler<kRGBA_F16_SkColorType, kLinear_SkColorProfileType, Blender>;
+ sampleStage->initStage<S>(next, srcPixmap);
+ }
break;
default:
SkFAIL("Not implemented. Unsupported src");
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