- Revision
- 132279
- Author
- commit-qu...@webkit.org
- Date
- 2012-10-23 16:10:50 -0700 (Tue, 23 Oct 2012)
Log Message
[BlackBerry] Cache TouchDown HitTestResult to avoid calling RenderLayer::hitTest unnecessarily
https://bugs.webkit.org/show_bug.cgi?id=99649
Patch by Mike Lattanzio <mlattan...@rim.com> on 2012-10-23
Reviewed by George Staikos.
Random latency before scroll starts on sites like http://pintrest.com
Internal PR225398
The chief problem here is the all the hit testing that we do for
touch events and simulated mouse events. If the render tree is dirty
hit tests can take a long time in Document::recalcStyle(). Masking
the flags that force style recalculations will make them fast, at the
expense that they might be happening on stale data.
Since we are only using these hit tests to look for event handlers -
we're not actually modifying anything, it is better to skip the
Document::recalcStyle() and save ourselves tons of time.
* Api/InRegionScroller.cpp:
(BlackBerry::WebKit::InRegionScrollerPrivate::calculateInRegionScrollableAreasForPoint):
* Api/WebPage.cpp:
(BlackBerry::WebKit::WebPagePrivate::WebPagePrivate):
(BlackBerry::WebKit::WebPage::touchEvent):
(BlackBerry::WebKit::WebPagePrivate::setScrollOriginPoint):
(BlackBerry::WebKit::WebPagePrivate::postponeDocumentStyleRecalc):
(WebKit):
(BlackBerry::WebKit::WebPagePrivate::resumeDocumentStyleRecalc):
(BlackBerry::WebKit::WebPagePrivate::hitTestResult):
(BlackBerry::WebKit::WebPagePrivate::clearCachedHitTestResult):
* Api/WebPage_p.h:
(WebPagePrivate):
* WebKitSupport/FatFingers.cpp:
(BlackBerry::WebKit::FatFingers::findBestPoint):
(BlackBerry::WebKit::FatFingers::getRelevantInfoFromCachedHitTest):
* WebKitSupport/FatFingers.h:
* WebKitSupport/TouchEventHandler.cpp:
(BlackBerry::WebKit::TouchEventHandler::handleTouchPoint):
Modified Paths
Diff
Modified: trunk/Source/WebKit/blackberry/Api/InRegionScroller.cpp (132278 => 132279)
--- trunk/Source/WebKit/blackberry/Api/InRegionScroller.cpp 2012-10-23 22:46:22 UTC (rev 132278)
+++ trunk/Source/WebKit/blackberry/Api/InRegionScroller.cpp 2012-10-23 23:10:50 UTC (rev 132279)
@@ -202,7 +202,7 @@
ASSERT(m_activeInRegionScrollableAreas.empty());
m_needsActiveScrollableAreaCalculation = false;
- HitTestResult result = m_webPage->m_mainFrame->eventHandler()->hitTestResultAtPoint(m_webPage->mapFromViewportToContents(point));
+ const HitTestResult& result = m_webPage->hitTestResult(m_webPage->mapFromViewportToContents(point));
Node* node = result.innerNonSharedNode();
if (!node || !node->renderer())
return;
Modified: trunk/Source/WebKit/blackberry/Api/WebPage.cpp (132278 => 132279)
--- trunk/Source/WebKit/blackberry/Api/WebPage.cpp 2012-10-23 22:46:22 UTC (rev 132278)
+++ trunk/Source/WebKit/blackberry/Api/WebPage.cpp 2012-10-23 23:10:50 UTC (rev 132279)
@@ -432,6 +432,8 @@
, m_deferredTasksTimer(this, &WebPagePrivate::deferredTasksTimerFired)
, m_selectPopup(0)
, m_autofillManager(AutofillManager::create(this))
+ , m_documentStyleRecalcPostponed(false)
+ , m_documentChildNeedsStyleRecalc(false)
{
static bool isInitialized = false;
if (!isInitialized) {
@@ -441,6 +443,7 @@
}
AuthenticationChallengeManager::instance()->pageCreated(this);
+ clearCachedHitTestResult();
}
WebPage::WebPage(WebPageClient* client, const BlackBerry::Platform::String& pageGroupName, const Platform::IntRect& rect)
@@ -4074,6 +4077,9 @@
else if (tEvent.m_type == Platform::TouchEvent::TouchStart || tEvent.m_type == Platform::TouchEvent::TouchCancel)
d->m_pluginMayOpenNewTab = false;
+ if (tEvent.m_type == Platform::TouchEvent::TouchStart)
+ d->clearCachedHitTestResult();
+
bool handled = false;
if (d->m_needTouchEvents && !event.hasGesture(Platform::Gesture::Injected))
@@ -4110,9 +4116,11 @@
if (!m_hasInRegionScrollableAreas)
return;
+ postponeDocumentStyleRecalc();
m_inRegionScroller->d->calculateInRegionScrollableAreasForPoint(point);
if (!m_inRegionScroller->d->activeInRegionScrollableAreas().empty())
m_client->notifyInRegionScrollableAreasChanged(m_inRegionScroller->d->activeInRegionScrollableAreas());
+ resumeDocumentStyleRecalc();
}
void WebPage::setScrollOriginPoint(const Platform::IntPoint& point)
@@ -6327,5 +6335,45 @@
return Platform::Graphics::Screen::primaryScreen()->size();
}
+bool WebPagePrivate::postponeDocumentStyleRecalc()
+{
+ if (Document* document = m_mainFrame->document()) {
+ m_documentChildNeedsStyleRecalc = document->childNeedsStyleRecalc();
+ document->clearChildNeedsStyleRecalc();
+
+ m_documentStyleRecalcPostponed = document->isPendingStyleRecalc();
+ document->unscheduleStyleRecalc();
+ }
}
+
+void WebPagePrivate::resumeDocumentStyleRecalc()
+{
+ if (Document* document = m_mainFrame->document()) {
+ if (m_documentChildNeedsStyleRecalc)
+ document->setChildNeedsStyleRecalc();
+
+ if (m_documentStyleRecalcPostponed)
+ document->scheduleStyleRecalc();
+ }
+
+ m_documentChildNeedsStyleRecalc = false;
+ m_documentStyleRecalcPostponed = false;
}
+
+const HitTestResult& WebPagePrivate::hitTestResult(const IntPoint& contentPos)
+{
+ if (m_cachedHitTestContentPos != contentPos) {
+ m_cachedHitTestContentPos = contentPos;
+ m_cachedHitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(m_cachedHitTestContentPos, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowShadowContent);
+ }
+
+ return m_cachedHitTestResult;
+}
+
+void WebPagePrivate::clearCachedHitTestResult()
+{
+ m_cachedHitTestContentPos = WebCore::IntPoint(-1, -1);
+}
+
+}
+}
Modified: trunk/Source/WebKit/blackberry/Api/WebPage_p.h (132278 => 132279)
--- trunk/Source/WebKit/blackberry/Api/WebPage_p.h 2012-10-23 22:46:22 UTC (rev 132278)
+++ trunk/Source/WebKit/blackberry/Api/WebPage_p.h 2012-10-23 23:10:50 UTC (rev 132279)
@@ -20,6 +20,7 @@
#define WebPage_p_h
#include "ChromeClient.h"
+#include "HitTestResult.h"
#include "InRegionScroller.h"
#include "InspectorClientBlackBerry.h"
#include "InspectorOverlay.h"
@@ -460,6 +461,12 @@
void applySizeOverride(int overrideWidth, int overrideHeight);
void setTextZoomFactor(float);
+ bool postponeDocumentStyleRecalc();
+ void resumeDocumentStyleRecalc();
+
+ const WebCore::HitTestResult& hitTestResult(const WebCore::IntPoint& contentPos);
+ void clearCachedHitTestResult();
+
WebCore::IntSize screenSize() const;
WebPage* m_webPage;
@@ -637,6 +644,12 @@
WebCore::PagePopupBlackBerry* m_selectPopup;
RefPtr<WebCore::AutofillManager> m_autofillManager;
+
+ bool m_documentStyleRecalcPostponed;
+ bool m_documentChildNeedsStyleRecalc;
+
+ WebCore::IntPoint m_cachedHitTestContentPos;
+ WebCore::HitTestResult m_cachedHitTestResult;
protected:
virtual ~WebPagePrivate();
};
Modified: trunk/Source/WebKit/blackberry/ChangeLog (132278 => 132279)
--- trunk/Source/WebKit/blackberry/ChangeLog 2012-10-23 22:46:22 UTC (rev 132278)
+++ trunk/Source/WebKit/blackberry/ChangeLog 2012-10-23 23:10:50 UTC (rev 132279)
@@ -1,3 +1,43 @@
+2012-10-23 Mike Lattanzio <mlattan...@rim.com>
+
+ [BlackBerry] Cache TouchDown HitTestResult to avoid calling RenderLayer::hitTest unnecessarily
+ https://bugs.webkit.org/show_bug.cgi?id=99649
+
+ Reviewed by George Staikos.
+
+ Random latency before scroll starts on sites like http://pintrest.com
+ Internal PR225398
+
+ The chief problem here is the all the hit testing that we do for
+ touch events and simulated mouse events. If the render tree is dirty
+ hit tests can take a long time in Document::recalcStyle(). Masking
+ the flags that force style recalculations will make them fast, at the
+ expense that they might be happening on stale data.
+
+ Since we are only using these hit tests to look for event handlers -
+ we're not actually modifying anything, it is better to skip the
+ Document::recalcStyle() and save ourselves tons of time.
+
+ * Api/InRegionScroller.cpp:
+ (BlackBerry::WebKit::InRegionScrollerPrivate::calculateInRegionScrollableAreasForPoint):
+ * Api/WebPage.cpp:
+ (BlackBerry::WebKit::WebPagePrivate::WebPagePrivate):
+ (BlackBerry::WebKit::WebPage::touchEvent):
+ (BlackBerry::WebKit::WebPagePrivate::setScrollOriginPoint):
+ (BlackBerry::WebKit::WebPagePrivate::postponeDocumentStyleRecalc):
+ (WebKit):
+ (BlackBerry::WebKit::WebPagePrivate::resumeDocumentStyleRecalc):
+ (BlackBerry::WebKit::WebPagePrivate::hitTestResult):
+ (BlackBerry::WebKit::WebPagePrivate::clearCachedHitTestResult):
+ * Api/WebPage_p.h:
+ (WebPagePrivate):
+ * WebKitSupport/FatFingers.cpp:
+ (BlackBerry::WebKit::FatFingers::findBestPoint):
+ (BlackBerry::WebKit::FatFingers::getRelevantInfoFromCachedHitTest):
+ * WebKitSupport/FatFingers.h:
+ * WebKitSupport/TouchEventHandler.cpp:
+ (BlackBerry::WebKit::TouchEventHandler::handleTouchPoint):
+
2012-10-23 Rob Buis <rb...@rim.com>
[BlackBerry] Make selection in search input box not overlap cancel button
Modified: trunk/Source/WebKit/blackberry/WebKitSupport/FatFingers.cpp (132278 => 132279)
--- trunk/Source/WebKit/blackberry/WebKitSupport/FatFingers.cpp 2012-10-23 22:46:22 UTC (rev 132278)
+++ trunk/Source/WebKit/blackberry/WebKitSupport/FatFingers.cpp 2012-10-23 23:10:50 UTC (rev 132279)
@@ -181,7 +181,7 @@
// targable is actually found by ::findIntersectingRegions, then we might replace what we just set below later on.
Element* elementUnderPoint;
Element* clickableElementUnderPoint;
- getRelevantInfoFromPoint(m_webPage->m_mainFrame->document(), m_contentPos, elementUnderPoint, clickableElementUnderPoint);
+ getRelevantInfoFromCachedHitTest(elementUnderPoint, clickableElementUnderPoint);
if (elementUnderPoint) {
result.m_nodeUnderFatFinger = elementUnderPoint;
@@ -500,15 +500,12 @@
m_cachedRectHitTestResults.add(document, intersectedNodes);
}
-void FatFingers::getRelevantInfoFromPoint(Document* document, const IntPoint& contentPos, Element*& elementUnderPoint, Element*& clickableElementUnderPoint) const
+void FatFingers::getRelevantInfoFromCachedHitTest(Element*& elementUnderPoint, Element*& clickableElementUnderPoint) const
{
elementUnderPoint = 0;
clickableElementUnderPoint = 0;
- if (!document || !document->renderer() || !document->frame())
- return;
-
- HitTestResult result = document->frame()->eventHandler()->hitTestResultAtPoint(contentPos, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowShadowContent);
+ const HitTestResult& result = m_webPage->hitTestResult(m_contentPos);
Node* node = result.innerNode();
while (node && !node->isElementNode())
node = node->parentNode();
Modified: trunk/Source/WebKit/blackberry/WebKitSupport/FatFingers.h (132278 => 132279)
--- trunk/Source/WebKit/blackberry/WebKitSupport/FatFingers.h 2012-10-23 22:46:22 UTC (rev 132278)
+++ trunk/Source/WebKit/blackberry/WebKitSupport/FatFingers.h 2012-10-23 23:10:50 UTC (rev 132279)
@@ -99,10 +99,7 @@
void getNodesFromRect(WebCore::Document*, const WebCore::IntPoint&, ListHashSet<RefPtr<WebCore::Node> >&);
// It mimics Document::elementFromPoint, but recursively hit-tests in case an inner frame is found.
- void getRelevantInfoFromPoint(WebCore::Document*,
- const WebCore::IntPoint&,
- WebCore::Element*& elementUnderPoint,
- WebCore::Element*& clickableElementUnderPoint) const;
+ void getRelevantInfoFromCachedHitTest(WebCore::Element*& elementUnderPoint, WebCore::Element*& clickableElementUnderPoint) const;
bool isElementClickable(WebCore::Element*) const;
Modified: trunk/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.cpp (132278 => 132279)
--- trunk/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.cpp 2012-10-23 22:46:22 UTC (rev 132278)
+++ trunk/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.cpp 2012-10-23 23:10:50 UTC (rev 132279)
@@ -199,6 +199,7 @@
IntPoint contentPos(m_webPage->mapFromViewportToContents(point.m_pos));
+ m_webPage->postponeDocumentStyleRecalc();
m_lastFatFingersResult = FatFingers(m_webPage, contentPos, FatFingers::ClickableElement).findBestPoint();
Element* elementUnderFatFinger = 0;
@@ -214,6 +215,8 @@
if (!possibleTargetNodeForMouseMoveEvents || (!possibleTargetNodeForMouseMoveEvents->hasEventListeners(eventNames().touchmoveEvent) && !m_convertTouchToMouse))
m_webPage->client()->notifyNoMouseMoveOrTouchMoveHandlers();
+ m_webPage->resumeDocumentStyleRecalc();
+
if (elementUnderFatFinger)
drawTapHighlight();