aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar msarett <msarett@google.com>2016-09-16 11:45:58 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-09-16 11:45:59 -0700
commitc0444615ed76360f680619ad4d1f92cda6181a50 (patch)
tree4c534202035fd7094967d435e2d986ef9f6ab7d8 /src/core
parentbfef32ff0ac743b10995985b891f5fd09fe918db (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.cpp62
-rw-r--r--src/core/SkColorSpaceXform.h27
-rw-r--r--src/core/SkNx.h22
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) {