Bug 1295921 - PB: Implement dispatching of pending main thread MediaDecoder tasks. r?jwwang draft
authorDan Glastonbury <dglastonbury@mozilla.com>
Tue, 27 Sep 2016 15:26:41 +1000
changeset 450831 f04eae06ddd9467003bb538780ed260f3e15b52b
parent 450830 d06b67edd6b9a8e62fabab93e06bfc8224e116cb
child 450832 c727af5916c4847841afd4b11c5ea646b7a7538a
push id38957
push userbmo:dglastonbury@mozilla.com
push dateMon, 19 Dec 2016 02:15:56 +0000
reviewersjwwang
bugs1295921
milestone53.0a1
Bug 1295921 - PB: Implement dispatching of pending main thread MediaDecoder tasks. r?jwwang Add support to flush pending tasks in the MainThread TailDispatcher, ensuring they are delivered in the correct order. This is used in the case that a video element with a suspended decoder is used in nsLayoutUtils::SurfaceFromElement. The 'has suspend taint' variable change needs to be dispatched to the MDSM TaskQueue before blocking the main thread to wait for the next frame. Once the variable change has been successfully dispatched, the MDSM with start decoding video frames again on it's thread pool. MozReview-Commit-ID: JrZepBGmjJt
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderStateMachine.h
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -1172,16 +1172,23 @@ void
 MediaDecoder::SeekingStarted()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
   mOwner->SeekStarted();
 }
 
 void
+MediaDecoder::DispatchPendingTasks()
+{
+  mDecoderStateMachine->DispatchPendingTasks();
+}
+}
+
+void
 MediaDecoder::ChangeState(PlayState aState)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!IsShutdown(), "SHUTDOWN is the final state.");
 
   if (mNextState == aState) {
     mNextState = PLAY_STATE_PAUSED;
   }
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -364,16 +364,19 @@ private:
   // Returns true if the decoder can't participate in video decode suspending.
   bool HasSuspendTaint() const;
 
   /******
    * The following methods must only be called on the main
    * thread.
    ******/
 
+  // Dispatch any pending tasks in the main thread tail dispatcher in order.
+  void DispatchPendingTasks();
+
   // Change to a new play state. This updates the mState variable and
   // notifies any thread blocking on this object's monitor of the
   // change. Call on the main thread only.
   virtual void ChangeState(PlayState aState);
 
   // Called from MetadataLoaded(). Creates audio tracks and adds them to its
   // owner's audio track list, and implies to video tracks respectively.
   // Call on the main thread only.
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -221,16 +221,26 @@ public:
       if (self->mAudioOffloading != aAudioOffloading) {
         self->mAudioOffloading = aAudioOffloading;
         self->ScheduleStateMachine();
       }
     });
     OwnerThread()->Dispatch(r.forget());
   }
 
+  void DispatchPendingTasks()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    AbstractThread* mainThread = AbstractThread::MainThread();
+    // Direct tasks need to be drained...
+    mainThread->TailDispatcher().DrainDirectTasks();
+    // ...before state and normal tasks.
+    mainThread->TailDispatchTasksFor(OwnerThread());
+  }
+
   // Drop reference to mResource. Only called during shutdown dance.
   void BreakCycles() {
     MOZ_ASSERT(NS_IsMainThread());
     mResource = nullptr;
   }
 
   TimedMetadataEventSource& TimedMetadataEvent() {
     return mMetadataManager.TimedMetadataEvent();