Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp

Issue 2951903003: Hold global GC heap lock while making audio thread access. (Closed)
Patch Set: consistent lock scope wrt heap object in question Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | third_party/WebKit/Source/platform/heap/PersistentNode.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/platform/heap/PersistentNode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698