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/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;