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

Unified Diff: Source/core/layout/LayoutView.cpp

Issue 1142283004: Implement a Hit Test Cache. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 7 months 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 side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698