Changeset 278392 in webkit
- Timestamp:
- Jun 2, 2021, 6:54:35 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 19 edited
-
ChangeLog (modified) (1 diff)
-
Headers.cmake (modified) (1 diff)
-
Modules/remoteplayback/RemotePlayback.cpp (modified) (1 diff)
-
Modules/remoteplayback/RemotePlayback.h (modified) (1 diff)
-
animation/DocumentTimelinesController.cpp (modified) (1 diff)
-
animation/DocumentTimelinesController.h (modified) (1 diff)
-
dom/FullscreenManager.cpp (modified) (1 diff)
-
dom/FullscreenManager.h (modified) (1 diff)
-
dom/GenericEventQueue.cpp (modified) (6 diffs)
-
dom/GenericEventQueue.h (modified) (4 diffs)
-
html/HTMLMediaElement.cpp (modified) (19 diffs)
-
html/HTMLMediaElement.h (modified) (3 diffs)
-
html/shadow/MediaControlTextTrackContainerElement.cpp (modified) (1 diff)
-
html/shadow/MediaControlTextTrackContainerElement.h (modified) (1 diff)
-
platform/DeferrableTask.h (modified) (3 diffs)
-
platform/GenericTaskQueue.h (modified) (4 diffs)
-
platform/RemoteCommandListener.cpp (modified) (1 diff)
-
platform/graphics/gpu/cocoa/GPUBufferMetal.mm (modified) (1 diff)
-
platform/graphics/gpu/cocoa/GPUQueueMetal.mm (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r278391 r278392 1 2021-06-02 Chris Dumez <cdumez@apple.com> 2 3 Port media code to the HTML event loop 4 https://bugs.webkit.org/show_bug.cgi?id=226543 5 6 Reviewed by Ryosuke Niwa. 7 8 Port media code to the HTML event loop so that event processing order is consistent 9 with non-media related events. To avoid having a very large patch, I made the following 10 changes: 11 - Update MainThreadGenericEventQueue to be based on the HTML event loop instead of a 12 global Timer. 13 - Introduce a EventLoopDeferrableTask which has the same API as DeferrableTask<Timer> but 14 uses the HTML event loop instead of a global Timer. Port media code to use 15 EventLoopDeferrableTask instead of DeferrableTask. 16 - Introduce an EventLoopTaskQueue which has the same API as GenericTaskQueue<Timer> 17 but uses the HTML event loop instead of a global Timer. Port media code to use 18 EventLoopTaskQueue instead of GenericTaskQueue<Timer>. 19 20 This effectively ports our entire media code to the HTML event loop. It allows new 21 media code to use the HTML event loop *directly* without fear of ordering issues. It also 22 allows us to refactor existing media code to use the HTML event loop *directly* when possible, 23 in an incremental fashion, without causing ordering issues. 24 25 * Headers.cmake: 26 * Modules/remoteplayback/RemotePlayback.cpp: 27 (WebCore::RemotePlayback::RemotePlayback): 28 * Modules/remoteplayback/RemotePlayback.h: 29 * animation/DocumentTimelinesController.cpp: 30 (WebCore::DocumentTimelinesController::DocumentTimelinesController): 31 * animation/DocumentTimelinesController.h: 32 * dom/FullscreenManager.cpp: 33 * dom/FullscreenManager.h: 34 * dom/GenericEventQueue.cpp: 35 (WebCore::MainThreadGenericEventQueue::MainThreadGenericEventQueue): 36 (WebCore::MainThreadGenericEventQueue::enqueueEvent): 37 (WebCore::MainThreadGenericEventQueue::close): 38 (WebCore::MainThreadGenericEventQueue::cancelAllEvents): 39 (WebCore::MainThreadGenericEventQueue::hasPendingEventsOfType const): 40 * dom/GenericEventQueue.h: 41 * html/HTMLMediaElement.cpp: 42 (WebCore::HTMLMediaElement::HTMLMediaElement): 43 * html/HTMLMediaElement.h: 44 * html/shadow/MediaControlTextTrackContainerElement.cpp: 45 (WebCore::MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement): 46 * html/shadow/MediaControlTextTrackContainerElement.h: 47 * platform/DeferrableTask.h: 48 (WebCore::DeferrableTaskBase::close): 49 (WebCore::DeferrableTaskBase::cancelTask): 50 (WebCore::DeferrableTaskBase::hasPendingTask const): 51 (WebCore::DeferrableTaskBase::isClosed const): 52 (WebCore::DeferrableTaskBase::setHasPendingTask): 53 * platform/GenericTaskQueue.h: 54 (WebCore::GenericTaskQueueBase::hasPendingTasks const): 55 (WebCore::GenericTaskQueueBase::isClosed const): 56 (WebCore::GenericTaskQueueBase::close): 57 (WebCore::GenericTaskQueueBase::cancelAllTasks): 58 (WebCore::GenericTaskQueueBase::incrementPendingTasks): 59 (WebCore::GenericTaskQueueBase::decremementPendingTasks): 60 1 61 2021-06-02 Alex Christensen <achristensen@webkit.org> 2 62 -
trunk/Source/WebCore/Headers.cmake
r278391 r278392 462 462 dom/EventListenerMap.h 463 463 dom/EventListenerOptions.h 464 dom/EventLoop.h 464 465 dom/EventModifierInit.h 465 466 dom/EventNames.h -
trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.cpp
r278253 r278392 52 52 , m_mediaElement(makeWeakPtr(element)) 53 53 , m_eventQueue(MainThreadGenericEventQueue::create(*this)) 54 , m_taskQueue(element.scriptExecutionContext()) 54 55 { 55 56 suspendIfNeeded(); -
trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.h
r278253 r278392 102 102 103 103 UniqueRef<MainThreadGenericEventQueue> m_eventQueue; 104 GenericTaskQueue<Timer>m_taskQueue;104 EventLoopTaskQueue m_taskQueue; 105 105 }; 106 106 -
trunk/Source/WebCore/animation/DocumentTimelinesController.cpp
r278253 r278392 44 44 45 45 DocumentTimelinesController::DocumentTimelinesController(Document& document) 46 : m_document(document) 46 : m_currentTimeClearingTaskQueue(&document) 47 , m_document(document) 47 48 { 48 49 if (auto* page = document.page()) { -
trunk/Source/WebCore/animation/DocumentTimelinesController.h
r278253 r278392 68 68 69 69 WeakHashSet<DocumentTimeline> m_timelines; 70 GenericTaskQueue<Timer>m_currentTimeClearingTaskQueue;70 EventLoopTaskQueue m_currentTimeClearingTaskQueue; 71 71 Document& m_document; 72 72 Markable<Seconds, Seconds::MarkableTraits> m_cachedCurrentTime; -
trunk/Source/WebCore/dom/FullscreenManager.cpp
r274588 r278392 49 49 FullscreenManager::FullscreenManager(Document& document) 50 50 : m_document { document } 51 , m_fullscreenTaskQueue { &document } 51 52 #if !RELEASE_LOG_DISABLED 52 53 , m_logIdentifier(LoggerHelper::uniqueLogIdentifier()) -
trunk/Source/WebCore/dom/FullscreenManager.h
r276880 r278392 120 120 Vector<RefPtr<Element>> m_fullscreenElementStack; 121 121 WeakPtr<RenderFullScreen> m_fullscreenRenderer { nullptr }; 122 GenericTaskQueue<Timer>m_fullscreenTaskQueue;122 EventLoopTaskQueue m_fullscreenTaskQueue; 123 123 Deque<RefPtr<Node>> m_fullscreenChangeEventTargetQueue; 124 124 Deque<RefPtr<Node>> m_fullscreenErrorEventTargetQueue; -
trunk/Source/WebCore/dom/GenericEventQueue.cpp
r269321 r278392 29 29 #include "Document.h" 30 30 #include "Event.h" 31 #include "EventLoop.h" 31 32 #include "EventTarget.h" 32 33 #include "Node.h" 33 34 #include "ScriptExecutionContext.h" 34 35 #include "Timer.h" 36 #include <wtf/Algorithms.h> 35 37 #include <wtf/MainThread.h> 36 38 #include <wtf/SetForScope.h> … … 41 43 : ActiveDOMObject(owner.scriptExecutionContext()) 42 44 , m_owner(owner) 43 , m_taskQueue(makeUniqueRef<GenericTaskQueue<Timer>>())44 45 { 45 46 } … … 47 48 void MainThreadGenericEventQueue::enqueueEvent(RefPtr<Event>&& event) 48 49 { 49 if (m_isClosed )50 if (m_isClosed || !scriptExecutionContext()) 50 51 return; 51 52 … … 55 56 m_pendingEvents.append(WTFMove(event)); 56 57 57 if (isSuspendedOrPausedByClient())58 return;59 60 m_taskQueue->enqueueTask(std::bind(&MainThreadGenericEventQueue::dispatchOneEvent, this));58 scriptExecutionContext()->eventLoop().queueTask(TaskSource::MediaElement, [weakThis = makeWeakPtr(*this)] { 59 if (weakThis) 60 weakThis->dispatchOneEvent(); 61 }); 61 62 } 62 63 … … 79 80 { 80 81 m_isClosed = true; 81 82 m_taskQueue->close(); 83 m_pendingEvents.clear(); 82 cancelAllEvents(); 84 83 } 85 84 86 85 void MainThreadGenericEventQueue::cancelAllEvents() 87 86 { 88 m_taskQueue->cancelAllTasks();87 weakPtrFactory().revokeAll(); 89 88 m_pendingEvents.clear(); 90 89 } … … 97 96 bool MainThreadGenericEventQueue::hasPendingEventsOfType(const AtomString& type) const 98 97 { 99 for (auto& event : m_pendingEvents) { 100 if (event->type() == type) 101 return true; 102 } 103 104 return false; 105 } 106 107 void MainThreadGenericEventQueue::setPaused(bool shouldPause) 108 { 109 if (m_isPausedByClient == shouldPause) 110 return; 111 112 m_isPausedByClient = shouldPause; 113 if (shouldPause) 114 m_taskQueue->cancelAllTasks(); 115 else 116 rescheduleAllEventsIfNeeded(); 117 } 118 119 void MainThreadGenericEventQueue::suspend(ReasonForSuspension) 120 { 121 if (m_isSuspended) 122 return; 123 124 m_isSuspended = true; 125 m_taskQueue->cancelAllTasks(); 126 } 127 128 void MainThreadGenericEventQueue::resume() 129 { 130 if (!m_isSuspended) 131 return; 132 133 m_isSuspended = false; 134 rescheduleAllEventsIfNeeded(); 135 } 136 137 void MainThreadGenericEventQueue::rescheduleAllEventsIfNeeded() 138 { 139 if (isSuspendedOrPausedByClient()) 140 return; 141 142 for (unsigned i = 0; i < m_pendingEvents.size(); ++i) 143 m_taskQueue->enqueueTask(std::bind(&MainThreadGenericEventQueue::dispatchOneEvent, this)); 98 return WTF::anyOf(m_pendingEvents, [&](auto& event) { return event->type() == type; }); 144 99 } 145 100 -
trunk/Source/WebCore/dom/GenericEventQueue.h
r259299 r278392 27 27 28 28 #include "ActiveDOMObject.h" 29 #include "GenericTaskQueue.h"30 29 #include <wtf/Deque.h> 31 30 #include <wtf/Forward.h> 32 31 #include <wtf/RefPtr.h> 33 32 #include <wtf/UniqueRef.h> 33 #include <wtf/WeakPtr.h> 34 34 35 35 namespace WebCore { … … 37 37 class Event; 38 38 class EventTarget; 39 class Timer;40 39 class ScriptExecutionContext; 41 40 42 // All instances of MainThreadGenericEventQueue use a shared Timer for dispatching events.43 41 // FIXME: We should port call sites to the HTML event loop and remove this class. 44 class MainThreadGenericEventQueue : public ActiveDOMObject {42 class MainThreadGenericEventQueue : public ActiveDOMObject, public CanMakeWeakPtr<MainThreadGenericEventQueue> { 45 43 WTF_MAKE_FAST_ALLOCATED; 46 44 public: … … 52 50 void cancelAllEvents(); 53 51 bool hasPendingEventsOfType(const AtomString&) const; 54 55 void setPaused(bool);56 57 bool isSuspended() const { return m_isSuspended; }58 52 59 53 bool hasPendingActivity() const; … … 67 61 const char* activeDOMObjectName() const final; 68 62 void stop() final; 69 void suspend(ReasonForSuspension) final;70 void resume() final;71 72 void rescheduleAllEventsIfNeeded();73 bool isSuspendedOrPausedByClient() const { return m_isSuspended || m_isPausedByClient; }74 63 75 64 EventTarget& m_owner; 76 UniqueRef<GenericTaskQueue<Timer>> m_taskQueue;77 65 Deque<RefPtr<Event>> m_pendingEvents; 78 66 bool m_isClosed { false }; 79 bool m_isPausedByClient { false };80 bool m_isSuspended { false };81 67 bool m_isFiringEvent { false }; 82 68 }; -
trunk/Source/WebCore/html/HTMLMediaElement.cpp
r278359 r278392 395 395 , m_playbackControlsManagerBehaviorRestrictionsTimer(*this, &HTMLMediaElement::playbackControlsManagerBehaviorRestrictionsTimerFired) 396 396 , m_seekToPlaybackPositionEndedTimer(*this, &HTMLMediaElement::seekToPlaybackPositionEndedTimerFired) 397 , m_configureTextTracksTask(&document) 398 , m_checkPlaybackTargetCompatibilityTask(&document) 399 , m_updateMediaStateTask(&document) 400 , m_mediaEngineUpdatedTask(&document) 397 401 , m_updatePlayStateTask(*this) 402 , m_resumeTask(&document) 403 , m_seekTask(&document) 404 , m_playbackControlsManagerBehaviorRestrictionsTask(&document) 405 , m_bufferedTimeRangesChangedTask(&document) 406 , m_promiseTaskQueue(&document) 407 , m_pauseAfterDetachedTaskQueue(&document) 408 , m_resourceSelectionTaskQueue(&document) 409 , m_visibilityChangeTaskQueue(&document) 410 , m_fullscreenTaskQueue(&document) 411 , m_playbackTargetIsWirelessQueue(&document) 398 412 , m_asyncEventQueue(MainThreadGenericEventQueue::create(*this)) 399 413 , m_lastTimeUpdateEventMovieTime(MediaTime::positiveInfiniteTime()) … … 435 449 , m_shouldAudioPlaybackRequireUserGesture(document.topDocument().audioPlaybackRequiresUserGesture() && !processingUserGestureForMedia()) 436 450 , m_shouldVideoPlaybackRequireUserGesture(document.topDocument().videoPlaybackRequiresUserGesture() && !processingUserGestureForMedia()) 451 #if ENABLE(ENCRYPTED_MEDIA) 452 , m_encryptedMediaQueue(&document) 453 #endif 437 454 #if ENABLE(WIRELESS_PLAYBACK_TARGET) 438 455 , m_remote(RemotePlayback::create(*this)) … … 568 585 m_isolatedWorld->clearWrappers(); 569 586 570 m_seekTask Queue.close();571 m_resumeTask Queue.close();587 m_seekTask.close(); 588 m_resumeTask.close(); 572 589 m_promiseTaskQueue.close(); 573 590 m_pauseAfterDetachedTaskQueue.close(); 574 m_playbackControlsManagerBehaviorRestrictions Queue.close();591 m_playbackControlsManagerBehaviorRestrictionsTask.close(); 575 592 m_resourceSelectionTaskQueue.close(); 576 593 m_visibilityChangeTaskQueue.close(); … … 981 998 void HTMLMediaElement::scheduleCheckPlaybackTargetCompatability() 982 999 { 983 if (m_checkPlaybackTargetCompat ablityTask.hasPendingTask())1000 if (m_checkPlaybackTargetCompatibilityTask.isPending()) 984 1001 return; 985 1002 986 1003 ALWAYS_LOG(LOGIDENTIFIER); 987 m_checkPlaybackTargetCompat ablityTask.scheduleTask([this] {988 checkPlaybackTargetCompat ablity();1004 m_checkPlaybackTargetCompatibilityTask.scheduleTask([this] { 1005 checkPlaybackTargetCompatibility(); 989 1006 }); 990 1007 } 991 1008 992 void HTMLMediaElement::checkPlaybackTargetCompat ablity()1009 void HTMLMediaElement::checkPlaybackTargetCompatibility() 993 1010 { 994 1011 #if ENABLE(WIRELESS_PLAYBACK_TARGET) … … 2958 2975 // already running. Abort that other instance of the algorithm without waiting for the step that 2959 2976 // it is running to complete. 2960 if (m_seekTask Queue.hasPendingTask()) {2977 if (m_seekTask.isPending()) { 2961 2978 INFO_LOG(LOGIDENTIFIER, "cancelling pending seeks"); 2962 m_seekTask Queue.cancelTask();2979 m_seekTask.cancelTask(); 2963 2980 if (m_pendingSeek) { 2964 2981 now = m_pendingSeek->now; … … 2982 2999 if (fromDOM) { 2983 3000 INFO_LOG(LOGIDENTIFIER, "enqueuing seek from ", now, " to ", time); 2984 m_seekTask Queue.scheduleTask(std::bind(&HTMLMediaElement::seekTask, this));3001 m_seekTask.scheduleTask(std::bind(&HTMLMediaElement::seekTask, this)); 2985 3002 } else 2986 3003 seekTask(); … … 3694 3711 m_volume = volume; 3695 3712 3696 if (m_volumeRevertTaskQueue. hasPendingTask())3713 if (m_volumeRevertTaskQueue.isPending()) 3697 3714 return { }; 3698 3715 … … 4482 4499 void HTMLMediaElement::scheduleConfigureTextTracks() 4483 4500 { 4484 if (m_configureTextTracksTask. hasPendingTask())4501 if (m_configureTextTracksTask.isPending()) 4485 4502 return; 4486 4503 … … 5030 5047 void HTMLMediaElement::scheduleMediaEngineWasUpdated() 5031 5048 { 5032 if (m_mediaEngineUpdatedTask. hasPendingTask())5049 if (m_mediaEngineUpdatedTask.isPending()) 5033 5050 return; 5034 5051 … … 5323 5340 void HTMLMediaElement::scheduleUpdatePlayState() 5324 5341 { 5325 if (m_updatePlayStateTask. hasPendingTask())5342 if (m_updatePlayStateTask.isPending()) 5326 5343 return; 5327 5344 … … 5461 5478 { 5462 5479 m_configureTextTracksTask.cancelTask(); 5463 m_checkPlaybackTargetCompat ablityTask.cancelTask();5480 m_checkPlaybackTargetCompatibilityTask.cancelTask(); 5464 5481 m_updateMediaStateTask.cancelTask(); 5465 5482 m_mediaEngineUpdatedTask.cancelTask(); … … 5623 5640 { 5624 5641 m_configureTextTracksTask.close(); 5625 m_checkPlaybackTargetCompat ablityTask.close();5642 m_checkPlaybackTargetCompatibilityTask.close(); 5626 5643 m_updateMediaStateTask.close(); 5627 5644 m_mediaEngineUpdatedTask.close(); 5628 5645 m_updatePlayStateTask.close(); 5629 m_resumeTask Queue.close();5630 m_seekTask Queue.close();5631 m_playbackControlsManagerBehaviorRestrictions Queue.close();5632 m_seekTask Queue.close();5633 m_resumeTask Queue.close();5646 m_resumeTask.close(); 5647 m_seekTask.close(); 5648 m_playbackControlsManagerBehaviorRestrictionsTask.close(); 5649 m_seekTask.close(); 5650 m_resumeTask.close(); 5634 5651 m_promiseTaskQueue.close(); 5635 5652 m_pauseAfterDetachedTaskQueue.close(); … … 5676 5693 Ref<HTMLMediaElement> protectedThis(*this); 5677 5694 5678 m_resumeTask Queue.cancelTask();5695 m_resumeTask.cancelTask(); 5679 5696 5680 5697 switch (reason) { … … 5709 5726 } 5710 5727 5711 if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED && !m_resumeTask Queue.hasPendingTask()) {5728 if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED && !m_resumeTask.isPending()) { 5712 5729 // Restart the load if it was aborted in the middle by moving the document to the back/forward cache. 5713 5730 // m_error is only left at MEDIA_ERR_ABORTED when the document becomes inactive (it is set to … … 5715 5732 // This behavior is not specified but it seems like a sensible thing to do. 5716 5733 // As it is not safe to immedately start loading now, let's schedule a load. 5717 m_resumeTask Queue.scheduleTask(std::bind(&HTMLMediaElement::prepareForLoad, this));5734 m_resumeTask.scheduleTask(std::bind(&HTMLMediaElement::prepareForLoad, this)); 5718 5735 } 5719 5736 … … 7138 7155 void HTMLMediaElement::mediaPlayerBufferedTimeRangesChanged() 7139 7156 { 7140 if (!m_textTracks || m_bufferedTimeRangesChanged Queue.hasPendingTask())7157 if (!m_textTracks || m_bufferedTimeRangesChangedTask.isPending()) 7141 7158 return; 7142 7159 7143 7160 auto logSiteIdentifier = LOGIDENTIFIER; 7144 7161 ALWAYS_LOG(logSiteIdentifier, "task scheduled"); 7145 m_bufferedTimeRangesChanged Queue.scheduleTask([this, logSiteIdentifier] {7162 m_bufferedTimeRangesChangedTask.scheduleTask([this, logSiteIdentifier] { 7146 7163 UNUSED_PARAM(logSiteIdentifier); 7147 7164 ALWAYS_LOG(logSiteIdentifier, "lambda(), task fired"); … … 7769 7786 void HTMLMediaElement::scheduleUpdateMediaState() 7770 7787 { 7771 if (m_updateMediaStateTask. hasPendingTask())7788 if (m_updateMediaStateTask.isPending()) 7772 7789 return; 7773 7790 … … 8040 8057 void HTMLMediaElement::playbackControlsManagerBehaviorRestrictionsTimerFired() 8041 8058 { 8042 if (m_playbackControlsManagerBehaviorRestrictions Queue.hasPendingTask())8059 if (m_playbackControlsManagerBehaviorRestrictionsTask.isPending()) 8043 8060 return; 8044 8061 … … 8047 8064 8048 8065 RefPtr<HTMLMediaElement> protectedThis(this); 8049 m_playbackControlsManagerBehaviorRestrictions Queue.scheduleTask([protectedThis] () {8066 m_playbackControlsManagerBehaviorRestrictionsTask.scheduleTask([protectedThis] () { 8050 8067 auto& mediaElementSession = protectedThis->mediaSession(); 8051 8068 if (protectedThis->isPlaying() || mediaElementSession.state() == PlatformMediaSession::Autoplaying || mediaElementSession.state() == PlatformMediaSession::Playing) -
trunk/Source/WebCore/html/HTMLMediaElement.h
r278359 r278392 186 186 187 187 void scheduleCheckPlaybackTargetCompatability(); 188 void checkPlaybackTargetCompat ablity();188 void checkPlaybackTargetCompatibility(); 189 189 void scheduleResolvePendingPlayPromises(); 190 190 void scheduleRejectPendingPlayPromises(Ref<DOMException>&&); … … 945 945 Timer m_playbackControlsManagerBehaviorRestrictionsTimer; 946 946 Timer m_seekToPlaybackPositionEndedTimer; 947 DeferrableTask<Timer>m_configureTextTracksTask;948 DeferrableTask<Timer> m_checkPlaybackTargetCompatablityTask;949 DeferrableTask<Timer>m_updateMediaStateTask;950 DeferrableTask<Timer>m_mediaEngineUpdatedTask;947 EventLoopDeferrableTask m_configureTextTracksTask; 948 EventLoopDeferrableTask m_checkPlaybackTargetCompatibilityTask; 949 EventLoopDeferrableTask m_updateMediaStateTask; 950 EventLoopDeferrableTask m_mediaEngineUpdatedTask; 951 951 DeferrableTask<HTMLMediaElement> m_updatePlayStateTask; 952 DeferrableTask<Timer> m_resumeTaskQueue;953 DeferrableTask<Timer> m_seekTaskQueue;954 DeferrableTask<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue;955 DeferrableTask<Timer> m_bufferedTimeRangesChangedQueue;956 GenericTaskQueue<Timer>m_promiseTaskQueue;957 GenericTaskQueue<Timer>m_pauseAfterDetachedTaskQueue;958 GenericTaskQueue<Timer>m_resourceSelectionTaskQueue;959 GenericTaskQueue<Timer>m_visibilityChangeTaskQueue;960 GenericTaskQueue<Timer>m_fullscreenTaskQueue;961 GenericTaskQueue<Timer>m_playbackTargetIsWirelessQueue;952 EventLoopDeferrableTask m_resumeTask; 953 EventLoopDeferrableTask m_seekTask; 954 EventLoopDeferrableTask m_playbackControlsManagerBehaviorRestrictionsTask; 955 EventLoopDeferrableTask m_bufferedTimeRangesChangedTask; 956 EventLoopTaskQueue m_promiseTaskQueue; 957 EventLoopTaskQueue m_pauseAfterDetachedTaskQueue; 958 EventLoopTaskQueue m_resourceSelectionTaskQueue; 959 EventLoopTaskQueue m_visibilityChangeTaskQueue; 960 EventLoopTaskQueue m_fullscreenTaskQueue; 961 EventLoopTaskQueue m_playbackTargetIsWirelessQueue; 962 962 RefPtr<TimeRanges> m_playedTimeRanges; 963 963 UniqueRef<MainThreadGenericEventQueue> m_asyncEventQueue; … … 1163 1163 bool m_attachingMediaKeys { false }; 1164 1164 bool m_playbackBlockedWaitingForKey { false }; 1165 GenericTaskQueue<Timer>m_encryptedMediaQueue;1165 EventLoopTaskQueue m_encryptedMediaQueue; 1166 1166 #endif 1167 1167 -
trunk/Source/WebCore/html/shadow/MediaControlTextTrackContainerElement.cpp
r277986 r278392 76 76 MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(Document& document, HTMLMediaElement& element) 77 77 : HTMLDivElement(divTag, document) 78 , m_taskQueue(&document) 78 79 , m_mediaElement(makeWeakPtr(&element)) 79 80 { -
trunk/Source/WebCore/html/shadow/MediaControlTextTrackContainerElement.h
r272190 r278392 98 98 std::unique_ptr<TextTrackRepresentation> m_textTrackRepresentation; 99 99 100 GenericTaskQueue<Timer>m_taskQueue;100 EventLoopTaskQueue m_taskQueue; 101 101 WeakPtr<HTMLMediaElement> m_mediaElement; 102 102 IntRect m_videoDisplaySize; -
trunk/Source/WebCore/platform/DeferrableTask.h
r253375 r278392 1 1 /* 2 * Copyright (C) 2018 Apple Inc. All rights reserved.2 * Copyright (C) 2018-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #include "ContextDestructionObserver.h" 29 #include "EventLoop.h" 28 30 #include "GenericTaskQueue.h" 31 #include "ScriptExecutionContext.h" 29 32 30 33 namespace WebCore { 31 34 32 template <typename T> 33 class DeferrableTask : public CanMakeWeakPtr<DeferrableTask<T>> { 35 class DeferrableTaskBase : public CanMakeWeakPtr<DeferrableTaskBase> { 34 36 public: 35 DeferrableTask()36 : m_dispatcher()37 {38 }39 40 DeferrableTask(T& t)41 : m_dispatcher(&t)42 {43 }44 45 typedef WTF::Function<void ()> TaskFunction;46 47 void scheduleTask(TaskFunction&& task)48 {49 if (m_isClosed)50 return;51 52 cancelTask();53 54 m_pendingTask = true;55 m_dispatcher.postTask([weakThis = makeWeakPtr(*this), task = WTFMove(task)] {56 if (!weakThis)57 return;58 ASSERT(weakThis->m_pendingTask);59 weakThis->m_pendingTask = false;60 task();61 });62 }63 64 37 void close() 65 38 { … … 70 43 void cancelTask() 71 44 { 72 CanMakeWeakPtr<DeferrableTask<T>>::weakPtrFactory().revokeAll();73 m_ pendingTask= false;45 weakPtrFactory().revokeAll(); 46 m_isPending = false; 74 47 } 75 bool hasPendingTask() const { return m_pendingTask; } 48 49 bool isPending() const { return m_isPending; } 50 51 protected: 52 ~DeferrableTaskBase() = default; 53 bool isClosed() const { return m_isClosed; } 54 void setIsPending(bool isPending) { m_isPending = isPending; } 55 56 private: 57 bool m_isPending { false }; 58 bool m_isClosed { false }; 59 }; 60 61 template <typename T> 62 class DeferrableTask : public DeferrableTaskBase { 63 public: 64 DeferrableTask() 65 : m_dispatcher() 66 { } 67 68 DeferrableTask(T& t) 69 : m_dispatcher(&t) 70 { } 71 72 void scheduleTask(Function<void()>&& task) 73 { 74 if (isClosed()) 75 return; 76 77 cancelTask(); 78 79 setIsPending(true); 80 m_dispatcher.postTask([weakThis = makeWeakPtr(*this), task = WTFMove(task)] { 81 if (!weakThis) 82 return; 83 ASSERT(weakThis->isPending()); 84 weakThis->setIsPending(false); 85 task(); 86 }); 87 } 76 88 77 89 private: 78 90 TaskDispatcher<T> m_dispatcher; 79 bool m_pendingTask { false }; 80 bool m_isClosed { false }; 91 }; 92 93 // Similar to DeferrableTask but based on the HTML event loop. 94 class EventLoopDeferrableTask : public DeferrableTaskBase, private ContextDestructionObserver { 95 public: 96 EventLoopDeferrableTask(ScriptExecutionContext* context) 97 : ContextDestructionObserver(context) 98 { } 99 100 // FIXME: Pass TaskSource instead of assuming TaskSource::MediaElement. 101 void scheduleTask(Function<void()>&& task) 102 { 103 if (isClosed() || !scriptExecutionContext()) 104 return; 105 106 cancelTask(); 107 108 setIsPending(true); 109 scriptExecutionContext()->eventLoop().queueTask(TaskSource::MediaElement, [weakThis = makeWeakPtr(*this), task = WTFMove(task)] { 110 if (!weakThis) 111 return; 112 ASSERT(weakThis->isPending()); 113 weakThis->setIsPending(false); 114 task(); 115 }); 116 } 81 117 }; 82 118 -
trunk/Source/WebCore/platform/GenericTaskQueue.h
r277958 r278392 26 26 #pragma once 27 27 28 #include "ContextDestructionObserver.h" 29 #include "EventLoop.h" 30 #include "ScriptExecutionContext.h" 28 31 #include "Timer.h" 29 32 #include <wtf/Deque.h> … … 76 79 }; 77 80 81 class GenericTaskQueueBase : public CanMakeWeakPtr<GenericTaskQueueBase> { 82 public: 83 bool hasPendingTasks() const { return m_pendingTasks; } 84 bool isClosed() const { return m_isClosed; } 85 86 void close() 87 { 88 cancelAllTasks(); 89 m_isClosed = true; 90 } 91 92 void cancelAllTasks() 93 { 94 weakPtrFactory().revokeAll(); 95 m_pendingTasks = 0; 96 } 97 98 protected: 99 ~GenericTaskQueueBase() = default; 100 void incrementPendingTasks() { ++m_pendingTasks; } 101 void decrementPendingTasks() { ASSERT(m_pendingTasks); --m_pendingTasks; } 102 103 private: 104 unsigned m_pendingTasks { 0 }; 105 bool m_isClosed { false }; 106 }; 107 78 108 template <typename T> 79 class GenericTaskQueue : public CanMakeWeakPtr<GenericTaskQueue<T>>{109 class GenericTaskQueue : public GenericTaskQueueBase { 80 110 WTF_MAKE_FAST_ALLOCATED; 81 111 public: … … 94 124 explicit GenericTaskQueue(T* t) 95 125 : m_dispatcher(makeUniqueRef<TaskDispatcher<T>>(t)) 96 , m_isClosed(!t)97 126 { 98 127 ASSERT(isMainThread()); 128 if (!t) 129 close(); 99 130 } 100 131 … … 105 136 } 106 137 107 typedef WTF::Function<void ()> TaskFunction; 108 109 void enqueueTask(TaskFunction&& task) 138 void enqueueTask(Function<void()>&& task) 110 139 { 111 if ( m_isClosed)140 if (isClosed()) 112 141 return; 113 142 114 ++m_pendingTasks;143 incrementPendingTasks(); 115 144 m_dispatcher->postTask([weakThis = makeWeakPtr(*this), task = WTFMove(task)] { 116 145 if (!weakThis) 117 146 return; 118 ASSERT(weakThis->m_pendingTasks); 119 --weakThis->m_pendingTasks; 147 weakThis->decrementPendingTasks(); 120 148 task(); 121 149 }); 122 150 } 123 151 124 void close()125 {126 cancelAllTasks();127 m_isClosed = true;128 }129 130 void cancelAllTasks()131 {132 CanMakeWeakPtr<GenericTaskQueue<T>>::weakPtrFactory().revokeAll();133 m_pendingTasks = 0;134 }135 136 bool hasPendingTasks() const { return m_pendingTasks; }137 bool isClosed() const { return m_isClosed; }138 139 152 private: 140 153 UniqueRef<TaskDispatcher<T>> m_dispatcher; 141 unsigned m_pendingTasks { 0 }; 142 bool m_isClosed { false }; 154 }; 155 156 // Similar to GenericTaskQueue but based on the HTML event loop. 157 class EventLoopTaskQueue : public GenericTaskQueueBase, private ContextDestructionObserver { 158 public: 159 EventLoopTaskQueue(ScriptExecutionContext* context) 160 : ContextDestructionObserver(context) 161 { } 162 163 // FIXME: Pass a TaskSource instead of assuming TaskSource::MediaElement. 164 void enqueueTask(Function<void()>&& task) 165 { 166 if (isClosed() || !scriptExecutionContext()) 167 return; 168 169 incrementPendingTasks(); 170 scriptExecutionContext()->eventLoop().queueTask(TaskSource::MediaElement, [weakThis = makeWeakPtr(*this), task = WTFMove(task)] { 171 if (!weakThis) 172 return; 173 weakThis->decrementPendingTasks(); 174 task(); 175 }); 176 } 143 177 }; 144 178 -
trunk/Source/WebCore/platform/RemoteCommandListener.cpp
r273967 r278392 72 72 void RemoteCommandListener::scheduleSupportedCommandsUpdate() 73 73 { 74 if (!m_updateCommandsTask. hasPendingTask()) {74 if (!m_updateCommandsTask.isPending()) { 75 75 m_updateCommandsTask.scheduleTask([this] () { 76 76 updateSupportedCommands(); -
trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm
r264006 r278392 184 184 } 185 185 186 ASSERT(!m_mappingCallback && !m_mappingCallbackTask. hasPendingTask());186 ASSERT(!m_mappingCallback && !m_mappingCallbackTask.isPending()); 187 187 188 188 // An existing callback means this buffer is in the mapped state. -
trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUQueueMetal.mm
r264006 r278392 97 97 } 98 98 99 if (m_presentTask. hasPendingTask() || !m_device || !m_device->swapChain())99 if (m_presentTask.isPending() || !m_device || !m_device->swapChain()) 100 100 return; 101 101
Note:
See TracChangeset
for help on using the changeset viewer.