Bug 1685399 - part3 : use actual invisible state to determine if we should suspend decoding. r=padenot
There is no need for decoder to use both "document visibility" and "element's layout visibility" to determine if we should suspend decoding. That can simply be done by checking `HTMLMediaElement::IsActuallyInvisible()`. Differential Revision: https://phabricator.services.mozilla.com/D101108
This commit is contained in:
@@ -7506,7 +7506,7 @@ void HTMLMediaElement::GetEMEInfo(dom::EMEDebugInfo& aInfo) {
|
|||||||
|
|
||||||
void HTMLMediaElement::NotifyDecoderActivityChanges() const {
|
void HTMLMediaElement::NotifyDecoderActivityChanges() const {
|
||||||
if (mDecoder) {
|
if (mDecoder) {
|
||||||
mDecoder->NotifyOwnerActivityChanged(!IsHidden(), mVisibilityState,
|
mDecoder->NotifyOwnerActivityChanged(IsActuallyInvisible(),
|
||||||
IsInComposedDoc());
|
IsInComposedDoc());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
#include "mozilla/StaticPrefs_media.h"
|
#include "mozilla/StaticPrefs_media.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
#include "Visibility.h"
|
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
@@ -198,13 +197,11 @@ void MediaDecoder::InitStatics() {
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS(MediaMemoryTracker, nsIMemoryReporter)
|
NS_IMPL_ISUPPORTS(MediaMemoryTracker, nsIMemoryReporter)
|
||||||
|
|
||||||
void MediaDecoder::NotifyOwnerActivityChanged(bool aIsDocumentVisible,
|
void MediaDecoder::NotifyOwnerActivityChanged(bool aIsOwnerInvisible,
|
||||||
Visibility aElementVisibility,
|
bool aIsOwnerConnected) {
|
||||||
bool aIsElementInTree) {
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||||
SetElementVisibility(aIsDocumentVisible, aElementVisibility,
|
SetElementVisibility(aIsOwnerInvisible, aIsOwnerConnected);
|
||||||
aIsElementInTree);
|
|
||||||
|
|
||||||
NotifyCompositor();
|
NotifyCompositor();
|
||||||
}
|
}
|
||||||
@@ -294,9 +291,8 @@ MediaDecoder::MediaDecoder(MediaDecoderInit& aInit)
|
|||||||
mVideoFrameContainer(aInit.mOwner->GetVideoFrameContainer()),
|
mVideoFrameContainer(aInit.mOwner->GetVideoFrameContainer()),
|
||||||
mMinimizePreroll(aInit.mMinimizePreroll),
|
mMinimizePreroll(aInit.mMinimizePreroll),
|
||||||
mFiredMetadataLoaded(false),
|
mFiredMetadataLoaded(false),
|
||||||
mIsDocumentVisible(false),
|
mIsOwnerInvisible(false),
|
||||||
mElementVisibility(Visibility::Untracked),
|
mIsOwnerConnected(false),
|
||||||
mIsElementInTree(false),
|
|
||||||
mForcedHidden(false),
|
mForcedHidden(false),
|
||||||
mHasSuspendTaint(aInit.mHasSuspendTaint),
|
mHasSuspendTaint(aInit.mHasSuspendTaint),
|
||||||
mPlaybackRate(aInit.mPlaybackRate),
|
mPlaybackRate(aInit.mPlaybackRate),
|
||||||
@@ -963,13 +959,11 @@ void MediaDecoder::NotifyCompositor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaDecoder::SetElementVisibility(bool aIsDocumentVisible,
|
void MediaDecoder::SetElementVisibility(bool aIsOwnerInvisible,
|
||||||
Visibility aElementVisibility,
|
bool aIsOwnerConnected) {
|
||||||
bool aIsElementInTree) {
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
mIsDocumentVisible = aIsDocumentVisible;
|
mIsOwnerInvisible = aIsOwnerInvisible;
|
||||||
mElementVisibility = aElementVisibility;
|
mIsOwnerConnected = aIsOwnerConnected;
|
||||||
mIsElementInTree = aIsElementInTree;
|
|
||||||
UpdateVideoDecodeMode();
|
UpdateVideoDecodeMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1018,8 +1012,8 @@ void MediaDecoder::UpdateVideoDecodeMode() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't suspend elements that is not in tree.
|
// Don't suspend elements that is not in a connected tree.
|
||||||
if (!mIsElementInTree) {
|
if (!mIsOwnerConnected) {
|
||||||
LOG("UpdateVideoDecodeMode(), set Normal because the element is not in "
|
LOG("UpdateVideoDecodeMode(), set Normal because the element is not in "
|
||||||
"tree.");
|
"tree.");
|
||||||
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
|
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
|
||||||
@@ -1042,27 +1036,12 @@ void MediaDecoder::UpdateVideoDecodeMode() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the element is in-tree with UNTRACKED visibility, that means the element
|
if (mIsOwnerInvisible) {
|
||||||
// is not close enough to the viewport so we have not start to update its
|
LOG("UpdateVideoDecodeMode(), set Suspend because of invisible element.");
|
||||||
// visibility. In this case, it's equals to invisible.
|
|
||||||
if (mIsElementInTree && mElementVisibility == Visibility::Untracked) {
|
|
||||||
LOG("UpdateVideoDecodeMode(), set Suspend because element hasn't be "
|
|
||||||
"updated visibility state.");
|
|
||||||
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Suspend);
|
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
|
|
||||||
// itself is visible.
|
|
||||||
if (mIsDocumentVisible &&
|
|
||||||
mElementVisibility == Visibility::ApproximatelyVisible) {
|
|
||||||
LOG("UpdateVideoDecodeMode(), set Normal because the element visible.");
|
|
||||||
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
|
|
||||||
} else {
|
} else {
|
||||||
LOG("UpdateVideoDecodeMode(), set Suspend because the element is not "
|
LOG("UpdateVideoDecodeMode(), set Normal because of visible element.");
|
||||||
"visible.");
|
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
|
||||||
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Suspend);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,6 @@ class MediaDecoderStateMachine;
|
|||||||
struct MediaPlaybackEvent;
|
struct MediaPlaybackEvent;
|
||||||
struct SharedDummyTrack;
|
struct SharedDummyTrack;
|
||||||
|
|
||||||
enum class Visibility : uint8_t;
|
|
||||||
|
|
||||||
struct MOZ_STACK_CLASS MediaDecoderInit {
|
struct MOZ_STACK_CLASS MediaDecoderInit {
|
||||||
MediaDecoderOwner* const mOwner;
|
MediaDecoderOwner* const mOwner;
|
||||||
const double mVolume;
|
const double mVolume;
|
||||||
@@ -141,9 +139,8 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
|
|||||||
virtual void Play();
|
virtual void Play();
|
||||||
|
|
||||||
// Notify activity of the decoder owner is changed.
|
// Notify activity of the decoder owner is changed.
|
||||||
virtual void NotifyOwnerActivityChanged(bool aIsDocumentVisible,
|
virtual void NotifyOwnerActivityChanged(bool aIsOwnerInvisible,
|
||||||
Visibility aElementVisibility,
|
bool aIsOwnerConnected);
|
||||||
bool aIsElementInTree);
|
|
||||||
|
|
||||||
// Pause video playback.
|
// Pause video playback.
|
||||||
virtual void Pause();
|
virtual void Pause();
|
||||||
@@ -307,9 +304,8 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
|
|||||||
bool CanPlayThrough();
|
bool CanPlayThrough();
|
||||||
|
|
||||||
// Called from HTMLMediaElement when owner document activity changes
|
// Called from HTMLMediaElement when owner document activity changes
|
||||||
virtual void SetElementVisibility(bool aIsDocumentVisible,
|
virtual void SetElementVisibility(bool aIsOwnerInvisible,
|
||||||
Visibility aElementVisibility,
|
bool aIsOwnerConnected);
|
||||||
bool aIsElementInTree);
|
|
||||||
|
|
||||||
// Force override the visible state to hidden.
|
// Force override the visible state to hidden.
|
||||||
// Called from HTMLMediaElement when testing of video decode suspend from
|
// Called from HTMLMediaElement when testing of video decode suspend from
|
||||||
@@ -569,14 +565,12 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
|
|||||||
// only be accessed from main thread.
|
// only be accessed from main thread.
|
||||||
UniquePtr<MediaInfo> mInfo;
|
UniquePtr<MediaInfo> mInfo;
|
||||||
|
|
||||||
// Tracks the visibility status of owner element's document.
|
// True if the owner element is actually visible to users.
|
||||||
bool mIsDocumentVisible;
|
bool mIsOwnerInvisible;
|
||||||
|
|
||||||
// Tracks the visibility status of owner element.
|
// True if the owner element is connected to a document tree.
|
||||||
Visibility mElementVisibility;
|
// https://dom.spec.whatwg.org/#connected
|
||||||
|
bool mIsOwnerConnected;
|
||||||
// Tracks the owner is in-tree or not.
|
|
||||||
bool mIsElementInTree;
|
|
||||||
|
|
||||||
// If true, forces the decoder to be considered hidden.
|
// If true, forces the decoder to be considered hidden.
|
||||||
bool mForcedHidden;
|
bool mForcedHidden;
|
||||||
|
|||||||
Reference in New Issue
Block a user