Chromium Code Reviews| Index: src/core/SkXfer4f.cpp |
| diff --git a/src/core/SkXfer4f.cpp b/src/core/SkXfer4f.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b177e49b18d972d6cd325096f9a7c4948604aa04 |
| --- /dev/null |
| +++ b/src/core/SkXfer4f.cpp |
| @@ -0,0 +1,134 @@ |
| +/* |
| + * 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 "SkXfer4f.h" |
| +#include "SkPM4fPriv.h" |
| +#include "SkUtils.h" |
| + |
| +/////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| +void CLEAR_pm41p(uint32_t dst[], const SkPM4f& src, int count) { |
|
mtklein
2016/01/29 15:23:00
pm41p / pm4np is a bit beyond my readability decry
|
| + sk_bzero(dst, count * sizeof(uint32_t)); |
| +} |
| + |
| +void CLEAR_pm4np(uint32_t dst[], const SkPM4f src[], int count) { |
| + sk_bzero(dst, count * sizeof(uint32_t)); |
| +} |
| + |
| +////////// |
| + |
| +template <bool isSRGB> void SRC_pm41p(uint32_t dst[], const SkPM4f& src, int count) { |
| + uint32_t res; |
| + if (isSRGB) { |
| + res = Sk4f_toS32(Sk4f::Load(src.fVec)); |
| + } else { |
| + res = Sk4f_toL32(Sk4f::Load(src.fVec)); |
| + } |
| + sk_memset32(dst, res, count); |
| +} |
| + |
| +template <bool isSRGB> void SRC_pm4np(uint32_t dst[], const SkPM4f src[], int count) { |
| + if (isSRGB) { |
| + SkPM4f_s32_src_mode(dst, src, count); |
| + } else { |
| + SkPM4f_l32_src_mode(dst, src, count); |
| + } |
| +} |
| + |
| +////////// |
| + |
| +void DST_pm41p(uint32_t dst[], const SkPM4f& src, int count) {} |
| +void DST_pm4np(uint32_t dst[], const SkPM4f src[], int count) {} |
| + |
| +////////// |
| + |
| +template <bool isSRGB> void SRCOVER_pm41p(uint32_t dst[], const SkPM4f& src, int count) { |
| + SkASSERT(src.isUnit()); |
| + Sk4f s4 = Sk4f::Load(src.fVec); |
| + Sk4f scale(1 - s4.kth<SkPM4f::A>()); |
| + |
| + if (!isSRGB) { |
| + s4 = s4 * Sk4f(255); |
|
mtklein
2016/01/29 15:41:31
I think if we break these problems apart into inde
|
| + } |
| + |
| + for (int i = 0; i < count; ++i) { |
| + if (isSRGB) { |
| + Sk4f d4 = Sk4f_fromS32(dst[i]); |
| + dst[i] = Sk4f_toS32(s4 + d4 * scale); |
| + } else { |
| + Sk4f d4 = to_4f(dst[i]); |
| + dst[i] = to_4b(s4 + d4 * scale + Sk4f(0.5f)); |
|
mtklein
2016/01/29 15:23:00
Add the half to s4 outside the loop too?
|
| + } |
| + } |
| +} |
| + |
| +template <bool isSRGB> void SRCOVER_pm4np(uint32_t dst[], const SkPM4f src[], int count) { |
| + if (isSRGB) { |
| + SkPM4f_s32_srcover_mode(dst, src, count); |
| + } else { |
| + SkPM4f_l32_srcover_mode(dst, src, count); |
| + } |
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| +struct Pair { |
|
mtklein
2016/01/29 15:23:00
This struct seems a little dangerous without an an
|
| + SkPM4fXfer1Proc fProc1; |
| + SkPM4fXferNProc fProcN; |
| +}; |
| + |
| +const Pair gClearPairs[] = { |
|
mtklein
2016/01/29 15:23:00
static for all these too?
|
| + { CLEAR_pm41p, CLEAR_pm4np }, |
| + { CLEAR_pm41p, CLEAR_pm4np }, |
| + { CLEAR_pm41p, CLEAR_pm4np }, |
| + { CLEAR_pm41p, CLEAR_pm4np }, |
| +}; |
| + |
| +const Pair gSrcPairs[] = { |
| + { SRC_pm41p<false>, SRC_pm4np<false> }, // linear [alpha ignored] |
| + { SRC_pm41p<false>, SRC_pm4np<false> }, // linear [opaque ignored] |
| + { SRC_pm41p<true>, SRC_pm4np<true> }, // srgb [alpha ignored] |
| + { SRC_pm41p<true>, SRC_pm4np<true> }, // srgb [opaque ignored] |
| +}; |
| + |
| +const Pair gDstPairs[] = { |
| + { DST_pm41p, DST_pm4np }, |
| + { DST_pm41p, DST_pm4np }, |
| + { DST_pm41p, DST_pm4np }, |
| + { DST_pm41p, DST_pm4np }, |
| +}; |
| + |
| +const Pair gSrcOverPairs[] = { |
| + { SRCOVER_pm41p<false>, SRCOVER_pm4np<false> }, // linear alpha |
| + { SRC_pm41p<false>, SRC_pm4np<false> }, // linear opaque |
| + { SRCOVER_pm41p<true>, SRCOVER_pm4np<true> }, // srgb alpha |
| + { SRC_pm41p<true>, SRC_pm4np<true> }, // srgb opaque |
| +}; |
| + |
| +static const Pair* find_pair(SkXfermode::Mode mode, uint32_t flags) { |
| + SkASSERT(0 == (flags & ~3)); |
| + const Pair* pairs = nullptr; |
| + |
| + switch (mode) { |
| + case SkXfermode::kClear_Mode: pairs = gClearPairs; |
|
mtklein
2016/01/29 15:23:00
I think you've missed some breaks?
|
| + case SkXfermode::kSrc_Mode: pairs = gSrcPairs; break; |
| + case SkXfermode::kDst_Mode: pairs = gDstPairs; |
| + case SkXfermode::kSrcOver_Mode: pairs = gSrcOverPairs; break; |
| + default: return nullptr; |
| + } |
| + return &pairs[flags & 3]; |
|
mtklein
2016/01/29 15:23:00
I think this could be a lot simpler if we return P
|
| +} |
| + |
| +SkPM4fXfer1Proc SkPM4fXfer1ProcFactory(SkXfermode::Mode mode, uint32_t flags) { |
| + const Pair* pair = find_pair(mode, flags); |
| + return pair ? pair->fProc1 : nullptr; |
| +} |
| + |
| +SkPM4fXferNProc SkPM4fXferNProcFactory(SkXfermode::Mode mode, uint32_t flags) { |
| + const Pair* pair = find_pair(mode, flags); |
| + return pair ? pair->fProcN : nullptr; |
| +} |