Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp

Issue 2272773002: Use intersection observer to control frame throttling (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/dom/IntersectionObserverController.h" 5 #include "core/dom/IntersectionObserverController.h"
6 6
7 #include "core/dom/Document.h" 7 #include "core/dom/Document.h"
8 #include "core/dom/IdleRequestOptions.h" 8 #include "core/dom/IdleRequestOptions.h"
9 #include "core/dom/TaskRunnerHelper.h"
9 #include "platform/TraceEvent.h" 10 #include "platform/TraceEvent.h"
11 #include "platform/scheduler/CancellableTaskFactory.h"
10 12
11 namespace blink { 13 namespace blink {
12 14
13 IntersectionObserverController* IntersectionObserverController::create(Document* document) 15 IntersectionObserverController* IntersectionObserverController::create(Document* document)
14 { 16 {
15 IntersectionObserverController* result = new IntersectionObserverController( document); 17 IntersectionObserverController* result = new IntersectionObserverController( document);
16 result->suspendIfNeeded(); 18 result->suspendIfNeeded();
17 return result; 19 return result;
18 } 20 }
19 21
20 IntersectionObserverController::IntersectionObserverController(Document* documen t) 22 IntersectionObserverController::IntersectionObserverController(Document* documen t)
21 : ActiveDOMObject(document) 23 : ActiveDOMObject(document)
24 , m_lowLatencyNotificationTask(CancellableTaskFactory::create(this, &Interse ctionObserverController::deliverLowLatencyNotifications))
22 , m_callbackID(0) 25 , m_callbackID(0)
23 , m_callbackFiredWhileSuspended(false) 26 , m_callbackFiredWhileSuspended(false)
24 { 27 {
25 } 28 }
26 29
27 IntersectionObserverController::~IntersectionObserverController() { } 30 IntersectionObserverController::~IntersectionObserverController() { }
28 31
29 void IntersectionObserverController::scheduleIntersectionObserverForDelivery(Int ersectionObserver& observer) 32 void IntersectionObserverController::scheduleIntersectionObserverForDelivery(Int ersectionObserver& observer)
30 { 33 {
34 if (observer.lowLatency()) {
35 scheduleLowLatencyNotification(observer);
36 } else {
37 scheduleIdleNotification(observer);
38 }
39 }
40
41 void IntersectionObserverController::scheduleIdleNotification(IntersectionObserv er& observer)
42 {
31 m_pendingIntersectionObservers.add(&observer); 43 m_pendingIntersectionObservers.add(&observer);
32 if (m_callbackID) 44 if (m_callbackID)
33 return; 45 return;
34 Document* document = toDocument(getExecutionContext()); 46 Document* document = toDocument(getExecutionContext());
35 if (!document) 47 if (!document)
36 return; 48 return;
37 IdleRequestOptions options; 49 IdleRequestOptions options;
38 // The IntersectionObserver spec mandates that notifications be sent within 100ms. 50 // The IntersectionObserver spec mandates that notifications be sent within 100ms.
39 options.setTimeout(100); 51 options.setTimeout(100);
40 m_callbackID = document->requestIdleCallback(this, options); 52 m_callbackID = document->requestIdleCallback(this, options);
41 } 53 }
42 54
55 void IntersectionObserverController::scheduleLowLatencyNotification(Intersection Observer& observer)
56 {
57 m_pendingLowLatencyIntersectionObservers.add(&observer);
58 if (!m_lowLatencyNotificationTask->isPending())
59 TaskRunnerHelper::get(TaskType::Unthrottled, getExecutionContext())->pos tTask(BLINK_FROM_HERE, m_lowLatencyNotificationTask->cancelAndCreate());
ojan 2016/09/10 02:18:27 In retrospect, I wonder if unthrottled task runner
haraken 2016/09/12 00:46:32 Just help me understand: IIUC, frame throttling is
60 }
61
43 void IntersectionObserverController::resume() 62 void IntersectionObserverController::resume()
44 { 63 {
45 // If the callback fired while DOM objects were suspended, notifications mig ht be late, so deliver 64 // If the callback fired while DOM objects were suspended, notifications mig ht be late, so deliver
46 // them right away (rather than waiting to fire again). 65 // them right away (rather than waiting to fire again).
66 deliverLowLatencyNotifications();
47 if (m_callbackFiredWhileSuspended) { 67 if (m_callbackFiredWhileSuspended) {
48 m_callbackFiredWhileSuspended = false; 68 m_callbackFiredWhileSuspended = false;
49 deliverIntersectionObservations(); 69 deliverIntersectionObservations();
50 } 70 }
51 } 71 }
52 72
53 void IntersectionObserverController::handleEvent(IdleDeadline*) 73 void IntersectionObserverController::handleEvent(IdleDeadline*)
54 { 74 {
55 DCHECK(m_callbackID); 75 DCHECK(m_callbackID);
56 m_callbackID = 0; 76 m_callbackID = 0;
(...skipping 10 matching lines...) Expand all
67 if (context->activeDOMObjectsAreSuspended()) { 87 if (context->activeDOMObjectsAreSuspended()) {
68 m_callbackFiredWhileSuspended = true; 88 m_callbackFiredWhileSuspended = true;
69 return; 89 return;
70 } 90 }
71 HeapHashSet<Member<IntersectionObserver>> observers; 91 HeapHashSet<Member<IntersectionObserver>> observers;
72 m_pendingIntersectionObservers.swap(observers); 92 m_pendingIntersectionObservers.swap(observers);
73 for (auto& observer : observers) 93 for (auto& observer : observers)
74 observer->deliver(); 94 observer->deliver();
75 } 95 }
76 96
97 void IntersectionObserverController::deliverLowLatencyNotifications()
98 {
99 ExecutionContext* context = getExecutionContext();
100 if (!context) {
101 m_pendingLowLatencyIntersectionObservers.clear();
102 return;
103 }
104 if (context->activeDOMObjectsAreSuspended()) {
105 // resume() will deliver low latency notifications directly.
106 return;
107 }
108 HeapHashSet<Member<IntersectionObserver>> observers;
109 m_pendingLowLatencyIntersectionObservers.swap(observers);
110 for (auto& observer : observers)
111 observer->deliver();
112 }
113
77 void IntersectionObserverController::computeTrackedIntersectionObservations() 114 void IntersectionObserverController::computeTrackedIntersectionObservations()
78 { 115 {
79 TRACE_EVENT0("blink", "IntersectionObserverController::computeTrackedInterse ctionObservations"); 116 TRACE_EVENT0("blink", "IntersectionObserverController::computeTrackedInterse ctionObservations");
80 for (auto& observer : m_trackedIntersectionObservers) { 117 for (auto& observer : m_trackedIntersectionObservers) {
81 observer->computeIntersectionObservations(); 118 observer->computeIntersectionObservations();
82 if (observer->hasEntries()) 119 if (observer->hasEntries())
83 scheduleIntersectionObserverForDelivery(*observer); 120 scheduleIntersectionObserverForDelivery(*observer);
84 } 121 }
85 } 122 }
86 123
87 void IntersectionObserverController::addTrackedObserver(IntersectionObserver& ob server) 124 void IntersectionObserverController::addTrackedObserver(IntersectionObserver& ob server)
88 { 125 {
89 m_trackedIntersectionObservers.add(&observer); 126 m_trackedIntersectionObservers.add(&observer);
90 } 127 }
91 128
92 void IntersectionObserverController::removeTrackedObserversForRoot(const Node& r oot) 129 void IntersectionObserverController::removeTrackedObserversForRoot(const Node& r oot)
93 { 130 {
94 HeapVector<Member<IntersectionObserver>> toRemove; 131 HeapVector<Member<IntersectionObserver>> toRemove;
95 for (auto& observer : m_trackedIntersectionObservers) { 132 for (auto& observer : m_trackedIntersectionObservers) {
96 if (observer->rootNode() == &root) 133 if (observer->rootNode() == &root)
97 toRemove.append(observer); 134 toRemove.append(observer);
98 } 135 }
99 m_trackedIntersectionObservers.removeAll(toRemove); 136 m_trackedIntersectionObservers.removeAll(toRemove);
100 } 137 }
101 138
102 DEFINE_TRACE(IntersectionObserverController) 139 DEFINE_TRACE(IntersectionObserverController)
103 { 140 {
104 visitor->trace(m_trackedIntersectionObservers); 141 visitor->trace(m_trackedIntersectionObservers);
105 visitor->trace(m_pendingIntersectionObservers); 142 visitor->trace(m_pendingIntersectionObservers);
143 visitor->trace(m_pendingLowLatencyIntersectionObservers);
106 ActiveDOMObject::trace(visitor); 144 ActiveDOMObject::trace(visitor);
107 IdleRequestCallback::trace(visitor); 145 IdleRequestCallback::trace(visitor);
108 } 146 }
109 147
110 } // namespace blink 148 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698