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

Side by Side Diff: Source/modules/webaudio/AbstractAudioContext.cpp

Issue 1140723003: Implement suspend() and resume() for OfflineAudioContext (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Bring ToT Created 5 years, 4 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 | « Source/modules/webaudio/AbstractAudioContext.h ('k') | Source/modules/webaudio/AudioContext.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) 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 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 686
687 // Find AudioBufferSourceNodes to see if we can stop playing them. 687 // Find AudioBufferSourceNodes to see if we can stop playing them.
688 for (AudioNode* node : m_activeSourceNodes) { 688 for (AudioNode* node : m_activeSourceNodes) {
689 if (node->handler().nodeType() == AudioHandler::NodeTypeAudioBufferSourc e) { 689 if (node->handler().nodeType() == AudioHandler::NodeTypeAudioBufferSourc e) {
690 AudioBufferSourceNode* sourceNode = static_cast<AudioBufferSourceNod e*>(node); 690 AudioBufferSourceNode* sourceNode = static_cast<AudioBufferSourceNod e*>(node);
691 sourceNode->audioBufferSourceHandler().handleStoppableSourceNode(); 691 sourceNode->audioBufferSourceHandler().handleStoppableSourceNode();
692 } 692 }
693 } 693 }
694 } 694 }
695 695
696 void AbstractAudioContext::performPostRenderTasks()
697 {
698 // Take care of AudioNode tasks where the tryLock() failed previously.
699 deferredTaskHandler().breakConnections();
700
701 // Dynamically clean up nodes which are no longer needed.
702 releaseFinishedSourceNodes();
703
704 deferredTaskHandler().handleDeferredTasks();
705 deferredTaskHandler().requestToDeleteHandlersOnMainThread();
706 }
707
696 void AbstractAudioContext::handlePreRenderTasks() 708 void AbstractAudioContext::handlePreRenderTasks()
697 { 709 {
698 ASSERT(isAudioThread()); 710 ASSERT(isAudioThread());
699 711
712 // For the precise offline audio rendering, we need these tasks to be
713 // performed every render quantum. Thus, we wait for the graph lock (rather
714 // than tryLock()) so we can run the pre-render tasks without deferring
715 // them.
716 //
717 // Also note that we do not need to run resolvePromiseForResume() here
718 // because the offline audio context keeps its own suspend/resume promise
719 // resolvers separately.
720 if (!hasRealtimeConstraint()) {
721 deferredTaskHandler().offlineContextLock();
722 deferredTaskHandler().handleDeferredTasks();
723 handleStoppableSourceNodes();
724 unlock();
725 return;
726 }
727
700 // At the beginning of every render quantum, try to update the internal rend ering graph state (from main thread changes). 728 // At the beginning of every render quantum, try to update the internal rend ering graph state (from main thread changes).
701 // It's OK if the tryLock() fails, we'll just take slightly longer to pick u p the changes. 729 // It's OK if the tryLock() fails, we'll just take slightly longer to pick u p the changes.
702 if (tryLock()) { 730 if (tryLock()) {
703 deferredTaskHandler().handleDeferredTasks(); 731 deferredTaskHandler().handleDeferredTasks();
704 732
705 resolvePromisesForResume(); 733 resolvePromisesForResume();
706 734
707 // Check to see if source nodes can be stopped because the end time has passed. 735 // Check to see if source nodes can be stopped because the end time has passed.
708 handleStoppableSourceNodes(); 736 handleStoppableSourceNodes();
709 737
710 unlock(); 738 unlock();
711 } 739 }
712 } 740 }
713 741
714 void AbstractAudioContext::handlePostRenderTasks() 742 void AbstractAudioContext::handlePostRenderTasks()
715 { 743 {
716 ASSERT(isAudioThread()); 744 ASSERT(isAudioThread());
717 745
746 // Same as |handlePreRenderTasks()|. We force to perform the post-render
747 // tasks for the offline rendering.
748 if (!hasRealtimeConstraint()) {
749 deferredTaskHandler().offlineContextLock();
750 performPostRenderTasks();
751 unlock();
752 return;
753 }
754
718 // Must use a tryLock() here too. Don't worry, the lock will very rarely be contended and this method is called frequently. 755 // Must use a tryLock() here too. Don't worry, the lock will very rarely be contended and this method is called frequently.
719 // The worst that can happen is that there will be some nodes which will tak e slightly longer than usual to be deleted or removed 756 // The worst that can happen is that there will be some nodes which will tak e slightly longer than usual to be deleted or removed
720 // from the render graph (in which case they'll render silence). 757 // from the render graph (in which case they'll render silence).
721 if (tryLock()) { 758 if (tryLock()) {
722 // Take care of AudioNode tasks where the tryLock() failed previously. 759 performPostRenderTasks();
723 deferredTaskHandler().breakConnections();
724
725 // Dynamically clean up nodes which are no longer needed.
726 releaseFinishedSourceNodes();
727
728 deferredTaskHandler().handleDeferredTasks();
729 deferredTaskHandler().requestToDeleteHandlersOnMainThread();
730
731 unlock(); 760 unlock();
732 } 761 }
733 } 762 }
734 763
735 void AbstractAudioContext::resolvePromisesForResumeOnMainThread() 764 void AbstractAudioContext::resolvePromisesForResumeOnMainThread()
736 { 765 {
737 ASSERT(isMainThread()); 766 ASSERT(isMainThread());
738 AutoLocker locker(this); 767 AutoLocker locker(this);
739 768
740 for (auto& resolver : m_resumeResolvers) { 769 for (auto& resolver : m_resumeResolvers) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 // This is called for both online and offline contexts. 822 // This is called for both online and offline contexts.
794 ASSERT(isMainThread()); 823 ASSERT(isMainThread());
795 ASSERT(m_destinationNode); 824 ASSERT(m_destinationNode);
796 825
797 if (m_contextState == Suspended) { 826 if (m_contextState == Suspended) {
798 destination()->audioDestinationHandler().startRendering(); 827 destination()->audioDestinationHandler().startRendering();
799 setContextState(Running); 828 setContextState(Running);
800 } 829 }
801 } 830 }
802 831
803 void AbstractAudioContext::fireCompletionEvent()
804 {
805 ASSERT(isMainThread());
806 if (!isMainThread())
807 return;
808
809 AudioBuffer* renderedBuffer = m_renderTarget.get();
810
811 // For an offline context, we set the state to closed here so that the oncom plete handler sees
812 // that the context has been closed.
813 setContextState(Closed);
814
815 ASSERT(renderedBuffer);
816 if (!renderedBuffer)
817 return;
818
819 // Avoid firing the event if the document has already gone away.
820 if (executionContext()) {
821 // Call the offline rendering completion event listener and resolve the promise too.
822 dispatchEvent(OfflineAudioCompletionEvent::create(renderedBuffer));
823 m_offlineResolver->resolve(renderedBuffer);
824 }
825 }
826
827 DEFINE_TRACE(AbstractAudioContext) 832 DEFINE_TRACE(AbstractAudioContext)
828 { 833 {
829 visitor->trace(m_offlineResolver);
830 visitor->trace(m_renderTarget); 834 visitor->trace(m_renderTarget);
831 visitor->trace(m_destinationNode); 835 visitor->trace(m_destinationNode);
832 visitor->trace(m_listener); 836 visitor->trace(m_listener);
833 // trace() can be called in AbstractAudioContext constructor, and 837 // trace() can be called in AbstractAudioContext constructor, and
834 // m_contextGraphMutex might be unavailable. 838 // m_contextGraphMutex might be unavailable.
835 if (m_didInitializeContextGraphMutex) { 839 if (m_didInitializeContextGraphMutex) {
836 AutoLocker lock(this); 840 AutoLocker lock(this);
837 visitor->trace(m_activeSourceNodes); 841 visitor->trace(m_activeSourceNodes);
838 } else { 842 } else {
839 visitor->trace(m_activeSourceNodes); 843 visitor->trace(m_activeSourceNodes);
840 } 844 }
841 visitor->trace(m_resumeResolvers); 845 visitor->trace(m_resumeResolvers);
842 RefCountedGarbageCollectedEventTargetWithInlineData<AbstractAudioContext>::t race(visitor); 846 RefCountedGarbageCollectedEventTargetWithInlineData<AbstractAudioContext>::t race(visitor);
843 ActiveDOMObject::trace(visitor); 847 ActiveDOMObject::trace(visitor);
844 } 848 }
845 849
846 SecurityOrigin* AbstractAudioContext::securityOrigin() const 850 SecurityOrigin* AbstractAudioContext::securityOrigin() const
847 { 851 {
848 if (executionContext()) 852 if (executionContext())
849 return executionContext()->securityOrigin(); 853 return executionContext()->securityOrigin();
850 854
851 return nullptr; 855 return nullptr;
852 } 856 }
853 857
854 } // namespace blink 858 } // namespace blink
855 859
856 #endif // ENABLE(WEB_AUDIO) 860 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« no previous file with comments | « Source/modules/webaudio/AbstractAudioContext.h ('k') | Source/modules/webaudio/AudioContext.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698