| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright (C) 2010, Google Inc. All rights reserved. |    2  * Copyright (C) 2010, 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 16 matching lines...) Expand all  Loading... | 
|   27 #include "modules/webaudio/AudioNodeOutput.h" |   27 #include "modules/webaudio/AudioNodeOutput.h" | 
|   28 #include "modules/webaudio/OfflineAudioContext.h" |   28 #include "modules/webaudio/OfflineAudioContext.h" | 
|   29 #include "platform/CrossThreadFunctional.h" |   29 #include "platform/CrossThreadFunctional.h" | 
|   30 #include "public/platform/Platform.h" |   30 #include "public/platform/Platform.h" | 
|   31  |   31  | 
|   32 namespace blink { |   32 namespace blink { | 
|   33  |   33  | 
|   34 void DeferredTaskHandler::lock() |   34 void DeferredTaskHandler::lock() | 
|   35 { |   35 { | 
|   36     // Don't allow regular lock in real-time audio thread. |   36     // Don't allow regular lock in real-time audio thread. | 
|   37     ASSERT(!isAudioThread()); |   37     DCHECK(!isAudioThread()); | 
|   38     m_contextGraphMutex.lock(); |   38     m_contextGraphMutex.lock(); | 
|   39 } |   39 } | 
|   40  |   40  | 
|   41 bool DeferredTaskHandler::tryLock() |   41 bool DeferredTaskHandler::tryLock() | 
|   42 { |   42 { | 
|   43     // Try to catch cases of using try lock on main thread |   43     // Try to catch cases of using try lock on main thread | 
|   44     // - it should use regular lock. |   44     // - it should use regular lock. | 
|   45     ASSERT(isAudioThread()); |   45     DCHECK(isAudioThread()); | 
|   46     if (!isAudioThread()) { |   46     if (!isAudioThread()) { | 
|   47         // In release build treat tryLock() as lock() (since above |   47         // In release build treat tryLock() as lock() (since above | 
|   48         // ASSERT(isAudioThread) never fires) - this is the best we can do. |   48         // ASSERT(isAudioThread) never fires) - this is the best we can do. | 
|   49         lock(); |   49         lock(); | 
|   50         return true; |   50         return true; | 
|   51     } |   51     } | 
|   52     return m_contextGraphMutex.tryLock(); |   52     return m_contextGraphMutex.tryLock(); | 
|   53 } |   53 } | 
|   54  |   54  | 
|   55 void DeferredTaskHandler::unlock() |   55 void DeferredTaskHandler::unlock() | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|   70  |   70  | 
|   71 #if ENABLE(ASSERT) |   71 #if ENABLE(ASSERT) | 
|   72 bool DeferredTaskHandler::isGraphOwner() |   72 bool DeferredTaskHandler::isGraphOwner() | 
|   73 { |   73 { | 
|   74     return m_contextGraphMutex.locked(); |   74     return m_contextGraphMutex.locked(); | 
|   75 } |   75 } | 
|   76 #endif |   76 #endif | 
|   77  |   77  | 
|   78 void DeferredTaskHandler::addDeferredBreakConnection(AudioHandler& node) |   78 void DeferredTaskHandler::addDeferredBreakConnection(AudioHandler& node) | 
|   79 { |   79 { | 
|   80     ASSERT(isAudioThread()); |   80     DCHECK(isAudioThread()); | 
|   81     m_deferredBreakConnectionList.append(&node); |   81     m_deferredBreakConnectionList.append(&node); | 
|   82 } |   82 } | 
|   83  |   83  | 
|   84 void DeferredTaskHandler::breakConnections() |   84 void DeferredTaskHandler::breakConnections() | 
|   85 { |   85 { | 
|   86     ASSERT(isAudioThread()); |   86     DCHECK(isAudioThread()); | 
|   87     ASSERT(isGraphOwner()); |   87     ASSERT(isGraphOwner()); | 
|   88  |   88  | 
|   89     for (unsigned i = 0; i < m_deferredBreakConnectionList.size(); ++i) |   89     for (unsigned i = 0; i < m_deferredBreakConnectionList.size(); ++i) | 
|   90         m_deferredBreakConnectionList[i]->breakConnectionWithLock(); |   90         m_deferredBreakConnectionList[i]->breakConnectionWithLock(); | 
|   91     m_deferredBreakConnectionList.clear(); |   91     m_deferredBreakConnectionList.clear(); | 
|   92 } |   92 } | 
|   93  |   93  | 
|   94 void DeferredTaskHandler::markSummingJunctionDirty(AudioSummingJunction* summing
     Junction) |   94 void DeferredTaskHandler::markSummingJunctionDirty(AudioSummingJunction* summing
     Junction) | 
|   95 { |   95 { | 
|   96     ASSERT(isGraphOwner()); |   96     ASSERT(isGraphOwner()); | 
|   97     m_dirtySummingJunctions.add(summingJunction); |   97     m_dirtySummingJunctions.add(summingJunction); | 
|   98 } |   98 } | 
|   99  |   99  | 
|  100 void DeferredTaskHandler::removeMarkedSummingJunction(AudioSummingJunction* summ
     ingJunction) |  100 void DeferredTaskHandler::removeMarkedSummingJunction(AudioSummingJunction* summ
     ingJunction) | 
|  101 { |  101 { | 
|  102     ASSERT(isMainThread()); |  102     DCHECK(isMainThread()); | 
|  103     AutoLocker locker(*this); |  103     AutoLocker locker(*this); | 
|  104     m_dirtySummingJunctions.remove(summingJunction); |  104     m_dirtySummingJunctions.remove(summingJunction); | 
|  105 } |  105 } | 
|  106  |  106  | 
|  107 void DeferredTaskHandler::markAudioNodeOutputDirty(AudioNodeOutput* output) |  107 void DeferredTaskHandler::markAudioNodeOutputDirty(AudioNodeOutput* output) | 
|  108 { |  108 { | 
|  109     ASSERT(isGraphOwner()); |  109     ASSERT(isGraphOwner()); | 
|  110     ASSERT(isMainThread()); |  110     DCHECK(isMainThread()); | 
|  111     m_dirtyAudioNodeOutputs.add(output); |  111     m_dirtyAudioNodeOutputs.add(output); | 
|  112 } |  112 } | 
|  113  |  113  | 
|  114 void DeferredTaskHandler::removeMarkedAudioNodeOutput(AudioNodeOutput* output) |  114 void DeferredTaskHandler::removeMarkedAudioNodeOutput(AudioNodeOutput* output) | 
|  115 { |  115 { | 
|  116     ASSERT(isGraphOwner()); |  116     ASSERT(isGraphOwner()); | 
|  117     ASSERT(isMainThread()); |  117     DCHECK(isMainThread()); | 
|  118     m_dirtyAudioNodeOutputs.remove(output); |  118     m_dirtyAudioNodeOutputs.remove(output); | 
|  119 } |  119 } | 
|  120  |  120  | 
|  121 void DeferredTaskHandler::handleDirtyAudioSummingJunctions() |  121 void DeferredTaskHandler::handleDirtyAudioSummingJunctions() | 
|  122 { |  122 { | 
|  123     ASSERT(isGraphOwner()); |  123     ASSERT(isGraphOwner()); | 
|  124  |  124  | 
|  125     for (AudioSummingJunction* junction : m_dirtySummingJunctions) |  125     for (AudioSummingJunction* junction : m_dirtySummingJunctions) | 
|  126         junction->updateRenderingState(); |  126         junction->updateRenderingState(); | 
|  127     m_dirtySummingJunctions.clear(); |  127     m_dirtySummingJunctions.clear(); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  166     ASSERT(isGraphOwner()); |  166     ASSERT(isGraphOwner()); | 
|  167  |  167  | 
|  168     if (m_automaticPullNodesNeedUpdating) { |  168     if (m_automaticPullNodesNeedUpdating) { | 
|  169         copyToVector(m_automaticPullNodes, m_renderingAutomaticPullNodes); |  169         copyToVector(m_automaticPullNodes, m_renderingAutomaticPullNodes); | 
|  170         m_automaticPullNodesNeedUpdating = false; |  170         m_automaticPullNodesNeedUpdating = false; | 
|  171     } |  171     } | 
|  172 } |  172 } | 
|  173  |  173  | 
|  174 void DeferredTaskHandler::processAutomaticPullNodes(size_t framesToProcess) |  174 void DeferredTaskHandler::processAutomaticPullNodes(size_t framesToProcess) | 
|  175 { |  175 { | 
|  176     ASSERT(isAudioThread()); |  176     DCHECK(isAudioThread()); | 
|  177  |  177  | 
|  178     for (unsigned i = 0; i < m_renderingAutomaticPullNodes.size(); ++i) |  178     for (unsigned i = 0; i < m_renderingAutomaticPullNodes.size(); ++i) | 
|  179         m_renderingAutomaticPullNodes[i]->processIfNecessary(framesToProcess); |  179         m_renderingAutomaticPullNodes[i]->processIfNecessary(framesToProcess); | 
|  180 } |  180 } | 
|  181  |  181  | 
|  182 void DeferredTaskHandler::addChangedChannelCountMode(AudioHandler* node) |  182 void DeferredTaskHandler::addChangedChannelCountMode(AudioHandler* node) | 
|  183 { |  183 { | 
|  184     ASSERT(isGraphOwner()); |  184     ASSERT(isGraphOwner()); | 
|  185     ASSERT(isMainThread()); |  185     DCHECK(isMainThread()); | 
|  186     m_deferredCountModeChange.add(node); |  186     m_deferredCountModeChange.add(node); | 
|  187 } |  187 } | 
|  188  |  188  | 
|  189 void DeferredTaskHandler::removeChangedChannelCountMode(AudioHandler* node) |  189 void DeferredTaskHandler::removeChangedChannelCountMode(AudioHandler* node) | 
|  190 { |  190 { | 
|  191     ASSERT(isGraphOwner()); |  191     ASSERT(isGraphOwner()); | 
|  192  |  192  | 
|  193     m_deferredCountModeChange.remove(node); |  193     m_deferredCountModeChange.remove(node); | 
|  194 } |  194 } | 
|  195  |  195  | 
|  196 void DeferredTaskHandler::addChangedChannelInterpretation(AudioHandler* node) |  196 void DeferredTaskHandler::addChangedChannelInterpretation(AudioHandler* node) | 
|  197 { |  197 { | 
|  198     ASSERT(isGraphOwner()); |  198     ASSERT(isGraphOwner()); | 
|  199     ASSERT(isMainThread()); |  199     DCHECK(isMainThread()); | 
|  200     m_deferredChannelInterpretationChange.add(node); |  200     m_deferredChannelInterpretationChange.add(node); | 
|  201 } |  201 } | 
|  202  |  202  | 
|  203 void DeferredTaskHandler::removeChangedChannelInterpretation(AudioHandler* node) |  203 void DeferredTaskHandler::removeChangedChannelInterpretation(AudioHandler* node) | 
|  204 { |  204 { | 
|  205     ASSERT(isGraphOwner()); |  205     ASSERT(isGraphOwner()); | 
|  206  |  206  | 
|  207     m_deferredChannelInterpretationChange.remove(node); |  207     m_deferredChannelInterpretationChange.remove(node); | 
|  208 } |  208 } | 
|  209  |  209  | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|  231 { |  231 { | 
|  232 } |  232 } | 
|  233  |  233  | 
|  234 PassRefPtr<DeferredTaskHandler> DeferredTaskHandler::create() |  234 PassRefPtr<DeferredTaskHandler> DeferredTaskHandler::create() | 
|  235 { |  235 { | 
|  236     return adoptRef(new DeferredTaskHandler()); |  236     return adoptRef(new DeferredTaskHandler()); | 
|  237 } |  237 } | 
|  238  |  238  | 
|  239 DeferredTaskHandler::~DeferredTaskHandler() |  239 DeferredTaskHandler::~DeferredTaskHandler() | 
|  240 { |  240 { | 
|  241     ASSERT(!m_automaticPullNodes.size()); |  241     DCHECK(!m_automaticPullNodes.size()); | 
|  242     if (m_automaticPullNodesNeedUpdating) |  242     if (m_automaticPullNodesNeedUpdating) | 
|  243         m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); |  243         m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); | 
|  244     ASSERT(!m_renderingAutomaticPullNodes.size()); |  244     DCHECK(!m_renderingAutomaticPullNodes.size()); | 
|  245 } |  245 } | 
|  246  |  246  | 
|  247 void DeferredTaskHandler::handleDeferredTasks() |  247 void DeferredTaskHandler::handleDeferredTasks() | 
|  248 { |  248 { | 
|  249     updateChangedChannelCountMode(); |  249     updateChangedChannelCountMode(); | 
|  250     updateChangedChannelInterpretation(); |  250     updateChangedChannelInterpretation(); | 
|  251     handleDirtyAudioSummingJunctions(); |  251     handleDirtyAudioSummingJunctions(); | 
|  252     handleDirtyAudioNodeOutputs(); |  252     handleDirtyAudioNodeOutputs(); | 
|  253     updateAutomaticPullNodes(); |  253     updateAutomaticPullNodes(); | 
|  254 } |  254 } | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  270 } |  270 } | 
|  271  |  271  | 
|  272 DeferredTaskHandler::OfflineGraphAutoLocker::OfflineGraphAutoLocker(OfflineAudio
     Context* context) |  272 DeferredTaskHandler::OfflineGraphAutoLocker::OfflineGraphAutoLocker(OfflineAudio
     Context* context) | 
|  273     : m_handler(context->deferredTaskHandler()) |  273     : m_handler(context->deferredTaskHandler()) | 
|  274 { |  274 { | 
|  275     m_handler.offlineLock(); |  275     m_handler.offlineLock(); | 
|  276 } |  276 } | 
|  277  |  277  | 
|  278 void DeferredTaskHandler::addRenderingOrphanHandler(PassRefPtr<AudioHandler> han
     dler) |  278 void DeferredTaskHandler::addRenderingOrphanHandler(PassRefPtr<AudioHandler> han
     dler) | 
|  279 { |  279 { | 
|  280     ASSERT(handler); |  280     DCHECK(handler); | 
|  281     ASSERT(!m_renderingOrphanHandlers.contains(handler)); |  281     DCHECK(!m_renderingOrphanHandlers.contains(handler)); | 
|  282     m_renderingOrphanHandlers.append(handler); |  282     m_renderingOrphanHandlers.append(handler); | 
|  283 } |  283 } | 
|  284  |  284  | 
|  285 void DeferredTaskHandler::requestToDeleteHandlersOnMainThread() |  285 void DeferredTaskHandler::requestToDeleteHandlersOnMainThread() | 
|  286 { |  286 { | 
|  287     ASSERT(isGraphOwner()); |  287     ASSERT(isGraphOwner()); | 
|  288     ASSERT(isAudioThread()); |  288     DCHECK(isAudioThread()); | 
|  289     if (m_renderingOrphanHandlers.isEmpty()) |  289     if (m_renderingOrphanHandlers.isEmpty()) | 
|  290         return; |  290         return; | 
|  291     m_deletableOrphanHandlers.appendVector(m_renderingOrphanHandlers); |  291     m_deletableOrphanHandlers.appendVector(m_renderingOrphanHandlers); | 
|  292     m_renderingOrphanHandlers.clear(); |  292     m_renderingOrphanHandlers.clear(); | 
|  293     Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H
     ERE, crossThreadBind(&DeferredTaskHandler::deleteHandlersOnMainThread, PassRefPt
     r<DeferredTaskHandler>(this))); |  293     Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H
     ERE, crossThreadBind(&DeferredTaskHandler::deleteHandlersOnMainThread, PassRefPt
     r<DeferredTaskHandler>(this))); | 
|  294 } |  294 } | 
|  295  |  295  | 
|  296 void DeferredTaskHandler::deleteHandlersOnMainThread() |  296 void DeferredTaskHandler::deleteHandlersOnMainThread() | 
|  297 { |  297 { | 
|  298     ASSERT(isMainThread()); |  298     DCHECK(isMainThread()); | 
|  299     AutoLocker locker(*this); |  299     AutoLocker locker(*this); | 
|  300     m_deletableOrphanHandlers.clear(); |  300     m_deletableOrphanHandlers.clear(); | 
|  301 } |  301 } | 
|  302  |  302  | 
|  303 void DeferredTaskHandler::clearHandlersToBeDeleted() |  303 void DeferredTaskHandler::clearHandlersToBeDeleted() | 
|  304 { |  304 { | 
|  305     ASSERT(isMainThread()); |  305     DCHECK(isMainThread()); | 
|  306     AutoLocker locker(*this); |  306     AutoLocker locker(*this); | 
|  307     m_renderingOrphanHandlers.clear(); |  307     m_renderingOrphanHandlers.clear(); | 
|  308     m_deletableOrphanHandlers.clear(); |  308     m_deletableOrphanHandlers.clear(); | 
|  309 } |  309 } | 
|  310  |  310  | 
|  311 void DeferredTaskHandler::setAudioThreadToCurrentThread() |  311 void DeferredTaskHandler::setAudioThreadToCurrentThread() | 
|  312 { |  312 { | 
|  313     ASSERT(!isMainThread()); |  313     DCHECK(!isMainThread()); | 
|  314     ThreadIdentifier thread = currentThread(); |  314     ThreadIdentifier thread = currentThread(); | 
|  315     releaseStore(&m_audioThread, thread); |  315     releaseStore(&m_audioThread, thread); | 
|  316 } |  316 } | 
|  317  |  317  | 
|  318 } // namespace blink |  318 } // namespace blink | 
|  319  |  319  | 
| OLD | NEW |