WebKit Bugzilla
Attachment 346634 Details for
Bug 188208
: Refactoring: Convert HTMLMediaElement::scheduleDelayedAction() to individually schedulable & cancelable tasks
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188208-20180806105653.patch (text/plain), 37.19 KB, created by
Jer Noble
on 2018-08-06 10:56:54 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jer Noble
Created:
2018-08-06 10:56:54 PDT
Size:
37.19 KB
patch
obsolete
>Subversion Revision: 234423 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 74e5096c249e3945d35870424c43470424521202..01f6c9a40d71a89b823c026afd270c1c18ec95ca 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,67 @@ >+2018-07-31 Jer Noble <jer.noble@apple.com> >+ >+ Refactoring: Convert HTMLMediaElement::scheduleDelayedAction() to individually schedulable & cancelable tasks >+ https://bugs.webkit.org/show_bug.cgi?id=188208 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Rather than have a single, monolithic, zero-duration-timer based dispatch for >+ a bunch of methods to be performed in a future run-loop, convert them all to >+ use a DeferrableTask, which in turn is a kind of GenericTaskQueue which can >+ enqueue only a single task at a time. Convert some other zero-duration-timer >+ and GenericTaskQueue dispatches to this new DeferrableTask. >+ >+ * WebCore.xcodeproj/project.pbxproj: >+ * html/HTMLMediaElement.cpp: >+ (WebCore::HTMLMediaElement::HTMLMediaElement): >+ (WebCore::HTMLMediaElement::finishParsingChildren): >+ (WebCore::HTMLMediaElement::scheduleCheckPlaybackTargetCompatability): >+ (WebCore::HTMLMediaElement::checkPlaybackTargetCompatablity): >+ (WebCore::HTMLMediaElement::prepareForLoad): >+ (WebCore::HTMLMediaElement::setReadyState): >+ (WebCore::HTMLMediaElement::seekWithTolerance): >+ (WebCore::HTMLMediaElement::setMuted): >+ (WebCore::HTMLMediaElement::mediaPlayerDidAddTextTrack): >+ (WebCore::HTMLMediaElement::didAddTextTrack): >+ (WebCore::HTMLMediaElement::scheduleConfigureTextTracks): >+ (WebCore::HTMLMediaElement::mediaPlayerTimeChanged): >+ (WebCore::HTMLMediaElement::scheduleMediaEngineWasUpdated): >+ (WebCore::HTMLMediaElement::mediaEngineWasUpdated): >+ (WebCore::HTMLMediaElement::mediaPlayerEngineUpdated): >+ (WebCore::HTMLMediaElement::scheduleUpdatePlayState): >+ (WebCore::HTMLMediaElement::updatePlayState): >+ (WebCore::HTMLMediaElement::setPlaying): >+ (WebCore::HTMLMediaElement::setPausedInternal): >+ (WebCore::HTMLMediaElement::cancelPendingTasks): >+ (WebCore::HTMLMediaElement::userCancelledLoad): >+ (WebCore::HTMLMediaElement::clearMediaPlayer): >+ (WebCore::HTMLMediaElement::contextDestroyed): >+ (WebCore::HTMLMediaElement::stop): >+ (WebCore::HTMLMediaElement::suspend): >+ (WebCore::HTMLMediaElement::resume): >+ (WebCore::HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged): >+ (WebCore::HTMLMediaElement::dispatchEvent): >+ (WebCore::HTMLMediaElement::removeEventListener): >+ (WebCore::HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent): >+ (WebCore::HTMLMediaElement::didBecomeFullscreenElement): >+ (WebCore::HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured): >+ (WebCore::HTMLMediaElement::scheduleUpdateMediaState): >+ (WebCore::HTMLMediaElement::updateMediaState): >+ (WebCore::HTMLMediaElement::playbackControlsManagerBehaviorRestrictionsTimerFired): >+ (WebCore::setFlags): Deleted. >+ (WebCore::clearFlags): Deleted. >+ (WebCore::actionName): Deleted. >+ (WebCore::HTMLMediaElement::scheduleDelayedAction): Deleted. >+ (WebCore::HTMLMediaElement::pendingActionTimerFired): Deleted. >+ * html/HTMLMediaElement.h: >+ * html/HTMLMediaElementEnums.h: >+ * platform/DeferrableTask.h: Added. >+ (WebCore::DeferrableTask::DeferrableTask): >+ (WebCore::DeferrableTask::scheduleTask): >+ (WebCore::DeferrableTask::close): >+ (WebCore::DeferrableTask::cancelTask): >+ (WebCore::DeferrableTask::hasPendingTask const): >+ > 2018-07-31 Zalan Bujtas <zalan@apple.com> > > [LFC][Floating] Add basic left/right floating positioning. >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 787dcfab57d1c2d5d2c9e6c2154c020813b0bdde..e10027d3cbda6989a684c7060f91e93fce53fa32 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -3986,6 +3986,7 @@ > CD7D33481C7A16BF00041293 /* CoreVideoSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = CD7D33461C7A16BF00041293 /* CoreVideoSoftLink.h */; }; > CD7DBB2918CA19C600C11066 /* CSSGridLineNamesValue.h in Headers */ = {isa = PBXBuildFile; fileRef = CD7DBB2718CA11FF00C11066 /* CSSGridLineNamesValue.h */; }; > CD7E05221651C28200C1201F /* WebCoreAVFResourceLoader.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD7E05211651A84100C1201F /* WebCoreAVFResourceLoader.mm */; }; >+ CD83D36221122A210076E11C /* DeferrableTask.h in Headers */ = {isa = PBXBuildFile; fileRef = CD83D35A211110820076E11C /* DeferrableTask.h */; settings = {ATTRIBUTES = (Private, ); }; }; > CD8A7BBB197735FE00CBD643 /* AudioSourceProviderAVFObjC.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD8A7BB9197735FE00CBD643 /* AudioSourceProviderAVFObjC.mm */; }; > CD8A7BBC197735FE00CBD643 /* AudioSourceProviderAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = CD8A7BBA197735FE00CBD643 /* AudioSourceProviderAVFObjC.h */; }; > CD8ACA891D237AA200ECC59E /* RemoteCommandListenerMac.h in Headers */ = {isa = PBXBuildFile; fileRef = CD8ACA871D237AA200ECC59E /* RemoteCommandListenerMac.h */; }; >@@ -13252,6 +13253,7 @@ > CD7DBB2718CA11FF00C11066 /* CSSGridLineNamesValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSGridLineNamesValue.h; sourceTree = "<group>"; }; > CD7E05201651A84100C1201F /* WebCoreAVFResourceLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCoreAVFResourceLoader.h; sourceTree = "<group>"; }; > CD7E05211651A84100C1201F /* WebCoreAVFResourceLoader.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreAVFResourceLoader.mm; sourceTree = "<group>"; }; >+ CD83D35A211110820076E11C /* DeferrableTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeferrableTask.h; sourceTree = "<group>"; }; > CD871C5C1FB52B6300F0B965 /* ISOSchemeTypeBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISOSchemeTypeBox.h; sourceTree = "<group>"; }; > CD871C5E1FB52B6400F0B965 /* ISOProtectionSchemeInfoBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ISOProtectionSchemeInfoBox.cpp; sourceTree = "<group>"; }; > CD871C5F1FB52B6400F0B965 /* ISOSchemeTypeBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ISOSchemeTypeBox.cpp; sourceTree = "<group>"; }; >@@ -24451,6 +24453,7 @@ > 37C738F21EDBDE87003F2B0B /* DateTimeChooserClient.h */, > 45FEA5CD156DDE8C00654101 /* Decimal.cpp */, > 45FEA5CE156DDE8C00654101 /* Decimal.h */, >+ CD83D35A211110820076E11C /* DeferrableTask.h */, > A79546420B5C4CB4007B438F /* DragData.cpp */, > A7B6E69D0B291A9600D0529F /* DragData.h */, > A7CFB3CF0B7ED10A0070C32D /* DragImage.cpp */, >@@ -30294,6 +30297,7 @@ > 97BC6A4B1505F081001B74AC /* SQLStatementErrorCallback.h in Headers */, > 97BC6A501505F081001B74AC /* SQLTransaction.h in Headers */, > FEE1811416C319E800084849 /* SQLTransactionBackend.h in Headers */, >+ CD83D36221122A210076E11C /* DeferrableTask.h in Headers */, > 97BC6A521505F081001B74AC /* SQLTransactionCallback.h in Headers */, > 97BC6A571505F081001B74AC /* SQLTransactionCoordinator.h in Headers */, > 97BC6A581505F081001B74AC /* SQLTransactionErrorCallback.h in Headers */, >diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp >index 8fbcb82eb22a473adb2dabddd7ce5a7ee9e8d6ef..ffc3922abbc4187bafd2186c3245c9ccde87f2c2 100644 >--- a/Source/WebCore/html/HTMLMediaElement.cpp >+++ b/Source/WebCore/html/HTMLMediaElement.cpp >@@ -197,48 +197,8 @@ static const double SeekTime = 0.2; > static const Seconds ScanRepeatDelay { 1.5_s }; > static const double ScanMaximumRate = 8; > static const double AutoplayInterferenceTimeThreshold = 10; >- > static const Seconds hideMediaControlsAfterEndedDelay { 6_s }; > >-static void setFlags(unsigned& value, unsigned flags) >-{ >- value |= flags; >-} >- >-static void clearFlags(unsigned& value, unsigned flags) >-{ >- value &= ~flags; >-} >- >-#if !RELEASE_LOG_DISABLED >-static String actionName(HTMLMediaElementEnums::DelayedActionType action) >-{ >- StringBuilder actionBuilder; >- >-#define ACTION(_actionType) \ >- if (action & (HTMLMediaElementEnums::_actionType)) { \ >- if (!actionBuilder.isEmpty()) \ >- actionBuilder.appendLiteral(", "); \ >- actionBuilder.append(#_actionType); \ >- } \ >- >- ACTION(LoadMediaResource); >- ACTION(ConfigureTextTracks); >- ACTION(TextTrackChangesNotification); >- ACTION(ConfigureTextTrackDisplay); >- ACTION(CheckPlaybackTargetCompatablity); >- ACTION(CheckMediaState); >- ACTION(MediaEngineUpdated); >- ACTION(UpdatePlayState); >- >-#undef ACTION >- >- String name = actionBuilder.toString(); >- ASSERT(!name.isEmpty()); >- return name; >-} >-#endif >- > #ifndef LOG_CACHED_TIME_WARNINGS > // Default to not logging warnings about excessive drift in the cached media time because it adds a > // fair amount of overhead and logging. >@@ -464,7 +424,6 @@ static uint64_t nextLogIdentifier() > HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser) > : HTMLElement(tagName, document) > , ActiveDOMObject(&document) >- , m_pendingActionTimer(*this, &HTMLMediaElement::pendingActionTimerFired) > , m_progressEventTimer(*this, &HTMLMediaElement::progressEventTimerFired) > , m_playbackProgressTimer(*this, &HTMLMediaElement::playbackProgressTimerFired) > , m_scanTimer(*this, &HTMLMediaElement::scanTimerFired) >@@ -910,7 +869,7 @@ void HTMLMediaElement::finishParsingChildren() > > #if ENABLE(VIDEO_TRACK) > if (childrenOfType<HTMLTrackElement>(*this).first()) >- scheduleDelayedAction(ConfigureTextTracks); >+ scheduleConfigureTextTracks(); > #endif > } > >@@ -1048,33 +1007,6 @@ void HTMLMediaElement::didRecalcStyle(Style::Change) > updateRenderer(); > } > >-void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType) >-{ >- if (!(actionType & m_pendingActionFlags)) >- ALWAYS_LOG(LOGIDENTIFIER, "setting ", actionName(actionType), " flag"); >- >-#if ENABLE(VIDEO_TRACK) >- if (actionType & ConfigureTextTracks) >- setFlags(m_pendingActionFlags, ConfigureTextTracks); >-#endif >- >-#if ENABLE(WIRELESS_PLAYBACK_TARGET) >- if (actionType & CheckPlaybackTargetCompatablity) >- setFlags(m_pendingActionFlags, CheckPlaybackTargetCompatablity); >-#endif >- >- if (actionType & CheckMediaState) >- setFlags(m_pendingActionFlags, CheckMediaState); >- >- if (actionType & MediaEngineUpdated) >- setFlags(m_pendingActionFlags, MediaEngineUpdated); >- >- if (actionType & UpdatePlayState) >- setFlags(m_pendingActionFlags, UpdatePlayState); >- >- m_pendingActionTimer.startOneShot(0_s); >-} >- > void HTMLMediaElement::scheduleNextSourceChild() > { > // Schedule the timer to try the next <source> element WITHOUT resetting state ala prepareForLoad. >@@ -1148,38 +1080,28 @@ bool HTMLMediaElement::hasEverNotifiedAboutPlaying() const > return m_hasEverNotifiedAboutPlaying; > } > >-void HTMLMediaElement::pendingActionTimerFired() >+void HTMLMediaElement::scheduleCheckPlaybackTargetCompatability() > { >- Ref<HTMLMediaElement> protectedThis(*this); // loadNextSourceChild may fire 'beforeload', which can make arbitrary DOM mutations. >- PendingActionFlags pendingActions = m_pendingActionFlags; >- m_pendingActionFlags = 0; >- >- if (!pendingActions) >+ if (m_checkPlaybackTargetCompatablityTask.hasPendingTask()) > return; > >- ALWAYS_LOG(LOGIDENTIFIER, "processing ", actionName(static_cast<DelayedActionType>(pendingActions)), " flag"); >- >-#if ENABLE(VIDEO_TRACK) >- if (pendingActions & ConfigureTextTracks) >- configureTextTracks(); >-#endif >+ auto logSiteIdentifier = LOGIDENTIFIER; >+ ALWAYS_LOG(logSiteIdentifier, "task scheduled"); >+ m_checkPlaybackTargetCompatablityTask.scheduleTask([this, logSiteIdentifier] { >+ ALWAYS_LOG(logSiteIdentifier, "- lambda(), task fired"); >+ checkPlaybackTargetCompatablity(); >+ }); >+} > >+void HTMLMediaElement::checkPlaybackTargetCompatablity() >+{ > #if ENABLE(WIRELESS_PLAYBACK_TARGET) >- if (pendingActions & CheckPlaybackTargetCompatablity && m_isPlayingToWirelessTarget && !m_player->canPlayToWirelessPlaybackTarget()) { >+ if (m_isPlayingToWirelessTarget && !m_player->canPlayToWirelessPlaybackTarget()) { > INFO_LOG(LOGIDENTIFIER, "calling setShouldPlayToPlaybackTarget(false)"); > m_failedToPlayToWirelessTarget = true; > m_player->setShouldPlayToPlaybackTarget(false); > } >- >- if (pendingActions & CheckMediaState) >- updateMediaState(); > #endif >- >- if (pendingActions & MediaEngineUpdated) >- mediaEngineWasUpdated(); >- >- if (pendingActions & UpdatePlayState) >- updatePlayState(); > } > > MediaError* HTMLMediaElement::error() const >@@ -1281,7 +1203,7 @@ void HTMLMediaElement::prepareForLoad() > // 1 - Abort any already-running instance of the resource selection algorithm for this element. > // Perform the cleanup required for the resource load algorithm to run. > stopPeriodicTimers(); >- m_pendingActionTimer.stop(); >+ cancelPendingTasks(); > m_resourceSelectionTaskQueue.cancelAllTasks(); > // FIXME: Figure out appropriate place to reset LoadTextTrackResource if necessary and set m_pendingActionFlags to 0 here. > m_sentEndEvent = false; >@@ -2539,7 +2461,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) > logMediaLoadRequest(document().page(), m_player->engineDescription(), String(), true); > > #if ENABLE(WIRELESS_PLAYBACK_TARGET) >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > #endif > > m_mediaSession->clientCharacteristicsChanged(); >@@ -2958,9 +2880,9 @@ void HTMLMediaElement::seekWithTolerance(const MediaTime& inTime, const MediaTim > // 3 - If the element's seeking IDL attribute is true, then another instance of this algorithm is > // already running. Abort that other instance of the algorithm without waiting for the step that > // it is running to complete. >- if (m_seekTaskQueue.hasPendingTasks()) { >+ if (m_seekTaskQueue.hasPendingTask()) { > INFO_LOG(LOGIDENTIFIER, "cancelling pending seeks"); >- m_seekTaskQueue.cancelAllTasks(); >+ m_seekTaskQueue.cancelTask(); > if (m_pendingSeek) { > now = m_pendingSeek->now; > m_pendingSeek = nullptr; >@@ -2982,7 +2904,7 @@ void HTMLMediaElement::seekWithTolerance(const MediaTime& inTime, const MediaTim > m_pendingSeek = std::make_unique<PendingSeek>(now, time, negativeTolerance, positiveTolerance); > if (fromDOM) { > INFO_LOG(LOGIDENTIFIER, "enqueuing seek from ", now, " to ", time); >- m_seekTaskQueue.enqueueTask(std::bind(&HTMLMediaElement::seekTask, this)); >+ m_seekTaskQueue.scheduleTask(std::bind(&HTMLMediaElement::seekTask, this)); > } else > seekTask(); > >@@ -3739,7 +3661,7 @@ void HTMLMediaElement::setMuted(bool muted) > #endif > > #if ENABLE(WIRELESS_PLAYBACK_TARGET) >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > #endif > m_mediaSession->canProduceAudioChanged(); > } >@@ -3987,7 +3909,7 @@ void HTMLMediaElement::mediaPlayerDidAddTextTrack(InbandTextTrackPrivate& track) > // 7. Set the new text track's mode to the mode consistent with the user's preferences and the requirements of > // the relevant specification for the data. > // - This will happen in configureTextTracks() >- scheduleDelayedAction(ConfigureTextTracks); >+ scheduleConfigureTextTracks(); > > // 8. Add the new text track to the media element's list of text tracks. > // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent >@@ -4159,7 +4081,7 @@ void HTMLMediaElement::didAddTextTrack(HTMLTrackElement& trackElement) > // Do not schedule the track loading until parsing finishes so we don't start before all tracks > // in the markup have been added. > if (!m_parsingInProgress) >- scheduleDelayedAction(ConfigureTextTracks); >+ scheduleConfigureTextTracks(); > > if (hasMediaControls()) > mediaControls()->closedCaptionTracksChanged(); >@@ -4463,6 +4385,19 @@ void HTMLMediaElement::setSelectedTextTrack(TextTrack* trackToSelect) > captionPreferences.setCaptionDisplayMode(displayMode); > } > >+void HTMLMediaElement::scheduleConfigureTextTracks() >+{ >+ if (m_configureTextTracksTask.hasPendingTask()) >+ return; >+ >+ auto logSiteIdentifier = LOGIDENTIFIER; >+ ALWAYS_LOG(logSiteIdentifier, "task scheduled"); >+ m_configureTextTracksTask.scheduleTask([this, logSiteIdentifier] { >+ ALWAYS_LOG(logSiteIdentifier, "- lambda(), task fired"); >+ configureTextTracks(); >+ }); >+} >+ > void HTMLMediaElement::configureTextTracks() > { > TrackGroup captionAndSubtitleTracks(TrackGroup::CaptionsAndSubtitles); >@@ -4803,7 +4738,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*) > m_sentEndEvent = false; > } > >- updatePlayState(UpdateState::Asynchronously); >+ scheduleUpdatePlayState(); > endProcessingMediaPlayerCallback(); > } > >@@ -5002,6 +4937,19 @@ GraphicsDeviceAdapter* HTMLMediaElement::mediaPlayerGraphicsDeviceAdapter(const > > #endif > >+void HTMLMediaElement::scheduleMediaEngineWasUpdated() >+{ >+ if (m_mediaEngineUpdatedTask.hasPendingTask()) >+ return; >+ >+ auto logSiteIdentifier = LOGIDENTIFIER; >+ ALWAYS_LOG(logSiteIdentifier, "task scheduled"); >+ m_mediaEngineUpdatedTask.scheduleTask([this, logSiteIdentifier] { >+ ALWAYS_LOG(logSiteIdentifier, "- lambda(), task fired"); >+ mediaEngineWasUpdated(); >+ }); >+} >+ > void HTMLMediaElement::mediaEngineWasUpdated() > { > INFO_LOG(LOGIDENTIFIER); >@@ -5033,7 +4981,7 @@ void HTMLMediaElement::mediaEngineWasUpdated() > #endif > > #if ENABLE(WIRELESS_PLAYBACK_TARGET) >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > #endif > } > >@@ -5047,7 +4995,7 @@ void HTMLMediaElement::mediaPlayerEngineUpdated(MediaPlayer*) > > m_havePreparedToPlay = false; > >- scheduleDelayedAction(MediaEngineUpdated); >+ scheduleMediaEngineWasUpdated(); > } > > void HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) >@@ -5293,13 +5241,21 @@ void HTMLMediaElement::updateVolume() > #endif > } > >-void HTMLMediaElement::updatePlayState(UpdateState updateState) >+void HTMLMediaElement::scheduleUpdatePlayState() > { >- if (updateState == UpdateState::Asynchronously) { >- scheduleDelayedAction(UpdatePlayState); >+ if (m_updatePlayStateTask.hasPendingTask()) > return; >- } > >+ auto logSiteIdentifier = LOGIDENTIFIER; >+ ALWAYS_LOG(logSiteIdentifier, "task scheduled"); >+ m_updatePlayStateTask.scheduleTask([this, logSiteIdentifier] { >+ ALWAYS_LOG(logSiteIdentifier, "- lambda(), task fired"); >+ updatePlayState(); >+ }); >+} >+ >+void HTMLMediaElement::updatePlayState() >+{ > if (!m_player) > return; > >@@ -5404,14 +5360,14 @@ void HTMLMediaElement::setPlaying(bool playing) > #endif > > #if ENABLE(WIRELESS_PLAYBACK_TARGET) >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > #endif > } > > void HTMLMediaElement::setPausedInternal(bool b) > { > m_pausedInternal = b; >- updatePlayState(UpdateState::Asynchronously); >+ scheduleUpdatePlayState(); > } > > void HTMLMediaElement::stopPeriodicTimers() >@@ -5420,6 +5376,16 @@ void HTMLMediaElement::stopPeriodicTimers() > m_playbackProgressTimer.stop(); > } > >+void HTMLMediaElement::cancelPendingTasks() >+{ >+ m_loadMediaResourceTask.cancelTask(); >+ m_configureTextTracksTask.cancelTask(); >+ m_checkPlaybackTargetCompatablityTask.cancelTask(); >+ m_updateMediaStateTask.cancelTask(); >+ m_mediaEngineUpdatedTask.cancelTask(); >+ m_updatePlayStateTask.cancelTask(); >+} >+ > void HTMLMediaElement::userCancelledLoad() > { > INFO_LOG(LOGIDENTIFIER); >@@ -5436,7 +5402,7 @@ void HTMLMediaElement::userCancelledLoad() > // If the media data fetching process is aborted by the user: > > // 1 - The user agent should cancel the fetching process. >- clearMediaPlayer(EveryDelayedAction); >+ clearMediaPlayer(); > > // 2 - Set the error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORTED. > m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED); >@@ -5478,10 +5444,8 @@ void HTMLMediaElement::userCancelledLoad() > #endif > } > >-void HTMLMediaElement::clearMediaPlayer(DelayedActionType flags) >+void HTMLMediaElement::clearMediaPlayer() > { >- INFO_LOG(LOGIDENTIFIER, "flags = ", actionName(flags)); >- > #if ENABLE(MEDIA_STREAM) > if (!m_settingMediaStreamSrcObject) > m_mediaStreamSrcObject = nullptr; >@@ -5525,9 +5489,8 @@ void HTMLMediaElement::clearMediaPlayer(DelayedActionType flags) > schedulePlaybackControlsManagerUpdate(); > > stopPeriodicTimers(); >- m_pendingActionTimer.stop(); >+ cancelPendingTasks(); > >- clearFlags(m_pendingActionFlags, flags); > m_loadState = WaitingForSource; > > #if ENABLE(VIDEO_TRACK) >@@ -5581,17 +5544,32 @@ void HTMLMediaElement::stopWithoutDestroyingMediaPlayer() > updateSleepDisabling(); > } > >-void HTMLMediaElement::contextDestroyed() >+void HTMLMediaElement::closeTaskQueues() > { >+ m_loadMediaResourceTask.close(); >+ m_configureTextTracksTask.close(); >+ m_checkPlaybackTargetCompatablityTask.close(); >+ m_updateMediaStateTask.close(); >+ m_mediaEngineUpdatedTask.close(); >+ m_updatePlayStateTask.close(); >+ m_resumeTaskQueue.close(); >+ m_seekTaskQueue.close(); >+ m_playbackControlsManagerBehaviorRestrictionsQueue.close(); > m_seekTaskQueue.close(); > m_resumeTaskQueue.close(); >- m_shadowDOMTaskQueue.close(); > m_promiseTaskQueue.close(); > m_pauseAfterDetachedTaskQueue.close(); >+ m_resourceSelectionTaskQueue.close(); >+ m_visibilityChangeTaskQueue.close(); > #if ENABLE(ENCRYPTED_MEDIA) > m_encryptedMediaQueue.close(); > #endif >+ m_asyncEventQueue.close(); >+} > >+void HTMLMediaElement::contextDestroyed() >+{ >+ closeTaskQueues(); > m_pendingPlayPromises.clear(); > > ActiveDOMObject::contextDestroyed(); >@@ -5603,17 +5581,13 @@ void HTMLMediaElement::stop() > > Ref<HTMLMediaElement> protectedThis(*this); > stopWithoutDestroyingMediaPlayer(); >- >- m_asyncEventQueue.close(); >- m_promiseTaskQueue.close(); >- m_resourceSelectionTaskQueue.close(); >- m_resumeTaskQueue.cancelAllTasks(); >+ closeTaskQueues(); > > // Once an active DOM object has been stopped it can not be restarted, so we can deallocate > // the media player now. Note that userCancelledLoad will already called clearMediaPlayer > // if the media was not fully loaded, but we need the same cleanup if the file was completely > // loaded and calling it again won't cause any problems. >- clearMediaPlayer(EveryDelayedAction); >+ clearMediaPlayer(); > > m_mediaSession->stopSession(); > } >@@ -5623,7 +5597,7 @@ void HTMLMediaElement::suspend(ReasonForSuspension reason) > INFO_LOG(LOGIDENTIFIER); > Ref<HTMLMediaElement> protectedThis(*this); > >- m_resumeTaskQueue.cancelAllTasks(); >+ m_resumeTaskQueue.cancelTask(); > > switch (reason) { > case ReasonForSuspension::PageCache: >@@ -5667,13 +5641,13 @@ void HTMLMediaElement::resume() > > m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequirePageConsentToResumeMedia); > >- if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED && !m_resumeTaskQueue.hasPendingTasks()) { >+ if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED && !m_resumeTaskQueue.hasPendingTask()) { > // Restart the load if it was aborted in the middle by moving the document to the page cache. > // m_error is only left at MEDIA_ERR_ABORTED when the document becomes inactive (it is set to > // MEDIA_ERR_ABORTED while the abortEvent is being sent, but cleared immediately afterwards). > // This behavior is not specified but it seems like a sensible thing to do. > // As it is not safe to immedately start loading now, let's schedule a load. >- m_resumeTaskQueue.enqueueTask(std::bind(&HTMLMediaElement::prepareForLoad, this)); >+ m_resumeTaskQueue.scheduleTask(std::bind(&HTMLMediaElement::prepareForLoad, this)); > } > > updateRenderer(); >@@ -5764,7 +5738,7 @@ void HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPl > scheduleEvent(eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent); > m_mediaSession->isPlayingToWirelessPlaybackTargetChanged(m_isPlayingToWirelessTarget); > m_mediaSession->canProduceAudioChanged(); >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > updateSleepDisabling(); > } > >@@ -5772,7 +5746,7 @@ void HTMLMediaElement::dispatchEvent(Event& event) > { > if (event.type() == eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent) { > m_failedToPlayToWirelessTarget = false; >- scheduleDelayedAction(CheckPlaybackTargetCompatablity); >+ scheduleCheckPlaybackTargetCompatability(); > } > > DEBUG_LOG(LOGIDENTIFIER, "dispatching '", event.type(), "'"); >@@ -5813,7 +5787,7 @@ bool HTMLMediaElement::removeEventListener(const AtomicString& eventType, EventL > if (didRemoveLastAvailabilityChangedListener) { > m_hasPlaybackTargetAvailabilityListeners = false; > m_mediaSession->setHasPlaybackTargetAvailabilityListeners(false); >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > } > > return true; >@@ -5826,7 +5800,7 @@ void HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent() > auto event = WebKitPlaybackTargetAvailabilityEvent::create(eventNames().webkitplaybacktargetavailabilitychangedEvent, hasTargets); > event->setTarget(this); > m_asyncEventQueue.enqueueEvent(WTFMove(event)); >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > } > > void HTMLMediaElement::setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&& device) >@@ -6052,7 +6026,7 @@ void HTMLMediaElement::didBecomeFullscreenElement() > m_waitingToEnterFullscreen = false; > if (hasMediaControls()) > mediaControls()->enteredFullscreen(); >- updatePlayState(UpdateState::Asynchronously); >+ scheduleUpdatePlayState(); > } > > void HTMLMediaElement::willStopBeingFullscreenElement() >@@ -6522,11 +6496,11 @@ void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMod > } > > m_processingPreferenceChange = true; >- clearFlags(m_pendingActionFlags, ConfigureTextTracks); >+ m_configureTextTracksTask.cancelTask(); > if (mode == Immediately) > configureTextTracks(); > else >- scheduleDelayedAction(ConfigureTextTracks); >+ scheduleConfigureTextTracks(); > } > > #endif >@@ -7601,13 +7575,21 @@ bool HTMLMediaElement::processingUserGestureForMedia() const > } > > #if ENABLE(WIRELESS_PLAYBACK_TARGET) >-void HTMLMediaElement::updateMediaState(UpdateState updateState) >+void HTMLMediaElement::scheduleUpdateMediaState() > { >- if (updateState == UpdateState::Asynchronously) { >- scheduleDelayedAction(CheckMediaState); >+ if (m_updateMediaStateTask.hasPendingTask()) > return; >- } > >+ auto logSiteIdentifier = LOGIDENTIFIER; >+ ALWAYS_LOG(logSiteIdentifier, "task scheduled"); >+ m_updateMediaStateTask.scheduleTask([this, logSiteIdentifier] { >+ ALWAYS_LOG(logSiteIdentifier, "- lambda(), task fired"); >+ updateMediaState(); >+ }); >+} >+ >+void HTMLMediaElement::updateMediaState() >+{ > MediaProducer::MediaStateFlags state = mediaState(); > if (m_mediaState == state) > return; >@@ -7914,14 +7896,14 @@ void HTMLMediaElement::schedulePlaybackControlsManagerUpdate() > > void HTMLMediaElement::playbackControlsManagerBehaviorRestrictionsTimerFired() > { >- if (m_playbackControlsManagerBehaviorRestrictionsQueue.hasPendingTasks()) >+ if (m_playbackControlsManagerBehaviorRestrictionsQueue.hasPendingTask()) > return; > > if (!m_mediaSession->hasBehaviorRestriction(MediaElementSession::RequireUserGestureToControlControlsManager)) > return; > > RefPtr<HTMLMediaElement> protectedThis(this); >- m_playbackControlsManagerBehaviorRestrictionsQueue.enqueueTask([protectedThis] () { >+ m_playbackControlsManagerBehaviorRestrictionsQueue.scheduleTask([protectedThis] () { > MediaElementSession* mediaElementSession = protectedThis->m_mediaSession.get(); > if (protectedThis->isPlaying() || mediaElementSession->state() == PlatformMediaSession::Autoplaying || mediaElementSession->state() == PlatformMediaSession::Playing) > return; >diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h >index a78ecfd3196b9fdeabc510277fca764ee3dd6a72..880174ab03d060b508fc6ab5f94a03efa9c031ec 100644 >--- a/Source/WebCore/html/HTMLMediaElement.h >+++ b/Source/WebCore/html/HTMLMediaElement.h >@@ -30,8 +30,8 @@ > #include "ActiveDOMObject.h" > #include "ApplicationStateChangeListener.h" > #include "AutoplayEvent.h" >+#include "DeferrableTask.h" > #include "GenericEventQueue.h" >-#include "GenericTaskQueue.h" > #include "HTMLElement.h" > #include "HTMLMediaElementEnums.h" > #include "MediaCanStartListener.h" >@@ -185,8 +185,8 @@ public: > MediaPlayerEnums::VideoGravity videoFullscreenGravity() const { return m_videoFullscreenGravity; } > #endif > >- using HTMLMediaElementEnums::DelayedActionType; >- void scheduleDelayedAction(DelayedActionType); >+ void scheduleCheckPlaybackTargetCompatability(); >+ void checkPlaybackTargetCompatablity(); > void scheduleResolvePendingPlayPromises(); > void scheduleRejectPendingPlayPromises(Ref<DOMException>&&); > using PlayPromiseVector = Vector<DOMPromiseDeferred<void>>; >@@ -367,6 +367,7 @@ public: > > struct TrackGroup; > void configureTextTrackGroupForLanguage(const TrackGroup&) const; >+ void scheduleConfigureTextTracks(); > void configureTextTracks(); > void configureTextTrackGroup(const TrackGroup&); > >@@ -656,6 +657,8 @@ private: > void mediaPlayerRenderingModeChanged(MediaPlayer*) override; > bool mediaPlayerAcceleratedCompositingEnabled() override; > void mediaPlayerEngineUpdated(MediaPlayer*) override; >+ >+ void scheduleMediaEngineWasUpdated(); > void mediaEngineWasUpdated(); > > void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) override; >@@ -747,6 +750,8 @@ private: > void startPlaybackProgressTimer(); > void startProgressEventTimer(); > void stopPeriodicTimers(); >+ void cancelPendingTasks(); >+ void closeTaskQueues(); > > void seek(const MediaTime&); > void seekInternal(const MediaTime&); >@@ -764,7 +769,7 @@ private: > void scheduleNextSourceChild(); > void loadNextSourceChild(); > void userCancelledLoad(); >- void clearMediaPlayer(DelayedActionType flags); >+ void clearMediaPlayer(); > bool havePotentialSourceChild(); > void noneSupported(); > void cancelPendingEventsAndCallbacks(); >@@ -797,9 +802,9 @@ private: > void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; } > void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; } > >- enum class UpdateState { Asynchronously, Synchronously }; >+ void scheduleUpdatePlayState(); >+ void updatePlayState(); > >- void updatePlayState(UpdateState updateState = UpdateState::Synchronously); > void updateVolume(); > void setPlaying(bool); > bool potentiallyPlaying() const; >@@ -895,7 +900,8 @@ private: > void prepareForDocumentSuspension() final; > void resumeFromDocumentSuspension() final; > >- void updateMediaState(UpdateState updateState = UpdateState::Synchronously); >+ void scheduleUpdateMediaState(); >+ void updateMediaState(); > bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; } > #endif > >@@ -929,18 +935,22 @@ private: > const Logger& mediaPlayerLogger() final { return logger(); } > #endif > >- Timer m_pendingActionTimer; > Timer m_progressEventTimer; > Timer m_playbackProgressTimer; > Timer m_scanTimer; > Timer m_playbackControlsManagerBehaviorRestrictionsTimer; > Timer m_seekToPlaybackPositionEndedTimer; >- GenericTaskQueue<Timer> m_resumeTaskQueue; >- GenericTaskQueue<Timer> m_seekTaskQueue; >- GenericTaskQueue<Timer> m_shadowDOMTaskQueue; >+ DeferrableTask<Timer> m_loadMediaResourceTask; >+ DeferrableTask<Timer> m_configureTextTracksTask; >+ DeferrableTask<Timer> m_checkPlaybackTargetCompatablityTask; >+ DeferrableTask<Timer> m_updateMediaStateTask; >+ DeferrableTask<Timer> m_mediaEngineUpdatedTask; >+ DeferrableTask<Timer> m_updatePlayStateTask; >+ DeferrableTask<Timer> m_resumeTaskQueue; >+ DeferrableTask<Timer> m_seekTaskQueue; >+ DeferrableTask<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue; > GenericTaskQueue<Timer> m_promiseTaskQueue; > GenericTaskQueue<Timer> m_pauseAfterDetachedTaskQueue; >- GenericTaskQueue<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue; > GenericTaskQueue<Timer> m_resourceSelectionTaskQueue; > GenericTaskQueue<Timer> m_visibilityChangeTaskQueue; > RefPtr<TimeRanges> m_playedTimeRanges; >diff --git a/Source/WebCore/html/HTMLMediaElementEnums.h b/Source/WebCore/html/HTMLMediaElementEnums.h >index cfa72fa73cdac711adf5498dab8c84f3c3019f4f..0d8a93dcfeb81aabc3b9bda477e9b2c09dac5e0e 100644 >--- a/Source/WebCore/html/HTMLMediaElementEnums.h >+++ b/Source/WebCore/html/HTMLMediaElementEnums.h >@@ -33,19 +33,6 @@ class HTMLMediaElementEnums : public MediaPlayerEnums { > public: > using MediaPlayerEnums::VideoFullscreenMode; > >- enum DelayedActionType { >- LoadMediaResource = 1 << 0, >- ConfigureTextTracks = 1 << 1, >- TextTrackChangesNotification = 1 << 2, >- ConfigureTextTrackDisplay = 1 << 3, >- CheckPlaybackTargetCompatablity = 1 << 4, >- CheckMediaState = 1 << 5, >- MediaEngineUpdated = 1 << 6, >- UpdatePlayState = 1 << 7, >- >- EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay | CheckPlaybackTargetCompatablity | CheckMediaState | UpdatePlayState, >- }; >- > enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA }; > enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE }; > enum TextTrackVisibilityCheckType { CheckTextTrackVisibility, AssumeTextTrackVisibilityChanged }; >diff --git a/Source/WebCore/platform/DeferrableTask.h b/Source/WebCore/platform/DeferrableTask.h >new file mode 100644 >index 0000000000000000000000000000000000000000..21c21166e3d805a01bc549f857e0f35c5eb1afad >--- /dev/null >+++ b/Source/WebCore/platform/DeferrableTask.h >@@ -0,0 +1,83 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "GenericTaskQueue.h" >+ >+namespace WebCore { >+ >+template <typename T> >+class DeferrableTask : public CanMakeWeakPtr<DeferrableTask<T>> { >+public: >+ DeferrableTask() >+ : m_dispatcher() >+ { >+ } >+ >+ DeferrableTask(T& t) >+ : m_dispatcher(t) >+ { >+ } >+ >+ typedef WTF::Function<void ()> TaskFunction; >+ >+ void scheduleTask(TaskFunction&& task) >+ { >+ if (m_isClosed) >+ return; >+ >+ cancelTask(); >+ >+ m_pendingTask = true; >+ m_dispatcher.postTask([weakThis = makeWeakPtr(*this), task = WTFMove(task)] { >+ if (!weakThis) >+ return; >+ ASSERT(weakThis->m_pendingTask); >+ weakThis->m_pendingTask = false; >+ task(); >+ }); >+ } >+ >+ void close() >+ { >+ cancelTask(); >+ m_isClosed = true; >+ } >+ >+ void cancelTask() >+ { >+ CanMakeWeakPtr<DeferrableTask<T>>::weakPtrFactory().revokeAll(); >+ m_pendingTask = false; >+ } >+ bool hasPendingTask() const { return m_pendingTask; } >+ >+private: >+ TaskDispatcher<T> m_dispatcher; >+ bool m_pendingTask { false }; >+ bool m_isClosed { false }; >+}; >+ >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188208
:
346216
|
346634
|
346639
|
346640
|
346643
|
352470