Avoid spurious "all repaint" layouts when scrolling WebViews on Retina displays
https://bugs.webkit.org/show_bug.cgi?id=119564
Reviewed by Beth Dakin.
When scrolling WebViews on Macs with Retina displays, AppKit uses
device pixels for the scroll offset, so [scrollView() documentVisibleRect]
can return a CGRect with non-integral origin. This rect is used by layout,
via layoutSize(), to decide whether the view size changed, which prompts
a full repaint. However, FrameView gets a value which has been rounded
by enclosingIntRect(), which increases the height or width by 1px if the
y or x offset is on a half-pixel, causing spurious full repaints.
Fix by plumbing through platformVisibleContentSize(), which just
gets the size of the -documentVisibleRect.
* page/FrameView.cpp:
(WebCore::FrameView::layout): Don't get layoutHeight and layoutWidth
separately, since that is two calls down into platformVisibleContentSize.
* platform/ScrollView.cpp:
(WebCore::ScrollView::unscaledVisibleContentSize):
(WebCore::ScrollView::platformVisibleContentSize):
* platform/ScrollView.h:
* platform/mac/ScrollViewMac.mm:
(WebCore::ScrollView::platformVisibleContentSize):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153810 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 07d3c27..c0a6ef1 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,5 +1,33 @@
2013-08-07 Simon Fraser <simon.fraser@apple.com>
+ Avoid spurious "all repaint" layouts when scrolling WebViews on Retina displays
+ https://bugs.webkit.org/show_bug.cgi?id=119564
+
+ Reviewed by Beth Dakin.
+
+ When scrolling WebViews on Macs with Retina displays, AppKit uses
+ device pixels for the scroll offset, so [scrollView() documentVisibleRect]
+ can return a CGRect with non-integral origin. This rect is used by layout,
+ via layoutSize(), to decide whether the view size changed, which prompts
+ a full repaint. However, FrameView gets a value which has been rounded
+ by enclosingIntRect(), which increases the height or width by 1px if the
+ y or x offset is on a half-pixel, causing spurious full repaints.
+
+ Fix by plumbing through platformVisibleContentSize(), which just
+ gets the size of the -documentVisibleRect.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::layout): Don't get layoutHeight and layoutWidth
+ separately, since that is two calls down into platformVisibleContentSize.
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::unscaledVisibleContentSize):
+ (WebCore::ScrollView::platformVisibleContentSize):
+ * platform/ScrollView.h:
+ * platform/mac/ScrollViewMac.mm:
+ (WebCore::ScrollView::platformVisibleContentSize):
+
+2013-08-07 Simon Fraser <simon.fraser@apple.com>
+
Be more aggressive about sending fake mouse events less frequently
https://bugs.webkit.org/show_bug.cgi?id=119563
<rdar://problem/14669029>
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index 370d766..ec548fa 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -1293,7 +1293,7 @@
LayoutSize oldSize = m_size;
- m_size = LayoutSize(layoutWidth(), layoutHeight());
+ m_size = layoutSize();
if (oldSize != m_size) {
m_needsFullRepaint = true;
diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp
index 1c9125b..f1d6551 100644
--- a/Source/WebCore/platform/ScrollView.cpp
+++ b/Source/WebCore/platform/ScrollView.cpp
@@ -221,7 +221,7 @@
IntSize ScrollView::unscaledVisibleContentSize(VisibleContentRectIncludesScrollbars scrollbarInclusion) const
{
if (platformWidget())
- return platformVisibleContentRect(scrollbarInclusion == IncludeScrollbars).size();
+ return platformVisibleContentSize(scrollbarInclusion == IncludeScrollbars);
if (!m_fixedVisibleContentRect.isEmpty())
return m_fixedVisibleContentRect.size();
@@ -1412,6 +1412,11 @@
return IntRect();
}
+IntSize ScrollView::platformVisibleContentSize(bool) const
+{
+ return IntSize();
+}
+
void ScrollView::platformSetContentsSize()
{
}
diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h
index 7061f3d..6088c01 100644
--- a/Source/WebCore/platform/ScrollView.h
+++ b/Source/WebCore/platform/ScrollView.h
@@ -388,6 +388,7 @@
void platformSetCanBlitOnScroll(bool);
bool platformCanBlitOnScroll() const;
IntRect platformVisibleContentRect(bool includeScrollbars) const;
+ IntSize platformVisibleContentSize(bool includeScrollbars) const;
void platformSetContentsSize();
IntRect platformContentsToScreen(const IntRect&) const;
IntPoint platformScreenToContents(const IntPoint&) const;
diff --git a/Source/WebCore/platform/mac/ScrollViewMac.mm b/Source/WebCore/platform/mac/ScrollViewMac.mm
index 66d36b9..aaffcf8 100644
--- a/Source/WebCore/platform/mac/ScrollViewMac.mm
+++ b/Source/WebCore/platform/mac/ScrollViewMac.mm
@@ -28,6 +28,7 @@
#import "BlockExceptions.h"
#import "FloatRect.h"
+#import "FloatSize.h"
#import "IntRect.h"
#import "Logging.h"
#import "NotImplemented.h"
@@ -116,6 +117,17 @@
return IntRect();
}
+IntSize ScrollView::platformVisibleContentSize(bool includeScrollbars) const
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ if (includeScrollbars)
+ return IntSize([scrollView() frame].size);
+
+ return expandedIntSize(FloatSize([scrollView() documentVisibleRect].size));
+ END_BLOCK_OBJC_EXCEPTIONS;
+ return IntSize();
+}
+
void ScrollView::platformSetContentsSize()
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;