Merge SkColorSpaceXform_XYZ and SkColorSpaceXform_Pipeline
authorMatt Sarett <msarett@google.com>
Wed, 4 Jan 2017 21:54:55 +0000 (16:54 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 4 Jan 2017 23:12:58 +0000 (23:12 +0000)
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 <mtklein@chromium.org>
Commit-Queue: Matt Sarett <msarett@google.com>

src/core/SkColorSpaceXform.cpp
src/core/SkColorSpaceXform_Base.h

index 6eaab83..d394d3b 100644 (file)
 #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> 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<SkColorSpaceXform>(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> 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 <Order kOrder>
-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 <Order kOrder>
-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 <Order kOrder>
 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 <SrcFormat kSrc,
@@ -898,13 +856,12 @@ template <SrcFormat kSrc,
           SkAlphaType kAlphaType,
           ColorSpaceMatch kCSM>
 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<kRGBA_Order>;
             sizeOfDstPixel = 8;
             break;
-        case kF32_Linear_DstFormat:
-            store   = store_f32<kRGBA_Order>;
-            store_1 = store_f32_1<kRGBA_Order>;
-            sizeOfDstPixel = 16;
-            break;
     }
 
     // We always clamp before converting to 8888 outputs (because we have to).
@@ -1117,7 +1069,19 @@ SkColorSpaceXform_XYZ<kSrc, kDst, kCSM>
 ::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<kSrc, kDst, kCSM>
 
 template <SrcFormat kSrc, DstFormat kDst, ColorSpaceMatch kCSM>
 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 <SrcGamma kSrc, DstFormat kDst, ColorSpaceMatch kCSM>
 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<kSrc, kDst, kCSM>
         }
     }
 
+    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<kSrc, kDst, kCSM>
                 default:
                     return false;
             }
-        case kRGBA_F32_ColorFormat:
-            switch (kDst) {
-                case kLinear_DstGamma:
-                    return apply_set_src<kSrc, kF32_Linear_DstFormat, kCSM>
-                            (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 <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
+bool SkColorSpaceXform_XYZ<kSrc, kDst, kCSM>
+::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<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space) {
-    if (kUseRasterPipeline) {
-        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Pipeline(
-                space, SkMatrix::I(), space, kNone_ColorSpaceMatch, kTable_SrcGamma,
-                kTable_DstGamma));
-    } else {
-        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
-                <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
-                (space, SkMatrix::I(), space));
-    }
+    return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
+            <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
+            (space, SkMatrix::I(), space));
 }
index 3d17f67..e208573 100644 (file)
@@ -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<SkData>             fDstStorage;
 
-    float                     fSrcToDst[16];
+    // Holds a 3x4 matrix.  Padding is useful for vector loading.
+    float                     fSrcToDst[13];
 
     friend class SkColorSpaceXform;
     friend std::unique_ptr<SkColorSpaceXform> 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<float>      fSrcStorage;
-    const uint8_t*            fDstGammaTables[3];
-    sk_sp<SkData>             fDstStorage;
-
-    float                     fSrcToDst[12];
-
-    ColorSpaceMatch           fCSM;
-    SrcGamma                  fSrcGamma;
-    DstGamma                  fDstGamma;
-
-    friend class SkColorSpaceXform;
-    friend std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space);
-};
-
 // For testing.  Bypasses opts for when src and dst color spaces are equal.
 std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space);