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
--- 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();