Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 #include "platform/scroll/ScrollAnimatorBase.h" | 118 #include "platform/scroll/ScrollAnimatorBase.h" |
| 119 #include "platform/scroll/ScrollbarTheme.h" | 119 #include "platform/scroll/ScrollbarTheme.h" |
| 120 #include "platform/text/TextStream.h" | 120 #include "platform/text/TextStream.h" |
| 121 #include "platform/tracing/TraceEvent.h" | 121 #include "platform/tracing/TraceEvent.h" |
| 122 #include "platform/tracing/TracedValue.h" | 122 #include "platform/tracing/TracedValue.h" |
| 123 #include "public/platform/WebDisplayItemList.h" | 123 #include "public/platform/WebDisplayItemList.h" |
| 124 #include "public/platform/WebFrameScheduler.h" | 124 #include "public/platform/WebFrameScheduler.h" |
| 125 #include "wtf/CurrentTime.h" | 125 #include "wtf/CurrentTime.h" |
| 126 #include "wtf/PtrUtil.h" | 126 #include "wtf/PtrUtil.h" |
| 127 #include "wtf/StdLibExtras.h" | 127 #include "wtf/StdLibExtras.h" |
| 128 #include <algorithm> | |
| 128 #include <memory> | 129 #include <memory> |
| 129 | 130 |
| 130 // Used to check for dirty layouts violating document lifecycle rules. | 131 // Used to check for dirty layouts violating document lifecycle rules. |
| 131 // If arg evaluates to true, the program will continue. If arg evaluates to | 132 // If arg evaluates to true, the program will continue. If arg evaluates to |
| 132 // false, program will crash if DCHECK_IS_ON() or return false from the current | 133 // false, program will crash if DCHECK_IS_ON() or return false from the current |
| 133 // function. | 134 // function. |
| 134 #define CHECK_FOR_DIRTY_LAYOUT(arg) \ | 135 #define CHECK_FOR_DIRTY_LAYOUT(arg) \ |
| 135 do { \ | 136 do { \ |
| 136 if (!(arg)) { \ | 137 if (!(arg)) { \ |
| 137 NOTREACHED(); \ | 138 NOTREACHED(); \ |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 166 m_baseBackgroundColor(Color::white), | 167 m_baseBackgroundColor(Color::white), |
| 167 m_mediaType(MediaTypeNames::screen), | 168 m_mediaType(MediaTypeNames::screen), |
| 168 m_safeToPropagateScrollToParent(true), | 169 m_safeToPropagateScrollToParent(true), |
| 169 m_scrollCorner(nullptr), | 170 m_scrollCorner(nullptr), |
| 170 m_stickyPositionObjectCount(0), | 171 m_stickyPositionObjectCount(0), |
| 171 m_inputEventsScaleFactorForEmulation(1), | 172 m_inputEventsScaleFactorForEmulation(1), |
| 172 m_layoutSizeFixedToFrameSize(true), | 173 m_layoutSizeFixedToFrameSize(true), |
| 173 m_didScrollTimer(this, &FrameView::didScrollTimerFired), | 174 m_didScrollTimer(this, &FrameView::didScrollTimerFired), |
| 174 m_browserControlsViewportAdjustment(0), | 175 m_browserControlsViewportAdjustment(0), |
| 175 m_needsUpdateWidgetGeometries(false), | 176 m_needsUpdateWidgetGeometries(false), |
| 176 m_needsUpdateViewportIntersection(true), | |
| 177 #if ENABLE(ASSERT) | 177 #if ENABLE(ASSERT) |
| 178 m_hasBeenDisposed(false), | 178 m_hasBeenDisposed(false), |
| 179 #endif | 179 #endif |
| 180 m_horizontalScrollbarMode(ScrollbarAuto), | 180 m_horizontalScrollbarMode(ScrollbarAuto), |
| 181 m_verticalScrollbarMode(ScrollbarAuto), | 181 m_verticalScrollbarMode(ScrollbarAuto), |
| 182 m_horizontalScrollbarLock(false), | 182 m_horizontalScrollbarLock(false), |
| 183 m_verticalScrollbarLock(false), | 183 m_verticalScrollbarLock(false), |
| 184 m_scrollbarsSuppressed(false), | 184 m_scrollbarsSuppressed(false), |
| 185 m_inUpdateScrollbars(false), | 185 m_inUpdateScrollbars(false), |
| 186 m_frameTimingRequestsDirty(true), | 186 m_frameTimingRequestsDirty(true), |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 // frames whose owner element is remote. | 304 // frames whose owner element is remote. |
| 305 Element* targetElement = frame().deprecatedLocalOwner(); | 305 Element* targetElement = frame().deprecatedLocalOwner(); |
| 306 if (!targetElement) | 306 if (!targetElement) |
| 307 return; | 307 return; |
| 308 | 308 |
| 309 m_visibilityObserver = new ElementVisibilityObserver( | 309 m_visibilityObserver = new ElementVisibilityObserver( |
| 310 targetElement, WTF::bind( | 310 targetElement, WTF::bind( |
| 311 [](FrameView* frameView, bool isVisible) { | 311 [](FrameView* frameView, bool isVisible) { |
| 312 frameView->updateRenderThrottlingStatus( | 312 frameView->updateRenderThrottlingStatus( |
| 313 !isVisible, frameView->m_subtreeThrottled); | 313 !isVisible, frameView->m_subtreeThrottled); |
| 314 frameView->maybeRecordLoadReason(); | 314 frameView->recordDeferredLoadingStats(); |
| 315 }, | 315 }, |
| 316 wrapWeakPersistent(this))); | 316 wrapWeakPersistent(this))); |
| 317 m_visibilityObserver->start(); | 317 m_visibilityObserver->start(); |
| 318 } | 318 } |
| 319 | 319 |
| 320 void FrameView::dispose() { | 320 void FrameView::dispose() { |
| 321 RELEASE_ASSERT(!isInPerformLayout()); | 321 RELEASE_ASSERT(!isInPerformLayout()); |
| 322 | 322 |
| 323 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) | 323 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) |
| 324 scrollAnimator->cancelAnimation(); | 324 scrollAnimator->cancelAnimation(); |
| (...skipping 4143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4468 } | 4468 } |
| 4469 | 4469 |
| 4470 void FrameView::setNeedsUpdateViewportIntersection() { | 4470 void FrameView::setNeedsUpdateViewportIntersection() { |
| 4471 for (FrameView* parent = parentFrameView(); parent; | 4471 for (FrameView* parent = parentFrameView(); parent; |
| 4472 parent = parent->parentFrameView()) | 4472 parent = parent->parentFrameView()) |
| 4473 parent->m_needsUpdateViewportIntersectionInSubtree = true; | 4473 parent->m_needsUpdateViewportIntersectionInSubtree = true; |
| 4474 } | 4474 } |
| 4475 | 4475 |
| 4476 void FrameView::updateViewportIntersectionsForSubtree( | 4476 void FrameView::updateViewportIntersectionsForSubtree( |
| 4477 DocumentLifecycle::LifecycleState targetState) { | 4477 DocumentLifecycle::LifecycleState targetState) { |
| 4478 // Notify javascript IntersectionObservers | 4478 if (targetState == DocumentLifecycle::PaintClean) { |
| 4479 if (targetState == DocumentLifecycle::PaintClean && | 4479 recordDeferredLoadingStats(); |
| 4480 frame().document()->intersectionObserverController()) | 4480 // Notify javascript IntersectionObservers |
| 4481 frame() | 4481 if (frame().document()->intersectionObserverController()) { |
| 4482 .document() | 4482 frame() |
| 4483 ->intersectionObserverController() | 4483 .document() |
| 4484 ->computeTrackedIntersectionObservations(); | 4484 ->intersectionObserverController() |
| 4485 ->computeTrackedIntersectionObservations(); | |
| 4486 } | |
| 4487 } | |
| 4485 | 4488 |
| 4486 if (!m_needsUpdateViewportIntersectionInSubtree) | 4489 if (!m_needsUpdateViewportIntersectionInSubtree) |
| 4487 return; | 4490 return; |
| 4488 m_needsUpdateViewportIntersectionInSubtree = false; | 4491 m_needsUpdateViewportIntersectionInSubtree = false; |
| 4489 | 4492 |
| 4490 for (Frame* child = m_frame->tree().firstChild(); child; | 4493 for (Frame* child = m_frame->tree().firstChild(); child; |
| 4491 child = child->tree().nextSibling()) { | 4494 child = child->tree().nextSibling()) { |
| 4492 if (!child->isLocalFrame()) | 4495 if (!child->isLocalFrame()) |
| 4493 continue; | 4496 continue; |
| 4494 if (FrameView* view = toLocalFrame(child)->view()) | 4497 if (FrameView* view = toLocalFrame(child)->view()) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4557 #if DCHECK_IS_ON() | 4560 #if DCHECK_IS_ON() |
| 4558 // Make sure we never have an unthrottled frame inside a throttled one. | 4561 // Make sure we never have an unthrottled frame inside a throttled one. |
| 4559 FrameView* parent = parentFrameView(); | 4562 FrameView* parent = parentFrameView(); |
| 4560 while (parent) { | 4563 while (parent) { |
| 4561 DCHECK(canThrottleRendering() || !parent->canThrottleRendering()); | 4564 DCHECK(canThrottleRendering() || !parent->canThrottleRendering()); |
| 4562 parent = parent->parentFrameView(); | 4565 parent = parent->parentFrameView(); |
| 4563 } | 4566 } |
| 4564 #endif | 4567 #endif |
| 4565 } | 4568 } |
| 4566 | 4569 |
| 4567 // TODO(esprehn): Rename this and the method on Document to | 4570 void FrameView::recordDeferredLoadingStats() { |
| 4568 // recordDeferredLoadReason(). | 4571 if (!frame().document()->frame() || !frame().isCrossOriginSubframe()) |
| 4569 void FrameView::maybeRecordLoadReason() { | 4572 return; |
| 4570 FrameView* parent = parentFrameView(); | 4573 FrameView* parent = parentFrameView(); |
| 4571 if (frame().document()->frame()) { | 4574 if (!parent) { |
| 4572 if (!parent) { | 4575 HTMLFrameOwnerElement* element = frame().deprecatedLocalOwner(); |
| 4573 HTMLFrameOwnerElement* element = frame().deprecatedLocalOwner(); | 4576 // We would fall into an else block on some teardowns and other weird cases. |
| 4574 if (!element) | 4577 if (!element || !element->layoutObject()) |
| 4575 frame().document()->maybeRecordLoadReason(WouldLoadOutOfProcess); | 4578 frame().document()->recordDeferredLoadReason(WouldLoadNoParent); |
| 4576 // Having no layout object means the frame is not drawn. | 4579 return; |
| 4577 else if (!element->layoutObject()) | 4580 } |
| 4578 frame().document()->maybeRecordLoadReason(WouldLoadDisplayNone); | 4581 // Small inaccuracy: frames with origins that match the top level might be |
| 4579 } else { | 4582 // nested in a cross-origin frame. To keep code simpler, count such frames as |
| 4580 // Assume the main frame has always loaded since we don't track its | 4583 // WouldLoadVisible, even when their parent is offscreen. |
| 4581 // visibility. | 4584 WouldLoadReason whyParentLoaded = WouldLoadVisible; |
| 4582 bool parentLoaded = | 4585 if (parent->parentFrameView() && parent->frame().isCrossOriginSubframe()) |
| 4583 !parent->parentFrameView() || | 4586 whyParentLoaded = parent->frame().document()->deferredLoadReason(); |
| 4584 parent->frame().document()->wouldLoadReason() > Created; | 4587 |
| 4585 // If the parent wasn't loaded, the children won't be either. | 4588 // If the parent wasn't loaded, the children won't be either. |
| 4586 if (parentLoaded) { | 4589 if (whyParentLoaded == Created) |
| 4587 if (frameRect().isEmpty()) | 4590 return; |
| 4588 frame().document()->maybeRecordLoadReason(WouldLoadZeroByZero); | 4591 if (frameRect().isEmpty() || frameRect().maxY() < 0 || |
| 4589 else if (frameRect().maxY() < 0 && frameRect().maxX() < 0) | 4592 frameRect().maxX() < 0) { |
| 4590 frame().document()->maybeRecordLoadReason(WouldLoadAboveAndLeft); | 4593 frame().document()->recordDeferredLoadReason(whyParentLoaded); |
| 4591 else if (frameRect().maxY() < 0) | 4594 return; |
| 4592 frame().document()->maybeRecordLoadReason(WouldLoadAbove); | 4595 } |
| 4593 else if (frameRect().maxX() < 0) | 4596 IntRect parentRect = parent->frameRect(); |
| 4594 frame().document()->maybeRecordLoadReason(WouldLoadLeft); | 4597 if (FrameView* grandParent = parent->parentFrameView()) |
| 4595 else if (!m_hiddenForThrottling) | 4598 parentRect = grandParent->contentsToRootFrame(parentRect); |
|
Z_DONOTUSE
2016/12/11 03:39:44
Unfortunately, I think this is n^2 in the frame tr
dgrogan
2016/12/20 22:27:08
I think it's nlgn in the common case but n^2 in th
| |
| 4596 frame().document()->maybeRecordLoadReason(WouldLoadVisible); | 4599 const IntRect childRect = parent->contentsToRootFrame(frameRect()); |
| 4597 } | 4600 // Optimization opportunity: Do some arithmetic instead of looping over each |
| 4601 // of the repositioned viewports. | |
| 4602 for (int i = 0; i <= 3; ++i) { | |
| 4603 IntRect expandedParentRect(parentRect); | |
| 4604 expandedParentRect.expand(0, i * parentRect.height()); | |
| 4605 if (expandedParentRect.intersects(childRect)) { | |
| 4606 frame().document()->recordDeferredLoadReason(static_cast<WouldLoadReason>( | |
| 4607 std::min(static_cast<int>(whyParentLoaded), WouldLoadVisible - i))); | |
| 4608 return; | |
| 4598 } | 4609 } |
| 4599 } | 4610 } |
| 4600 } | 4611 } |
| 4601 | 4612 |
| 4602 bool FrameView::shouldThrottleRendering() const { | 4613 bool FrameView::shouldThrottleRendering() const { |
| 4603 return canThrottleRendering() && m_frame->document() && | 4614 return canThrottleRendering() && m_frame->document() && |
| 4604 lifecycle().throttlingAllowed(); | 4615 lifecycle().throttlingAllowed(); |
| 4605 } | 4616 } |
| 4606 | 4617 |
| 4607 bool FrameView::canThrottleRendering() const { | 4618 bool FrameView::canThrottleRendering() const { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4646 DCHECK(m_frame->isMainFrame()); | 4657 DCHECK(m_frame->isMainFrame()); |
| 4647 return m_initialViewportSize.width(); | 4658 return m_initialViewportSize.width(); |
| 4648 } | 4659 } |
| 4649 | 4660 |
| 4650 int FrameView::initialViewportHeight() const { | 4661 int FrameView::initialViewportHeight() const { |
| 4651 DCHECK(m_frame->isMainFrame()); | 4662 DCHECK(m_frame->isMainFrame()); |
| 4652 return m_initialViewportSize.height(); | 4663 return m_initialViewportSize.height(); |
| 4653 } | 4664 } |
| 4654 | 4665 |
| 4655 } // namespace blink | 4666 } // namespace blink |
| OLD | NEW |