Bug 1346116 part 2 - consider a video is in-tree or not in the suspend-video-decoding policy; r=jwwang
authorKaku Kuo <kaku@mozilla.com>
Sun, 12 Mar 2017 14:02:04 +0800
changeset 347427 f7ca43d48a42b0f9b0e2b0e80d0aa820a6c2a0d7
parent 347426 096a4818b8c7aa485e30946a6f045e01cfd3b90e
child 347428 c4688144319f23332b7d90b486677c6e4acd5457
push id31496
push usercbook@mozilla.com
push dateTue, 14 Mar 2017 13:21:57 +0000
treeherdermozilla-central@9a26ed658fdc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwwang
bugs1346116
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1346116 part 2 - consider a video is in-tree or not in the suspend-video-decoding policy; r=jwwang We never suspend videos that is NOT in-tree because we found that, according to the Telemetry data, most (>70%) videos which are used as the argument of drawImage() are not in-tree. So, by preventing suspending not-in-tree videos, we should be able to alleviate the pain of not able to resume video decoders synchronously. MozReview-Commit-ID: 8eqs0pHZLIt
dom/html/HTMLMediaElement.cpp
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -7399,17 +7399,18 @@ HTMLMediaElement::GetEMEInfo(nsString& a
   aEMEInfo.Append(sessionsInfo);
 }
 
 void
 HTMLMediaElement::NotifyDecoderActivityChanges() const
 {
   if (mDecoder) {
     mDecoder->NotifyOwnerActivityChanged(!IsHidden(),
-                                         mVisibilityState == Visibility::APPROXIMATELY_VISIBLE);
+                                         mVisibilityState == Visibility::APPROXIMATELY_VISIBLE,
+                                         IsInUncomposedDoc());
   }
 }
 
 bool HasDebuggerPrivilege(JSContext* aCx, JSObject* aObj)
 {
   return nsContentUtils::CallerHasPermission(aCx,
                                              NS_LITERAL_STRING("debugger"));
  }
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -293,21 +293,22 @@ MediaDecoder::ResourceCallback::NotifyBy
       self->mDecoder->NotifyBytesConsumed(aBytes, aOffset);
     }
   });
   mAbstractMainThread->Dispatch(r.forget());
 }
 
 void
 MediaDecoder::NotifyOwnerActivityChanged(bool aIsDocumentVisible,
-                                         bool aIsElementVisible)
+                                         bool aIsElementVisible,
+                                         bool aIsElementInTree)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
-  SetElementVisibility(aIsDocumentVisible, aIsElementVisible);
+  SetElementVisibility(aIsDocumentVisible, aIsElementVisible, aIsElementInTree);
 
   NotifyCompositor();
 }
 
 void
 MediaDecoder::Pause()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -392,16 +393,17 @@ MediaDecoder::MediaDecoder(MediaDecoderO
   , mVideoFrameContainer(aOwner->GetVideoFrameContainer())
   , mPlaybackStatistics(new MediaChannelStatistics())
   , mPinnedForSeek(false)
   , mMinimizePreroll(false)
   , mMediaTracksConstructed(false)
   , mFiredMetadataLoaded(false)
   , mIsDocumentVisible(false)
   , mIsElementVisible(false)
+  , mIsElementInTree(false)
   , mForcedHidden(false)
   , mHasSuspendTaint(false)
   , INIT_MIRROR(mStateMachineIsShutdown, true)
   , INIT_MIRROR(mBuffered, TimeIntervals())
   , INIT_MIRROR(mNextFrameStatus, MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE)
   , INIT_MIRROR(mCurrentPosition, 0)
   , INIT_MIRROR(mStateMachineDuration, NullableTimeUnit())
   , INIT_MIRROR(mPlaybackPosition, 0)
@@ -1303,21 +1305,23 @@ MediaDecoder::NotifyCompositor()
   if (layerManager) {
     RefPtr<KnowsCompositor> knowsCompositor = layerManager->AsShadowForwarder();
     mCompositorUpdatedEvent.Notify(knowsCompositor);
   }
 }
 
 void
 MediaDecoder::SetElementVisibility(bool aIsDocumentVisible,
-                                   bool aIsElementVisible)
+                                   bool aIsElementVisible,
+                                   bool aIsElementInTree)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mIsDocumentVisible = aIsDocumentVisible;
   mIsElementVisible = aIsElementVisible;
+  mIsElementInTree = aIsElementInTree;
   UpdateVideoDecodeMode();
 }
 
 void
 MediaDecoder::SetForcedHidden(bool aForcedHidden)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mForcedHidden = aForcedHidden;
@@ -1341,16 +1345,22 @@ MediaDecoder::UpdateVideoDecodeMode()
   }
 
   // If mHasSuspendTaint is set, never suspend the video decoder.
   if (mHasSuspendTaint) {
     mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
     return;
   }
 
+  // Don't suspend elements that is not in tree.
+  if (!mIsElementInTree) {
+    mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
+    return;
+  }
+
   // If mForcedHidden is set, suspend the video decoder anyway.
   if (mForcedHidden) {
     mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Suspend);
     return;
   }
 
   // Otherwise, depends on the owner's visibility state.
   // A element is visible only if its document is visible and the element
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -185,17 +185,18 @@ public:
   nsresult InitializeStateMachine();
 
   // Start playback of a video. 'Load' must have previously been
   // called.
   virtual nsresult Play();
 
   // Notify activity of the decoder owner is changed.
   virtual void NotifyOwnerActivityChanged(bool aIsDocumentVisible,
-                                          bool aIsElementVisible);
+                                          bool aIsElementVisible,
+                                          bool aIsElementInTree);
 
   // Pause video playback.
   virtual void Pause();
   // Adjust the speed of the playback, optionally with pitch correction,
   virtual void SetVolume(double aVolume);
 
   virtual void SetPlaybackRate(double aPlaybackRate);
   void SetPreservesPitch(bool aPreservesPitch);
@@ -368,17 +369,18 @@ private:
   // to buffer, given the current download and playback rates.
   virtual bool CanPlayThrough();
 
   void SetAudioChannel(dom::AudioChannel aChannel) { mAudioChannel = aChannel; }
   dom::AudioChannel GetAudioChannel() { return mAudioChannel; }
 
   // Called from HTMLMediaElement when owner document activity changes
   virtual void SetElementVisibility(bool aIsDocumentVisible,
-                                    bool aIsElementVisible);
+                                    bool aIsElementVisible,
+                                    bool aIsElementInTree);
 
   // Force override the visible state to hidden.
   // Called from HTMLMediaElement when testing of video decode suspend from mochitests.
   void SetForcedHidden(bool aForcedHidden);
 
   // Mark the decoder as tainted, meaning suspend-video-decoder is disabled.
   void SetSuspendTaint(bool aTaint);
 
@@ -716,19 +718,22 @@ protected:
 
   // Stores media info, including info of audio tracks and video tracks, should
   // only be accessed from main thread.
   nsAutoPtr<MediaInfo> mInfo;
 
   // Tracks the visibility status of owner element's document.
   bool mIsDocumentVisible;
 
-  // Tracks the visibliity status of owner element.
+  // Tracks the visibility status of owner element.
   bool mIsElementVisible;
 
+  // Tracks the owner is in-tree or not.
+  bool mIsElementInTree;
+
   // If true, forces the decoder to be considered hidden.
   bool mForcedHidden;
 
   // True if the decoder has a suspend taint - meaning suspend-video-decoder is
   // disabled.
   bool mHasSuspendTaint;
 
   // A listener to receive metadata updates from MDSM.