WebKit Bugzilla
Attachment 346216 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-20180731162005.patch (text/plain), 35.05 KB, created by
Jer Noble
on 2018-07-31 16:20:06 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jer Noble
Created:
2018-07-31 16:20:06 PDT
Size:
35.05 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..80d55128e76aeb09c7ddfe5c1ec481f415b68cb3 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -13252,6 +13252,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 +24452,7 @@ > 37C738F21EDBDE87003F2B0B /* DateTimeChooserClient.h */, > 45FEA5CD156DDE8C00654101 /* Decimal.cpp */, > 45FEA5CE156DDE8C00654101 /* Decimal.h */, >+ CD83D35A211110820076E11C /* DeferrableTask.h */, > A79546420B5C4CB4007B438F /* DragData.cpp */, > A7B6E69D0B291A9600D0529F /* DragData.h */, > A7CFB3CF0B7ED10A0070C32D /* DragImage.cpp */, >diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp >index 8fbcb82eb22a473adb2dabddd7ce5a7ee9e8d6ef..6029a1b8c03fe2b61166cb43d85b56b35367fce8 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,27 @@ 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 >+ ALWAYS_LOG(LOGIDENTIFIER, "task scheduled"); >+ m_checkPlaybackTargetCompatablityTask.scheduleTask([this] { >+ ALWAYS_LOG(LOGIDENTIFIER, "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 +1202,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 +2460,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 +2879,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 +2903,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 +3660,7 @@ void HTMLMediaElement::setMuted(bool muted) > #endif > > #if ENABLE(WIRELESS_PLAYBACK_TARGET) >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > #endif > m_mediaSession->canProduceAudioChanged(); > } >@@ -3987,7 +3908,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 +4080,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 +4384,18 @@ void HTMLMediaElement::setSelectedTextTrack(TextTrack* trackToSelect) > captionPreferences.setCaptionDisplayMode(displayMode); > } > >+void HTMLMediaElement::scheduleConfigureTextTracks() >+{ >+ if (m_configureTextTracksTask.hasPendingTask()) >+ return; >+ >+ ALWAYS_LOG(LOGIDENTIFIER, "task scheduled"); >+ m_configureTextTracksTask.scheduleTask([this] { >+ ALWAYS_LOG(LOGIDENTIFIER, "task fired"); >+ configureTextTracks(); >+ }); >+} >+ > void HTMLMediaElement::configureTextTracks() > { > TrackGroup captionAndSubtitleTracks(TrackGroup::CaptionsAndSubtitles); >@@ -4803,7 +4736,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*) > m_sentEndEvent = false; > } > >- updatePlayState(UpdateState::Asynchronously); >+ scheduleUpdatePlayState(); > endProcessingMediaPlayerCallback(); > } > >@@ -5002,6 +4935,18 @@ GraphicsDeviceAdapter* HTMLMediaElement::mediaPlayerGraphicsDeviceAdapter(const > > #endif > >+void HTMLMediaElement::scheduleMediaEngineWasUpdated() >+{ >+ if (m_mediaEngineUpdatedTask.hasPendingTask()) >+ return; >+ >+ ALWAYS_LOG(LOGIDENTIFIER, "task scheduled"); >+ m_mediaEngineUpdatedTask.scheduleTask([this] { >+ ALWAYS_LOG(LOGIDENTIFIER, "task fired"); >+ mediaEngineWasUpdated(); >+ }); >+} >+ > void HTMLMediaElement::mediaEngineWasUpdated() > { > INFO_LOG(LOGIDENTIFIER); >@@ -5033,7 +4978,7 @@ void HTMLMediaElement::mediaEngineWasUpdated() > #endif > > #if ENABLE(WIRELESS_PLAYBACK_TARGET) >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > #endif > } > >@@ -5047,7 +4992,7 @@ void HTMLMediaElement::mediaPlayerEngineUpdated(MediaPlayer*) > > m_havePreparedToPlay = false; > >- scheduleDelayedAction(MediaEngineUpdated); >+ scheduleMediaEngineWasUpdated(); > } > > void HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) >@@ -5293,13 +5238,20 @@ void HTMLMediaElement::updateVolume() > #endif > } > >-void HTMLMediaElement::updatePlayState(UpdateState updateState) >+void HTMLMediaElement::scheduleUpdatePlayState() > { >- if (updateState == UpdateState::Asynchronously) { >- scheduleDelayedAction(UpdatePlayState); >+ if (m_updatePlayStateTask.hasPendingTask()) > return; >- } > >+ ALWAYS_LOG(LOGIDENTIFIER, "task scheduled"); >+ m_updatePlayStateTask.scheduleTask([this] { >+ ALWAYS_LOG(LOGIDENTIFIER, "task fired"); >+ updatePlayState(); >+ }); >+} >+ >+void HTMLMediaElement::updatePlayState() >+{ > if (!m_player) > return; > >@@ -5404,14 +5356,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 +5372,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 +5398,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 +5440,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 +5485,8 @@ void HTMLMediaElement::clearMediaPlayer(DelayedActionType flags) > schedulePlaybackControlsManagerUpdate(); > > stopPeriodicTimers(); >- m_pendingActionTimer.stop(); >+ cancelPendingTasks(); > >- clearFlags(m_pendingActionFlags, flags); > m_loadState = WaitingForSource; > > #if ENABLE(VIDEO_TRACK) >@@ -5583,9 +5542,17 @@ void HTMLMediaElement::stopWithoutDestroyingMediaPlayer() > > void HTMLMediaElement::contextDestroyed() > { >+ 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(); > #if ENABLE(ENCRYPTED_MEDIA) >@@ -5603,17 +5570,25 @@ void HTMLMediaElement::stop() > > Ref<HTMLMediaElement> protectedThis(*this); > stopWithoutDestroyingMediaPlayer(); >- >+ 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_asyncEventQueue.close(); > m_promiseTaskQueue.close(); > m_resourceSelectionTaskQueue.close(); >- m_resumeTaskQueue.cancelAllTasks(); >+ m_resumeTaskQueue.cancelTask(); > > // 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 +5598,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 +5642,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 +5739,7 @@ void HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPl > scheduleEvent(eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent); > m_mediaSession->isPlayingToWirelessPlaybackTargetChanged(m_isPlayingToWirelessTarget); > m_mediaSession->canProduceAudioChanged(); >- updateMediaState(UpdateState::Asynchronously); >+ scheduleUpdateMediaState(); > updateSleepDisabling(); > } > >@@ -5772,7 +5747,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 +5788,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 +5801,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 +6027,7 @@ void HTMLMediaElement::didBecomeFullscreenElement() > m_waitingToEnterFullscreen = false; > if (hasMediaControls()) > mediaControls()->enteredFullscreen(); >- updatePlayState(UpdateState::Asynchronously); >+ scheduleUpdatePlayState(); > } > > void HTMLMediaElement::willStopBeingFullscreenElement() >@@ -6522,11 +6497,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 +7576,20 @@ 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; >- } > >+ ALWAYS_LOG(LOGIDENTIFIER, "task scheduled"); >+ m_updateMediaStateTask.scheduleTask([this] { >+ ALWAYS_LOG(LOGIDENTIFIER, "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..c2b6d4b0941493c7334776fb01edb442445cfc2f 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,7 @@ private: > void startPlaybackProgressTimer(); > void startProgressEventTimer(); > void stopPeriodicTimers(); >+ void cancelPendingTasks(); > > void seek(const MediaTime&); > void seekInternal(const MediaTime&); >@@ -764,7 +768,7 @@ private: > void scheduleNextSourceChild(); > void loadNextSourceChild(); > void userCancelledLoad(); >- void clearMediaPlayer(DelayedActionType flags); >+ void clearMediaPlayer(); > bool havePotentialSourceChild(); > void noneSupported(); > void cancelPendingEventsAndCallbacks(); >@@ -797,9 +801,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 +899,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 +934,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..4e754f319e0802273ab72be8892d137a2b34a759 >--- /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<GenericTaskQueue<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