From: Matt Sarett Date: Wed, 4 Jan 2017 21:54:55 +0000 (-0500) Subject: Merge SkColorSpaceXform_XYZ and SkColorSpaceXform_Pipeline X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~55^2~1004 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=26a0543579cf7473de2099ce0d056ac8aba83811;p=platform%2Fupstream%2FlibSkiaSharp.git Merge SkColorSpaceXform_XYZ and SkColorSpaceXform_Pipeline Use the pipeline implementation to handle F32. This refactor has been broken away from the following mega-CL. https://skia-review.googlesource.com/c/6260/ Change-Id: I79d8992f8c4a7e4dbf674a78484057a6b7f4f123 Reviewed-on: https://skia-review.googlesource.com/6585 Reviewed-by: Mike Klein Commit-Queue: Matt Sarett --- diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp index 6eaab83..d394d3b 100644 --- a/src/core/SkColorSpaceXform.cpp +++ b/src/core/SkColorSpaceXform.cpp @@ -19,12 +19,6 @@ #include "SkRasterPipeline.h" #include "SkSRGB.h" -#if 0 -static constexpr bool kUseRasterPipeline = true; -#else -static constexpr bool kUseRasterPipeline = false; -#endif - static constexpr float sk_linear_from_2dot2[256] = { 0.000000000000000000f, 0.000005077051900662f, 0.000023328004666099f, 0.000056921765712193f, 0.000107187362341244f, 0.000175123977503027f, 0.000261543754548491f, 0.000367136269815943f, @@ -331,27 +325,6 @@ std::unique_ptr SkColorSpaceXform::New(SkColorSpace* srcSpace } } - if (kUseRasterPipeline) { - SrcGamma srcGamma = srcSpaceXYZ->gammaIsLinear() ? kLinear_SrcGamma : kTable_SrcGamma; - DstGamma dstGamma; - switch (dstSpaceXYZ->gammaNamed()) { - case kSRGB_SkGammaNamed: - dstGamma = kSRGB_DstGamma; - break; - case k2Dot2Curve_SkGammaNamed: - dstGamma = k2Dot2_DstGamma; - break; - case kLinear_SkGammaNamed: - dstGamma = kLinear_DstGamma; - break; - default: - dstGamma = kTable_DstGamma; - break; - } - return std::unique_ptr(new SkColorSpaceXform_Pipeline( - srcSpaceXYZ, srcToDst, dstSpaceXYZ, csm, srcGamma, dstGamma)); - } - switch (csm) { case kNone_ColorSpaceMatch: switch (dstSpaceXYZ->gammaNamed()) { @@ -468,12 +441,12 @@ std::unique_ptr SkColorSpaceXform::New(SkColorSpace* srcSpace #define AI SK_ALWAYS_INLINE -static AI void load_matrix(const float matrix[16], +static AI void load_matrix(const float matrix[13], Sk4f& rXgXbX, Sk4f& rYgYbY, Sk4f& rZgZbZ, Sk4f& rTgTbT) { - rXgXbX = Sk4f::Load(matrix + 0); - rYgYbY = Sk4f::Load(matrix + 4); - rZgZbZ = Sk4f::Load(matrix + 8); - rTgTbT = Sk4f::Load(matrix + 12); + rXgXbX = Sk4f::Load(matrix + 0); + rYgYbY = Sk4f::Load(matrix + 3); + rZgZbZ = Sk4f::Load(matrix + 6); + rTgTbT = Sk4f::Load(matrix + 9); } enum Order { @@ -786,20 +759,6 @@ static AI void store_f16_1(void* dst, const uint32_t* src, } template -static AI 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 -static AI 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 static AI void store_f16_opaque(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, const uint8_t* const[3]) { Sk4h::Store4(dst, SkFloatToHalf_finite_ftz(dr), @@ -890,7 +849,6 @@ enum DstFormat { kBGRA_8888_2Dot2_DstFormat, kBGRA_8888_Table_DstFormat, kF16_Linear_DstFormat, - kF32_Linear_DstFormat, }; template static void color_xform_RGBA(void* dst, const void* vsrc, int len, - const float* const srcTables[3], const float matrix[16], + const float* const srcTables[3], const float matrix[13], const uint8_t* const dstTables[3]) { LoadFn load; Load1Fn load_1; const bool kLoadAlpha = (kPremul_SkAlphaType == kAlphaType) || - (kF16_Linear_DstFormat == kDst) || - (kF32_Linear_DstFormat == kDst); + (kF16_Linear_DstFormat == kDst); switch (kSrc) { case kRGBA_8888_Linear_SrcFormat: if (kLoadAlpha) { @@ -995,11 +952,6 @@ static void color_xform_RGBA(void* dst, const void* vsrc, int len, store_f16_1; sizeOfDstPixel = 8; break; - case kF32_Linear_DstFormat: - store = store_f32; - store_1 = store_f32_1; - sizeOfDstPixel = 16; - break; } // We always clamp before converting to 8888 outputs (because we have to). @@ -1117,7 +1069,19 @@ SkColorSpaceXform_XYZ ::SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst, SkColorSpace_XYZ* dstSpace) { - srcToDst.asColMajorf(fSrcToDst); + fSrcToDst[ 0] = srcToDst.get(0, 0); + fSrcToDst[ 1] = srcToDst.get(1, 0); + fSrcToDst[ 2] = srcToDst.get(2, 0); + fSrcToDst[ 3] = srcToDst.get(0, 1); + fSrcToDst[ 4] = srcToDst.get(1, 1); + fSrcToDst[ 5] = srcToDst.get(2, 1); + fSrcToDst[ 6] = srcToDst.get(0, 2); + fSrcToDst[ 7] = srcToDst.get(1, 2); + fSrcToDst[ 8] = srcToDst.get(2, 2); + fSrcToDst[ 9] = srcToDst.get(0, 3); + fSrcToDst[10] = srcToDst.get(1, 3); + fSrcToDst[11] = srcToDst.get(2, 3); + fSrcToDst[12] = 0.0f; const int numSrcTables = num_tables(srcSpace); const size_t srcEntries = numSrcTables * 256; @@ -1134,7 +1098,7 @@ SkColorSpaceXform_XYZ template static AI bool apply_set_alpha(void* dst, const void* src, int len, SkAlphaType alphaType, - const float* const srcTables[3], const float matrix[16], + const float* const srcTables[3], const float matrix[13], const uint8_t* const dstTables[3]) { switch (alphaType) { case kOpaque_SkAlphaType: @@ -1156,7 +1120,7 @@ static AI bool apply_set_alpha(void* dst, const void* src, int len, SkAlphaType template static AI bool apply_set_src(void* dst, const void* src, int len, SkAlphaType alphaType, - const float* const srcTables[3], const float matrix[16], + const float* const srcTables[3], const float matrix[13], const uint8_t* const dstTables[3], SkColorSpaceXform::ColorFormat srcColorFormat) { switch (srcColorFormat) { @@ -1211,6 +1175,10 @@ bool SkColorSpaceXform_XYZ } } + if (kRGBA_F32_ColorFormat == dstColorFormat) { + return this->applyPipeline(dstColorFormat, dst, srcColorFormat, src, len, alphaType); + } + switch (dstColorFormat) { case kRGBA_8888_ColorFormat: switch (kDst) { @@ -1259,16 +1227,8 @@ bool SkColorSpaceXform_XYZ default: return false; } - case kRGBA_F32_ColorFormat: - switch (kDst) { - case kLinear_DstGamma: - return apply_set_src - (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, - srcColorFormat); - default: - return false; - } default: + SkASSERT(false); return false; } } @@ -1281,93 +1241,44 @@ bool SkColorSpaceXform::apply(ColorFormat dstColorFormat, void* dst, ColorFormat /////////////////////////////////////////////////////////////////////////////////////////////////// -SkColorSpaceXform_Pipeline::SkColorSpaceXform_Pipeline(SkColorSpace_XYZ* srcSpace, - const SkMatrix44& srcToDst, - SkColorSpace_XYZ* dstSpace, - ColorSpaceMatch csm, - SrcGamma srcGamma, - DstGamma dstGamma) - : fCSM(csm) - , fSrcGamma(srcGamma) - , fDstGamma(dstGamma) -{ - fSrcToDst[ 0] = srcToDst.get(0, 0); - fSrcToDst[ 1] = srcToDst.get(1, 0); - fSrcToDst[ 2] = srcToDst.get(2, 0); - fSrcToDst[ 3] = srcToDst.get(0, 1); - fSrcToDst[ 4] = srcToDst.get(1, 1); - fSrcToDst[ 5] = srcToDst.get(2, 1); - fSrcToDst[ 6] = srcToDst.get(0, 2); - fSrcToDst[ 7] = srcToDst.get(1, 2); - fSrcToDst[ 8] = srcToDst.get(2, 2); - fSrcToDst[ 9] = srcToDst.get(0, 3); - fSrcToDst[10] = srcToDst.get(1, 3); - fSrcToDst[11] = srcToDst.get(2, 3); - - const int numSrcTables = num_tables(srcSpace); - const size_t srcEntries = numSrcTables * 256; - const bool srcGammasAreMatching = (1 >= numSrcTables); - fSrcStorage.reset(srcEntries); - build_gamma_tables(fSrcGammaTables, fSrcStorage.get(), 256, srcSpace, kToLinear, - srcGammasAreMatching); - - const int numDstTables = num_tables(dstSpace); - dstSpace->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables); -} +template +bool SkColorSpaceXform_XYZ +::applyPipeline(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, + const void* src, int len, SkAlphaType alphaType) const { + SkRasterPipeline pipeline; -bool SkColorSpaceXform_Pipeline::onApply(ColorFormat dstColorFormat, void* dst, - ColorFormat srcColorFormat, const void* src, int len, - SkAlphaType alphaType) const { - if (kFull_ColorSpaceMatch == fCSM) { - if (kPremul_SkAlphaType != alphaType) { - if ((kRGBA_8888_ColorFormat == dstColorFormat && - kRGBA_8888_ColorFormat == srcColorFormat) || - (kBGRA_8888_ColorFormat == dstColorFormat && - kBGRA_8888_ColorFormat == srcColorFormat)) - { - memcpy(dst, src, len * sizeof(uint32_t)); - return true; + LoadTablesContext loadTables; + switch (srcColorFormat) { + case kRGBA_8888_ColorFormat: + if (kLinear_SrcGamma == kSrc) { + pipeline.append(SkRasterPipeline::load_8888, &src); + } else { + loadTables.fSrc = (const uint32_t*) src; + loadTables.fR = fSrcGammaTables[0]; + loadTables.fG = fSrcGammaTables[1]; + loadTables.fB = fSrcGammaTables[2]; + pipeline.append(SkRasterPipeline::load_tables, &loadTables); } - if ((kRGBA_8888_ColorFormat == dstColorFormat && - kBGRA_8888_ColorFormat == srcColorFormat) || - (kBGRA_8888_ColorFormat == dstColorFormat && - kRGBA_8888_ColorFormat == srcColorFormat)) - { - SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len); - return true; + break; + case kBGRA_8888_ColorFormat: + if (kLinear_SrcGamma == kSrc) { + pipeline.append(SkRasterPipeline::load_8888, &src); + } else { + loadTables.fSrc = (const uint32_t*) src; + loadTables.fR = fSrcGammaTables[2]; + loadTables.fG = fSrcGammaTables[1]; + loadTables.fB = fSrcGammaTables[0]; + pipeline.append(SkRasterPipeline::load_tables, &loadTables); } - } - } - - if (kRGBA_F16_ColorFormat == srcColorFormat || kRGBA_F32_ColorFormat == srcColorFormat) { - return false; - } - - SkRasterPipeline pipeline; - LoadTablesContext loadTables; - if (kLinear_SrcGamma == fSrcGamma) { - pipeline.append(SkRasterPipeline::load_8888, &src); - if (kBGRA_8888_ColorFormat == srcColorFormat) { pipeline.append(SkRasterPipeline::swap_rb); - } - } else { - loadTables.fSrc = (const uint32_t*) src; - loadTables.fG = fSrcGammaTables[1]; - if (kRGBA_8888_ColorFormat == srcColorFormat) { - loadTables.fR = fSrcGammaTables[0]; - loadTables.fB = fSrcGammaTables[2]; - pipeline.append(SkRasterPipeline::load_tables, &loadTables); - } else { - loadTables.fR = fSrcGammaTables[2]; - loadTables.fB = fSrcGammaTables[0]; - pipeline.append(SkRasterPipeline::load_tables, &loadTables); - pipeline.append(SkRasterPipeline::swap_rb); - } + break; + default: + return false; } - if (kNone_ColorSpaceMatch == fCSM) { + if (kNone_ColorSpaceMatch == kCSM) { pipeline.append(SkRasterPipeline::matrix_3x4, fSrcToDst); if (kRGBA_8888_ColorFormat == dstColorFormat || kBGRA_8888_ColorFormat == dstColorFormat) { @@ -1384,7 +1295,7 @@ bool SkColorSpaceXform_Pipeline::onApply(ColorFormat dstColorFormat, void* dst, } StoreTablesContext storeTables; - switch (fDstGamma) { + switch (kDst) { case kSRGB_DstGamma: pipeline.append(SkRasterPipeline::to_srgb); break; @@ -1397,7 +1308,7 @@ bool SkColorSpaceXform_Pipeline::onApply(ColorFormat dstColorFormat, void* dst, switch (dstColorFormat) { case kRGBA_8888_ColorFormat: - if (kTable_DstGamma == fDstGamma) { + if (kTable_DstGamma == kDst) { storeTables.fDst = (uint32_t*) dst; storeTables.fR = fDstGammaTables[0]; storeTables.fG = fDstGammaTables[1]; @@ -1409,7 +1320,7 @@ bool SkColorSpaceXform_Pipeline::onApply(ColorFormat dstColorFormat, void* dst, } break; case kBGRA_8888_ColorFormat: - if (kTable_DstGamma == fDstGamma) { + if (kTable_DstGamma == kDst) { storeTables.fDst = (uint32_t*) dst; storeTables.fR = fDstGammaTables[2]; storeTables.fG = fDstGammaTables[1]; @@ -1423,13 +1334,13 @@ bool SkColorSpaceXform_Pipeline::onApply(ColorFormat dstColorFormat, void* dst, } break; case kRGBA_F16_ColorFormat: - if (kLinear_DstGamma != fDstGamma) { + if (kLinear_DstGamma != kDst) { return false; } pipeline.append(SkRasterPipeline::store_f16, &dst); break; case kRGBA_F32_ColorFormat: - if (kLinear_DstGamma != fDstGamma) { + if (kLinear_DstGamma != kDst) { return false; } pipeline.append(SkRasterPipeline::store_f32, &dst); @@ -1443,13 +1354,7 @@ bool SkColorSpaceXform_Pipeline::onApply(ColorFormat dstColorFormat, void* dst, /////////////////////////////////////////////////////////////////////////////////////////////////// std::unique_ptr SlowIdentityXform(SkColorSpace_XYZ* space) { - if (kUseRasterPipeline) { - return std::unique_ptr(new SkColorSpaceXform_Pipeline( - space, SkMatrix::I(), space, kNone_ColorSpaceMatch, kTable_SrcGamma, - kTable_DstGamma)); - } else { - return std::unique_ptr(new SkColorSpaceXform_XYZ - - (space, SkMatrix::I(), space)); - } + return std::unique_ptr(new SkColorSpaceXform_XYZ + + (space, SkMatrix::I(), space)); } diff --git a/src/core/SkColorSpaceXform_Base.h b/src/core/SkColorSpaceXform_Base.h index 3d17f67..e208573 100644 --- a/src/core/SkColorSpaceXform_Base.h +++ b/src/core/SkColorSpaceXform_Base.h @@ -56,6 +56,9 @@ protected: int count, SkAlphaType alphaType) const override; private: + bool applyPipeline(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src, + int count, SkAlphaType alphaType) const; + SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst, SkColorSpace_XYZ* dstSpace); @@ -65,7 +68,8 @@ private: const uint8_t* fDstGammaTables[3]; sk_sp fDstStorage; - float fSrcToDst[16]; + // Holds a 3x4 matrix. Padding is useful for vector loading. + float fSrcToDst[13]; friend class SkColorSpaceXform; friend std::unique_ptr SlowIdentityXform(SkColorSpace_XYZ* space); @@ -86,32 +90,6 @@ struct StoreTablesContext { int fCount; }; -class SkColorSpaceXform_Pipeline : public SkColorSpaceXform_Base { -protected: - virtual bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src, - int count, SkAlphaType alphaType) const; - -private: - SkColorSpaceXform_Pipeline(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst, - SkColorSpace_XYZ* dstSpace, ColorSpaceMatch csm, SrcGamma srcGamma, - DstGamma dstGamma); - - // Contain pointers into storage or pointers into precomputed tables. - const float* fSrcGammaTables[3]; - SkAutoTMalloc fSrcStorage; - const uint8_t* fDstGammaTables[3]; - sk_sp fDstStorage; - - float fSrcToDst[12]; - - ColorSpaceMatch fCSM; - SrcGamma fSrcGamma; - DstGamma fDstGamma; - - friend class SkColorSpaceXform; - friend std::unique_ptr SlowIdentityXform(SkColorSpace_XYZ* space); -}; - // For testing. Bypasses opts for when src and dst color spaces are equal. std::unique_ptr SlowIdentityXform(SkColorSpace_XYZ* space);