diff options
-rw-r--r-- | src/core/SkLinearBitmapPipeline.cpp | 63 | ||||
-rw-r--r-- | src/opts/SkNx_neon.h | 8 | ||||
-rw-r--r-- | src/opts/SkNx_sse.h | 11 |
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; |