File: double4.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (97 lines) | stat: -rw-r--r-- 3,253 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/354829279): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#ifndef UI_GFX_GEOMETRY_DOUBLE4_H_
#define UI_GFX_GEOMETRY_DOUBLE4_H_

#include <type_traits>

namespace gfx {

// This header defines Double4 type for vectorized SIMD operations used in
// optimized transformation code. The type should be only used for local
// variables, or inline function parameters or return values. Don't use the
// type in other cases (e.g. for class data members) due to constraints
// (e.g. alignment).
//
// Here are some examples of usages:
//
//   double matrix[4][4] = ...;
//   // The scalar value will be applied to all components.
//   Double4 c0 = Load(matrix[0]) + 5;
//   Double4 c1 = Load(matrix[1]) * Double4{1, 2, 3, 4};
//
//   Double4 v = c0 * c1;
//   // s0/s1/s2/s3 are preferred to x/y/z/w for consistency.
//   double a = v.s0 + Sum(c1);
//   // v.s3210 is equivalent to {v.s3, v.s2, v.s1, v.s0}.
//   // Should use this form instead of __builtin_shufflevector() etc.
//   Double4 swapped = {v[3], v[2], v[1], v[0]};
//
//   // Logical operations.
//   bool b1 = AllTrue(swapped == c0);
//   // & is preferred to && to reduce branches.
//   bool b2 = AllTrue((c0 == c1) & (c0 == v) & (c0 >= swapped));
//
//   Store(swapped, matrix_[2]);
//   Store(v, matrix_[3]);
//
// We use the gcc extension (supported by clang) instead of the clang extension
// to make sure the code can compile with either gcc or clang.
//
// For more details, see
//   https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html

#if !defined(__GNUC__) && !defined(__clang__)
#error Unsupported compiler.
#endif

typedef double __attribute__((vector_size(4 * sizeof(double)))) Double4;
typedef float __attribute__((vector_size(4 * sizeof(float)))) Float4;

ALWAYS_INLINE double Sum(Double4 v) {
  return v[0] + v[1] + v[2] + v[3];
}

ALWAYS_INLINE Double4 LoadDouble4(const double s[4]) {
  return Double4{s[0], s[1], s[2], s[3]};
}

ALWAYS_INLINE void StoreDouble4(Double4 v, double d[4]) {
  d[0] = v[0];
  d[1] = v[1];
  d[2] = v[2];
  d[3] = v[3];
}

// The parameter should be the result of Double4/Float4 operations that would
// produce bool results if they were original scalar operators, e.g.
//   auto b4 = double4_a == double4_b;
// A zero value of a component of |b4| means false, otherwise true.
// This function checks whether all 4 components in |b4| are true.
// |&| instead of |&&| is used to avoid branches, which results shorter and
// faster code in most cases. It's used like:
//   if (AllTrue(double4_a == double4_b))
//     ...
//   if (AllTrue((double4_a1 == double4_b1) & (double4_a2 == double4_b2)))
//     ...
typedef int64_t __attribute__((vector_size(4 * sizeof(int64_t))))
DoubleBoolean4;
ALWAYS_INLINE int64_t AllTrue(DoubleBoolean4 b4) {
  return b4[0] & b4[1] & b4[2] & b4[3];
}

typedef int32_t __attribute__((vector_size(4 * sizeof(int32_t)))) FloatBoolean4;
ALWAYS_INLINE int32_t AllTrue(FloatBoolean4 b4) {
  return b4[0] & b4[1] & b4[2] & b4[3];
}

}  // namespace gfx

#endif  // UI_GFX_GEOMETRY_DOUBLE4_H_