Changeset 187031 in webkit
- Timestamp:
- Jul 20, 2015 1:16:18 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r187018 r187031 1 2015-07-20 Andreas Kling <akling@apple.com> 2 3 Improve behavior of media elements in page cache. 4 <https://webkit.org/b/147020> 5 <rdar://problem/21712311> 6 7 Reviewed by Chris Dumez. 8 9 Add some coverage for suspend/resume of queued events on cached media elements. 10 11 * media/restore-from-page-cache-expected.txt: 12 * media/restore-from-page-cache.html: 13 1 14 2015-07-19 Tim Horton <timothy_horton@apple.com> 2 15 -
trunk/LayoutTests/media/restore-from-page-cache-expected.txt
r186569 r187031 6 6 EXPECTED (loadCount == '0') OK 7 7 *** Page going into cache 8 *** Changing playbackRate just before going into cache, to schedule a ratechange event. 9 *** Changing volume just before going into cache, to schedule a volumechange event. 8 10 *** Page returned from cache 9 11 EXPECTED (loadCount == '1') OK 10 12 EXPECTED (videoComputedStyle.width == '320px') OK 11 13 EXPECTED (videoComputedStyle.height == '240px') OK 14 *** ratechange event fired. This should happen AFTER returning from cache. 15 *** volumechange event fired. This should happen AFTER returning from cache. 12 16 -
trunk/LayoutTests/media/restore-from-page-cache.html
r186569 r187031 34 34 } 35 35 } 36 36 37 function pagehide() 38 { 39 // Have the video element generate some events that need to be suspended. 40 // We use multiple events to verify that they fire in the correct order. 41 consoleWrite("*** Changing playbackRate just before going into cache, to schedule a ratechange event."); 42 document.getElementsByTagName("video")[0].playbackRate = 2; 43 consoleWrite("*** Changing volume just before going into cache, to schedule a volumechange event."); 44 document.getElementsByTagName("video")[0].volume = 0.5; 45 } 46 37 47 function canplaythrough() 38 48 { 39 49 testExpected("loadCount", 0); 40 50 if (!loadCount) { 51 video = document.getElementsByTagName('video')[0]; 41 52 consoleWrite("*** Page going into cache"); 42 53 setTimeout('window.location = "data:text/html,<script>history.back()<" + "/script>"', 0); 43 54 } 44 55 ++loadCount; 56 } 57 58 function propertyChangeCallback(evt) 59 { 60 consoleWrite("*** " + evt.type + " event fired. This should happen AFTER returning from cache."); 45 61 } 46 62 … … 53 69 54 70 video.src = mediaFile; 71 72 video.onratechange = propertyChangeCallback; 73 video.onvolumechange = propertyChangeCallback; 55 74 } 56 75 57 76 window.onpageshow = pageshow; 77 window.onpagehide = pagehide; 58 78 </script> 59 79 </head> -
trunk/Source/WebCore/ChangeLog
r187026 r187031 1 2015-07-20 Andreas Kling <akling@apple.com> 2 3 Improve behavior of media elements in page cache. 4 <https://webkit.org/b/147020> 5 <rdar://problem/21712311> 6 7 Reviewed by Chris Dumez. 8 9 Make improvements for media elements when transitioning in/out of page cache: 10 11 - Events that were scheduled when going into cache will now be delivered 12 when the page is restored from cache. 13 14 - Data buffering is turned off while in the cache. This reduces the memory 15 cost of cached pages with media elements on iOS (where mediaserverd would 16 keep upcoming video frames in memory for cached pages.) 17 18 Test: media/restore-from-page-cache.html (amended) 19 20 * dom/GenericEventQueue.h: 21 * dom/GenericEventQueue.cpp: 22 (WebCore::GenericEventQueue::enqueueEvent): 23 (WebCore::GenericEventQueue::suspend): 24 (WebCore::GenericEventQueue::resume): 25 26 Add a simple suspend/resume mechanism to GenericEventQueue that can 27 be used to support page caching. 28 29 * html/HTMLMediaElement.cpp: 30 (WebCore::HTMLMediaElement::stop): 31 (WebCore::HTMLMediaElement::suspend): 32 (WebCore::HTMLMediaElement::resume): 33 (WebCore::HTMLMediaElement::stopWithoutDestroyingMediaPlayer): 34 35 Adapt to event queueing changes and add calls to setShouldBufferData(). 36 37 * html/HTMLSourceElement.h: 38 * html/HTMLSourceElement.cpp: 39 (WebCore::HTMLSourceElement::HTMLSourceElement): 40 (WebCore::HTMLSourceElement::create): 41 (WebCore::HTMLSourceElement::activeDOMObjectName): 42 (WebCore::HTMLSourceElement::canSuspendForPageCache): 43 (WebCore::HTMLSourceElement::suspend): 44 (WebCore::HTMLSourceElement::resume): 45 (WebCore::HTMLSourceElement::stop): 46 47 Turn HTMLSourceElement into an ActiveDOMObject so it gets all the 48 appropriate page cache notifications directly. Suspend the delayed 49 error event delivery timer when cached. 50 1 51 2015-07-20 Mark Lam <mark.lam@apple.com> 2 52 -
trunk/Source/WebCore/dom/GenericEventQueue.cpp
r176024 r187031 46 46 } 47 47 48 boolGenericEventQueue::enqueueEvent(PassRefPtr<Event> event)48 void GenericEventQueue::enqueueEvent(PassRefPtr<Event> event) 49 49 { 50 50 if (m_isClosed) 51 return false;51 return; 52 52 53 53 if (event->target() == &m_owner) … … 55 55 56 56 m_pendingEvents.append(event); 57 58 if (m_isSuspended) 59 return; 60 57 61 pendingQueues().append(m_weakPtrFactory.createWeakPtr()); 58 62 if (!sharedTimer().isActive()) 59 63 sharedTimer().startOneShot(0); 60 61 return true;62 64 } 63 65 … … 121 123 } 122 124 125 void GenericEventQueue::suspend() 126 { 127 ASSERT(!m_isSuspended); 128 m_isSuspended = true; 129 m_weakPtrFactory.revokeAll(); 123 130 } 131 132 void GenericEventQueue::resume() 133 { 134 ASSERT(m_isSuspended); 135 m_isSuspended = false; 136 137 if (m_pendingEvents.isEmpty()) 138 return; 139 140 for (unsigned i = 0; i < m_pendingEvents.size(); ++i) 141 pendingQueues().append(m_weakPtrFactory.createWeakPtr()); 142 143 if (!sharedTimer().isActive()) 144 sharedTimer().startOneShot(0); 145 } 146 147 } -
trunk/Source/WebCore/dom/GenericEventQueue.h
r176024 r187031 43 43 ~GenericEventQueue(); 44 44 45 boolenqueueEvent(PassRefPtr<Event>);45 void enqueueEvent(PassRefPtr<Event>); 46 46 void close(); 47 47 48 48 void cancelAllEvents(); 49 49 bool hasPendingEvents() const; 50 51 void suspend(); 52 void resume(); 50 53 51 54 private: … … 60 63 WeakPtrFactory<GenericEventQueue> m_weakPtrFactory; 61 64 bool m_isClosed; 65 bool m_isSuspended { false }; 62 66 }; 63 67 -
trunk/Source/WebCore/html/HTMLMediaElement.cpp
r186980 r187031 4891 4891 4892 4892 stopPeriodicTimers(); 4893 cancelPendingEventsAndCallbacks(); 4893 4894 updateSleepDisabling(); 4895 } 4896 4897 void HTMLMediaElement::stop() 4898 { 4899 LOG(Media, "HTMLMediaElement::stop(%p)", this); 4900 4901 stopWithoutDestroyingMediaPlayer(); 4894 4902 4895 4903 m_asyncEventQueue.close(); 4896 4897 updateSleepDisabling();4898 }4899 4900 void HTMLMediaElement::stop()4901 {4902 LOG(Media, "HTMLMediaElement::stop(%p)", this);4903 4904 stopWithoutDestroyingMediaPlayer();4905 4904 4906 4905 // Once an active DOM object has been stopped it can not be restarted, so we can deallocate … … 4919 4918 case PageCache: 4920 4919 stopWithoutDestroyingMediaPlayer(); 4920 m_asyncEventQueue.suspend(); 4921 setShouldBufferData(false); 4921 4922 m_mediaSession->addBehaviorRestriction(MediaElementSession::RequirePageConsentToResumeMedia); 4922 4923 break; … … 4935 4936 4936 4937 m_inActiveDocument = true; 4938 4939 m_asyncEventQueue.resume(); 4940 4941 setShouldBufferData(true); 4937 4942 4938 4943 if (!m_mediaSession->pageAllowsPlaybackAfterResuming(*this)) -
trunk/Source/WebCore/html/HTMLSourceElement.cpp
r177996 r187031 41 41 inline HTMLSourceElement::HTMLSourceElement(const QualifiedName& tagName, Document& document) 42 42 : HTMLElement(tagName, document) 43 , ActiveDOMObject(&document) 43 44 , m_errorEventTimer(*this, &HTMLSourceElement::errorEventTimerFired) 44 45 { … … 49 50 Ref<HTMLSourceElement> HTMLSourceElement::create(const QualifiedName& tagName, Document& document) 50 51 { 51 return adoptRef(*new HTMLSourceElement(tagName, document)); 52 Ref<HTMLSourceElement> sourceElement = adoptRef(*new HTMLSourceElement(tagName, document)); 53 sourceElement->suspendIfNeeded(); 54 return sourceElement; 52 55 } 53 56 … … 122 125 } 123 126 127 const char* HTMLSourceElement::activeDOMObjectName() const 128 { 129 return "HTMLSourceElement"; 130 } 131 132 bool HTMLSourceElement::canSuspendForPageCache() const 133 { 134 return true; 135 } 136 137 void HTMLSourceElement::suspend(ReasonForSuspension why) 138 { 139 if (why == PageCache) { 140 m_shouldRescheduleErrorEventOnResume = m_errorEventTimer.isActive(); 141 m_errorEventTimer.stop(); 142 } 143 } 144 145 void HTMLSourceElement::resume() 146 { 147 if (m_shouldRescheduleErrorEventOnResume) { 148 m_errorEventTimer.startOneShot(0); 149 m_shouldRescheduleErrorEventOnResume = false; 150 } 151 } 152 153 void HTMLSourceElement::stop() 154 { 155 cancelPendingErrorEvent(); 156 } 157 124 158 } 125 159 -
trunk/Source/WebCore/html/HTMLSourceElement.h
r177996 r187031 33 33 namespace WebCore { 34 34 35 class HTMLSourceElement final : public HTMLElement {35 class HTMLSourceElement final : public HTMLElement, public ActiveDOMObject { 36 36 public: 37 37 static Ref<HTMLSourceElement> create(const QualifiedName&, Document&); … … 53 53 virtual bool isURLAttribute(const Attribute&) const override; 54 54 55 // ActiveDOMObject. 56 const char* activeDOMObjectName() const override; 57 bool canSuspendForPageCache() const override; 58 void suspend(ReasonForSuspension) override; 59 void resume() override; 60 void stop() override; 61 55 62 void errorEventTimerFired(); 56 63 57 64 Timer m_errorEventTimer; 65 bool m_shouldRescheduleErrorEventOnResume { false }; 58 66 }; 59 67
Note: See TracChangeset
for help on using the changeset viewer.