OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 12 matching lines...) Expand all Loading... |
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 */ | 27 */ |
28 | 28 |
29 #ifndef AudioArray_h | 29 #ifndef AudioArray_h |
30 #define AudioArray_h | 30 #define AudioArray_h |
31 | 31 |
32 #include <string.h> | 32 #include <string.h> |
| 33 #include <wtf/FastMalloc.h> |
33 #include <wtf/Vector.h> | 34 #include <wtf/Vector.h> |
34 | 35 |
35 namespace WebCore { | 36 namespace WebCore { |
36 | 37 |
37 template<typename T> | 38 template<typename T> |
38 class AudioArray : public Vector<T> { | 39 class AudioArray { |
39 public: | 40 public: |
40 AudioArray() : Vector<T>(0) { } | 41 AudioArray() : m_allocation(0), m_alignedData(0), m_size(0) { } |
41 explicit AudioArray(size_t n) : Vector<T>(n, 0) { } | 42 explicit AudioArray(size_t n) : m_allocation(0), m_alignedData(0), m_size(0) |
| 43 { |
| 44 allocate(n); |
| 45 } |
| 46 |
| 47 ~AudioArray() |
| 48 { |
| 49 fastFree(m_allocation); |
| 50 } |
| 51 |
| 52 // It's OK to call allocate() multiple times, but data will *not* be copied
from an initial allocation |
| 53 // if re-allocated. Allocations are zero-initialized. |
| 54 void allocate(size_t n) |
| 55 { |
| 56 // 16-byte alignment for 128bit SIMD. |
| 57 const size_t alignment = 16; |
| 58 |
| 59 if (m_allocation) |
| 60 fastFree(m_allocation); |
| 61 |
| 62 bool isAllocationGood = false; |
| 63 |
| 64 while (!isAllocationGood) { |
| 65 // Initially we try to allocate the exact size, but if it's not alig
ned |
| 66 // then we'll have to reallocate and from then on allocate extra. |
| 67 static size_t extraAllocationBytes = 0; |
| 68 |
| 69 T* allocation = static_cast<T*>(fastMalloc(sizeof(T) * n + extraAllo
cationBytes)); |
| 70 T* alignedData = alignedAddress(allocation, alignment); |
| 71 |
| 72 if (alignedData == allocation || extraAllocationBytes == alignment)
{ |
| 73 m_allocation = allocation; |
| 74 m_alignedData = alignedData; |
| 75 m_size = n; |
| 76 isAllocationGood = true; |
| 77 zero(); |
| 78 } else { |
| 79 extraAllocationBytes = alignment; // always allocate extra after
the first alignment failure. |
| 80 fastFree(allocation); |
| 81 } |
| 82 } |
| 83 } |
| 84 |
| 85 T* data() { return m_alignedData; } |
| 86 const T* data() const { return m_alignedData; } |
| 87 size_t size() const { return m_size; } |
| 88 |
| 89 T& at(size_t i) |
| 90 { |
| 91 ASSERT(i < size()); |
| 92 return data()[i]; |
| 93 } |
| 94 |
| 95 T& operator[](size_t i) { return at(i); } |
42 | 96 |
43 void zero() { memset(this->data(), 0, sizeof(T) * this->size()); } | 97 void zero() { memset(this->data(), 0, sizeof(T) * this->size()); } |
44 | 98 |
45 void zeroRange(unsigned start, unsigned end) | 99 void zeroRange(unsigned start, unsigned end) |
46 { | 100 { |
47 bool isSafe = (start <= end) && (end <= this->size()); | 101 bool isSafe = (start <= end) && (end <= this->size()); |
48 ASSERT(isSafe); | 102 ASSERT(isSafe); |
49 if (!isSafe) | 103 if (!isSafe) |
50 return; | 104 return; |
51 | 105 |
52 memset(this->data() + start, 0, sizeof(T) * (end - start)); | 106 memset(this->data() + start, 0, sizeof(T) * (end - start)); |
53 } | 107 } |
54 | 108 |
55 void copyToRange(T* sourceData, unsigned start, unsigned end) | 109 void copyToRange(T* sourceData, unsigned start, unsigned end) |
56 { | 110 { |
57 bool isSafe = (start <= end) && (end <= this->size()); | 111 bool isSafe = (start <= end) && (end <= this->size()); |
58 ASSERT(isSafe); | 112 ASSERT(isSafe); |
59 if (!isSafe) | 113 if (!isSafe) |
60 return; | 114 return; |
61 | 115 |
62 memcpy(this->data() + start, sourceData, sizeof(T) * (end - start)); | 116 memcpy(this->data() + start, sourceData, sizeof(T) * (end - start)); |
63 } | 117 } |
| 118 |
| 119 private: |
| 120 static T* alignedAddress(T* address, intptr_t alignment) |
| 121 { |
| 122 intptr_t value = reinterpret_cast<intptr_t>(address); |
| 123 return reinterpret_cast<T*>((value + alignment - 1) & ~(alignment - 1)); |
| 124 } |
| 125 |
| 126 T* m_allocation; |
| 127 T* m_alignedData; |
| 128 size_t m_size; |
64 }; | 129 }; |
65 | 130 |
66 typedef AudioArray<float> AudioFloatArray; | 131 typedef AudioArray<float> AudioFloatArray; |
67 typedef AudioArray<double> AudioDoubleArray; | 132 typedef AudioArray<double> AudioDoubleArray; |
68 | 133 |
69 } // WebCore | 134 } // WebCore |
70 | 135 |
71 #endif // AudioArray_h | 136 #endif // AudioArray_h |
OLD | NEW |