aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkLinearBitmapPipeline.cpp63
-rw-r--r--src/opts/SkNx_neon.h8
-rw-r--r--src/opts/SkNx_sse.h11
3 files changed, 56 insertions, 26 deletions
diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp
index 4d4a4cfe4d..e836746a89 100644
--- a/src/core/SkLinearBitmapPipeline.cpp
+++ b/src/core/SkLinearBitmapPipeline.cpp
@@ -707,11 +707,17 @@ public:
}
};
-template <SkColorProfileType colorProfile>
-class Passthrough8888 {
+enum class ColorOrder {
+ kRGBA = false,
+ kBGRA = true,
+};
+template <SkColorProfileType colorProfile, ColorOrder colorOrder>
+class Pixel8888 {
public:
- Passthrough8888(int width, const uint32_t* src)
- : fSrc{src}, fWidth{width}{ }
+ Pixel8888(int width, const uint32_t* src) : fSrc{src}, fWidth{width}{ }
+ Pixel8888(const SkPixmap& srcPixmap)
+ : fSrc{srcPixmap.addr32()}
+ , fWidth{static_cast<int>(srcPixmap.rowBytes() / 4)} { }
void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) {
Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
@@ -719,11 +725,11 @@ public:
Sk4i bufferLoc = YIs * fWidth + XIs;
switch (n) {
case 3:
- *px2 = getPixel(fSrc, bufferLoc[2]);
+ *px2 = this->getPixel(fSrc, bufferLoc[2]);
case 2:
- *px1 = getPixel(fSrc, bufferLoc[1]);
+ *px1 = this->getPixel(fSrc, bufferLoc[1]);
case 1:
- *px0 = getPixel(fSrc, bufferLoc[0]);
+ *px0 = this->getPixel(fSrc, bufferLoc[0]);
default:
break;
}
@@ -733,24 +739,28 @@ public:
Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
Sk4i bufferLoc = YIs * fWidth + XIs;
- *px0 = getPixel(fSrc, bufferLoc[0]);
- *px1 = getPixel(fSrc, bufferLoc[1]);
- *px2 = getPixel(fSrc, bufferLoc[2]);
- *px3 = getPixel(fSrc, bufferLoc[3]);
+ *px0 = this->getPixel(fSrc, bufferLoc[0]);
+ *px1 = this->getPixel(fSrc, bufferLoc[1]);
+ *px2 = this->getPixel(fSrc, bufferLoc[2]);
+ *px3 = this->getPixel(fSrc, bufferLoc[3]);
}
- const uint32_t* row(int y) { return fSrc + y * fWidth[0]; }
-
-private:
Sk4f getPixel(const uint32_t* src, int index) {
Sk4b bytePixel = Sk4b::Load((uint8_t *)(&src[index]));
Sk4f pixel = SkNx_cast<float, uint8_t>(bytePixel);
+ if (colorOrder == ColorOrder::kBGRA) {
+ pixel = SkNx_shuffle<2, 1, 0, 3>(pixel);
+ }
pixel = pixel * Sk4f{1.0f/255.0f};
if (colorProfile == kSRGB_SkColorProfileType) {
pixel = sRGBFast::sRGBToLinear(pixel);
}
return pixel;
}
+
+ const uint32_t* row(int y) { return fSrc + y * fWidth[0]; }
+
+private:
const uint32_t* const fSrc;
const Sk4i fWidth;
};
@@ -827,6 +837,11 @@ private:
SourceStrategy fStrategy;
};
+using Pixel8888SRGB = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kRGBA>;
+using Pixel8888LRGB = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kRGBA>;
+using Pixel8888SBGR = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kBGRA>;
+using Pixel8888LBGR = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kBGRA>;
+
static SkLinearBitmapPipeline::BilerpProcessorInterface* choose_pixel_sampler(
SkLinearBitmapPipeline::PixelPlacerInterface* next,
const SkPixmap& srcPixmap,
@@ -834,19 +849,17 @@ static SkLinearBitmapPipeline::BilerpProcessorInterface* choose_pixel_sampler(
const SkImageInfo& imageInfo = srcPixmap.info();
switch (imageInfo.colorType()) {
case kRGBA_8888_SkColorType:
+ if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
+ sampleStage->Initialize<Sampler<Pixel8888SRGB>>(next, srcPixmap);
+ } else {
+ sampleStage->Initialize<Sampler<Pixel8888LRGB>>(next, srcPixmap);
+ }
+ break;
case kBGRA_8888_SkColorType:
- if (kN32_SkColorType == imageInfo.colorType()) {
- if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
- sampleStage->Initialize<Sampler<Passthrough8888<kSRGB_SkColorProfileType>>>(
- next, static_cast<int>(srcPixmap.rowBytes() / 4),
- srcPixmap.addr32());
- } else {
- sampleStage->Initialize<Sampler<Passthrough8888<kLinear_SkColorProfileType>>>(
- next, static_cast<int>(srcPixmap.rowBytes() / 4),
- srcPixmap.addr32());
- }
+ if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
+ sampleStage->Initialize<Sampler<Pixel8888SBGR>>(next, srcPixmap);
} else {
- SkFAIL("Not implemented. No 8888 Swizzle");
+ sampleStage->Initialize<Sampler<Pixel8888LBGR>>(next, srcPixmap);
}
break;
default:
diff --git a/src/opts/SkNx_neon.h b/src/opts/SkNx_neon.h
index 1acd7a00f4..52b2e73798 100644
--- a/src/opts/SkNx_neon.h
+++ b/src/opts/SkNx_neon.h
@@ -305,12 +305,20 @@ public:
SkNx(const uint8x8_t& vec) : fVec(vec) {}
SkNx() {}
+ SkNx(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+ fVec = (uint8x8_t){a,b,c,d, 0,0,0,0};
+ }
static SkNx Load(const void* ptr) {
return (uint8x8_t)vld1_dup_u32((const uint32_t*)ptr);
}
void store(void* ptr) const {
return vst1_lane_u32((uint32_t*)ptr, (uint32x2_t)fVec, 0);
}
+ uint8_t operator[](int k) const {
+ SkASSERT(0 <= k && k < 4);
+ union { uint8x8_t v; uint8_t us[8]; } pun = {fVec};
+ return pun.us[k&3];
+ }
// TODO as needed
diff --git a/src/opts/SkNx_sse.h b/src/opts/SkNx_sse.h
index b6da080317..34b58c10ed 100644
--- a/src/opts/SkNx_sse.h
+++ b/src/opts/SkNx_sse.h
@@ -235,12 +235,21 @@ public:
template <>
class SkNx<4, uint8_t> {
public:
+ SkNx() {}
SkNx(const __m128i& vec) : fVec(vec) {}
+ SkNx(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
+ : fVec(_mm_setr_epi8(a,b,c,d, 0,0,0,0, 0,0,0,0, 0,0,0,0)) {}
+
- SkNx() {}
static SkNx Load(const void* ptr) { return _mm_cvtsi32_si128(*(const int*)ptr); }
void store(void* ptr) const { *(int*)ptr = _mm_cvtsi128_si32(fVec); }
+ uint8_t operator[](int k) const {
+ SkASSERT(0 <= k && k < 4);
+ union { __m128i v; uint8_t us[16]; } pun = {fVec};
+ return pun.us[k&3];
+ }
+
// TODO as needed
__m128i fVec;