bug 1197028 introduce AudioBlockBuffer r=padenot
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 03 Sep 2015 18:45:14 +1200
changeset 294145 6f71147e33e7d128c491257b34304e52fe63bcc6
parent 294144 61f99bbb1adf650b2d5ca701fcbd5084b1a5d15b
child 294146 9e530224d97f8653a148aae99871bdd35d42b8f4
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1197028
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1197028 introduce AudioBlockBuffer r=padenot At this point AudioBlockBuffer is just like SharedBuffer but always with float channels of length 128.
dom/media/SharedBuffer.h
dom/media/webaudio/AudioBlock.cpp
--- a/dom/media/SharedBuffer.h
+++ b/dom/media/SharedBuffer.h
@@ -36,19 +36,19 @@ protected:
   // Protected destructor, to discourage deletion outside of Release():
   virtual ~ThreadSharedObject() {}
 };
 
 /**
  * Heap-allocated chunk of arbitrary data with threadsafe refcounting.
  * Typically you would allocate one of these, fill it in, and then treat it as
  * immutable while it's shared.
- * This only guarantees 4-byte alignment of the data. For alignment we
- * simply assume that the refcount is at least 4-byte aligned and its size
- * is divisible by 4.
+ * This only guarantees 4-byte alignment of the data. For alignment we simply
+ * assume that the memory from malloc is at least 4-byte aligned and the
+ * refcount's size is large enough that SharedBuffer's size is divisible by 4.
  */
 class SharedBuffer : public ThreadSharedObject {
 public:
   void* Data() { return this + 1; }
 
   static already_AddRefed<SharedBuffer> Create(size_t aSize)
   {
     CheckedInt<size_t> size = sizeof(SharedBuffer);
--- a/dom/media/webaudio/AudioBlock.cpp
+++ b/dom/media/webaudio/AudioBlock.cpp
@@ -3,41 +3,75 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AudioBlock.h"
 
 namespace mozilla {
 
+/**
+ * Heap-allocated buffer of channels of 128-sample float arrays, with
+ * threadsafe refcounting.  Typically you would allocate one of these, fill it
+ * in, and then treat it as immutable while it's shared.
+ * This only guarantees 4-byte alignment of the data. For alignment we simply
+ * assume that the memory from malloc is at least 4-byte aligned and the
+ * refcount's size is large enough that AudioBlockBuffer's size is divisible
+ * by 4.
+ */
+class AudioBlockBuffer final : public ThreadSharedObject {
+public:
+  float* ChannelData(uint32_t aChannel)
+  {
+    return reinterpret_cast<float*>(this + 1) + aChannel * WEBAUDIO_BLOCK_SIZE;
+  }
+
+  static already_AddRefed<AudioBlockBuffer> Create(uint32_t aChannelCount)
+  {
+    CheckedInt<size_t> size = WEBAUDIO_BLOCK_SIZE;
+    size *= aChannelCount;
+    size *= sizeof(float);
+    size += sizeof(AudioBlockBuffer);
+    if (!size.isValid()) {
+      MOZ_CRASH();
+    }
+    void* m = moz_xmalloc(size.value());
+    nsRefPtr<AudioBlockBuffer> p = new (m) AudioBlockBuffer();
+    NS_ASSERTION((reinterpret_cast<char*>(p.get() + 1) - reinterpret_cast<char*>(p.get())) % 4 == 0,
+                 "AudioBlockBuffers should be at least 4-byte aligned");
+    return p.forget();
+  }
+
+  virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
+  {
+    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
+  }
+
+private:
+  AudioBlockBuffer() {}
+};
+
 void
 AllocateAudioBlock(uint32_t aChannelCount, AudioChunk* aChunk)
 {
   if (aChunk->mBuffer && !aChunk->mBuffer->IsShared() &&
       aChunk->ChannelCount() == aChannelCount) {
     MOZ_ASSERT(aChunk->mBufferFormat == AUDIO_FORMAT_FLOAT32);
     MOZ_ASSERT(aChunk->mDuration == WEBAUDIO_BLOCK_SIZE);
     // No need to allocate again.
     aChunk->mVolume = 1.0f;
     return;
   }
 
-  CheckedInt<size_t> size = WEBAUDIO_BLOCK_SIZE;
-  size *= aChannelCount;
-  size *= sizeof(float);
-  if (!size.isValid()) {
-    MOZ_CRASH();
-  }
   // XXX for SIMD purposes we should do something here to make sure the
   // channel buffers are 16-byte aligned.
-  nsRefPtr<SharedBuffer> buffer = SharedBuffer::Create(size.value());
+  nsRefPtr<AudioBlockBuffer> buffer = AudioBlockBuffer::Create(aChannelCount);
   aChunk->mDuration = WEBAUDIO_BLOCK_SIZE;
   aChunk->mChannelData.SetLength(aChannelCount);
-  float* data = static_cast<float*>(buffer->Data());
   for (uint32_t i = 0; i < aChannelCount; ++i) {
-    aChunk->mChannelData[i] = data + i*WEBAUDIO_BLOCK_SIZE;
+    aChunk->mChannelData[i] = buffer->ChannelData(i);
   }
   aChunk->mBuffer = buffer.forget();
   aChunk->mVolume = 1.0f;
   aChunk->mBufferFormat = AUDIO_FORMAT_FLOAT32;
 }
 
 } // namespace mozilla