[iOS WK2] Avoid creating tiles that are too large for rendering
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Mar 2016 02:07:47 +0000 (02:07 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Mar 2016 02:07:47 +0000 (02:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=156050
rdar://problem/25424541

Reviewed by Darin Adler.

In the case of a WKWebView which is sized large enough to show an entire document
(for example, when enclosed inside a UIScrollView), we would create tiles that were
larger than CoreAnimation was willing to deal with.

* platform/graphics/ca/TileController.cpp:
(WebCore::TileController::tileSize): Take the device scale, and the max IOSurface size
into account when computing the max tile size.
* platform/graphics/cocoa/IOSurface.mm:
(IOSurface::maximumSize): CoreAnimation imposes limits in addition to the size reported
by IOSurfaceGetPropertyMaximum(), namely an 8k cap, so mimic that here.
(IOSurface::ensurePlatformContext): Typo.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@198875 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ca/TileController.cpp
Source/WebCore/platform/graphics/cocoa/IOSurface.mm

index 80deae0..39eeead 100644 (file)
@@ -1,3 +1,23 @@
+2016-03-30  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Avoid creating tiles that are too large for rendering
+        https://bugs.webkit.org/show_bug.cgi?id=156050
+        rdar://problem/25424541
+
+        Reviewed by Darin Adler.
+
+        In the case of a WKWebView which is sized large enough to show an entire document
+        (for example, when enclosed inside a UIScrollView), we would create tiles that were
+        larger than CoreAnimation was willing to deal with.
+        
+        * platform/graphics/ca/TileController.cpp:
+        (WebCore::TileController::tileSize): Take the device scale, and the max IOSurface size
+        into account when computing the max tile size.
+        * platform/graphics/cocoa/IOSurface.mm:
+        (IOSurface::maximumSize): CoreAnimation imposes limits in addition to the size reported
+        by IOSurfaceGetPropertyMaximum(), namely an 8k cap, so mimic that here.
+        (IOSurface::ensurePlatformContext): Typo.
+
 2016-03-30  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
 
         [EFL][CMake] WebKit include path has been added to system include path
index 99b5b62..4df6efb 100644 (file)
 #include <utility>
 #include <wtf/MainThread.h>
 
+#if USE(IOSURFACE)
+#include "IOSurface.h"
+#endif
+
 #if PLATFORM(IOS)
 #include "MemoryPressureHandler.h"
 #include "TileControllerMemoryHandlerIOS.h"
@@ -489,16 +493,23 @@ IntSize TileController::tileSize() const
     if (m_inLiveResize || m_tileSizeLocked)
         return tileGrid().tileSize();
 
+    IntSize maxTileSize(kGiantTileSize, kGiantTileSize);
+#if USE(IOSURFACE)
+    IntSize surfaceSizeLimit = IOSurface::maximumSize();
+    surfaceSizeLimit.scale(1 / m_deviceScaleFactor);
+    maxTileSize = maxTileSize.shrunkTo(surfaceSizeLimit);
+#endif
+    
     if (owningGraphicsLayer()->platformCALayerUseGiantTiles())
-        return IntSize(kGiantTileSize, kGiantTileSize);
+        return maxTileSize;
 
     IntSize tileSize(kDefaultTileSize, kDefaultTileSize);
 
     if (m_scrollability == NotScrollable) {
         IntSize scaledSize = expandedIntSize(boundsWithoutMargin().size() * tileGrid().scale());
-        tileSize = scaledSize.constrainedBetween(IntSize(kDefaultTileSize, kDefaultTileSize), IntSize(kGiantTileSize, kGiantTileSize));
+        tileSize = scaledSize.constrainedBetween(IntSize(kDefaultTileSize, kDefaultTileSize), maxTileSize);
     } else if (m_scrollability == VerticallyScrollable)
-        tileSize.setWidth(std::min(std::max<int>(ceilf(boundsWithoutMargin().width() * tileGrid().scale()), kDefaultTileSize), kGiantTileSize));
+        tileSize.setWidth(std::min(std::max<int>(ceilf(boundsWithoutMargin().width() * tileGrid().scale()), kDefaultTileSize), maxTileSize.width()));
 
     LOG_WITH_STREAM(Scrolling, stream << "TileController::tileSize newSize=" << tileSize);
 
index 9fa6f23..d6d9780 100644 (file)
@@ -239,7 +239,13 @@ IOSurface::IOSurface(IOSurfaceRef surface, ColorSpace colorSpace)
 
 IntSize IOSurface::maximumSize()
 {
-    return IntSize(IOSurfaceGetPropertyMaximum(kIOSurfaceWidth), IOSurfaceGetPropertyMaximum(kIOSurfaceHeight));
+    IntSize maxSize(IOSurfaceGetPropertyMaximum(kIOSurfaceWidth), IOSurfaceGetPropertyMaximum(kIOSurfaceHeight));
+#if PLATFORM(IOS)
+    // Match limits imposed by CA. FIXME: should have API for this <rdar://problem/25454148>
+    const int iOSMaxSurfaceDimension = 8 * 1024;
+    maxSize = maxSize.shrunkTo({ iOSMaxSurfaceDimension, iOSMaxSurfaceDimension });
+#endif
+    return maxSize;
 }
 
 MachSendRight IOSurface::createSendRight() const
@@ -288,7 +294,7 @@ CGContextRef IOSurface::ensurePlatformContext()
     case Format::RGB10:
     case Format::RGB10A8:
         // A half-float format will be used if CG needs to read back the IOSurface contents,
-        // but for an IOSurface-to-IOSurface copy, there shoud be no conversion.
+        // but for an IOSurface-to-IOSurface copy, there should be no conversion.
         bitsPerComponent = 16;
         bitsPerPixel = 64;
         bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder16Host | kCGBitmapFloatComponents;