OSDN Git Service

1eaa6e66e4cb7f6dbba839c74e3e242dc8bfaea3
[android-x86/frameworks-native.git] / include / ui / TVecHelpers.h
1 /*
2  * Copyright 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #ifndef UI_TVECHELPERS_H_
19 #define UI_TVECHELPERS_H_
20
21 #include <math.h>
22 #include <stdint.h>
23 #include <sys/types.h>
24
25 #include <cmath>
26 #include <limits>
27 #include <iostream>
28
29 #define PURE __attribute__((pure))
30
31 namespace android {
32 namespace details {
33 // -------------------------------------------------------------------------------------
34
35 /*
36  * No user serviceable parts here.
37  *
38  * Don't use this file directly, instead include ui/vec{2|3|4}.h
39  */
40
41 /*
42  * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
43  * operators on a vector of type BASE<T>.
44  *
45  * BASE only needs to implement operator[] and size().
46  * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
47  * get all the functionality here.
48  */
49
50 template <template<typename T> class VECTOR, typename T>
51 class TVecAddOperators {
52 public:
53     /* compound assignment from a another vector of the same size but different
54      * element type.
55      */
56     template<typename OTHER>
57     VECTOR<T>& operator +=(const VECTOR<OTHER>& v) {
58         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
59         for (size_t i = 0; i < lhs.size(); i++) {
60             lhs[i] += v[i];
61         }
62         return lhs;
63     }
64     template<typename OTHER>
65     VECTOR<T>& operator -=(const VECTOR<OTHER>& v) {
66         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
67         for (size_t i = 0; i < lhs.size(); i++) {
68             lhs[i] -= v[i];
69         }
70         return lhs;
71     }
72
73     /* compound assignment from a another vector of the same type.
74      * These operators can be used for implicit conversion and  handle operations
75      * like "vector *= scalar" by letting the compiler implicitly convert a scalar
76      * to a vector (assuming the BASE<T> allows it).
77      */
78     VECTOR<T>& operator +=(const VECTOR<T>& v) {
79         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
80         for (size_t i = 0; i < lhs.size(); i++) {
81             lhs[i] += v[i];
82         }
83         return lhs;
84     }
85     VECTOR<T>& operator -=(const VECTOR<T>& v) {
86         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
87         for (size_t i = 0; i < lhs.size(); i++) {
88             lhs[i] -= v[i];
89         }
90         return lhs;
91     }
92
93     /*
94      * NOTE: the functions below ARE NOT member methods. They are friend functions
95      * with they definition inlined with their declaration. This makes these
96      * template functions available to the compiler when (and only when) this class
97      * is instantiated, at which point they're only templated on the 2nd parameter
98      * (the first one, BASE<T> being known).
99      */
100
101     /* The operators below handle operation between vectors of the same size
102      * but of a different element type.
103      */
104     template<typename RT>
105     friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<RT>& rv) {
106         // don't pass lv by reference because we need a copy anyways
107         return lv += rv;
108     }
109     template<typename RT>
110     friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<RT>& rv) {
111         // don't pass lv by reference because we need a copy anyways
112         return lv -= rv;
113     }
114
115     /* The operators below (which are not templates once this class is instanced,
116      * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
117      * These handle operations like "vector + scalar" and "scalar + vector" by
118      * letting the compiler implicitly convert a scalar to a vector (assuming
119      * the BASE<T> allows it).
120      */
121     friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<T>& rv) {
122         // don't pass lv by reference because we need a copy anyways
123         return lv += rv;
124     }
125     friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<T>& rv) {
126         // don't pass lv by reference because we need a copy anyways
127         return lv -= rv;
128     }
129 };
130
131 template<template<typename T> class VECTOR, typename T>
132 class TVecProductOperators {
133 public:
134     /* compound assignment from a another vector of the same size but different
135      * element type.
136      */
137     template<typename OTHER>
138     VECTOR<T>& operator *=(const VECTOR<OTHER>& v) {
139         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
140         for (size_t i = 0; i < lhs.size(); i++) {
141             lhs[i] *= v[i];
142         }
143         return lhs;
144     }
145     template<typename OTHER>
146     VECTOR<T>& operator /=(const VECTOR<OTHER>& v) {
147         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
148         for (size_t i = 0; i < lhs.size(); i++) {
149             lhs[i] /= v[i];
150         }
151         return lhs;
152     }
153
154     /* compound assignment from a another vector of the same type.
155      * These operators can be used for implicit conversion and  handle operations
156      * like "vector *= scalar" by letting the compiler implicitly convert a scalar
157      * to a vector (assuming the BASE<T> allows it).
158      */
159     VECTOR<T>& operator *=(const VECTOR<T>& v) {
160         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
161         for (size_t i = 0; i < lhs.size(); i++) {
162             lhs[i] *= v[i];
163         }
164         return lhs;
165     }
166     VECTOR<T>& operator /=(const VECTOR<T>& v) {
167         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
168         for (size_t i = 0; i < lhs.size(); i++) {
169             lhs[i] /= v[i];
170         }
171         return lhs;
172     }
173
174     /*
175      * NOTE: the functions below ARE NOT member methods. They are friend functions
176      * with they definition inlined with their declaration. This makes these
177      * template functions available to the compiler when (and only when) this class
178      * is instantiated, at which point they're only templated on the 2nd parameter
179      * (the first one, BASE<T> being known).
180      */
181
182     /* The operators below handle operation between vectors of the same size
183      * but of a different element type.
184      */
185     template<typename RT>
186     friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<RT>& rv) {
187         // don't pass lv by reference because we need a copy anyways
188         return lv *= rv;
189     }
190     template<typename RT>
191     friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<RT>& rv) {
192         // don't pass lv by reference because we need a copy anyways
193         return lv /= rv;
194     }
195
196     /* The operators below (which are not templates once this class is instanced,
197      * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
198      * These handle operations like "vector * scalar" and "scalar * vector" by
199      * letting the compiler implicitly convert a scalar to a vector (assuming
200      * the BASE<T> allows it).
201      */
202     friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<T>& rv) {
203         // don't pass lv by reference because we need a copy anyways
204         return lv *= rv;
205     }
206     friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<T>& rv) {
207         // don't pass lv by reference because we need a copy anyways
208         return lv /= rv;
209     }
210 };
211
212 /*
213  * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
214  *
215  * BASE only needs to implement operator[] and size().
216  * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
217  * get all the functionality here.
218  *
219  * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
220  */
221 template<template<typename T> class VECTOR, typename T>
222 class TVecUnaryOperators {
223 public:
224     VECTOR<T>& operator ++() {
225         VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
226         for (size_t i = 0; i < rhs.size(); i++) {
227             ++rhs[i];
228         }
229         return rhs;
230     }
231     VECTOR<T>& operator --() {
232         VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
233         for (size_t i = 0; i < rhs.size(); i++) {
234             --rhs[i];
235         }
236         return rhs;
237     }
238     VECTOR<T> operator -() const {
239         VECTOR<T> r(VECTOR<T>::NO_INIT);
240         VECTOR<T> const& rv(static_cast<VECTOR<T> const&>(*this));
241         for (size_t i = 0; i < r.size(); i++) {
242             r[i] = -rv[i];
243         }
244         return r;
245     }
246 };
247
248 /*
249  * TVecComparisonOperators implements relational/comparison operators
250  * on a vector of type BASE<T>.
251  *
252  * BASE only needs to implement operator[] and size().
253  * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
254  * get all the functionality here.
255  */
256 template<template<typename T> class VECTOR, typename T>
257 class TVecComparisonOperators {
258 public:
259     /*
260      * NOTE: the functions below ARE NOT member methods. They are friend functions
261      * with they definition inlined with their declaration. This makes these
262      * template functions available to the compiler when (and only when) this class
263      * is instantiated, at which point they're only templated on the 2nd parameter
264      * (the first one, BASE<T> being known).
265      */
266     template<typename RT>
267     friend inline
268     bool PURE operator ==(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
269         for (size_t i = 0; i < lv.size(); i++)
270             if (lv[i] != rv[i])
271                 return false;
272         return true;
273     }
274
275     template<typename RT>
276     friend inline
277     bool PURE operator !=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
278         return !operator ==(lv, rv);
279     }
280
281     template<typename RT>
282     friend inline
283     bool PURE operator >(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
284         for (size_t i = 0; i < lv.size(); i++) {
285             if (lv[i] == rv[i]) {
286                 continue;
287             }
288             return lv[i] > rv[i];
289         }
290         return false;
291     }
292
293     template<typename RT>
294     friend inline
295     constexpr bool PURE operator <=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
296         return !(lv > rv);
297     }
298
299     template<typename RT>
300     friend inline
301     bool PURE operator <(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
302         for (size_t i = 0; i < lv.size(); i++) {
303             if (lv[i] == rv[i]) {
304                 continue;
305             }
306             return lv[i] < rv[i];
307         }
308         return false;
309     }
310
311     template<typename RT>
312     friend inline
313     constexpr bool PURE operator >=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
314         return !(lv < rv);
315     }
316 };
317
318 /*
319  * TVecFunctions implements functions on a vector of type BASE<T>.
320  *
321  * BASE only needs to implement operator[] and size().
322  * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
323  * get all the functionality here.
324  */
325 template<template<typename T> class VECTOR, typename T>
326 class TVecFunctions {
327 public:
328     /*
329      * NOTE: the functions below ARE NOT member methods. They are friend functions
330      * with they definition inlined with their declaration. This makes these
331      * template functions available to the compiler when (and only when) this class
332      * is instantiated, at which point they're only templated on the 2nd parameter
333      * (the first one, BASE<T> being known).
334      */
335     template<typename RT>
336     friend inline T PURE dot(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
337         T r(0);
338         for (size_t i = 0; i < lv.size(); i++) {
339             //r = std::fma(lv[i], rv[i], r);
340             r += lv[i] * rv[i];
341         }
342         return r;
343     }
344
345     friend inline constexpr T PURE norm(const VECTOR<T>& lv) {
346         return std::sqrt(dot(lv, lv));
347     }
348
349     friend inline constexpr T PURE length(const VECTOR<T>& lv) {
350         return norm(lv);
351     }
352
353     friend inline constexpr T PURE norm2(const VECTOR<T>& lv) {
354         return dot(lv, lv);
355     }
356
357     friend inline constexpr T PURE length2(const VECTOR<T>& lv) {
358         return norm2(lv);
359     }
360
361     template<typename RT>
362     friend inline constexpr T PURE distance(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
363         return length(rv - lv);
364     }
365
366     template<typename RT>
367     friend inline constexpr T PURE distance2(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
368         return length2(rv - lv);
369     }
370
371     friend inline constexpr VECTOR<T> PURE normalize(const VECTOR<T>& lv) {
372         return lv * (T(1) / length(lv));
373     }
374
375     friend inline VECTOR<T> PURE rcp(VECTOR<T> v) {
376         return T(1) / v;
377     }
378
379     friend inline VECTOR<T> PURE abs(VECTOR<T> v) {
380         for (size_t i=0 ; i<v.size() ; i++) {
381             v[i] = std::abs(v[i]);
382         }
383         return v;
384     }
385
386     friend inline VECTOR<T> PURE floor(VECTOR<T> v) {
387         for (size_t i=0 ; i<v.size() ; i++) {
388             v[i] = std::floor(v[i]);
389         }
390         return v;
391     }
392
393     friend inline VECTOR<T> PURE ceil(VECTOR<T> v) {
394         for (size_t i=0 ; i<v.size() ; i++) {
395             v[i] = std::ceil(v[i]);
396         }
397         return v;
398     }
399
400     friend inline VECTOR<T> PURE round(VECTOR<T> v) {
401         for (size_t i=0 ; i<v.size() ; i++) {
402             v[i] = std::round(v[i]);
403         }
404         return v;
405     }
406
407     friend inline VECTOR<T> PURE inversesqrt(VECTOR<T> v) {
408         for (size_t i=0 ; i<v.size() ; i++) {
409             v[i] = T(1) / std::sqrt(v[i]);
410         }
411         return v;
412     }
413
414     friend inline VECTOR<T> PURE sqrt(VECTOR<T> v) {
415         for (size_t i=0 ; i<v.size() ; i++) {
416             v[i] = std::sqrt(v[i]);
417         }
418         return v;
419     }
420
421     friend inline VECTOR<T> PURE pow(VECTOR<T> v, T p) {
422         for (size_t i=0 ; i<v.size() ; i++) {
423             v[i] = std::pow(v[i], p);
424         }
425         return v;
426     }
427
428     friend inline VECTOR<T> PURE saturate(const VECTOR<T>& lv) {
429         return clamp(lv, T(0), T(1));
430     }
431
432     friend inline VECTOR<T> PURE clamp(VECTOR<T> v, T min, T max) {
433         for (size_t i=0 ; i< v.size() ; i++) {
434             v[i] = std::min(max, std::max(min, v[i]));
435         }
436         return v;
437     }
438
439     friend inline VECTOR<T> PURE fma(const VECTOR<T>& lv, const VECTOR<T>& rv, VECTOR<T> a) {
440         for (size_t i=0 ; i<lv.size() ; i++) {
441             //a[i] = std::fma(lv[i], rv[i], a[i]);
442             a[i] += (lv[i] * rv[i]);
443         }
444         return a;
445     }
446
447     friend inline VECTOR<T> PURE min(const VECTOR<T>& u, VECTOR<T> v) {
448         for (size_t i=0 ; i<v.size() ; i++) {
449             v[i] = std::min(u[i], v[i]);
450         }
451         return v;
452     }
453
454     friend inline VECTOR<T> PURE max(const VECTOR<T>& u, VECTOR<T> v) {
455         for (size_t i=0 ; i<v.size() ; i++) {
456             v[i] = std::max(u[i], v[i]);
457         }
458         return v;
459     }
460
461     friend inline T PURE max(const VECTOR<T>& v) {
462         T r(std::numeric_limits<T>::lowest());
463         for (size_t i=0 ; i<v.size() ; i++) {
464             r = std::max(r, v[i]);
465         }
466         return r;
467     }
468
469     friend inline T PURE min(const VECTOR<T>& v) {
470         T r(std::numeric_limits<T>::max());
471         for (size_t i=0 ; i<v.size() ; i++) {
472             r = std::min(r, v[i]);
473         }
474         return r;
475     }
476 };
477
478 /*
479  * TVecDebug implements functions on a vector of type BASE<T>.
480  *
481  * BASE only needs to implement operator[] and size().
482  * By simply inheriting from TVecDebug<BASE, T> BASE will automatically
483  * get all the functionality here.
484  */
485 template<template<typename T> class VECTOR, typename T>
486 class TVecDebug {
487 public:
488     /*
489      * NOTE: the functions below ARE NOT member methods. They are friend functions
490      * with they definition inlined with their declaration. This makes these
491      * template functions available to the compiler when (and only when) this class
492      * is instantiated, at which point they're only templated on the 2nd parameter
493      * (the first one, BASE<T> being known).
494      */
495     friend std::ostream& operator<<(std::ostream& stream, const VECTOR<T>& v) {
496         stream << "< ";
497         for (size_t i = 0; i < v.size() - 1; i++) {
498             stream << T(v[i]) << ", ";
499         }
500         stream << T(v[v.size() - 1]) << " >";
501         return stream;
502     }
503 };
504
505 #undef PURE
506
507 // -------------------------------------------------------------------------------------
508 }  // namespace details
509 }  // namespace android
510
511
512 #endif  // UI_TVECHELPERS_H_