Index: Source/WebCore/platform/audio/AudioArray.h |
=================================================================== |
--- Source/WebCore/platform/audio/AudioArray.h (revision 93809) |
+++ Source/WebCore/platform/audio/AudioArray.h (working copy) |
@@ -30,16 +30,70 @@ |
#define AudioArray_h |
#include <string.h> |
+#include <wtf/FastMalloc.h> |
#include <wtf/Vector.h> |
namespace WebCore { |
template<typename T> |
-class AudioArray : public Vector<T> { |
+class AudioArray { |
public: |
- AudioArray() : Vector<T>(0) { } |
- explicit AudioArray(size_t n) : Vector<T>(n, 0) { } |
+ AudioArray() : m_allocation(0), m_alignedData(0), m_size(0) { } |
+ explicit AudioArray(size_t n) : m_allocation(0), m_alignedData(0), m_size(0) |
+ { |
+ allocate(n); |
+ } |
+ ~AudioArray() |
+ { |
+ fastFree(m_allocation); |
+ } |
+ |
+ // It's OK to call allocate() multiple times, but data will *not* be copied from an initial allocation |
+ // if re-allocated. Allocations are zero-initialized. |
+ void allocate(size_t n) |
+ { |
+ // 16-byte alignment for 128bit SIMD. |
+ const size_t alignment = 16; |
+ |
+ if (m_allocation) |
+ fastFree(m_allocation); |
+ |
+ bool isAllocationGood = false; |
+ |
+ while (!isAllocationGood) { |
+ // Initially we try to allocate the exact size, but if it's not aligned |
+ // then we'll have to reallocate and from then on allocate extra. |
+ static size_t extraAllocationBytes = 0; |
+ |
+ T* allocation = static_cast<T*>(fastMalloc(sizeof(T) * n + extraAllocationBytes)); |
+ T* alignedData = alignedAddress(allocation, alignment); |
+ |
+ if (alignedData == allocation || extraAllocationBytes == alignment) { |
+ m_allocation = allocation; |
+ m_alignedData = alignedData; |
+ m_size = n; |
+ isAllocationGood = true; |
+ zero(); |
+ } else { |
+ extraAllocationBytes = alignment; // always allocate extra after the first alignment failure. |
+ fastFree(allocation); |
+ } |
+ } |
+ } |
+ |
+ T* data() { return m_alignedData; } |
+ const T* data() const { return m_alignedData; } |
+ size_t size() const { return m_size; } |
+ |
+ T& at(size_t i) |
+ { |
+ ASSERT(i < size()); |
+ return data()[i]; |
+ } |
+ |
+ T& operator[](size_t i) { return at(i); } |
+ |
void zero() { memset(this->data(), 0, sizeof(T) * this->size()); } |
void zeroRange(unsigned start, unsigned end) |
@@ -61,6 +115,17 @@ |
memcpy(this->data() + start, sourceData, sizeof(T) * (end - start)); |
} |
+ |
+private: |
+ static T* alignedAddress(T* address, intptr_t alignment) |
+ { |
+ intptr_t value = reinterpret_cast<intptr_t>(address); |
+ return reinterpret_cast<T*>((value + alignment - 1) & ~(alignment - 1)); |
+ } |
+ |
+ T* m_allocation; |
+ T* m_alignedData; |
+ size_t m_size; |
}; |
typedef AudioArray<float> AudioFloatArray; |