Home | History | Annotate | Download | only in pixelflinger2
      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) {}
     39     Vec4() {}
     40     Vec4(Type X, Type Y, Type Z, Type W) : x(X), y(Y), z(Z), w(W) {}
     41     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 
     74     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 
     82     void LShr(const unsigned shift) { u[0] >>= shift; u[1] >>= shift; u[2] >>= shift; u[3] >>= shift; }
     83     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_