Index: src/core/SkSpanProcs.cpp |
diff --git a/src/core/SkSpanProcs.cpp b/src/core/SkSpanProcs.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..efbce9704a8ceb35f48c696db069dd89d82388b7 |
--- /dev/null |
+++ b/src/core/SkSpanProcs.cpp |
@@ -0,0 +1,95 @@ |
+/* |
+ * Copyright 2016 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "SkColorFilter.h" |
+#include "SkHalf.h" |
+#include "SkNx.h" |
+#include "SkPaint.h" |
+#include "SkPixmap.h" |
+#include "SkPM4f.h" |
+#include "SkPM4fPriv.h" |
+#include "SkSpanProcs.h" |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+static void load_l32(const SkPixmap& src, int x, int y, SkPM4f span[], int count) { |
+ SkASSERT(count > 0); |
+ const uint32_t* addr = src.addr32(x, y); |
+ SkASSERT(src.addr32(x + count - 1, y)); |
+ |
+ for (int i = 0; i < count; ++i) { |
+ (SkNx_cast<float>(Sk4b::Load(&addr[i])) * Sk4f(1.0f/255)).store(span[i].fVec); |
+ } |
+} |
+ |
+static void load_s32(const SkPixmap& src, int x, int y, SkPM4f span[], int count) { |
+ SkASSERT(count > 0); |
+ const uint32_t* addr = src.addr32(x, y); |
+ SkASSERT(src.addr32(x + count - 1, y)); |
+ |
+ for (int i = 0; i < count; ++i) { |
+ srgb_to_linear(SkNx_cast<float>(Sk4b::Load(&addr[i])) * Sk4f(1.0f/255)).store(span[i].fVec); |
+ } |
+} |
+ |
+static void load_f16(const SkPixmap& src, int x, int y, SkPM4f span[], int count) { |
+ SkASSERT(count > 0); |
+ const uint64_t* addr = src.addr64(x, y); |
+ SkASSERT(src.addr64(x + count - 1, y)); |
+ |
+ for (int i = 0; i < count; ++i) { |
+ SkHalfToFloat_01(addr[i]).store(span[i].fVec); |
+ } |
+} |
+ |
+SkLoadSpanProc SkLoadSpanProc_Choose(const SkImageInfo& info) { |
+ switch (info.colorType()) { |
+ case kN32_SkColorType: |
+ return info.isSRGB() ? load_s32 : load_l32; |
+ case kRGBA_F16_SkColorType: |
+ return load_f16; |
+ default: |
+ return nullptr; |
+ } |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+static void noop_filterspan(const SkPaint& paint, SkPM4f[], int) { |
+ SkASSERT(!paint.getColorFilter()); |
+ SkASSERT(0xFF == paint.getAlpha()); |
+} |
+ |
+static void alpha_filterspan(const SkPaint& paint, SkPM4f span[], int count) { |
+ SkASSERT(!paint.getColorFilter()); |
+ SkASSERT(0xFF != paint.getAlpha()); |
+ const Sk4f scale = Sk4f(paint.getAlpha() * (1.0f/255)); |
+ for (int i = 0; i < count; ++i) { |
+ (Sk4f::Load(span[i].fVec) * scale).store(span[i].fVec); |
+ } |
+} |
+ |
+static void colorfilter_filterspan(const SkPaint& paint, SkPM4f span[], int count) { |
+ SkASSERT(paint.getColorFilter()); |
+ SkASSERT(0xFF == paint.getAlpha()); |
+ paint.getColorFilter()->filterSpan4f(span, count, span); |
+} |
+ |
+static void colorfilter_alpha_filterspan(const SkPaint& paint, SkPM4f span[], int count) { |
+ SkASSERT(paint.getColorFilter()); |
+ SkASSERT(0xFF != paint.getAlpha()); |
+ alpha_filterspan(paint, span, count); |
+ paint.getColorFilter()->filterSpan4f(span, count, span); |
+} |
+ |
+SkFilterSpanProc SkFilterSpanProc_Choose(const SkPaint& paint) { |
+ if (paint.getColorFilter()) { |
+ return 0xFF == paint.getAlpha() ? colorfilter_filterspan : colorfilter_alpha_filterspan; |
+ } else { |
+ return 0xFF == paint.getAlpha() ? noop_filterspan : alpha_filterspan; |
+ } |
+} |