OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011, Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 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 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 if (!is_render_bus_allocated) | 166 if (!is_render_bus_allocated) |
167 return; | 167 return; |
168 | 168 |
169 // Start rendering. | 169 // Start rendering. |
170 DoOfflineRendering(); | 170 DoOfflineRendering(); |
171 } | 171 } |
172 | 172 |
173 void OfflineAudioDestinationHandler::DoOfflineRendering() { | 173 void OfflineAudioDestinationHandler::DoOfflineRendering() { |
174 DCHECK(!IsMainThread()); | 174 DCHECK(!IsMainThread()); |
175 | 175 |
176 unsigned number_of_channels = render_target_->numberOfChannels(); | 176 unsigned number_of_channels; |
| 177 Vector<float*> destinations; |
| 178 { |
| 179 // Main thread GCs cannot happen while we're reading out channel |
| 180 // data. Detect that condition by trying to take the cross-thread |
| 181 // persistent lock which is held while a GC runs. If the lock is |
| 182 // already held, simply delay rendering until the next quantum. |
| 183 CrossThreadPersistentRegion::LockScope gc_lock( |
| 184 ProcessHeap::GetCrossThreadPersistentRegion(), true); |
| 185 if (!gc_lock.HasLock()) |
| 186 return; |
| 187 |
| 188 number_of_channels = render_target_->numberOfChannels(); |
| 189 destinations.ReserveInitialCapacity(number_of_channels); |
| 190 for (unsigned i = 0; i < number_of_channels; ++i) |
| 191 destinations.push_back(render_target_->getChannelData(i).View()->Data()); |
| 192 } |
177 | 193 |
178 // Reset the suspend flag. | 194 // Reset the suspend flag. |
179 should_suspend_ = false; | 195 should_suspend_ = false; |
180 | 196 |
181 // If there is more to process and there is no suspension at the moment, | 197 // If there is more to process and there is no suspension at the moment, |
182 // do continue to render quanta. Then calling OfflineAudioContext.resume() | 198 // do continue to render quanta. Then calling OfflineAudioContext.resume() |
183 // will pick up the render loop again from where it was suspended. | 199 // will pick up the render loop again from where it was suspended. |
184 while (frames_to_process_ > 0 && !should_suspend_) { | 200 while (frames_to_process_ > 0 && !should_suspend_) { |
185 // Suspend the rendering and update m_shouldSuspend if a scheduled | 201 // Suspend the rendering and update m_shouldSuspend if a scheduled |
186 // suspend found at the current sample frame. Otherwise render one | 202 // suspend found at the current sample frame. Otherwise render one |
187 // quantum and return false. | 203 // quantum and return false. |
188 should_suspend_ = RenderIfNotSuspended( | 204 should_suspend_ = RenderIfNotSuspended( |
189 0, render_bus_.Get(), AudioUtilities::kRenderQuantumFrames); | 205 0, render_bus_.Get(), AudioUtilities::kRenderQuantumFrames); |
190 | 206 |
191 if (should_suspend_) | 207 if (should_suspend_) |
192 return; | 208 return; |
193 | 209 |
194 size_t frames_available_to_copy = | 210 size_t frames_available_to_copy = |
195 std::min(frames_to_process_, | 211 std::min(frames_to_process_, |
196 static_cast<size_t>(AudioUtilities::kRenderQuantumFrames)); | 212 static_cast<size_t>(AudioUtilities::kRenderQuantumFrames)); |
197 | 213 |
198 for (unsigned channel_index = 0; channel_index < number_of_channels; | 214 for (unsigned channel_index = 0; channel_index < number_of_channels; |
199 ++channel_index) { | 215 ++channel_index) { |
200 const float* source = render_bus_->Channel(channel_index)->Data(); | 216 const float* source = render_bus_->Channel(channel_index)->Data(); |
201 float* destination = | 217 memcpy(destinations[channel_index] + frames_processed_, source, |
202 render_target_->getChannelData(channel_index).View()->Data(); | |
203 memcpy(destination + frames_processed_, source, | |
204 sizeof(float) * frames_available_to_copy); | 218 sizeof(float) * frames_available_to_copy); |
205 } | 219 } |
206 | 220 |
207 frames_processed_ += frames_available_to_copy; | 221 frames_processed_ += frames_available_to_copy; |
208 | 222 |
209 DCHECK_GE(frames_to_process_, frames_available_to_copy); | 223 DCHECK_GE(frames_to_process_, frames_available_to_copy); |
210 frames_to_process_ -= frames_available_to_copy; | 224 frames_to_process_ -= frames_available_to_copy; |
211 } | 225 } |
212 | 226 |
213 // Finish up the rendering loop if there is no more to process. | 227 // Finish up the rendering loop if there is no more to process. |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 SetHandler(OfflineAudioDestinationHandler::Create(*this, render_target)); | 358 SetHandler(OfflineAudioDestinationHandler::Create(*this, render_target)); |
345 } | 359 } |
346 | 360 |
347 OfflineAudioDestinationNode* OfflineAudioDestinationNode::Create( | 361 OfflineAudioDestinationNode* OfflineAudioDestinationNode::Create( |
348 BaseAudioContext* context, | 362 BaseAudioContext* context, |
349 AudioBuffer* render_target) { | 363 AudioBuffer* render_target) { |
350 return new OfflineAudioDestinationNode(*context, render_target); | 364 return new OfflineAudioDestinationNode(*context, render_target); |
351 } | 365 } |
352 | 366 |
353 } // namespace blink | 367 } // namespace blink |
OLD | NEW |