| 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 * |
| 11 * This library is free software; you can redistribute it and/or | 11 * This library is free software; you can redistribute it and/or |
| 12 * modify it under the terms of the GNU Library General Public | 12 * modify it under the terms of the GNU Library General Public |
| 13 * License as published by the Free Software Foundation; either | 13 * License as published by the Free Software Foundation; either |
| 14 * version 2 of the License, or (at your option) any later version. | 14 * version 2 of the License, or (at your option) any later version. |
| 15 * | 15 * |
| 16 * This library is distributed in the hope that it will be useful, | 16 * This library is distributed in the hope that it will be useful, |
| 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 19 * Library General Public License for more details. | 19 * Library General Public License for more details. |
| 20 * | 20 * |
| 21 * You should have received a copy of the GNU Library General Public License | 21 * You should have received a copy of the GNU Library General Public License |
| 22 * along with this library; see the file COPYING.LIB. If not, write to | 22 * along with this library; see the file COPYING.LIB. If not, write to |
| 23 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 23 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 24 * Boston, MA 02110-1301, USA. | 24 * Boston, MA 02110-1301, USA. |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "core/frame/FrameView.h" | 27 #include "core/frame/FrameView.h" |
| 28 | 28 |
| 29 #include <algorithm> |
| 29 #include <memory> | 30 #include <memory> |
| 30 #include "core/HTMLNames.h" | 31 #include "core/HTMLNames.h" |
| 31 #include "core/MediaTypeNames.h" | 32 #include "core/MediaTypeNames.h" |
| 32 #include "core/animation/DocumentAnimations.h" | 33 #include "core/animation/DocumentAnimations.h" |
| 33 #include "core/css/FontFaceSet.h" | 34 #include "core/css/FontFaceSet.h" |
| 34 #include "core/dom/AXObjectCache.h" | 35 #include "core/dom/AXObjectCache.h" |
| 35 #include "core/dom/DOMNodeIds.h" | 36 #include "core/dom/DOMNodeIds.h" |
| 36 #include "core/dom/ElementVisibilityObserver.h" | 37 #include "core/dom/ElementVisibilityObserver.h" |
| 37 #include "core/dom/Fullscreen.h" | 38 #include "core/dom/Fullscreen.h" |
| 38 #include "core/dom/IntersectionObserverCallback.h" | 39 #include "core/dom/IntersectionObserverCallback.h" |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 if (!targetElement) | 322 if (!targetElement) |
| 322 return; | 323 return; |
| 323 | 324 |
| 324 m_visibilityObserver = new ElementVisibilityObserver( | 325 m_visibilityObserver = new ElementVisibilityObserver( |
| 325 targetElement, WTF::bind( | 326 targetElement, WTF::bind( |
| 326 [](FrameView* frameView, bool isVisible) { | 327 [](FrameView* frameView, bool isVisible) { |
| 327 if (!frameView) | 328 if (!frameView) |
| 328 return; | 329 return; |
| 329 frameView->updateRenderThrottlingStatus( | 330 frameView->updateRenderThrottlingStatus( |
| 330 !isVisible, frameView->m_subtreeThrottled); | 331 !isVisible, frameView->m_subtreeThrottled); |
| 331 frameView->maybeRecordLoadReason(); | |
| 332 }, | 332 }, |
| 333 wrapWeakPersistent(this))); | 333 wrapWeakPersistent(this))); |
| 334 m_visibilityObserver->start(); | 334 m_visibilityObserver->start(); |
| 335 } | 335 } |
| 336 | 336 |
| 337 void FrameView::dispose() { | 337 void FrameView::dispose() { |
| 338 RELEASE_ASSERT(!isInPerformLayout()); | 338 RELEASE_ASSERT(!isInPerformLayout()); |
| 339 | 339 |
| 340 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) | 340 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) |
| 341 scrollAnimator->cancelAnimation(); | 341 scrollAnimator->cancelAnimation(); |
| (...skipping 4404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4746 void FrameView::updateViewportIntersectionsForSubtree( | 4746 void FrameView::updateViewportIntersectionsForSubtree( |
| 4747 DocumentLifecycle::LifecycleState targetState) { | 4747 DocumentLifecycle::LifecycleState targetState) { |
| 4748 // TODO(dcheng): Since widget tree updates are deferred, FrameViews might | 4748 // TODO(dcheng): Since widget tree updates are deferred, FrameViews might |
| 4749 // still be in the widget hierarchy even though the associated Document is | 4749 // still be in the widget hierarchy even though the associated Document is |
| 4750 // already detached. Investigate if this check and a similar check in | 4750 // already detached. Investigate if this check and a similar check in |
| 4751 // lifecycle updates are still needed when there are no more deferred widget | 4751 // lifecycle updates are still needed when there are no more deferred widget |
| 4752 // updates: https://crbug.com/561683 | 4752 // updates: https://crbug.com/561683 |
| 4753 if (!frame().document()->isActive()) | 4753 if (!frame().document()->isActive()) |
| 4754 return; | 4754 return; |
| 4755 | 4755 |
| 4756 // Notify javascript IntersectionObservers | 4756 if (targetState == DocumentLifecycle::PaintClean) { |
| 4757 if (targetState == DocumentLifecycle::PaintClean && | 4757 recordDeferredLoadingStats(); |
| 4758 frame().document()->intersectionObserverController()) | 4758 // Notify javascript IntersectionObservers |
| 4759 frame() | 4759 if (frame().document()->intersectionObserverController()) { |
| 4760 .document() | 4760 frame() |
| 4761 ->intersectionObserverController() | 4761 .document() |
| 4762 ->computeTrackedIntersectionObservations(); | 4762 ->intersectionObserverController() |
| 4763 ->computeTrackedIntersectionObservations(); |
| 4764 } |
| 4765 } |
| 4763 | 4766 |
| 4764 // Don't throttle display:none frames (see updateRenderThrottlingStatus). | 4767 // Don't throttle display:none frames (see updateRenderThrottlingStatus). |
| 4765 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner(); | 4768 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner(); |
| 4766 if (m_hiddenForThrottling && ownerElement && !ownerElement->layoutObject()) { | 4769 if (m_hiddenForThrottling && ownerElement && !ownerElement->layoutObject()) { |
| 4767 // No need to notify children because descendants of display:none frames | 4770 // No need to notify children because descendants of display:none frames |
| 4768 // should remain throttled. | 4771 // should remain throttled. |
| 4769 updateRenderThrottlingStatus(m_hiddenForThrottling, m_subtreeThrottled, | 4772 updateRenderThrottlingStatus(m_hiddenForThrottling, m_subtreeThrottled, |
| 4770 DontForceThrottlingInvalidation, | 4773 DontForceThrottlingInvalidation, |
| 4771 DontNotifyChildren); | 4774 DontNotifyChildren); |
| 4772 DCHECK(!canThrottleRendering()); | 4775 DCHECK(!canThrottleRendering()); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4866 #if DCHECK_IS_ON() | 4869 #if DCHECK_IS_ON() |
| 4867 // Make sure we never have an unthrottled frame inside a throttled one. | 4870 // Make sure we never have an unthrottled frame inside a throttled one. |
| 4868 FrameView* parent = parentFrameView(); | 4871 FrameView* parent = parentFrameView(); |
| 4869 while (parent) { | 4872 while (parent) { |
| 4870 DCHECK(canThrottleRendering() || !parent->canThrottleRendering()); | 4873 DCHECK(canThrottleRendering() || !parent->canThrottleRendering()); |
| 4871 parent = parent->parentFrameView(); | 4874 parent = parent->parentFrameView(); |
| 4872 } | 4875 } |
| 4873 #endif | 4876 #endif |
| 4874 } | 4877 } |
| 4875 | 4878 |
| 4876 // TODO(esprehn): Rename this and the method on Document to | 4879 void FrameView::recordDeferredLoadingStats() { |
| 4877 // recordDeferredLoadReason(). | 4880 if (!frame().document()->frame() || !frame().isCrossOriginSubframe()) |
| 4878 void FrameView::maybeRecordLoadReason() { | 4881 return; |
| 4882 |
| 4879 FrameView* parent = parentFrameView(); | 4883 FrameView* parent = parentFrameView(); |
| 4880 if (frame().document()->frame()) { | 4884 if (!parent) { |
| 4881 if (!parent) { | 4885 HTMLFrameOwnerElement* element = frame().deprecatedLocalOwner(); |
| 4882 HTMLFrameOwnerElement* element = frame().deprecatedLocalOwner(); | 4886 // We would fall into an else block on some teardowns and other weird cases. |
| 4883 if (!element) | 4887 if (!element || !element->layoutObject()) |
| 4884 frame().document()->maybeRecordLoadReason(WouldLoadOutOfProcess); | 4888 frame().document()->recordDeferredLoadReason(WouldLoadNoParent); |
| 4885 // Having no layout object means the frame is not drawn. | 4889 return; |
| 4886 else if (!element->layoutObject()) | |
| 4887 frame().document()->maybeRecordLoadReason(WouldLoadDisplayNone); | |
| 4888 } else { | |
| 4889 // Assume the main frame has always loaded since we don't track its | |
| 4890 // visibility. | |
| 4891 bool parentLoaded = | |
| 4892 !parent->parentFrameView() || | |
| 4893 parent->frame().document()->wouldLoadReason() > Created; | |
| 4894 // If the parent wasn't loaded, the children won't be either. | |
| 4895 if (parentLoaded) { | |
| 4896 if (frameRect().isEmpty()) | |
| 4897 frame().document()->maybeRecordLoadReason(WouldLoadZeroByZero); | |
| 4898 else if (frameRect().maxY() < 0 && frameRect().maxX() < 0) | |
| 4899 frame().document()->maybeRecordLoadReason(WouldLoadAboveAndLeft); | |
| 4900 else if (frameRect().maxY() < 0) | |
| 4901 frame().document()->maybeRecordLoadReason(WouldLoadAbove); | |
| 4902 else if (frameRect().maxX() < 0) | |
| 4903 frame().document()->maybeRecordLoadReason(WouldLoadLeft); | |
| 4904 else if (!m_hiddenForThrottling) | |
| 4905 frame().document()->maybeRecordLoadReason(WouldLoadVisible); | |
| 4906 } | |
| 4907 } | |
| 4908 } | 4890 } |
| 4891 // Small inaccuracy: frames with origins that match the top level might be |
| 4892 // nested in a cross-origin frame. To keep code simpler, count such frames as |
| 4893 // WouldLoadVisible, even when their parent is offscreen. |
| 4894 WouldLoadReason whyParentLoaded = WouldLoadVisible; |
| 4895 if (parent->parentFrameView() && parent->frame().isCrossOriginSubframe()) |
| 4896 whyParentLoaded = parent->frame().document()->deferredLoadReason(); |
| 4897 |
| 4898 // If the parent wasn't loaded, the children won't be either. |
| 4899 if (whyParentLoaded == Created) |
| 4900 return; |
| 4901 // These frames are never meant to be seen so we will need to load them. |
| 4902 if (frameRect().isEmpty() || frameRect().maxY() < 0 || |
| 4903 frameRect().maxX() < 0) { |
| 4904 frame().document()->recordDeferredLoadReason(whyParentLoaded); |
| 4905 return; |
| 4906 } |
| 4907 |
| 4908 IntRect parentRect = parent->frameRect(); |
| 4909 // First clause: for this rough data collection we assume the user never |
| 4910 // scrolls right. |
| 4911 if (frameRect().x() >= parentRect.width() || parentRect.height() <= 0) |
| 4912 return; |
| 4913 |
| 4914 int thisFrameScreensAway = 0; |
| 4915 // If an frame is created above the current scoll position, this logic counts |
| 4916 // it as visible. |
| 4917 if (frameRect().y() > parent->getScrollOffset().height()) { |
| 4918 thisFrameScreensAway = |
| 4919 (frameRect().y() - parent->getScrollOffset().height()) / |
| 4920 parentRect.height(); |
| 4921 } |
| 4922 DCHECK_GE(thisFrameScreensAway, 0); |
| 4923 |
| 4924 int parentScreensAway = 0; |
| 4925 if (whyParentLoaded <= WouldLoadVisible) |
| 4926 parentScreensAway = WouldLoadVisible - whyParentLoaded; |
| 4927 |
| 4928 int totalScreensAway = thisFrameScreensAway + parentScreensAway; |
| 4929 |
| 4930 // We're collecting data for frames that are at most 3 screens away. |
| 4931 if (totalScreensAway > 3) |
| 4932 return; |
| 4933 |
| 4934 frame().document()->recordDeferredLoadReason( |
| 4935 static_cast<WouldLoadReason>(WouldLoadVisible - totalScreensAway)); |
| 4909 } | 4936 } |
| 4910 | 4937 |
| 4911 bool FrameView::shouldThrottleRendering() const { | 4938 bool FrameView::shouldThrottleRendering() const { |
| 4912 return canThrottleRendering() && m_frame->document() && | 4939 return canThrottleRendering() && m_frame->document() && |
| 4913 lifecycle().throttlingAllowed(); | 4940 lifecycle().throttlingAllowed(); |
| 4914 } | 4941 } |
| 4915 | 4942 |
| 4916 bool FrameView::canThrottleRendering() const { | 4943 bool FrameView::canThrottleRendering() const { |
| 4917 if (m_lifecycleUpdatesThrottled) | 4944 if (m_lifecycleUpdatesThrottled) |
| 4918 return true; | 4945 return true; |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5219 void FrameView::setAnimationHost( | 5246 void FrameView::setAnimationHost( |
| 5220 std::unique_ptr<CompositorAnimationHost> host) { | 5247 std::unique_ptr<CompositorAnimationHost> host) { |
| 5221 m_animationHost = std::move(host); | 5248 m_animationHost = std::move(host); |
| 5222 } | 5249 } |
| 5223 | 5250 |
| 5224 LayoutUnit FrameView::caretWidth() const { | 5251 LayoutUnit FrameView::caretWidth() const { |
| 5225 return LayoutUnit(getHostWindow()->windowToViewportScalar(1)); | 5252 return LayoutUnit(getHostWindow()->windowToViewportScalar(1)); |
| 5226 } | 5253 } |
| 5227 | 5254 |
| 5228 } // namespace blink | 5255 } // namespace blink |
| OLD | NEW |