| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  * Copyright 2016 Google Inc. | 
|  | 3  * | 
|  | 4  * Use of this source code is governed by a BSD-style license that can be | 
|  | 5  * found in the LICENSE file. | 
|  | 6  */ | 
|  | 7 | 
|  | 8 #include "SkHalf.h" | 
|  | 9 #include "SkPM4fPriv.h" | 
|  | 10 #include "SkUtils.h" | 
|  | 11 #include "SkXfermode.h" | 
|  | 12 | 
|  | 13 static void sk_memset64(uint64_t dst[], uint64_t value, int count) { | 
|  | 14     for (int i = 0; i < count; ++i) { | 
|  | 15         dst[i] = value; | 
|  | 16     } | 
|  | 17 } | 
|  | 18 | 
|  | 19 struct U64ProcPair { | 
|  | 20     SkXfermode::U64Proc1 fP1; | 
|  | 21     SkXfermode::U64ProcN fPN; | 
|  | 22 }; | 
|  | 23 | 
|  | 24 enum DstType { | 
|  | 25     kU16_Dst, | 
|  | 26     kF16_Dst, | 
|  | 27 }; | 
|  | 28 | 
|  | 29 static Sk4f lerp_by_coverage(const Sk4f& src, const Sk4f& dst, uint8_t srcCovera
     ge) { | 
|  | 30     return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f)); | 
|  | 31 } | 
|  | 32 | 
|  | 33 template <DstType D> Sk4f unit_to_dst_bias(const Sk4f& x4) { | 
|  | 34     return (D == kU16_Dst) ? x4 * Sk4f(65535) : x4; | 
|  | 35 } | 
|  | 36 | 
|  | 37 // returns value already biased by 65535 | 
|  | 38 static Sk4f load_from_u16(uint64_t value) { | 
|  | 39     return SkNx_cast<float>(Sk4h::Load(&value)); | 
|  | 40 } | 
|  | 41 | 
|  | 42 // takes floats already biased by 65535 | 
|  | 43 static uint64_t store_to_u16(const Sk4f& x4) { | 
|  | 44     uint64_t value; | 
|  | 45     SkNx_cast<uint16_t>(x4 + Sk4f(0.5f)).store(&value); | 
|  | 46     return value; | 
|  | 47 } | 
|  | 48 | 
|  | 49 static Sk4f load_from_f16(uint64_t value) { | 
|  | 50     const uint16_t* u16 = reinterpret_cast<const uint16_t*>(&value); | 
|  | 51     float f4[4]; | 
|  | 52     for (int i = 0; i < 4; ++i) { | 
|  | 53         f4[i] = SkHalfToFloat(u16[i]); | 
|  | 54     } | 
|  | 55     return Sk4f::Load(f4); | 
|  | 56 } | 
|  | 57 | 
|  | 58 static uint64_t store_to_f16(const Sk4f& x4) { | 
|  | 59     uint64_t value; | 
|  | 60     uint16_t* u16 = reinterpret_cast<uint16_t*>(&value); | 
|  | 61 | 
|  | 62     float f4[4]; | 
|  | 63     x4.store(f4); | 
|  | 64     for (int i = 0; i < 4; ++i) { | 
|  | 65         u16[i] = SkFloatToHalf(f4[i]); | 
|  | 66     } | 
|  | 67     return value; | 
|  | 68 } | 
|  | 69 | 
|  | 70 // Returns dst in its "natural" bias (either unit-float or 16bit int) | 
|  | 71 // | 
|  | 72 template <DstType D> Sk4f load_from_dst(uint64_t dst) { | 
|  | 73     return (D == kU16_Dst) ? load_from_u16(dst) : load_from_f16(dst); | 
|  | 74 } | 
|  | 75 | 
|  | 76 // Assumes x4 is already in the "natural" bias (either unit-float or 16bit int) | 
|  | 77 template <DstType D> uint64_t store_to_dst(const Sk4f& x4) { | 
|  | 78     return (D == kU16_Dst) ? store_to_u16(x4) : store_to_f16(x4); | 
|  | 79 } | 
|  | 80 | 
|  | 81 ////////////////////////////////////////////////////////////////////////////////
     /////////////////// | 
|  | 82 | 
|  | 83 template <DstType D> void src_1(const SkXfermode::U64State& state, uint64_t dst[
     ], | 
|  | 84                                 const SkPM4f& src, int count, const SkAlpha aa[]
     ) { | 
|  | 85     const Sk4f s4 = unit_to_dst_bias<D>(Sk4f::Load(src.fVec)); | 
|  | 86     if (aa) { | 
|  | 87         for (int i = 0; i < count; ++i) { | 
|  | 88             const Sk4f d4 = load_from_dst<D>(dst[i]); | 
|  | 89             dst[i] = store_to_dst<D>(lerp_by_coverage(s4, d4, aa[i])); | 
|  | 90         } | 
|  | 91     } else { | 
|  | 92         sk_memset64(dst, store_to_dst<D>(s4), count); | 
|  | 93     } | 
|  | 94 } | 
|  | 95 | 
|  | 96 template <DstType D> void src_n(const SkXfermode::U64State& state, uint64_t dst[
     ], | 
|  | 97                                 const SkPM4f src[], int count, const SkAlpha aa[
     ]) { | 
|  | 98     if (aa) { | 
|  | 99         for (int i = 0; i < count; ++i) { | 
|  | 100             const Sk4f s4 = unit_to_dst_bias<D>(Sk4f::Load(src[i].fVec)); | 
|  | 101             const Sk4f d4 = load_from_dst<D>(dst[i]); | 
|  | 102             dst[i] = store_to_dst<D>(lerp_by_coverage(s4, d4, aa[i])); | 
|  | 103         } | 
|  | 104     } else { | 
|  | 105         for (int i = 0; i < count; ++i) { | 
|  | 106             const Sk4f s4 = unit_to_dst_bias<D>(Sk4f::Load(src[i].fVec)); | 
|  | 107             dst[i] = store_to_dst<D>(s4); | 
|  | 108         } | 
|  | 109     } | 
|  | 110 } | 
|  | 111 | 
|  | 112 const U64ProcPair gU64Procs_Src[] = { | 
|  | 113     { src_1<kU16_Dst>, src_n<kU16_Dst>  },   // U16     alpha | 
|  | 114     { src_1<kU16_Dst>, src_n<kU16_Dst>  },   // U16     opaque | 
|  | 115     { src_1<kF16_Dst>, src_n<kF16_Dst>  },   // F16     alpha | 
|  | 116     { src_1<kF16_Dst>, src_n<kF16_Dst>  },   // F16     opaque | 
|  | 117 }; | 
|  | 118 | 
|  | 119 ////////////////////////////////////////////////////////////////////////////////
     /////////////////// | 
|  | 120 | 
|  | 121 template <DstType D> void srcover_1(const SkXfermode::U64State& state, uint64_t 
     dst[], | 
|  | 122                                     const SkPM4f& src, int count, const SkAlpha 
     aa[]) { | 
|  | 123     const Sk4f s4 = Sk4f::Load(src.fVec); | 
|  | 124     const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); | 
|  | 125     const Sk4f s4bias = unit_to_dst_bias<D>(s4); | 
|  | 126     for (int i = 0; i < count; ++i) { | 
|  | 127         const Sk4f d4bias = load_from_dst<D>(dst[i]); | 
|  | 128         const Sk4f r4bias = s4bias + d4bias * dst_scale; | 
|  | 129         if (aa) { | 
|  | 130             dst[i] = store_to_dst<D>(lerp_by_coverage(r4bias, d4bias, aa[i])); | 
|  | 131         } else { | 
|  | 132             dst[i] = store_to_dst<D>(r4bias); | 
|  | 133         } | 
|  | 134     } | 
|  | 135 } | 
|  | 136 | 
|  | 137 template <DstType D> void srcover_n(const SkXfermode::U64State& state, uint64_t 
     dst[], | 
|  | 138                                     const SkPM4f src[], int count, const SkAlpha
      aa[]) { | 
|  | 139     for (int i = 0; i < count; ++i) { | 
|  | 140         const Sk4f s4 = Sk4f::Load(src[i].fVec); | 
|  | 141         const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); | 
|  | 142         const Sk4f s4bias = unit_to_dst_bias<D>(s4); | 
|  | 143         const Sk4f d4bias = load_from_dst<D>(dst[i]); | 
|  | 144         const Sk4f r4bias = s4bias + d4bias * dst_scale; | 
|  | 145         if (aa) { | 
|  | 146             dst[i] = store_to_dst<D>(lerp_by_coverage(r4bias, d4bias, aa[i])); | 
|  | 147         } else { | 
|  | 148             dst[i] = store_to_dst<D>(r4bias); | 
|  | 149         } | 
|  | 150     } | 
|  | 151 } | 
|  | 152 | 
|  | 153 const U64ProcPair gU64Procs_SrcOver[] = { | 
|  | 154     { srcover_1<kU16_Dst>,  srcover_n<kU16_Dst> },   // U16     alpha | 
|  | 155     { src_1<kU16_Dst>,      src_n<kU16_Dst>     },   // U16     opaque | 
|  | 156     { srcover_1<kF16_Dst>,  srcover_n<kF16_Dst> },   // F16     alpha | 
|  | 157     { src_1<kF16_Dst>,      src_n<kF16_Dst>     },   // F16     opaque | 
|  | 158 }; | 
|  | 159 | 
|  | 160 ////////////////////////////////////////////////////////////////////////////////
     /////////////////// | 
|  | 161 | 
|  | 162 static U64ProcPair find_procs(SkXfermode::Mode mode, uint32_t flags) { | 
|  | 163     SkASSERT(0 == (flags & ~3)); | 
|  | 164     flags &= 3; | 
|  | 165 | 
|  | 166     switch (mode) { | 
|  | 167         case SkXfermode::kSrc_Mode:     return gU64Procs_Src[flags]; | 
|  | 168         case SkXfermode::kSrcOver_Mode: return gU64Procs_SrcOver[flags]; | 
|  | 169         default: | 
|  | 170             break; | 
|  | 171     } | 
|  | 172     return { nullptr, nullptr }; | 
|  | 173 } | 
|  | 174 | 
|  | 175 SkXfermode::U64Proc1 SkXfermode::GetU64Proc1(Mode mode, uint32_t flags) { | 
|  | 176     return find_procs(mode, flags).fP1; | 
|  | 177 } | 
|  | 178 | 
|  | 179 SkXfermode::U64ProcN SkXfermode::GetU64ProcN(Mode mode, uint32_t flags) { | 
|  | 180     return find_procs(mode, flags).fPN; | 
|  | 181 } | 
| OLD | NEW | 
|---|