| Index: Source/core/layout/LayoutView.cpp
|
| diff --git a/Source/core/layout/LayoutView.cpp b/Source/core/layout/LayoutView.cpp
|
| index d5102965e0d2959f55fff0960a523db1cbae834d..e52cea29f08306741b988dde2f4adf11b78d09b4 100644
|
| --- a/Source/core/layout/LayoutView.cpp
|
| +++ b/Source/core/layout/LayoutView.cpp
|
| @@ -28,7 +28,6 @@
|
| #include "core/html/HTMLFrameOwnerElement.h"
|
| #include "core/html/HTMLIFrameElement.h"
|
| #include "core/layout/ColumnInfo.h"
|
| -#include "core/layout/HitTestResult.h"
|
| #include "core/layout/LayoutFlowThread.h"
|
| #include "core/layout/LayoutGeometryMap.h"
|
| #include "core/layout/LayoutPart.h"
|
| @@ -42,6 +41,7 @@
|
| #include "platform/TraceEvent.h"
|
| #include "platform/geometry/FloatQuad.h"
|
| #include "platform/geometry/TransformState.h"
|
| +#include "platform/graphics/GraphicsLayer.h"
|
| #include "platform/graphics/paint/DisplayItemList.h"
|
|
|
| namespace blink {
|
| @@ -59,6 +59,7 @@ LayoutView::LayoutView(Document* document)
|
| , m_layoutQuoteHead(nullptr)
|
| , m_layoutCounterCount(0)
|
| , m_hitTestCount(0)
|
| + , m_hitTestCacheHits(0)
|
| , m_pendingSelection(PendingSelection::create())
|
| {
|
| // init LayoutObject attributes
|
| @@ -78,15 +79,10 @@ LayoutView::~LayoutView()
|
|
|
| bool LayoutView::hitTest(HitTestResult& result)
|
| {
|
| - return hitTest(result.hitTestRequest(), result.hitTestLocation(), result);
|
| -}
|
| -
|
| -bool LayoutView::hitTest(const HitTestRequest& request, const HitTestLocation& location, HitTestResult& result)
|
| -{
|
| TRACE_EVENT0("blink", "LayoutView::hitTest");
|
| m_hitTestCount++;
|
|
|
| - ASSERT(!location.isRectBasedTest() || request.listBased());
|
| + ASSERT(!result.hitTestLocation().isRectBasedTest() || result.hitTestRequest().listBased());
|
|
|
| // We have to recursively update layout/style here because otherwise, when the hit test recurses
|
| // into a child document, it could trigger a layout on the parent document, which can destroy DeprecatedPaintLayer
|
| @@ -96,18 +92,57 @@ bool LayoutView::hitTest(const HitTestRequest& request, const HitTestLocation& l
|
| frameView()->updateLayoutAndStyleForPainting();
|
| commitPendingSelection();
|
|
|
| - bool hitLayer = layer()->hitTest(request, location, result);
|
| + bool cacheHit = false;
|
| + // Determine if we should use the hit test cache.
|
| + if (frameView()->layoutCount() == m_hitTestCacheLayoutCount) {
|
| + if (!m_hitTestCacheResult.hitTestLocation().isRectBasedTest() && !result.hitTestLocation().isRectBasedTest() && m_hitTestCacheResult.validityRect().contains(result.hitTestLocation().point())) {
|
| + if (result.hitTestRequest().equalForCacheability(m_hitTestCacheResult.hitTestRequest())) {
|
| + m_hitTestCacheHits++;
|
| + cacheHit = true;
|
| + }
|
| + }
|
| + }
|
| + bool hitLayer = layer()->hitTest(result);
|
|
|
| // FrameView scrollbars are not the same as Layer scrollbars tested by Layer::hitTestOverflowControls,
|
| // so we need to test FrameView scrollbars separately here. Note that it's important we do this after
|
| // the hit test above, because that may overwrite the entire HitTestResult when it finds a hit.
|
| - IntPoint framePoint = frameView()->contentsToFrame(location.roundedPoint());
|
| + IntPoint framePoint = frameView()->contentsToFrame(result.hitTestLocation().roundedPoint());
|
| if (Scrollbar* frameScrollbar = frameView()->scrollbarAtFramePoint(framePoint))
|
| result.setScrollbar(frameScrollbar);
|
|
|
| + if (cacheHit) {
|
| + if (!m_hitTestCacheResult.equalForCacheability(result)) {
|
| + for (int i = 0; i < 10; ++i) {
|
| + layer()->hitTest(result);
|
| + }
|
| +
|
| + WTF_LOG_ERROR("Hit failure with %lf %lf cache %lf %lf", result.hitTestLocation().point().x().toDouble(), result.hitTestLocation().point().y().toDouble(), m_hitTestCacheResult.hitTestLocation().point().x().toDouble(), m_hitTestCacheResult.hitTestLocation().point().y().toDouble());
|
| +
|
| + // DCHECK that the cache hit is the same as the actual result
|
| + ASSERT(false);
|
| + }
|
| + }
|
| + if (hitLayer) {
|
| + m_hitTestCacheResult = result;
|
| + m_hitTestCacheLayoutCount = frameView()->layoutCount();
|
| +
|
| + // TODO(dtapuska): We shouldn't send the hit cache result to the compositor if
|
| + // we aren't displaying it in HUD: as it slows everything down.
|
| + if (layer()->graphicsLayerBacking()) {
|
| + layer()->graphicsLayerBacking()->platformLayer()->setHitCacheRect(enclosingIntRect(m_hitTestCacheResult.validityRect()));
|
| + }
|
| + }
|
| +
|
| return hitLayer;
|
| }
|
|
|
| +void LayoutView::clearHitTestCache()
|
| +{
|
| + m_hitTestCacheResult = HitTestResult();
|
| + m_hitTestCacheLayoutCount = 0;
|
| +}
|
| +
|
| void LayoutView::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit, LogicalExtentComputedValues& computedValues) const
|
| {
|
| computedValues.m_extent = (!shouldUsePrintingLayout() && m_frameView) ? LayoutUnit(viewLogicalHeight()) : logicalHeight;
|
| @@ -883,11 +918,12 @@ float LayoutView::zoomFactor() const
|
| return m_frameView->frame().pageZoomFactor();
|
| }
|
|
|
| -void LayoutView::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
|
| +void LayoutView::updateHitTestResult(HitTestResult& result, const LayoutPoint& point, const LayoutRect& rect)
|
| {
|
| if (result.innerNode())
|
| return;
|
|
|
| + result.intersectValidityRect(rect);
|
| Node* node = document().documentElement();
|
| if (node) {
|
| LayoutPoint adjustedPoint = point;
|
|
|