Add support for F32 sources to SkColorSpaceXform
authorMatt Sarett <msarett@google.com>
Mon, 20 Mar 2017 23:06:18 +0000 (19:06 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Tue, 21 Mar 2017 12:46:37 +0000 (12:46 +0000)
This also subtlely allows clients to convert between F32 and F16.

BUG=skia:

CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD

Change-Id: Ied5f2295fce00c69d8cf85730be899f3f8597915
Reviewed-on: https://skia-review.googlesource.com/9914
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Matt Sarett <msarett@google.com>

gm/colorspacexform.cpp
include/core/SkColorSpaceXform.h
src/core/SkColorSpaceXform.cpp
src/core/SkColorSpaceXform_A2B.cpp
src/core/SkRasterPipeline.h
src/opts/SkRasterPipeline_opts.h

index dfb3437..4657f6a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 Google Inc.
+ * Copyright 2016 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
@@ -7,6 +7,7 @@
 
 #include "gm.h"
 #include "SkColor.h"
+#include "SkColorSpace_Base.h"
 #include "SkColorSpaceXform.h"
 #include "SkRect.h"
 
@@ -35,15 +36,22 @@ protected:
         SkMatrix44 wideGamut(SkMatrix44::kUninitialized_Constructor);
         wideGamut.set3x3RowMajorf(kWideGamutRGB_toXYZD50);
 
+        // Test BGRA input.
         sk_sp<SkColorSpace> srcSpace = SkColorSpace::MakeSRGB();
         sk_sp<SkColorSpace> dstSpace =
                 SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, wideGamut);
         std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(srcSpace.get(),
                                                                           dstSpace.get());
-
-        xform->apply(SkColorSpaceXform::kRGBA_F32_ColorFormat, fWideGamutColors,
+        xform->apply(SkColorSpaceXform::kRGBA_F32_ColorFormat, fWideGamutColors0,
                      SkColorSpaceXform::kBGRA_8888_ColorFormat, colors, kNumColors,
                      kOpaque_SkAlphaType);
+
+        // Test F32 input.
+        srcSpace = as_CSB(srcSpace)->makeLinearGamma();
+        xform = SkColorSpaceXform::New(srcSpace.get(), dstSpace.get());
+        xform->apply(SkColorSpaceXform::kRGBA_F32_ColorFormat, fWideGamutColors1,
+                     SkColorSpaceXform::kRGBA_F32_ColorFormat, fSRGBColors, kNumColors,
+                     kOpaque_SkAlphaType);
     }
 
     SkString onShortName() override {
@@ -51,7 +59,7 @@ protected:
     }
 
     SkISize onISize() override {
-        return SkISize::Make(500, 200);
+        return SkISize::Make(500, 300);
     }
 
     void onDraw(SkCanvas* canvas) override {
@@ -73,14 +81,17 @@ protected:
         // Wide gamut colors should appear darker - we are simulating a more intense display.
         drawColors(fSRGBColors);
         canvas->translate(0.0f, 100.0f);
-        drawColors(fWideGamutColors);
+        drawColors(fWideGamutColors0);
+        canvas->translate(0.0f, 100.0f);
+        drawColors(fWideGamutColors1);
     }
 
 private:
     static constexpr int kNumColors = 10;
 
     SkColor4f fSRGBColors[kNumColors];
-    SkColor4f fWideGamutColors[kNumColors];
+    SkColor4f fWideGamutColors0[kNumColors];
+    SkColor4f fWideGamutColors1[kNumColors];
 
     typedef skiagm::GM INHERITED;
 };
index fc38b7c..16392a0 100644 (file)
@@ -33,14 +33,14 @@ public:
         kRGBA_U16_BE_ColorFormat,  // Src only
 
         kRGBA_F16_ColorFormat,
-        kRGBA_F32_ColorFormat,     // Dst only
+        kRGBA_F32_ColorFormat,
     };
 
     /**
      *  Apply the color conversion to a |src| buffer, storing the output in the |dst| buffer.
      *
-     *  F32 is only supported as a dst color format. F16 and F32 are only supported when the color
-     *  space is linear. This function will return false in unsupported cases.
+     *  F16 and F32 are only supported when the color space is linear. This function will return
+     *  false in unsupported cases.
      *
      *  @param dst            Stored in the format described by |dstColorFormat|
      *  @param src            Stored in the format described by |srcColorFormat|
index 33e01c9..b81c23c 100644 (file)
@@ -1061,6 +1061,7 @@ bool SkColorSpaceXform_XYZ<kCSM>
     }
 
     if (kRGBA_F32_ColorFormat == dstColorFormat ||
+        kRGBA_F32_ColorFormat == srcColorFormat ||
         kRGBA_F16_ColorFormat == srcColorFormat ||
         kRGBA_U16_BE_ColorFormat == srcColorFormat ||
         kRGB_U16_BE_ColorFormat == srcColorFormat ||
@@ -1170,6 +1171,12 @@ bool SkColorSpaceXform_XYZ<kCSM>
             }
             pipeline.append(SkRasterPipeline::load_f16, &src);
             break;
+        case kRGBA_F32_ColorFormat:
+            if (kLinear_SrcGamma != fSrcGamma) {
+                return false;
+            }
+            pipeline.append(SkRasterPipeline::load_f32, &src);
+            break;
         case kRGBA_U16_BE_ColorFormat:
             switch (fSrcGamma) {
                 case kLinear_SrcGamma:
@@ -1206,8 +1213,6 @@ bool SkColorSpaceXform_XYZ<kCSM>
                     break;
             }
             break;
-        default:
-            return false;
     }
 
     if (kNone_ColorSpaceMatch == kCSM) {
index cde07f5..433c9a1 100644 (file)
@@ -35,7 +35,7 @@ bool SkColorSpaceXform_A2B::onApply(ColorFormat dstFormat, void* dst, ColorForma
             pipeline.append(SkRasterPipeline::load_rgb_u16_be, &src);
             break;
         default:
-            SkCSXformPrintf("F16/F32 source color format not supported\n");
+            SkCSXformPrintf("F16/F32 sources must be linear.\n");
             return false;
     }
 
index 0d2bfa4..01bd683 100644 (file)
     M(set_rgb) M(swap_rb)                                        \
     M(from_srgb) M(to_srgb)                                      \
     M(from_2dot2) M(to_2dot2)                                    \
-    M(constant_color) M(seed_shader) M(store_f32)                \
+    M(constant_color) M(seed_shader)                             \
     M(load_a8)   M(store_a8)                                     \
     M(load_g8)                                                   \
     M(load_565)  M(store_565)                                    \
     M(load_4444) M(store_4444)                                   \
     M(load_f16)  M(store_f16)                                    \
+    M(load_f32)  M(store_f32)                                    \
     M(load_8888) M(store_8888)                                   \
     M(load_u16_be) M(load_rgb_u16_be) M(store_u16_be)            \
     M(load_tables_u16_be) M(load_tables_rgb_u16_be)              \
index 07f1e5a..3b15efa 100644 (file)
@@ -149,7 +149,8 @@ SI void SK_VECTORCALL just_return(size_t, void**, SkNf, SkNf, SkNf, SkNf,
 template <typename T>
 SI SkNx<N,T> load(size_t tail, const T* src) {
     if (tail) {
-        T buf[8] = {0};
+        T buf[8];
+        memset(buf, 0, 8*sizeof(T));
         switch (tail & (N-1)) {
             case 7: buf[6] = src[6];
             case 6: buf[5] = src[5];
@@ -574,6 +575,17 @@ STAGE_CTX(store_f16, uint64_t**) {
     }
 }
 
+STAGE_CTX(load_f32, const SkPM4f**) {
+    auto ptr = *ctx + x;
+
+    const void* src = ptr;
+    SkNx<N, SkPM4f> px;
+    if (tail) {
+        px = load(tail, ptr);
+        src = &px;
+    }
+    SkNf::Load4(src, &r, &g, &b, &a);
+}
 STAGE_CTX(store_f32, SkPM4f**) {
     auto ptr = *ctx + x;