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

Side by Side Diff: third_party/WebKit/Source/core/frame/FrameView.cpp

Issue 1449623002: IntersectionObserver: second cut. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Clarify the tear-down path for observers and observations. Created 5 years, 1 month 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 /* 1 /*
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 * 1999 Lars Knoll <knoll@kde.org> 3 * 1999 Lars Knoll <knoll@kde.org>
4 * 1999 Antti Koivisto <koivisto@kde.org> 4 * 1999 Antti Koivisto <koivisto@kde.org>
5 * 2000 Dirk Mueller <mueller@kde.org> 5 * 2000 Dirk Mueller <mueller@kde.org>
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9 * Copyright (C) 2009 Google Inc. All rights reserved. 9 * Copyright (C) 2009 Google Inc. All rights reserved.
10 * 10 *
(...skipping 15 matching lines...) Expand all
26 26
27 #include "config.h" 27 #include "config.h"
28 #include "core/frame/FrameView.h" 28 #include "core/frame/FrameView.h"
29 29
30 #include "core/HTMLNames.h" 30 #include "core/HTMLNames.h"
31 #include "core/MediaTypeNames.h" 31 #include "core/MediaTypeNames.h"
32 #include "core/css/FontFaceSet.h" 32 #include "core/css/FontFaceSet.h"
33 #include "core/css/resolver/StyleResolver.h" 33 #include "core/css/resolver/StyleResolver.h"
34 #include "core/dom/AXObjectCache.h" 34 #include "core/dom/AXObjectCache.h"
35 #include "core/dom/Fullscreen.h" 35 #include "core/dom/Fullscreen.h"
36 #include "core/dom/IntersectionObservationRegistry.h"
36 #include "core/editing/EditingUtilities.h" 37 #include "core/editing/EditingUtilities.h"
37 #include "core/editing/FrameSelection.h" 38 #include "core/editing/FrameSelection.h"
38 #include "core/editing/RenderedPosition.h" 39 #include "core/editing/RenderedPosition.h"
39 #include "core/editing/markers/DocumentMarkerController.h" 40 #include "core/editing/markers/DocumentMarkerController.h"
40 #include "core/fetch/ResourceFetcher.h" 41 #include "core/fetch/ResourceFetcher.h"
41 #include "core/frame/FrameHost.h" 42 #include "core/frame/FrameHost.h"
42 #include "core/frame/LocalFrame.h" 43 #include "core/frame/LocalFrame.h"
43 #include "core/frame/Settings.h" 44 #include "core/frame/Settings.h"
44 #include "core/html/HTMLFrameElement.h" 45 #include "core/html/HTMLFrameElement.h"
45 #include "core/html/HTMLPlugInElement.h" 46 #include "core/html/HTMLPlugInElement.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 static bool s_initialTrackAllPaintInvalidations = false; 115 static bool s_initialTrackAllPaintInvalidations = false;
115 116
116 FrameView::FrameView(LocalFrame* frame) 117 FrameView::FrameView(LocalFrame* frame)
117 : m_frame(frame) 118 : m_frame(frame)
118 , m_displayMode(WebDisplayModeBrowser) 119 , m_displayMode(WebDisplayModeBrowser)
119 , m_canHaveScrollbars(true) 120 , m_canHaveScrollbars(true)
120 , m_hasPendingLayout(false) 121 , m_hasPendingLayout(false)
121 , m_inSynchronousPostLayout(false) 122 , m_inSynchronousPostLayout(false)
122 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) 123 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
123 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired) 124 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired)
124 , m_intersectionObserverNotificationFactory(CancellableTaskFactory::create(t his, &FrameView::notifyIntersectionObservers)) 125 , m_renderThrottlingObserverNotificationFactory(CancellableTaskFactory::crea te(this, &FrameView::notifyRenderThrottlingObservers))
125 , m_isTransparent(false) 126 , m_isTransparent(false)
126 , m_baseBackgroundColor(Color::white) 127 , m_baseBackgroundColor(Color::white)
127 , m_mediaType(MediaTypeNames::screen) 128 , m_mediaType(MediaTypeNames::screen)
128 , m_safeToPropagateScrollToParent(true) 129 , m_safeToPropagateScrollToParent(true)
129 , m_isTrackingPaintInvalidations(false) 130 , m_isTrackingPaintInvalidations(false)
130 , m_scrollCorner(nullptr) 131 , m_scrollCorner(nullptr)
131 , m_inputEventsScaleFactorForEmulation(1) 132 , m_inputEventsScaleFactorForEmulation(1)
132 , m_layoutSizeFixedToFrameSize(true) 133 , m_layoutSizeFixedToFrameSize(true)
133 , m_didScrollTimer(this, &FrameView::didScrollTimerFired) 134 , m_didScrollTimer(this, &FrameView::didScrollTimerFired)
134 , m_topControlsViewportAdjustment(0) 135 , m_topControlsViewportAdjustment(0)
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 279
279 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing 280 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing
280 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|. 281 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|.
281 m_autoSizeInfo.clear(); 282 m_autoSizeInfo.clear();
282 283
283 if (m_postLayoutTasksTimer.isActive()) 284 if (m_postLayoutTasksTimer.isActive())
284 m_postLayoutTasksTimer.stop(); 285 m_postLayoutTasksTimer.stop();
285 286
286 if (m_didScrollTimer.isActive()) 287 if (m_didScrollTimer.isActive())
287 m_didScrollTimer.stop(); 288 m_didScrollTimer.stop();
288 m_intersectionObserverNotificationFactory->cancel(); 289 m_renderThrottlingObserverNotificationFactory->cancel();
289 290
290 // FIXME: Do we need to do something here for OOPI? 291 // FIXME: Do we need to do something here for OOPI?
291 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner(); 292 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
292 // TODO(dcheng): It seems buggy that we can have an owner element that 293 // TODO(dcheng): It seems buggy that we can have an owner element that
293 // points to another Widget. 294 // points to another Widget.
294 if (ownerElement && ownerElement->ownedWidget() == this) 295 if (ownerElement && ownerElement->ownedWidget() == this)
295 ownerElement->setWidget(nullptr); 296 ownerElement->setWidget(nullptr);
296 297
297 #if ENABLE(ASSERT) 298 #if ENABLE(ASSERT)
298 m_hasBeenDisposed = true; 299 m_hasBeenDisposed = true;
(...skipping 2089 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 // This must be called from the root frame, since it recurses down, not up. 2389 // This must be called from the root frame, since it recurses down, not up.
2389 // Otherwise the lifecycles of the frames might be out of sync. 2390 // Otherwise the lifecycles of the frames might be out of sync.
2390 ASSERT(m_frame->isLocalRoot()); 2391 ASSERT(m_frame->isLocalRoot());
2391 2392
2392 // Updating layout can run script, which can tear down the FrameView. 2393 // Updating layout can run script, which can tear down the FrameView.
2393 RefPtrWillBeRawPtr<FrameView> protector(this); 2394 RefPtrWillBeRawPtr<FrameView> protector(this);
2394 2395
2395 updateStyleAndLayoutIfNeededRecursive(); 2396 updateStyleAndLayoutIfNeededRecursive();
2396 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean); 2397 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean);
2397 2398
2398 if (phases == OnlyUpToLayoutClean) { 2399 if (phases == OnlyUpToLayoutClean)
2399 updateViewportIntersectionsForSubtree();
2400 return; 2400 return;
2401 }
2402 2401
2403 if (LayoutView* view = layoutView()) { 2402 if (LayoutView* view = layoutView()) {
2404 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp dateLayerTreeEvent::data(m_frame.get())); 2403 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp dateLayerTreeEvent::data(m_frame.get()));
2405 2404
2406 // This was required for slimming paint v1 but is only temporarily 2405 // This was required for slimming paint v1 but is only temporarily
2407 // needed for slimming paint v2. 2406 // needed for slimming paint v2.
2408 view->compositor()->updateIfNeededRecursive(); 2407 view->compositor()->updateIfNeededRecursive();
2409 scrollContentsIfNeededRecursive(); 2408 scrollContentsIfNeededRecursive();
2410 2409
2411 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean); 2410 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean);
(...skipping 1530 matching lines...) Expand 10 before | Expand all | Expand 10 after
3942 3941
3943 void FrameView::setNeedsUpdateViewportIntersection() 3942 void FrameView::setNeedsUpdateViewportIntersection()
3944 { 3943 {
3945 m_needsUpdateViewportIntersection = true; 3944 m_needsUpdateViewportIntersection = true;
3946 for (FrameView* parent = parentFrameView(); parent; parent = parent->parentF rameView()) 3945 for (FrameView* parent = parentFrameView(); parent; parent = parent->parentF rameView())
3947 parent->m_needsUpdateViewportIntersectionInSubtree = true; 3946 parent->m_needsUpdateViewportIntersectionInSubtree = true;
3948 } 3947 }
3949 3948
3950 void FrameView::updateViewportIntersectionIfNeeded() 3949 void FrameView::updateViewportIntersectionIfNeeded()
3951 { 3950 {
3952 // TODO(skyostil): Replace this with a real intersection observer. 3951 if (m_needsUpdateViewportIntersection) {
3953 if (!m_needsUpdateViewportIntersection) 3952 FrameView* parent = parentFrameView();
3954 return; 3953 if (parent) {
3954 ASSERT(!parent->m_needsUpdateViewportIntersection);
3955
3956 // If our parent is hidden, then we are too.
3957 if (parent->m_viewportIntersection.isEmpty()) {
3958 m_viewportIntersection = parent->m_viewportIntersection;
3959 } else {
3960 // Transform our bounds into the root frame's content coordinate space,
3961 // making sure we have valid layout data in our parent document. If our
3962 // parent is throttled, we'll use possible stale layout informat ion and
3963 // rely on the fact that another lifecycle update will be schedu led once
3964 // our parent becomes unthrottled.
3965 ASSERT(parent->lifecycle().state() >= DocumentLifecycle::LayoutC lean || parent->shouldThrottleRendering());
3966 m_viewportIntersection = parent->contentsToRootFrame(frameRect() );
3967
3968 // TODO(skyostil): Expand the viewport to make it less likely to see stale content while scrolling.
3969 IntRect viewport = parent->m_viewportIntersection;
3970 m_viewportIntersection.intersect(viewport);
3971 }
3972 } else {
3973 m_viewportIntersection = frameRect();
3974 }
3975 }
3976
3955 m_needsUpdateViewportIntersection = false; 3977 m_needsUpdateViewportIntersection = false;
3956 m_viewportIntersectionValid = true; 3978 m_viewportIntersectionValid = true;
3957
3958 FrameView* parent = parentFrameView();
3959 if (!parent) {
3960 m_viewportIntersection = frameRect();
3961 return;
3962 }
3963 ASSERT(!parent->m_needsUpdateViewportIntersection);
3964
3965 // If our parent is hidden, then we are too.
3966 if (parent->m_viewportIntersection.isEmpty()) {
3967 m_viewportIntersection = parent->m_viewportIntersection;
3968 return;
3969 }
3970
3971 // Transform our bounds into the root frame's content coordinate space,
3972 // making sure we have valid layout data in our parent document. If our
3973 // parent is throttled, we'll use possible stale layout information and
3974 // rely on the fact that another lifecycle update will be scheduled once
3975 // our parent becomes unthrottled.
3976 ASSERT(parent->lifecycle().state() >= DocumentLifecycle::LayoutClean || pare nt->shouldThrottleRendering());
3977 m_viewportIntersection = parent->contentsToRootFrame(frameRect());
3978
3979 // TODO(skyostil): Expand the viewport to make it less likely to see stale c ontent while scrolling.
3980 IntRect viewport = parent->m_viewportIntersection;
3981 m_viewportIntersection.intersect(viewport);
3982 } 3979 }
3983 3980
3984 void FrameView::updateViewportIntersectionsForSubtree() 3981 void FrameView::updateViewportIntersectionsForSubtree()
3985 { 3982 {
3986 bool hadValidIntersection = m_viewportIntersectionValid; 3983 bool hadValidIntersection = m_viewportIntersectionValid;
3987 bool hadEmptyIntersection = m_viewportIntersection.isEmpty(); 3984 bool hadEmptyIntersection = m_viewportIntersection.isEmpty();
3988 updateViewportIntersectionIfNeeded(); 3985 updateViewportIntersectionIfNeeded();
3986
3987 // Notify javascript IntersectionObservers
3988 frame().document()->intersectionObservationRegistry()->computeIntersectionOb servations();
3989
3990 // Adjust render throttling for iframes based on visibility
3989 bool shouldNotify = !hadValidIntersection || hadEmptyIntersection != m_viewp ortIntersection.isEmpty(); 3991 bool shouldNotify = !hadValidIntersection || hadEmptyIntersection != m_viewp ortIntersection.isEmpty();
3990 if (shouldNotify && !m_intersectionObserverNotificationFactory->isPending()) 3992 if (shouldNotify && !m_renderThrottlingObserverNotificationFactory->isPendin g())
3991 m_frame->frameScheduler()->timerTaskRunner()->postTask(BLINK_FROM_HERE, m_intersectionObserverNotificationFactory->cancelAndCreate()); 3993 m_frame->frameScheduler()->timerTaskRunner()->postTask(BLINK_FROM_HERE, m_renderThrottlingObserverNotificationFactory->cancelAndCreate());
3992 3994
3993 if (!m_needsUpdateViewportIntersectionInSubtree) 3995 if (!m_needsUpdateViewportIntersectionInSubtree)
3994 return; 3996 return;
3995 m_needsUpdateViewportIntersectionInSubtree = false; 3997 m_needsUpdateViewportIntersectionInSubtree = false;
3996 3998
3997 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) { 3999 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) {
3998 if (!child->isLocalFrame()) 4000 if (!child->isLocalFrame())
3999 continue; 4001 continue;
4000 if (FrameView* view = toLocalFrame(child)->view()) 4002 if (FrameView* view = toLocalFrame(child)->view())
4001 view->updateViewportIntersectionsForSubtree(); 4003 view->updateViewportIntersectionsForSubtree();
4002 } 4004 }
4003 } 4005 }
4004 4006
4005 void FrameView::notifyIntersectionObservers() 4007 void FrameView::notifyRenderThrottlingObservers()
4006 { 4008 {
4007 TRACE_EVENT0("blink", "FrameView::notifyIntersectionObservers"); 4009 TRACE_EVENT0("blink", "FrameView::notifyRenderThrottlingObservers");
4008 ASSERT(!isInPerformLayout()); 4010 ASSERT(!isInPerformLayout());
4009 ASSERT(!m_frame->document()->inStyleRecalc()); 4011 ASSERT(!m_frame->document()->inStyleRecalc());
4010 bool wasThrottled = canThrottleRendering(); 4012 bool wasThrottled = canThrottleRendering();
4011 4013
4012 // Only offscreen frames can be throttled. 4014 // Only offscreen frames can be throttled.
4013 m_hiddenForThrottling = m_viewportIntersectionValid && m_viewportIntersectio n.isEmpty(); 4015 m_hiddenForThrottling = m_viewportIntersectionValid && m_viewportIntersectio n.isEmpty();
4014 4016
4015 // We only throttle the rendering pipeline in cross-origin frames. This is 4017 // We only throttle the rendering pipeline in cross-origin frames. This is
4016 // to avoid a situation where an ancestor frame directly depends on the 4018 // to avoid a situation where an ancestor frame directly depends on the
4017 // pipeline timing of a descendant and breaks as a result of throttling. 4019 // pipeline timing of a descendant and breaks as a result of throttling.
(...skipping 23 matching lines...) Expand all
4041 } 4043 }
4042 4044
4043 bool FrameView::canThrottleRendering() const 4045 bool FrameView::canThrottleRendering() const
4044 { 4046 {
4045 if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled()) 4047 if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled())
4046 return false; 4048 return false;
4047 return m_hiddenForThrottling && m_crossOriginForThrottling; 4049 return m_hiddenForThrottling && m_crossOriginForThrottling;
4048 } 4050 }
4049 4051
4050 } // namespace blink 4052 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698