diff options
author | msarett <msarett@google.com> | 2016-09-16 11:45:58 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-09-16 11:45:59 -0700 |
commit | c0444615ed76360f680619ad4d1f92cda6181a50 (patch) | |
tree | 4c534202035fd7094967d435e2d986ef9f6ab7d8 /src/core | |
parent | bfef32ff0ac743b10995985b891f5fd09fe918db (diff) |
Support Float32 output from SkColorSpaceXform
* Adds Float32 support to SkColorSpaceXform
* Changes API to allows clients to ask for F32, updates clients to
new API
* Adds Sk4f_load4 and Sk4f_store4 to SkNx
* Make use of new xform in SkGr.cpp
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2339233003
CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot
Committed: https://skia.googlesource.com/skia/+/43d6651111374b5d1e4ddd9030dcf079b448ec47
Review-Url: https://codereview.chromium.org/2339233003
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkColorSpaceXform.cpp | 62 | ||||
-rw-r--r-- | src/core/SkColorSpaceXform.h | 27 | ||||
-rw-r--r-- | src/core/SkNx.h | 22 |
3 files changed, 87 insertions, 24 deletions
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp index 599adc90f9..b1dda34817 100644 --- a/src/core/SkColorSpaceXform.cpp +++ b/src/core/SkColorSpaceXform.cpp @@ -908,8 +908,23 @@ static inline void store_f16_1(void* dst, const uint32_t* src, } template <SwapRB kSwapRB> +static inline void store_f32(void* dst, const uint32_t* src, + Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, + const uint8_t* const[3]) { + Sk4f_store4(dst, dr, dg, db, da); +} + +template <SwapRB kSwapRB> +static inline void store_f32_1(void* dst, const uint32_t* src, + Sk4f& rgba, const Sk4f& a, + const uint8_t* const[3]) { + rgba = Sk4f(rgba[0], rgba[1], rgba[2], a[3]); + rgba.store((float*) dst); +} + +template <SwapRB kSwapRB> static inline void store_f16_opaque(void* dst, const uint32_t* src, - Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, + Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, const uint8_t* const[3]) { Sk4h_store4(dst, SkFloatToHalf_finite_ftz(dr), SkFloatToHalf_finite_ftz(dg), @@ -919,7 +934,7 @@ static inline void store_f16_opaque(void* dst, const uint32_t* src, template <SwapRB kSwapRB> static inline void store_f16_1_opaque(void* dst, const uint32_t* src, - Sk4f& rgba, const Sk4f& a, + Sk4f& rgba, const Sk4f&, const uint8_t* const[3]) { uint64_t tmp; SkFloatToHalf_finite_ftz(rgba).store(&tmp); @@ -1089,6 +1104,7 @@ enum DstFormat { k8888_2Dot2_DstFormat, k8888_Table_DstFormat, kF16_Linear_DstFormat, + kF32_Linear_DstFormat, }; template <SrcFormat kSrc, @@ -1101,9 +1117,12 @@ static void color_xform_RGBA(void* dst, const uint32_t* src, int len, const uint8_t* const dstTables[3]) { LoadFn load; Load1Fn load_1; + static constexpr bool loadAlpha = (kPremul_SkAlphaType == kAlphaType) || + (kF16_Linear_DstFormat == kDst) || + (kF32_Linear_DstFormat == kDst); switch (kSrc) { case kRGBA_8888_Linear_SrcFormat: - if (kPremul_SkAlphaType == kAlphaType || kF16_Linear_DstFormat == kDst) { + if (loadAlpha) { load = load_rgba_linear; load_1 = load_rgba_linear_1; } else { @@ -1112,7 +1131,7 @@ static void color_xform_RGBA(void* dst, const uint32_t* src, int len, } break; case kRGBA_8888_Table_SrcFormat: - if (kPremul_SkAlphaType == kAlphaType || kF16_Linear_DstFormat == kDst) { + if (loadAlpha) { load = load_rgba_from_tables; load_1 = load_rgba_from_tables_1; } else { @@ -1153,6 +1172,11 @@ static void color_xform_RGBA(void* dst, const uint32_t* src, int len, store_f16_1<kSwapRB>; sizeOfDstPixel = 8; break; + case kF32_Linear_DstFormat: + store = store_f32<kSwapRB>; + store_1 = store_f32_1<kSwapRB>; + sizeOfDstPixel = 16; + break; } do_color_xform<kAlphaType, kCSM> @@ -1245,7 +1269,7 @@ static inline void apply_set_src(void* dst, const uint32_t* src, int len, SkAlph template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM> void SkColorSpaceXform_Base<kSrc, kDst, kCSM> -::apply(void* dst, const uint32_t* src, int len, SkColorType dstColorType, SkAlphaType alphaType) +::apply(void* dst, const uint32_t* src, int len, ColorFormat dstColorFormat, SkAlphaType alphaType) const { if (kFull_ColorSpaceMatch == kCSM) { @@ -1255,13 +1279,14 @@ const // linear space. break; default: - switch (dstColorType) { - case kRGBA_8888_SkColorType: + switch (dstColorFormat) { + case kRGBA_8888_ColorFormat: return (void) memcpy(dst, src, len * sizeof(uint32_t)); - case kBGRA_8888_SkColorType: + case kBGRA_8888_ColorFormat: return SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len); - case kRGBA_F16_SkColorType: - // There's still work to do to xform to linear F16. + case kRGBA_F16_ColorFormat: + case kRGBA_F32_ColorFormat: + // There's still work to do to xform to linear floats. break; default: SkASSERT(false); @@ -1283,8 +1308,8 @@ const src = (const uint32_t*) storage.get(); } - switch (dstColorType) { - case kRGBA_8888_SkColorType: + switch (dstColorFormat) { + case kRGBA_8888_ColorFormat: switch (kDst) { case kLinear_DstGamma: return apply_set_src<kSrc, k8888_Linear_DstFormat, kCSM, kNo_SwapRB> @@ -1299,7 +1324,7 @@ const return apply_set_src<kSrc, k8888_Table_DstFormat, kCSM, kNo_SwapRB> (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables); } - case kBGRA_8888_SkColorType: + case kBGRA_8888_ColorFormat: switch (kDst) { case kLinear_DstGamma: return apply_set_src<kSrc, k8888_Linear_DstFormat, kCSM, kYes_SwapRB> @@ -1314,7 +1339,7 @@ const return apply_set_src<kSrc, k8888_Table_DstFormat, kCSM, kYes_SwapRB> (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables); } - case kRGBA_F16_SkColorType: + case kRGBA_F16_ColorFormat: switch (kDst) { case kLinear_DstGamma: return apply_set_src<kSrc, kF16_Linear_DstFormat, kCSM, kNo_SwapRB> @@ -1323,6 +1348,15 @@ const SkASSERT(false); return; } + case kRGBA_F32_ColorFormat: + switch (kDst) { + case kLinear_DstGamma: + return apply_set_src<kSrc, kF32_Linear_DstFormat, kCSM, kNo_SwapRB> + (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr); + default: + SkASSERT(false); + return; + } default: SkASSERT(false); return; diff --git a/src/core/SkColorSpaceXform.h b/src/core/SkColorSpaceXform.h index c80cd15dca..6c996a9c09 100644 --- a/src/core/SkColorSpaceXform.h +++ b/src/core/SkColorSpaceXform.h @@ -25,20 +25,27 @@ public: static std::unique_ptr<SkColorSpaceXform> New(const sk_sp<SkColorSpace>& srcSpace, const sk_sp<SkColorSpace>& dstSpace); + enum ColorFormat : uint8_t { + kRGBA_8888_ColorFormat, + kBGRA_8888_ColorFormat, + kRGBA_F16_ColorFormat, + kRGBA_F32_ColorFormat, + }; + /** * Apply the color conversion to a |src| buffer, storing the output in the |dst| buffer. * - * @param dst Stored in the format described by |dstColorType| and |dstAlphaType| - * @param src Stored as RGBA_8888, kUnpremul (note kOpaque is a form of kUnpremul) - * @param len Number of pixels in the buffers - * @param dstColorType Describes color type of |dst| - * @param dstAlphaType Describes alpha type of |dst| - * kUnpremul preserves input alpha values - * kPremul performs a premultiplication and also preserves alpha values - * kOpaque optimization hint, |dst| alphas set to 1 + * @param dst Stored in the format described by |dstColorType| and |dstAlphaType| + * @param src Stored as RGBA_8888, kUnpremul (note kOpaque is a form of kUnpremul) + * @param len Number of pixels in the buffers + * @param dstColorFormat Describes color format of |dst| + * @param dstAlphaType Describes alpha type of |dst| + * kUnpremul preserves input alpha values + * kPremul performs a premultiplication and also preserves alpha values + * kOpaque optimization hint, |dst| alphas set to 1 * */ - virtual void apply(void* dst, const uint32_t* src, int len, SkColorType dstColorType, + virtual void apply(void* dst, const uint32_t* src, int len, ColorFormat dstColorFormat, SkAlphaType dstAlphaType) const = 0; virtual ~SkColorSpaceXform() {} @@ -66,7 +73,7 @@ template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM> class SkColorSpaceXform_Base : public SkColorSpaceXform { public: - void apply(void* dst, const uint32_t* src, int len, SkColorType dstColorType, + void apply(void* dst, const uint32_t* src, int len, ColorFormat dstColorFormat, SkAlphaType dstAlphaType) const override; static constexpr int kDstGammaTableSize = 1024; diff --git a/src/core/SkNx.h b/src/core/SkNx.h index 881a475ce0..6bca856d8b 100644 --- a/src/core/SkNx.h +++ b/src/core/SkNx.h @@ -332,6 +332,28 @@ SI void Sk4h_store4(void* dst, const Sk4h& r, const Sk4h& g, const Sk4h& b, cons Sk4h(r[3], g[3], b[3], a[3]).store(dst64 + 3); } +// Load 4 Sk4f and transpose them (512 bits total). +SI void Sk4f_load4(const void* vptr, Sk4f* r, Sk4f* g, Sk4f* b, Sk4f* a) { + const float* ptr = (const float*) vptr; + auto p0 = Sk4f::Load(ptr + 0), + p1 = Sk4f::Load(ptr + 4), + p2 = Sk4f::Load(ptr + 8), + p3 = Sk4f::Load(ptr + 12); + *r = { p0[0], p1[0], p2[0], p3[0] }; + *g = { p0[1], p1[1], p2[1], p3[1] }; + *b = { p0[2], p1[2], p2[2], p3[2] }; + *a = { p0[3], p1[3], p2[3], p3[3] }; +} + +// Transpose 4 Sk4f and store (512 bits total). +SI void Sk4f_store4(void* vdst, const Sk4f& r, const Sk4f& g, const Sk4f& b, const Sk4f& a) { + float* dst = (float*) vdst; + Sk4f(r[0], g[0], b[0], a[0]).store(dst + 0); + Sk4f(r[1], g[1], b[1], a[1]).store(dst + 4); + Sk4f(r[2], g[2], b[2], a[2]).store(dst + 8); + Sk4f(r[3], g[3], b[3], a[3]).store(dst + 12); +} + #endif SI void Sk4f_ToBytes(uint8_t p[16], const Sk4f& a, const Sk4f& b, const Sk4f& c, const Sk4f& d) { |