| 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;
|
|
|