1 /** 2 ** 3 ** Copyright 2010, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifndef _PIXELFLINGER2_VECTOR4_H_ 19 #define _PIXELFLINGER2_VECTOR4_H_ 20 21 #ifdef __cplusplus 22 23 template <typename Type> struct Vec4 { 24 union { 25 struct { Type x, y, z, w; }; 26 struct { Type r, g, b, a; }; 27 struct { Type S, T, R, Q; }; 28 #if !USE_FIXED_POINT 29 float f[4]; 30 unsigned u[4]; 31 int i[4]; 32 #endif 33 #if defined(__ARM_HAVE_NEON) && USE_NEON 34 float32x4_t f4; 35 #endif 36 }; 37 38 //Vec4() : x(0), y(0), z(0), w(0) {} Vec4Vec439 Vec4() {} Vec4Vec440 Vec4(Type X, Type Y, Type Z, Type W) : x(X), y(Y), z(Z), w(W) {} Vec4Vec441 Vec4(Type X) : x(X), y(X), z(X), w(X) {} 42 43 #define VECTOR4_OP_UNARY(op,rhs) { \ 44 x op rhs.x; \ 45 y op rhs.y; \ 46 z op rhs.z; \ 47 w op rhs.w; } 48 49 #define VECTOR4_OP_UNARY_SCALAR(op,rhs) { \ 50 x op rhs; \ 51 y op rhs; \ 52 z op rhs; \ 53 w op rhs; } 54 55 inline void operator += (const Vec4<Type> & rhs) __attribute__((always_inline)) 56 VECTOR4_OP_UNARY(+=,rhs) 57 inline void operator -= (const Vec4<Type> & rhs) __attribute__((always_inline)) 58 VECTOR4_OP_UNARY(-=,rhs) 59 inline void operator *= (const Vec4<Type> & rhs) __attribute__((always_inline)) 60 VECTOR4_OP_UNARY(*=,rhs) 61 inline void operator /= (const Vec4<Type> & rhs) __attribute__((always_inline)) 62 VECTOR4_OP_UNARY(/=,rhs) 63 inline void operator *= (Type rhs) __attribute__((always_inline)) 64 VECTOR4_OP_UNARY_SCALAR(*=,rhs) 65 inline void operator /= (Type rhs) __attribute__((always_inline)) 66 VECTOR4_OP_UNARY_SCALAR(/=,rhs) 67 68 inline Vec4 operator+(const Vec4 & rhs) const 69 { Vec4 res = *this; res += rhs; return res; } 70 71 #undef VECTOR4_OP_UNARY 72 #undef VECTOR4_OP_UNARY_SCALAR 73 CrossProduct3Vec474 void CrossProduct3(const Vec4<Type> & lhs, const Vec4<Type> & rhs) 75 { 76 x = lhs.y * rhs.z - lhs.z * rhs.y; 77 y = lhs.z * rhs.x - lhs.x * rhs.z; 78 z = lhs.y * rhs.x - lhs.x * rhs.y; 79 w = 0; 80 } 81 LShrVec482 void LShr(const unsigned shift) { u[0] >>= shift; u[1] >>= shift; u[2] >>= shift; u[3] >>= shift; } AShrVec483 void AShr(const unsigned shift) { i[0] >>= shift; i[1] >>= shift; i[2] >>= shift; i[3] >>= shift; } 84 85 bool operator==(const Vec4 & rhs) const { return u[0] == rhs.u[0] && u[1] == rhs.u[1] && u[2] == rhs.u[2] && u[3] == rhs.u[3]; } 86 bool operator!=(const Vec4 & rhs) const { return !(*this == rhs); } 87 }; 88 89 #if defined(__ARM_HAVE_NEON) && USE_NEON 90 template <> inline void Vec4<float>::operator += (const Vec4<float> & rhs) __attribute__((always_inline)); 91 template <> inline void Vec4<float>::operator += (const Vec4<float> & rhs) 92 { f4 = vaddq_f32(f4, rhs.f4); } 93 template <> inline void Vec4<float>::operator -= (const Vec4<float> & rhs) __attribute__((always_inline)); 94 template <> inline void Vec4<float>::operator -= (const Vec4<float> & rhs) 95 { f4 = vsubq_f32(f4, rhs.f4); } 96 template <> inline void Vec4<float>::operator *= (float rhs) __attribute__((always_inline)); 97 template <> inline void Vec4<float>::operator *= (float rhs) 98 { f4 = vmulq_n_f32(f4, rhs); } 99 template <> inline void Vec4<float>::operator /= (float rhs) __attribute__((always_inline)); 100 template <> inline void Vec4<float>::operator /= (float rhs) 101 { f4 = vmulq_n_f32(f4, 1 / rhs); } 102 #endif // #if defined(__ARM_HAVE_NEON) && USE_NEON 103 104 #if USE_FIXED_POINT 105 deprecated, should be removed 106 /*#define FIXED_POINT_ONE 0x10000 107 #define FIXED_POINT_SHIFT 16 108 struct FixedPoint 109 { 110 int val; 111 //FixedPoint() {} 112 //explicit FixedPoint(int v) : val(v << FIXED_POINT_SHIFT) {} 113 //explicit FixedPoint(float v) : val(v * (2 << FIXED_POINT_SHIFT)) {} 114 //explicit FixedPoint(double v) : val(v * (2 << FIXED_POINT_SHIFT)) {} 115 static FixedPoint From(int v) { FixedPoint x; x.val = v << FIXED_POINT_SHIFT; return x; } 116 static FixedPoint From(unsigned v) { FixedPoint x; x.val = v << FIXED_POINT_SHIFT; return x; } 117 static FixedPoint From(float v) { FixedPoint x; x.val = v * (2 << FIXED_POINT_SHIFT); return x; } 118 static FixedPoint One() { FixedPoint x; x.val = FIXED_POINT_ONE; return x; } 119 static FixedPoint Zero() { FixedPoint x; x.val = 0; return x; } 120 FixedPoint operator-() const 121 { 122 FixedPoint res; 123 res.val = -val; 124 return res; 125 } 126 FixedPoint operator+(const FixedPoint & rhs) const 127 { 128 FixedPoint res; 129 res.val = val + rhs.val; 130 return res; 131 } 132 FixedPoint operator-(const FixedPoint & rhs) const 133 { 134 FixedPoint res; 135 res.val = val - rhs.val; 136 return res; 137 } 138 FixedPoint operator*(const FixedPoint & rhs) const 139 { 140 FixedPoint res; 141 res.val = (val >> 8) * (rhs.val >> 8); 142 return res; 143 } 144 FixedPoint operator/(const FixedPoint & rhs) const 145 { 146 FixedPoint res; 147 148 long long lh = (long long)val << 32, rh = rhs.val | 1; 149 lh /= rh; 150 rh = (lh >> 16) & 0xffffffffL; 151 res.val = rh; 152 return res; 153 154 //res.val = ((val << 2) / (rhs.val >> 6 | 1)) << 8; 155 //return res; 156 } 157 void operator+=(const FixedPoint & rhs) { val += rhs.val; } 158 void operator-=(const FixedPoint & rhs) { val += rhs.val; } 159 void operator*=(const FixedPoint & rhs) { *this = *this * rhs; } 160 void operator/=(const FixedPoint & rhs) { *this = *this / rhs; } 161 162 bool operator<(const FixedPoint & rhs) const { return val < rhs.val; } 163 bool operator>(const FixedPoint & rhs) const { return val > rhs.val; } 164 bool operator<=(const FixedPoint & rhs) const { return val <= rhs.val; } 165 bool operator>=(const FixedPoint & rhs) const { return val >= rhs.val; } 166 bool operator==(const FixedPoint & rhs) const { return val == rhs.val; } 167 bool operator!=(const FixedPoint & rhs) const { return val != rhs.val; } 168 169 operator int() const { return val >> FIXED_POINT_SHIFT; } 170 operator unsigned() const { return val >> FIXED_POINT_SHIFT; } 171 operator float() const { return (float)val / FIXED_POINT_ONE; } 172 }; 173 174 typedef FixedPoint VectorComp_t; 175 typedef Vec4<VectorComp_t> Vector4; 176 #define Vector4_CTR(x,y,z,w) Vector4(FixedPoint::From(x), FixedPoint::From(y), \ 177 FixedPoint::From(z), FixedPoint::From(w)) 178 #define VectorComp_t_CTR(x) FixedPoint::From(x) 179 #define VectorComp_t_Zero FixedPoint::Zero() 180 #define VectorComp_t_One FixedPoint::One()*/ 181 182 #else // if USE_FIXED_POINT 183 184 typedef float VectorComp_t; 185 typedef struct Vec4<VectorComp_t> Vector4; 186 #define Vector4_CTR(x,y,z,w) Vector4(x,y,z,w) 187 #define VectorComp_t_CTR(x) (float)(x) 188 #define VectorComp_t_Zero 0 189 #define VectorComp_t_One 1 190 191 #endif // if USE_FIXED_POINT 192 193 #else // #ifdef __cplusplus 194 195 //typedef float Vector4 [4]; 196 typedef struct { float x, y, z, w; } Vector4; 197 198 #define VECTOR4_OP_UNARY(v,op,s) \ 199 v.x op s.x; \ 200 v.y op s.y; \ 201 v.z op s.z; \ 202 v.w op s.w; 203 204 #define VECTOR4_OP_UNARY_SCALAR(v,op,s) \ 205 v.x op s; \ 206 v.y op s; \ 207 v.z op s; \ 208 v.w op s; 209 210 #define VECTOR4_CTR(x,y,z,w) \ 211 ((Vector4){x,y,z,w}) 212 213 #endif // #ifdef __cplusplus 214 215 #endif // #ifndef _PIXELFLINGER2_VECTOR4_H_