- Revision
- 111555
- Author
- [email protected]
- Date
- 2012-03-21 09:52:38 -0700 (Wed, 21 Mar 2012)
Log Message
[chromium] Use floating point scroll deltas for layers
https://bugs.webkit.org/show_bug.cgi?id=81546
Patch by Sami Kyostila <[email protected]> on 2012-03-21
Reviewed by James Robinson.
Source/WebCore:
Use floating point scroll deltas for layers instead of integral scroll
deltas. This is because due to page scaling it may be necessary to
scroll layers in sub-CSS-pixel steps to avoid visible jumps. When the
floating point scroll offset is committed to the main thread, it is
truncated to integer, but the fractional part is kept on the CC side to
make sure fractional scroll offsets are accumulated correctly over
multiple commits.
Test: CCLayerTreeHostTestFractionalScroll
* platform/graphics/FloatPoint.h:
(WebCore::toSize):
(WebCore):
* platform/graphics/chromium/cc/CCLayerImpl.cpp:
(WebCore::CCLayerImpl::scrollBy):
(WebCore::CCLayerImpl::setScrollDelta):
* platform/graphics/chromium/cc/CCLayerImpl.h:
(WebCore::CCLayerImpl::scrollDelta):
(CCLayerImpl):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::startPageScaleAnimation):
(WebCore::CCLayerTreeHostImpl::adjustScrollsForPageScaleChange):
(WebCore::CCLayerTreeHostImpl::processScrollDeltas):
(WebCore::CCLayerTreeHostImpl::animatePageScale):
Source/WebKit/chromium:
New unit test for accumulating fractional scroll deltas across multiple commits.
* tests/CCLayerTreeHostTest.cpp:
(CCLayerTreeHostTestFractionalScroll):
(WTF::CCLayerTreeHostTestFractionalScroll::CCLayerTreeHostTestFractionalScroll):
(WTF::CCLayerTreeHostTestFractionalScroll::beginTest):
(WTF::CCLayerTreeHostTestFractionalScroll::drawLayersOnCCThread):
(WTF::CCLayerTreeHostTestFractionalScroll::applyScrollAndScale):
(WTF::CCLayerTreeHostTestFractionalScroll::afterTest):
(WTF):
(WTF::TEST_F):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (111554 => 111555)
--- trunk/Source/WebCore/ChangeLog 2012-03-21 16:46:41 UTC (rev 111554)
+++ trunk/Source/WebCore/ChangeLog 2012-03-21 16:52:38 UTC (rev 111555)
@@ -1,3 +1,35 @@
+2012-03-21 Sami Kyostila <[email protected]>
+
+ [chromium] Use floating point scroll deltas for layers
+ https://bugs.webkit.org/show_bug.cgi?id=81546
+
+ Reviewed by James Robinson.
+
+ Use floating point scroll deltas for layers instead of integral scroll
+ deltas. This is because due to page scaling it may be necessary to
+ scroll layers in sub-CSS-pixel steps to avoid visible jumps. When the
+ floating point scroll offset is committed to the main thread, it is
+ truncated to integer, but the fractional part is kept on the CC side to
+ make sure fractional scroll offsets are accumulated correctly over
+ multiple commits.
+
+ Test: CCLayerTreeHostTestFractionalScroll
+
+ * platform/graphics/FloatPoint.h:
+ (WebCore::toSize):
+ (WebCore):
+ * platform/graphics/chromium/cc/CCLayerImpl.cpp:
+ (WebCore::CCLayerImpl::scrollBy):
+ (WebCore::CCLayerImpl::setScrollDelta):
+ * platform/graphics/chromium/cc/CCLayerImpl.h:
+ (WebCore::CCLayerImpl::scrollDelta):
+ (CCLayerImpl):
+ * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+ (WebCore::CCLayerTreeHostImpl::startPageScaleAnimation):
+ (WebCore::CCLayerTreeHostImpl::adjustScrollsForPageScaleChange):
+ (WebCore::CCLayerTreeHostImpl::processScrollDeltas):
+ (WebCore::CCLayerTreeHostImpl::animatePageScale):
+
2012-03-21 Li Yin <[email protected]>
[WebSocket]The Sec-WebSocket-Accept MUST NOT appear more than once in an HTTP response
Modified: trunk/Source/WebCore/platform/graphics/FloatSize.h (111554 => 111555)
--- trunk/Source/WebCore/platform/graphics/FloatSize.h 2012-03-21 16:46:41 UTC (rev 111554)
+++ trunk/Source/WebCore/platform/graphics/FloatSize.h 2012-03-21 16:52:38 UTC (rev 111555)
@@ -178,6 +178,11 @@
return IntSize(static_cast<int>(roundf(p.width())), static_cast<int>(roundf(p.height())));
}
+inline IntSize flooredIntSize(const FloatSize& p)
+{
+ return IntSize(static_cast<int>(p.width()), static_cast<int>(p.height()));
+}
+
inline IntSize expandedIntSize(const FloatSize& p)
{
return IntSize(clampToInteger(ceilf(p.width())), clampToInteger(ceilf(p.height())));
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp (111554 => 111555)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp 2012-03-21 16:46:41 UTC (rev 111554)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp 2012-03-21 16:52:38 UTC (rev 111555)
@@ -187,9 +187,9 @@
ASSERT_NOT_REACHED();
}
-void CCLayerImpl::scrollBy(const IntSize& scroll)
+void CCLayerImpl::scrollBy(const FloatSize& scroll)
{
- IntSize newDelta = m_scrollDelta + scroll;
+ FloatSize newDelta = m_scrollDelta + scroll;
IntSize minDelta = -toSize(m_scrollPosition);
IntSize maxDelta = m_maxScrollPosition - toSize(m_scrollPosition);
// Clamp newDelta so that position + delta stays within scroll bounds.
@@ -525,7 +525,7 @@
noteLayerPropertyChangedForSubtree();
}
-void CCLayerImpl::setScrollDelta(const IntSize& scrollDelta)
+void CCLayerImpl::setScrollDelta(const FloatSize& scrollDelta)
{
if (m_scrollDelta == scrollDelta)
return;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h (111554 => 111555)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h 2012-03-21 16:46:41 UTC (rev 111554)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h 2012-03-21 16:52:38 UTC (rev 111555)
@@ -174,8 +174,8 @@
const IntSize& maxScrollPosition() const {return m_maxScrollPosition; }
void setMaxScrollPosition(const IntSize& maxScrollPosition) { m_maxScrollPosition = maxScrollPosition; }
- const IntSize& scrollDelta() const { return m_scrollDelta; }
- void setScrollDelta(const IntSize&);
+ const FloatSize& scrollDelta() const { return m_scrollDelta; }
+ void setScrollDelta(const FloatSize&);
float pageScaleDelta() const { return m_pageScaleDelta; }
void setPageScaleDelta(float);
@@ -183,7 +183,7 @@
const IntSize& sentScrollDelta() const { return m_sentScrollDelta; }
void setSentScrollDelta(const IntSize& sentScrollDelta) { m_sentScrollDelta = sentScrollDelta; }
- void scrollBy(const IntSize& scroll);
+ void scrollBy(const FloatSize& scroll);
bool scrollable() const { return m_scrollable; }
void setScrollable(bool scrollable) { m_scrollable = scrollable; }
@@ -305,7 +305,7 @@
bool m_drawsContent;
- IntSize m_scrollDelta;
+ FloatSize m_scrollDelta;
IntSize m_sentScrollDelta;
IntSize m_maxScrollPosition;
float m_pageScaleDelta;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp (111554 => 111555)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp 2012-03-21 16:46:41 UTC (rev 111554)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp 2012-03-21 16:52:38 UTC (rev 111555)
@@ -153,7 +153,7 @@
if (!m_scrollLayerImpl)
return;
- IntSize scrollTotal = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
+ IntSize scrollTotal = flooredIntSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
scrollTotal.scale(m_pageScaleDelta);
float scaleTotal = m_pageScale * m_pageScaleDelta;
IntSize scaledContentSize = contentSize();
@@ -517,7 +517,7 @@
// We also need to convert impl-side scroll deltas to pageScale space.
if (m_scrollLayerImpl) {
- IntSize scrollDelta = m_scrollLayerImpl->scrollDelta();
+ FloatSize scrollDelta = m_scrollLayerImpl->scrollDelta();
scrollDelta.scale(pageScaleChange);
m_scrollLayerImpl->setScrollDelta(scrollDelta);
}
@@ -676,7 +676,7 @@
// Compute where the scroll offset/page scale would be if fully pinch-zoomed
// out from the anchor point.
- FloatSize scrollBegin = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
+ IntSize scrollBegin = flooredIntSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
scrollBegin.scale(m_pageScaleDelta);
float scaleBegin = m_pageScale * m_pageScaleDelta;
float pageScaleDeltaToSend = m_minPageScale / m_pageScale;
@@ -724,7 +724,7 @@
// FIXME: track scrolls from layers other than the root
CCLayerTreeHostCommon::ScrollUpdateInfo scroll;
scroll.layerId = m_scrollLayerImpl->id();
- scroll.scrollDelta = m_scrollLayerImpl->scrollDelta();
+ scroll.scrollDelta = flooredIntSize(m_scrollLayerImpl->scrollDelta());
scrollInfo->scrolls.append(scroll);
m_scrollLayerImpl->setSentScrollDelta(scroll.scrollDelta);
@@ -746,7 +746,7 @@
if (!m_pageScaleAnimation)
return;
- IntSize scrollTotal = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
+ IntSize scrollTotal = flooredIntSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(monotonicTime) / m_pageScale);
IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(monotonicTime);
Modified: trunk/Source/WebKit/chromium/ChangeLog (111554 => 111555)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-03-21 16:46:41 UTC (rev 111554)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-03-21 16:52:38 UTC (rev 111555)
@@ -1,3 +1,22 @@
+2012-03-21 Sami Kyostila <[email protected]>
+
+ [chromium] Use floating point scroll deltas for layers
+ https://bugs.webkit.org/show_bug.cgi?id=81546
+
+ Reviewed by James Robinson.
+
+ New unit test for accumulating fractional scroll deltas across multiple commits.
+
+ * tests/CCLayerTreeHostTest.cpp:
+ (CCLayerTreeHostTestFractionalScroll):
+ (WTF::CCLayerTreeHostTestFractionalScroll::CCLayerTreeHostTestFractionalScroll):
+ (WTF::CCLayerTreeHostTestFractionalScroll::beginTest):
+ (WTF::CCLayerTreeHostTestFractionalScroll::drawLayersOnCCThread):
+ (WTF::CCLayerTreeHostTestFractionalScroll::applyScrollAndScale):
+ (WTF::CCLayerTreeHostTestFractionalScroll::afterTest):
+ (WTF):
+ (WTF::TEST_F):
+
2012-03-21 Joshua Bell <[email protected]>
[Chromium] IndexedDB: Expose necessary IDB exception codes through WebKit API
Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp (111554 => 111555)
--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2012-03-21 16:46:41 UTC (rev 111554)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2012-03-21 16:52:38 UTC (rev 111555)
@@ -2225,4 +2225,57 @@
runTestThreaded();
}
+class CCLayerTreeHostTestFractionalScroll : public CCLayerTreeHostTestThreadOnly {
+public:
+ CCLayerTreeHostTestFractionalScroll()
+ : m_scrollAmount(1.75, 0)
+ {
+ }
+
+ virtual void beginTest()
+ {
+ m_layerTreeHost->rootLayer()->setScrollable(true);
+ postSetNeedsCommitToMainThread();
+ }
+
+ virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
+ {
+ CCLayerImpl* root = impl->rootLayer();
+ root->setMaxScrollPosition(IntSize(100, 100));
+
+ // Check that a fractional scroll delta is correctly accumulated over multiple commits.
+ if (impl->frameNumber() == 1) {
+ EXPECT_EQ(root->scrollPosition(), IntPoint(0, 0));
+ EXPECT_EQ(root->scrollDelta(), FloatSize(0, 0));
+ postSetNeedsCommitToMainThread();
+ } else if (impl->frameNumber() == 2) {
+ EXPECT_EQ(root->scrollPosition(), flooredIntPoint(m_scrollAmount));
+ EXPECT_EQ(root->scrollDelta(), FloatSize(fmod(m_scrollAmount.width(), 1), 0));
+ postSetNeedsCommitToMainThread();
+ } else if (impl->frameNumber() == 3) {
+ EXPECT_EQ(root->scrollPosition(), flooredIntPoint(m_scrollAmount + m_scrollAmount));
+ EXPECT_EQ(root->scrollDelta(), FloatSize(fmod(2 * m_scrollAmount.width(), 1), 0));
+ endTest();
+ }
+ root->scrollBy(m_scrollAmount);
+ }
+
+ virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale)
+ {
+ IntPoint position = m_layerTreeHost->rootLayer()->scrollPosition();
+ m_layerTreeHost->rootLayer()->setScrollPosition(position + scrollDelta);
+ }
+
+ virtual void afterTest()
+ {
+ }
+private:
+ FloatSize m_scrollAmount;
+};
+
+TEST_F(CCLayerTreeHostTestFractionalScroll, runMultiThread)
+{
+ runTestThreaded();
+}
+
} // namespace