Commit 270ab3a5 authored by timothy_horton@apple.com's avatar timothy_horton@apple.com
Browse files

Add optional debug logging when we fall into/out of threaded scrolling

https://bugs.webkit.org/show_bug.cgi?id=93898
<rdar://problem/12089098>

Reviewed by Simon Fraser.

Add logging when we enter and exit the threaded scrolling mode, and logs the reasons we
fall into main-thread scrolling.

The logging output looks like this:
    SCROLLING: Switching to main-thread scrolling mode. Time: 15843.554718 Reason(s): viewport-constrained objects
    SCROLLING: Switching to threaded scrolling mode. Time: 15844.550866
    SCROLLING: Switching to main-thread scrolling mode. Time: 15845.551214 Reason(s): viewport-constrained objects
    SCROLLING: Switching to threaded scrolling mode. Time: 15846.552619
    SCROLLING: Switching to main-thread scrolling mode. Time: 15847.553587 Reason(s): viewport-constrained objects
    SCROLLING: Switching to threaded scrolling mode. Time: 15848.554084

No new tests, as this is just debugging logging.

* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::updateShouldUpdateScrollLayerPositionOnMainThread):
Construct a bitfield describing the reasons we fall into main-thread scrolling mode.

* page/scrolling/ScrollingCoordinatorNone.cpp:
(WebCore::ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/ScrollingTreeNode.cpp:
(WebCore::ScrollingTreeNode::ScrollingTreeNode):
* page/scrolling/ScrollingTreeNode.h:
(WebCore::ScrollingTreeNode::shouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/ScrollingTreeState.cpp:
(WebCore::ScrollingTreeState::ScrollingTreeState):
(WebCore::ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/ScrollingTreeState.h:
(WebCore::ScrollingTreeState::shouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/chromium/ScrollingCoordinatorChromium.cpp:
(WebCore::ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread):
Use the reasons bitfield instead of a boolean.

* page/scrolling/ScrollingCoordinator.h:
(ScrollingCoordinator):
Add MainThreadScrollingReasons enum, with the current reasons that we might fallback to main-thread scrolling.

* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::scrollingPerformanceLoggingEnabled):
Fix a typo (scrollingPeformanceLoggingEnabled -> scrollingPerformanceLoggingEnabled).

* page/scrolling/mac/ScrollingTreeNodeMac.mm:
(WebCore::ScrollingTreeNodeMac::update):
(WebCore::ScrollingTreeNodeMac::setScrollPosition):
(WebCore::logThreadedScrollingMode):
Pretty-print the scrolling mode and shouldUpdateScrollLayerPositionOnMainThreadReason.

Update the scrolling tree's scrollingPerformanceLoggingEnabled preference
before the early-return if we don't have layer debugging borders on.

* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::updatePreferences):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@128521 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent bcd32823
2012-09-13 Tim Horton <timothy_horton@apple.com>
Add optional debug logging when we fall into/out of threaded scrolling
https://bugs.webkit.org/show_bug.cgi?id=93898
<rdar://problem/12089098>
Reviewed by Simon Fraser.
Add logging when we enter and exit the threaded scrolling mode, and logs the reasons we
fall into main-thread scrolling.
The logging output looks like this:
SCROLLING: Switching to main-thread scrolling mode. Time: 15843.554718 Reason(s): viewport-constrained objects
SCROLLING: Switching to threaded scrolling mode. Time: 15844.550866
SCROLLING: Switching to main-thread scrolling mode. Time: 15845.551214 Reason(s): viewport-constrained objects
SCROLLING: Switching to threaded scrolling mode. Time: 15846.552619
SCROLLING: Switching to main-thread scrolling mode. Time: 15847.553587 Reason(s): viewport-constrained objects
SCROLLING: Switching to threaded scrolling mode. Time: 15848.554084
No new tests, as this is just debugging logging.
* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::updateShouldUpdateScrollLayerPositionOnMainThread):
Construct a bitfield describing the reasons we fall into main-thread scrolling mode.
* page/scrolling/ScrollingCoordinatorNone.cpp:
(WebCore::ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/ScrollingTreeNode.cpp:
(WebCore::ScrollingTreeNode::ScrollingTreeNode):
* page/scrolling/ScrollingTreeNode.h:
(WebCore::ScrollingTreeNode::shouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/ScrollingTreeState.cpp:
(WebCore::ScrollingTreeState::ScrollingTreeState):
(WebCore::ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/ScrollingTreeState.h:
(WebCore::ScrollingTreeState::shouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/chromium/ScrollingCoordinatorChromium.cpp:
(WebCore::ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread):
* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread):
Use the reasons bitfield instead of a boolean.
* page/scrolling/ScrollingCoordinator.h:
(ScrollingCoordinator):
Add MainThreadScrollingReasons enum, with the current reasons that we might fallback to main-thread scrolling.
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::scrollingPerformanceLoggingEnabled):
Fix a typo (scrollingPeformanceLoggingEnabled -> scrollingPerformanceLoggingEnabled).
* page/scrolling/mac/ScrollingTreeNodeMac.mm:
(WebCore::ScrollingTreeNodeMac::update):
(WebCore::ScrollingTreeNodeMac::setScrollPosition):
(WebCore::logThreadedScrollingMode):
Pretty-print the scrolling mode and shouldUpdateScrollLayerPositionOnMainThreadReason.
2012-09-13 Joshua Bell <jsbell@chromium.org>
 
[V8] Binding: Generate batched attribute/const/callback struct names can collide
......@@ -384,11 +384,20 @@ void ScrollingCoordinator::updateShouldUpdateScrollLayerPositionOnMainThread()
{
FrameView* frameView = m_page->mainFrame()->view();
setShouldUpdateScrollLayerPositionOnMainThread(m_forceMainThreadScrollLayerPositionUpdates
|| frameView->hasSlowRepaintObjects()
|| (!supportsFixedPositionLayers() && frameView->hasViewportConstrainedObjects())
|| (supportsFixedPositionLayers() && hasNonLayerFixedObjects(frameView))
|| m_page->mainFrame()->document()->isImageDocument());
MainThreadScrollingReasons mainThreadScrollingReasons = (MainThreadScrollingReasons)0;
if (m_forceMainThreadScrollLayerPositionUpdates)
mainThreadScrollingReasons |= ForcedOnMainThread;
if (frameView->hasSlowRepaintObjects())
mainThreadScrollingReasons |= HasSlowRepaintObjects;
if (!supportsFixedPositionLayers() && frameView->hasViewportConstrainedObjects())
mainThreadScrollingReasons |= HasViewportConstrainedObjectsWithoutSupportingFixedLayers;
if (supportsFixedPositionLayers() && hasNonLayerFixedObjects(frameView))
mainThreadScrollingReasons |= HasNonLayerFixedObjects;
if (m_page->mainFrame()->document()->isImageDocument())
mainThreadScrollingReasons |= IsImageDocument;
setShouldUpdateScrollLayerPositionOnMainThread(mainThreadScrollingReasons);
}
void ScrollingCoordinator::setForceMainThreadScrollLayerPositionUpdates(bool forceMainThreadScrollLayerPositionUpdates)
......@@ -435,14 +444,14 @@ void ScrollingCoordinator::setWheelEventHandlerCount(unsigned wheelEventHandlerC
scheduleTreeStateCommit();
}
void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(bool shouldUpdateScrollLayerPositionOnMainThread)
void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons reasons)
{
// The FrameView's GraphicsLayer is likely to be out-of-synch with the PlatformLayer
// at this point. So we'll update it before we switch back to main thread scrolling
// in order to avoid layer positioning bugs.
if (shouldUpdateScrollLayerPositionOnMainThread)
if (reasons)
updateMainFrameScrollLayerPosition();
m_scrollingTreeState->setShouldUpdateScrollLayerPositionOnMainThread(shouldUpdateScrollLayerPositionOnMainThread);
m_scrollingTreeState->setShouldUpdateScrollLayerPositionOnMainThread(reasons);
scheduleTreeStateCommit();
}
......
......@@ -44,6 +44,8 @@
namespace WebCore {
typedef unsigned MainThreadScrollingReasons;
class FrameView;
class GraphicsLayer;
class Page;
......@@ -127,6 +129,14 @@ public:
// Attach/detach layer position to ancestor fixed position container.
void setLayerIsFixedToContainerLayer(GraphicsLayer*, bool);
enum MainThreadScrollingReasonFlags {
ForcedOnMainThread = 1 << 0,
HasSlowRepaintObjects = 1 << 1,
HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 2,
HasNonLayerFixedObjects = 1 << 3,
IsImageDocument = 1 << 4
};
private:
explicit ScrollingCoordinator(Page*);
......@@ -155,7 +165,7 @@ private:
void setScrollParameters(const ScrollParameters&);
void setWheelEventHandlerCount(unsigned);
void setShouldUpdateScrollLayerPositionOnMainThread(bool);
void setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons);
void updateMainFrameScrollLayerPosition();
......
......@@ -67,7 +67,7 @@ void ScrollingCoordinator::setWheelEventHandlerCount(unsigned)
{
}
void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(bool)
void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons)
{
}
......
......@@ -224,7 +224,7 @@ void ScrollingTree::setScrollingPerformanceLoggingEnabled(bool flag)
m_scrollingPerformanceLoggingEnabled = flag;
}
bool ScrollingTree::scrollingPeformanceLoggingEnabled()
bool ScrollingTree::scrollingPerformanceLoggingEnabled()
{
return m_scrollingPerformanceLoggingEnabled;
}
......
......@@ -98,7 +98,7 @@ public:
#endif
void setScrollingPerformanceLoggingEnabled(bool flag);
bool scrollingPeformanceLoggingEnabled();
bool scrollingPerformanceLoggingEnabled();
private:
explicit ScrollingTree(ScrollingCoordinator*);
......
......@@ -34,7 +34,7 @@ namespace WebCore {
ScrollingTreeNode::ScrollingTreeNode(ScrollingTree* scrollingTree)
: m_scrollingTree(scrollingTree)
, m_shouldUpdateScrollLayerPositionOnMainThread(false)
, m_shouldUpdateScrollLayerPositionOnMainThread(0)
, m_horizontalScrollElasticity(ScrollElasticityNone)
, m_verticalScrollElasticity(ScrollElasticityNone)
, m_hasEnabledHorizontalScrollbar(false)
......
......@@ -30,6 +30,7 @@
#include "IntRect.h"
#include "ScrollTypes.h"
#include "ScrollingCoordinator.h"
#include <wtf/PassOwnPtr.h>
namespace WebCore {
......@@ -47,7 +48,7 @@ public:
virtual void handleWheelEvent(const PlatformWheelEvent&) = 0;
virtual void setScrollPosition(const IntPoint&) = 0;
bool shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; }
MainThreadScrollingReasons shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; }
protected:
explicit ScrollingTreeNode(ScrollingTree*);
......@@ -74,7 +75,7 @@ private:
IntSize m_contentsSize;
IntPoint m_scrollOrigin;
bool m_shouldUpdateScrollLayerPositionOnMainThread;
MainThreadScrollingReasons m_shouldUpdateScrollLayerPositionOnMainThread;
ScrollElasticity m_horizontalScrollElasticity;
ScrollElasticity m_verticalScrollElasticity;
......
......@@ -38,7 +38,7 @@ PassOwnPtr<ScrollingTreeState> ScrollingTreeState::create()
ScrollingTreeState::ScrollingTreeState()
: m_changedProperties(0)
, m_wheelEventHandlerCount(0)
, m_shouldUpdateScrollLayerPositionOnMainThread(false)
, m_shouldUpdateScrollLayerPositionOnMainThread(0)
, m_horizontalScrollElasticity(ScrollElasticityNone)
, m_verticalScrollElasticity(ScrollElasticityNone)
, m_hasEnabledHorizontalScrollbar(false)
......@@ -88,12 +88,12 @@ void ScrollingTreeState::setWheelEventHandlerCount(unsigned wheelEventHandlerCou
m_changedProperties |= WheelEventHandlerCount;
}
void ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThread(bool shouldUpdateScrollLayerPositionOnMainThread)
void ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons reasons)
{
if (m_shouldUpdateScrollLayerPositionOnMainThread == shouldUpdateScrollLayerPositionOnMainThread)
if (m_shouldUpdateScrollLayerPositionOnMainThread == reasons)
return;
m_shouldUpdateScrollLayerPositionOnMainThread = shouldUpdateScrollLayerPositionOnMainThread;
m_shouldUpdateScrollLayerPositionOnMainThread = reasons;
m_changedProperties |= ShouldUpdateScrollLayerPositionOnMainThread;
}
......
......@@ -32,6 +32,7 @@
#include "IntRect.h"
#include "Region.h"
#include "ScrollTypes.h"
#include "ScrollingCoordinator.h"
#include <wtf/PassOwnPtr.h>
#if PLATFORM(MAC)
......@@ -81,8 +82,8 @@ public:
unsigned wheelEventHandlerCount() const { return m_wheelEventHandlerCount; }
void setWheelEventHandlerCount(unsigned);
bool shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; }
void setShouldUpdateScrollLayerPositionOnMainThread(bool);
MainThreadScrollingReasons shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; }
void setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons);
ScrollElasticity horizontalScrollElasticity() const { return m_horizontalScrollElasticity; }
void setHorizontalScrollElasticity(ScrollElasticity);
......@@ -126,7 +127,7 @@ private:
unsigned m_wheelEventHandlerCount;
bool m_shouldUpdateScrollLayerPositionOnMainThread;
MainThreadScrollingReasons m_shouldUpdateScrollLayerPositionOnMainThread;
ScrollElasticity m_horizontalScrollElasticity;
ScrollElasticity m_verticalScrollElasticity;
......
......@@ -223,12 +223,12 @@ void ScrollingCoordinator::setWheelEventHandlerCount(unsigned wheelEventHandlerC
m_private->scrollLayer()->setHaveWheelEventHandlers(wheelEventHandlerCount > 0);
}
void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(bool should)
void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons reasons)
{
// We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves.
setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view()));
if (m_private->scrollLayer())
m_private->scrollLayer()->setShouldScrollOnMainThread(should);
m_private->scrollLayer()->setShouldScrollOnMainThread(reasons);
}
bool ScrollingCoordinator::supportsFixedPositionLayers() const
......
......@@ -29,6 +29,7 @@
#if ENABLE(THREADED_SCROLLING)
#include "PlatformWheelEvent.h"
#include "ScrollingCoordinator.h"
#include "ScrollingTree.h"
#include "ScrollingTreeState.h"
#include "Settings.h"
......@@ -37,9 +38,13 @@
#include <wtf/CurrentTime.h>
#include <wtf/Deque.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/CString.h>
namespace WebCore {
static void logThreadedScrollingMode(unsigned mainThreadScrollingReasons);
PassOwnPtr<ScrollingTreeNode> ScrollingTreeNode::create(ScrollingTree* scrollingTree)
{
return adoptPtr(new ScrollingTreeNodeMac(scrollingTree));
......@@ -70,15 +75,22 @@ void ScrollingTreeNodeMac::update(ScrollingTreeState* state)
if (state->changedProperties() & (ScrollingTreeState::ScrollLayer | ScrollingTreeState::ContentsSize | ScrollingTreeState::ViewportRect))
updateMainFramePinState(scrollPosition());
if ((state->changedProperties() & ScrollingTreeState::ShouldUpdateScrollLayerPositionOnMainThread) && shouldUpdateScrollLayerPositionOnMainThread()) {
// We're transitioning to the slow "update scroll layer position on the main thread" mode.
// Initialize the probable main thread scroll position with the current scroll layer position.
if (state->changedProperties() & ScrollingTreeState::RequestedScrollPosition)
m_probableMainThreadScrollPosition = state->requestedScrollPosition();
else {
CGPoint scrollLayerPosition = m_scrollLayer.get().position;
m_probableMainThreadScrollPosition = IntPoint(-scrollLayerPosition.x, -scrollLayerPosition.y);
if ((state->changedProperties() & ScrollingTreeState::ShouldUpdateScrollLayerPositionOnMainThread)) {
unsigned mainThreadScrollingReasons = this->shouldUpdateScrollLayerPositionOnMainThread();
if (mainThreadScrollingReasons) {
// We're transitioning to the slow "update scroll layer position on the main thread" mode.
// Initialize the probable main thread scroll position with the current scroll layer position.
if (state->changedProperties() & ScrollingTreeState::RequestedScrollPosition)
m_probableMainThreadScrollPosition = state->requestedScrollPosition();
else {
CGPoint scrollLayerPosition = m_scrollLayer.get().position;
m_probableMainThreadScrollPosition = IntPoint(-scrollLayerPosition.x, -scrollLayerPosition.y);
}
}
if (scrollingTree()->scrollingPerformanceLoggingEnabled())
logThreadedScrollingMode(mainThreadScrollingReasons);
}
}
......@@ -240,7 +252,7 @@ void ScrollingTreeNodeMac::setScrollPosition(const IntPoint& scrollPosition)
setScrollPositionWithoutContentEdgeConstraints(newScrollPosition);
if (scrollingTree()->scrollingPeformanceLoggingEnabled())
if (scrollingTree()->scrollingPerformanceLoggingEnabled())
logExposedUnfilledArea();
}
......@@ -330,6 +342,30 @@ void ScrollingTreeNodeMac::logExposedUnfilledArea()
WTFLogAlways("SCROLLING: Exposed tileless area. Time: %f Unfilled Pixels: %u\n", WTF::monotonicallyIncreasingTime(), unfilledArea);
}
static void logThreadedScrollingMode(unsigned mainThreadScrollingReasons)
{
if (mainThreadScrollingReasons) {
StringBuilder reasonsDescription;
if (mainThreadScrollingReasons & ScrollingCoordinator::ForcedOnMainThread)
reasonsDescription.append("forced,");
if (mainThreadScrollingReasons & ScrollingCoordinator::HasSlowRepaintObjects)
reasonsDescription.append("slow-repaint objects,");
if (mainThreadScrollingReasons & ScrollingCoordinator::HasViewportConstrainedObjectsWithoutSupportingFixedLayers)
reasonsDescription.append("viewport-constrained objects,");
if (mainThreadScrollingReasons & ScrollingCoordinator::HasNonLayerFixedObjects)
reasonsDescription.append("non-layer viewport-constrained objects,");
if (mainThreadScrollingReasons & ScrollingCoordinator::IsImageDocument)
reasonsDescription.append("image document,");
// Strip the trailing comma.
String reasonsDescriptionTrimmed = reasonsDescription.toString().left(reasonsDescription.length() - 1);
WTFLogAlways("SCROLLING: Switching to main-thread scrolling mode. Time: %f Reason(s): %s\n", WTF::monotonicallyIncreasingTime(), reasonsDescriptionTrimmed.ascii().data());
} else
WTFLogAlways("SCROLLING: Switching to threaded scrolling mode. Time: %f\n", WTF::monotonicallyIncreasingTime());
}
} // namespace WebCore
#endif // ENABLE(THREADED_SCROLLING)
2012-09-13 Tim Horton <timothy_horton@apple.com>
Add optional debug logging when we fall into/out of threaded scrolling
https://bugs.webkit.org/show_bug.cgi?id=93898
<rdar://problem/12089098>
Reviewed by Simon Fraser.
Update the scrolling tree's scrollingPerformanceLoggingEnabled preference
before the early-return if we don't have layer debugging borders on.
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::updatePreferences):
2012-09-13 Sudarsana Nagineni <sudarsana.nagineni@linux.intel.com>
 
[WK2][WTR] WebKitTestRunner needs testRunner.callShouldCloseOnWebView
......
......@@ -205,6 +205,9 @@ void TiledCoreAnimationDrawingArea::setPageOverlayNeedsDisplay(const IntRect& re
void TiledCoreAnimationDrawingArea::updatePreferences(const WebPreferencesStore&)
{
bool scrollingPerformanceLoggingEnabled = m_webPage->scrollingPerformanceLoggingEnabled();
ScrollingThread::dispatch(bind(&ScrollingTree::setScrollingPerformanceLoggingEnabled, m_webPage->corePage()->scrollingCoordinator()->scrollingTree(), scrollingPerformanceLoggingEnabled));
bool showDebugBorders = m_webPage->corePage()->settings()->showDebugBorders();
if (showDebugBorders == !!m_debugInfoLayer)
......@@ -218,10 +221,7 @@ void TiledCoreAnimationDrawingArea::updatePreferences(const WebPreferencesStore&
m_debugInfoLayer = nullptr;
}
bool scrollingPerformanceLoggingEnabled = m_webPage->scrollingPerformanceLoggingEnabled();
ScrollingThread::dispatch(bind(&ScrollingTree::setDebugRootLayer, m_webPage->corePage()->scrollingCoordinator()->scrollingTree(), m_debugInfoLayer));
ScrollingThread::dispatch(bind(&ScrollingTree::setScrollingPerformanceLoggingEnabled, m_webPage->corePage()->scrollingCoordinator()->scrollingTree(), scrollingPerformanceLoggingEnabled));
}
void TiledCoreAnimationDrawingArea::dispatchAfterEnsuringUpdatedScrollPosition(const Function<void ()>& functionRef)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment