1 /*
2 * Copyright 2015 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 "SkUtils.h"
9
10 namespace { // See Sk4px.h
11
12 static_assert(sizeof(Sk4px) == 16, "This file uses memcpy / sk_memset32, so exact size matters.");
13
DupPMColor(SkPMColor px)14 inline Sk4px Sk4px::DupPMColor(SkPMColor px) {
15 Sk4px px4 = Sk16b();
16 sk_memset32((uint32_t*)&px4, px, 4);
17 return px4;
18 }
19
Load4(const SkPMColor px[4])20 inline Sk4px Sk4px::Load4(const SkPMColor px[4]) {
21 Sk4px px4 = Sk16b();
22 memcpy(&px4, px, 16);
23 return px4;
24 }
25
Load2(const SkPMColor px[2])26 inline Sk4px Sk4px::Load2(const SkPMColor px[2]) {
27 Sk4px px2 = Sk16b();
28 memcpy(&px2, px, 8);
29 return px2;
30 }
31
Load1(const SkPMColor px[1])32 inline Sk4px Sk4px::Load1(const SkPMColor px[1]) {
33 Sk4px px1 = Sk16b();
34 memcpy(&px1, px, 4);
35 return px1;
36 }
37
store4(SkPMColor px[4])38 inline void Sk4px::store4(SkPMColor px[4]) const { memcpy(px, this, 16); }
store2(SkPMColor px[2])39 inline void Sk4px::store2(SkPMColor px[2]) const { memcpy(px, this, 8); }
store1(SkPMColor px[1])40 inline void Sk4px::store1(SkPMColor px[1]) const { memcpy(px, this, 4); }
41
widenLo()42 inline Sk4px::Wide Sk4px::widenLo() const {
43 return Sk16h((*this)[ 0], (*this)[ 1], (*this)[ 2], (*this)[ 3],
44 (*this)[ 4], (*this)[ 5], (*this)[ 6], (*this)[ 7],
45 (*this)[ 8], (*this)[ 9], (*this)[10], (*this)[11],
46 (*this)[12], (*this)[13], (*this)[14], (*this)[15]);
47 }
48
widenHi()49 inline Sk4px::Wide Sk4px::widenHi() const { return this->widenLo() << 8; }
50
widenLoHi()51 inline Sk4px::Wide Sk4px::widenLoHi() const { return this->widenLo() + this->widenHi(); }
52
mulWiden(const Sk16b & other)53 inline Sk4px::Wide Sk4px::mulWiden(const Sk16b& other) const {
54 return this->widenLo() * Sk4px(other).widenLo();
55 }
56
addNarrowHi(const Sk16h & other)57 inline Sk4px Sk4px::Wide::addNarrowHi(const Sk16h& other) const {
58 Sk4px::Wide r = (*this + other) >> 8;
59 return Sk16b(r[ 0], r[ 1], r[ 2], r[ 3],
60 r[ 4], r[ 5], r[ 6], r[ 7],
61 r[ 8], r[ 9], r[10], r[11],
62 r[12], r[13], r[14], r[15]);
63 }
64
div255()65 inline Sk4px Sk4px::Wide::div255() const {
66 // Calculated as ((x+128) + ((x+128)>>8)) >> 8.
67 auto v = *this + Sk16h(128);
68 return v.addNarrowHi(v>>8);
69 }
70
alphas()71 inline Sk4px Sk4px::alphas() const {
72 static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
73 return Sk16b((*this)[ 3], (*this)[ 3], (*this)[ 3], (*this)[ 3],
74 (*this)[ 7], (*this)[ 7], (*this)[ 7], (*this)[ 7],
75 (*this)[11], (*this)[11], (*this)[11], (*this)[11],
76 (*this)[15], (*this)[15], (*this)[15], (*this)[15]);
77 }
78
Load4Alphas(const SkAlpha a[4])79 inline Sk4px Sk4px::Load4Alphas(const SkAlpha a[4]) {
80 return Sk16b(a[0], a[0], a[0], a[0],
81 a[1], a[1], a[1], a[1],
82 a[2], a[2], a[2], a[2],
83 a[3], a[3], a[3], a[3]);
84 }
85
Load2Alphas(const SkAlpha a[2])86 inline Sk4px Sk4px::Load2Alphas(const SkAlpha a[2]) {
87 return Sk16b(a[0], a[0], a[0], a[0],
88 a[1], a[1], a[1], a[1],
89 0,0,0,0,
90 0,0,0,0);
91 }
92
zeroAlphas()93 inline Sk4px Sk4px::zeroAlphas() const {
94 static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
95 return Sk16b((*this)[ 0], (*this)[ 1], (*this)[ 2], 0,
96 (*this)[ 4], (*this)[ 5], (*this)[ 6], 0,
97 (*this)[ 8], (*this)[ 9], (*this)[10], 0,
98 (*this)[12], (*this)[13], (*this)[14], 0);
99 }
100
zeroColors()101 inline Sk4px Sk4px::zeroColors() const {
102 static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
103 return Sk16b(0,0,0, (*this)[ 3],
104 0,0,0, (*this)[ 7],
105 0,0,0, (*this)[11],
106 0,0,0, (*this)[15]);
107 }
108
109 } // namespace
110