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:
alwu 2021-01-14 19:54:42 +00:00
Родитель 9edb9d310f
Коммит 4b46783098
3 изменённых файлов: 25 добавлений и 52 удалений

Просмотреть файл

@ -7506,7 +7506,7 @@ void HTMLMediaElement::GetEMEInfo(dom::EMEDebugInfo& aInfo) {
void HTMLMediaElement::NotifyDecoderActivityChanges() const {
if (mDecoder) {
mDecoder->NotifyOwnerActivityChanged(!IsHidden(), mVisibilityState,
mDecoder->NotifyOwnerActivityChanged(IsActuallyInvisible(),
IsInComposedDoc());
}
}

Просмотреть файл

@ -26,7 +26,6 @@
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Telemetry.h"
#include "Visibility.h"
#include "mozilla/Unused.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
@ -198,13 +197,11 @@ void MediaDecoder::InitStatics() {
NS_IMPL_ISUPPORTS(MediaMemoryTracker, nsIMemoryReporter)
void MediaDecoder::NotifyOwnerActivityChanged(bool aIsDocumentVisible,
Visibility aElementVisibility,
bool aIsElementInTree) {
void MediaDecoder::NotifyOwnerActivityChanged(bool aIsOwnerInvisible,
bool aIsOwnerConnected) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
SetElementVisibility(aIsDocumentVisible, aElementVisibility,
aIsElementInTree);
SetElementVisibility(aIsOwnerInvisible, aIsOwnerConnected);
NotifyCompositor();
}
@ -294,9 +291,8 @@ MediaDecoder::MediaDecoder(MediaDecoderInit& aInit)
mVideoFrameContainer(aInit.mOwner->GetVideoFrameContainer()),
mMinimizePreroll(aInit.mMinimizePreroll),
mFiredMetadataLoaded(false),
mIsDocumentVisible(false),
mElementVisibility(Visibility::Untracked),
mIsElementInTree(false),
mIsOwnerInvisible(false),
mIsOwnerConnected(false),
mForcedHidden(false),
mHasSuspendTaint(aInit.mHasSuspendTaint),
mPlaybackRate(aInit.mPlaybackRate),
@ -963,13 +959,11 @@ void MediaDecoder::NotifyCompositor() {
}
}
void MediaDecoder::SetElementVisibility(bool aIsDocumentVisible,
Visibility aElementVisibility,
bool aIsElementInTree) {
void MediaDecoder::SetElementVisibility(bool aIsOwnerInvisible,
bool aIsOwnerConnected) {
MOZ_ASSERT(NS_IsMainThread());
mIsDocumentVisible = aIsDocumentVisible;
mElementVisibility = aElementVisibility;
mIsElementInTree = aIsElementInTree;
mIsOwnerInvisible = aIsOwnerInvisible;
mIsOwnerConnected = aIsOwnerConnected;
UpdateVideoDecodeMode();
}
@ -1018,8 +1012,8 @@ void MediaDecoder::UpdateVideoDecodeMode() {
return;
}
// Don't suspend elements that is not in tree.
if (!mIsElementInTree) {
// Don't suspend elements that is not in a connected tree.
if (!mIsOwnerConnected) {
LOG("UpdateVideoDecodeMode(), set Normal because the element is not in "
"tree.");
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
@ -1042,27 +1036,12 @@ void MediaDecoder::UpdateVideoDecodeMode() {
return;
}
// If the element is in-tree with UNTRACKED visibility, that means the element
// is not close enough to the viewport so we have not start to update its
// 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.");
if (mIsOwnerInvisible) {
LOG("UpdateVideoDecodeMode(), set Suspend because of invisible element.");
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 {
LOG("UpdateVideoDecodeMode(), set Suspend because the element is not "
"visible.");
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Suspend);
LOG("UpdateVideoDecodeMode(), set Normal because of visible element.");
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
}
}

Просмотреть файл

@ -50,8 +50,6 @@ class MediaDecoderStateMachine;
struct MediaPlaybackEvent;
struct SharedDummyTrack;
enum class Visibility : uint8_t;
struct MOZ_STACK_CLASS MediaDecoderInit {
MediaDecoderOwner* const mOwner;
const double mVolume;
@ -141,9 +139,8 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
virtual void Play();
// Notify activity of the decoder owner is changed.
virtual void NotifyOwnerActivityChanged(bool aIsDocumentVisible,
Visibility aElementVisibility,
bool aIsElementInTree);
virtual void NotifyOwnerActivityChanged(bool aIsOwnerInvisible,
bool aIsOwnerConnected);
// Pause video playback.
virtual void Pause();
@ -307,9 +304,8 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
bool CanPlayThrough();
// Called from HTMLMediaElement when owner document activity changes
virtual void SetElementVisibility(bool aIsDocumentVisible,
Visibility aElementVisibility,
bool aIsElementInTree);
virtual void SetElementVisibility(bool aIsOwnerInvisible,
bool aIsOwnerConnected);
// Force override the visible state to hidden.
// 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.
UniquePtr<MediaInfo> mInfo;
// Tracks the visibility status of owner element's document.
bool mIsDocumentVisible;
// True if the owner element is actually visible to users.
bool mIsOwnerInvisible;
// Tracks the visibility status of owner element.
Visibility mElementVisibility;
// Tracks the owner is in-tree or not.
bool mIsElementInTree;
// True if the owner element is connected to a document tree.
// https://dom.spec.whatwg.org/#connected
bool mIsOwnerConnected;
// If true, forces the decoder to be considered hidden.
bool mForcedHidden;