Index: third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp |
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp |
index dbdb3f937f598f7f37bb4aad6f082e6f24f0c087..9e59de76adad1f0546002607d3debee247514c2b 100644 |
--- a/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp |
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp |
@@ -6,7 +6,9 @@ |
#include "core/dom/Document.h" |
#include "core/dom/IdleRequestOptions.h" |
+#include "core/dom/TaskRunnerHelper.h" |
#include "platform/TraceEvent.h" |
+#include "platform/scheduler/CancellableTaskFactory.h" |
namespace blink { |
@@ -19,6 +21,7 @@ IntersectionObserverController* IntersectionObserverController::create(Document* |
IntersectionObserverController::IntersectionObserverController(Document* document) |
: ActiveDOMObject(document) |
+ , m_lowLatencyNotificationTask(CancellableTaskFactory::create(this, &IntersectionObserverController::deliverLowLatencyNotifications)) |
, m_callbackID(0) |
, m_callbackFiredWhileSuspended(false) |
{ |
@@ -28,6 +31,15 @@ IntersectionObserverController::~IntersectionObserverController() { } |
void IntersectionObserverController::scheduleIntersectionObserverForDelivery(IntersectionObserver& observer) |
{ |
+ if (observer.lowLatency()) { |
+ scheduleLowLatencyNotification(observer); |
+ } else { |
+ scheduleIdleNotification(observer); |
+ } |
+} |
+ |
+void IntersectionObserverController::scheduleIdleNotification(IntersectionObserver& observer) |
+{ |
m_pendingIntersectionObservers.add(&observer); |
if (m_callbackID) |
return; |
@@ -40,10 +52,18 @@ void IntersectionObserverController::scheduleIntersectionObserverForDelivery(Int |
m_callbackID = document->requestIdleCallback(this, options); |
} |
+void IntersectionObserverController::scheduleLowLatencyNotification(IntersectionObserver& observer) |
+{ |
+ m_pendingLowLatencyIntersectionObservers.add(&observer); |
+ if (!m_lowLatencyNotificationTask->isPending()) |
+ TaskRunnerHelper::get(TaskType::Unthrottled, getExecutionContext())->postTask(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
|
+} |
+ |
void IntersectionObserverController::resume() |
{ |
// If the callback fired while DOM objects were suspended, notifications might be late, so deliver |
// them right away (rather than waiting to fire again). |
+ deliverLowLatencyNotifications(); |
if (m_callbackFiredWhileSuspended) { |
m_callbackFiredWhileSuspended = false; |
deliverIntersectionObservations(); |
@@ -74,6 +94,23 @@ void IntersectionObserverController::deliverIntersectionObservations() |
observer->deliver(); |
} |
+void IntersectionObserverController::deliverLowLatencyNotifications() |
+{ |
+ ExecutionContext* context = getExecutionContext(); |
+ if (!context) { |
+ m_pendingLowLatencyIntersectionObservers.clear(); |
+ return; |
+ } |
+ if (context->activeDOMObjectsAreSuspended()) { |
+ // resume() will deliver low latency notifications directly. |
+ return; |
+ } |
+ HeapHashSet<Member<IntersectionObserver>> observers; |
+ m_pendingLowLatencyIntersectionObservers.swap(observers); |
+ for (auto& observer : observers) |
+ observer->deliver(); |
+} |
+ |
void IntersectionObserverController::computeTrackedIntersectionObservations() |
{ |
TRACE_EVENT0("blink", "IntersectionObserverController::computeTrackedIntersectionObservations"); |
@@ -103,6 +140,7 @@ DEFINE_TRACE(IntersectionObserverController) |
{ |
visitor->trace(m_trackedIntersectionObservers); |
visitor->trace(m_pendingIntersectionObservers); |
+ visitor->trace(m_pendingLowLatencyIntersectionObservers); |
ActiveDOMObject::trace(visitor); |
IdleRequestCallback::trace(visitor); |
} |