[iOS WebKit2] Swipe snapshots should be taken asynchronously
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 May 2014 07:37:35 +0000 (07:37 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 May 2014 07:37:35 +0000 (07:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=132417
<rdar://problem/16535921>

Reviewed by Anders Carlsson.

Reorganize takeViewSnapshot to return a ViewSnaphot with the image
filled in (the other properties are filled in by ViewSnapshotStore).

Make ViewSnapshotStore use a fixed size instead of count for the snapshot cache.
iOS doesn't use purgeable snapshots, so make the cache much smaller there.

Use CARenderServerCaptureLayerWithTransform to achieve async snapshotting.

Rename WebKit::ViewSnapshotStore::Snapshot to WebKit::ViewSnapshot so that
it can be forward-declared in a bunch of places.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _takeViewSnapshot:]):
Use CARenderServerCaptureLayerWithTransform.

* UIProcess/API/Cocoa/WKWebViewInternal.h:
* UIProcess/API/mac/WKView.mm:
(createIOSurfaceFromImage):
(-[WKView _takeViewSnapshot:]):
Adjust to the new push model.

* UIProcess/API/mac/WKViewInternal.h:
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::takeViewSnapshot):
* UIProcess/WebPageProxy.h:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::takeViewSnapshot):
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::takeViewSnapshot):
Plumbing.

* UIProcess/ios/ViewGestureControllerIOS.mm:
(WebKit::ViewGestureController::beginSwipeGesture):
(WebKit::ViewGestureController::endSwipeGesture):
Realize an object that can be used as the layer contents from the slot ID.

* UIProcess/ios/WebMemoryPressureHandlerIOS.cpp:
(WebKit::WebMemoryPressureHandler::sharedHandler):
(WebKit::WebMemoryPressureHandler::WebMemoryPressureHandler):
* UIProcess/WebMemoryPressureHandlerIOS.h:
Add a memory pressure handler for the UI process. This does not use
WebCore's platform independent memory pressure handler because that
mechanism only allows for one handler per process, and we don't want to
stomp on any handlers installed by WebKit1 in a process where the WebKits coexist.

* UIProcess/ios/WKContentView.h:
* UIProcess/ios/WKContentView.mm:
(-[WKContentView _takeViewSnapshot]): Deleted.
Get rid of an unnecessary bounce through WKContentView.

* UIProcess/mac/ViewGestureControllerMac.mm:
(WebKit::ViewGestureController::retrieveSnapshotForItem):
(WebKit::ViewGestureController::endSwipeGesture):
Use the new name, ViewSnapshot.

* UIProcess/mac/ViewSnapshotStore.h:
(WebKit::ViewSnapshot::ViewSnapshot):
* UIProcess/mac/ViewSnapshotStore.mm:
(WebKit::ViewSnapshotStore::ViewSnapshotStore):
(WebKit::ViewSnapshotStore::~ViewSnapshotStore):
(WebKit::ViewSnapshotStore::snapshottingContext):
Use a custom CAContext for snapshotting so that snapshots don't
disappear when the main context is destroyed on hibernation.

(WebKit::ViewSnapshotStore::removeSnapshotImage):
(WebKit::ViewSnapshotStore::pruneSnapshots):
(WebKit::ViewSnapshotStore::recordSnapshot):
(WebKit::ViewSnapshotStore::getSnapshot):
(WebKit::ViewSnapshotStore::discardSnapshots):
(WebKit::ViewSnapshot::clearImage):
(WebKit::ViewSnapshot::hasImage):
(WebKit::createIOSurfaceFromImage): Deleted.
(WebKit::ViewSnapshotStore::Snapshot::clearImage): Deleted.
(WebKit::ViewSnapshotStore::Snapshot::hasImage): Deleted.
Cache by image size instead of counts.

* WebKit2.xcodeproj/project.pbxproj:

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

22 files changed:
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h
Source/WebKit2/UIProcess/API/mac/WKView.mm
Source/WebKit2/UIProcess/API/mac/WKViewInternal.h
Source/WebKit2/UIProcess/PageClient.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/ios/PageClientImplIOS.h
Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm
Source/WebKit2/UIProcess/ios/ViewGestureControllerIOS.mm
Source/WebKit2/UIProcess/ios/WKContentView.h
Source/WebKit2/UIProcess/ios/WKContentView.mm
Source/WebKit2/UIProcess/ios/WebMemoryPressureHandlerIOS.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/ios/WebMemoryPressureHandlerIOS.h [new file with mode: 0644]
Source/WebKit2/UIProcess/mac/PageClientImpl.h
Source/WebKit2/UIProcess/mac/PageClientImpl.mm
Source/WebKit2/UIProcess/mac/ViewGestureControllerMac.mm
Source/WebKit2/UIProcess/mac/ViewSnapshotStore.h
Source/WebKit2/UIProcess/mac/ViewSnapshotStore.mm
Source/WebKit2/UIProcess/mac/WebContextMac.mm
Source/WebKit2/WebKit2.xcodeproj/project.pbxproj

index 47ff3d4..60ef8cd 100644 (file)
@@ -1,3 +1,92 @@
+2014-05-05  Tim Horton  <timothy_horton@apple.com>
+
+        [iOS WebKit2] Swipe snapshots should be taken asynchronously
+        https://bugs.webkit.org/show_bug.cgi?id=132417
+        <rdar://problem/16535921>
+
+        Reviewed by Anders Carlsson.
+
+        Reorganize takeViewSnapshot to return a ViewSnaphot with the image
+        filled in (the other properties are filled in by ViewSnapshotStore).
+
+        Make ViewSnapshotStore use a fixed size instead of count for the snapshot cache.
+        iOS doesn't use purgeable snapshots, so make the cache much smaller there.
+
+        Use CARenderServerCaptureLayerWithTransform to achieve async snapshotting.
+
+        Rename WebKit::ViewSnapshotStore::Snapshot to WebKit::ViewSnapshot so that
+        it can be forward-declared in a bunch of places.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _takeViewSnapshot:]):
+        Use CARenderServerCaptureLayerWithTransform.
+
+        * UIProcess/API/Cocoa/WKWebViewInternal.h:
+        * UIProcess/API/mac/WKView.mm:
+        (createIOSurfaceFromImage):
+        (-[WKView _takeViewSnapshot:]):
+        Adjust to the new push model.
+
+        * UIProcess/API/mac/WKViewInternal.h:
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::takeViewSnapshot):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::takeViewSnapshot):
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::takeViewSnapshot):
+        Plumbing.
+
+        * UIProcess/ios/ViewGestureControllerIOS.mm:
+        (WebKit::ViewGestureController::beginSwipeGesture):
+        (WebKit::ViewGestureController::endSwipeGesture):
+        Realize an object that can be used as the layer contents from the slot ID.
+
+        * UIProcess/ios/WebMemoryPressureHandlerIOS.cpp:
+        (WebKit::WebMemoryPressureHandler::sharedHandler):
+        (WebKit::WebMemoryPressureHandler::WebMemoryPressureHandler):
+        * UIProcess/WebMemoryPressureHandlerIOS.h:
+        Add a memory pressure handler for the UI process. This does not use
+        WebCore's platform independent memory pressure handler because that
+        mechanism only allows for one handler per process, and we don't want to
+        stomp on any handlers installed by WebKit1 in a process where the WebKits coexist.
+
+        * UIProcess/ios/WKContentView.h:
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView _takeViewSnapshot]): Deleted.
+        Get rid of an unnecessary bounce through WKContentView.
+
+        * UIProcess/mac/ViewGestureControllerMac.mm:
+        (WebKit::ViewGestureController::retrieveSnapshotForItem):
+        (WebKit::ViewGestureController::endSwipeGesture):
+        Use the new name, ViewSnapshot.
+
+        * UIProcess/mac/ViewSnapshotStore.h:
+        (WebKit::ViewSnapshot::ViewSnapshot):
+        * UIProcess/mac/ViewSnapshotStore.mm:
+        (WebKit::ViewSnapshotStore::ViewSnapshotStore):
+        (WebKit::ViewSnapshotStore::~ViewSnapshotStore):
+        (WebKit::ViewSnapshotStore::snapshottingContext):
+        Use a custom CAContext for snapshotting so that snapshots don't
+        disappear when the main context is destroyed on hibernation.
+
+        (WebKit::ViewSnapshotStore::removeSnapshotImage):
+        (WebKit::ViewSnapshotStore::pruneSnapshots):
+        (WebKit::ViewSnapshotStore::recordSnapshot):
+        (WebKit::ViewSnapshotStore::getSnapshot):
+        (WebKit::ViewSnapshotStore::discardSnapshots):
+        (WebKit::ViewSnapshot::clearImage):
+        (WebKit::ViewSnapshot::hasImage):
+        (WebKit::createIOSurfaceFromImage): Deleted.
+        (WebKit::ViewSnapshotStore::Snapshot::clearImage): Deleted.
+        (WebKit::ViewSnapshotStore::Snapshot::hasImage): Deleted.
+        Cache by image size instead of counts.
+
+        * WebKit2.xcodeproj/project.pbxproj:
+
 2014-05-04  Pratik Solanki  <psolanki@apple.com>
 
         Reduce calls to CFURLCacheCopySharedURLCache
index a46e86e..bb195de 100644 (file)
@@ -36,6 +36,7 @@
 #import "RemoteObjectRegistryMessages.h"
 #import "UIDelegate.h"
 #import "ViewGestureController.h"
+#import "ViewSnapshotStore.h"
 #import "WKBackForwardListInternal.h"
 #import "WKBackForwardListItemInternal.h"
 #import "WKBrowsingContextHandleInternal.h"
@@ -54,6 +55,7 @@
 #import "WebCertificateInfo.h"
 #import "WebContext.h"
 #import "WebFormSubmissionListenerProxy.h"
+#import "WebKitSystemInterface.h"
 #import "WebPageGroup.h"
 #import "WebPageProxy.h"
 #import "WebProcessProxy.h"
@@ -71,6 +73,8 @@
 #import "WKWebViewContentProviderRegistry.h"
 #import <CoreGraphics/CGFloat.h>
 #import <UIKit/UIPeripheralHost_Private.h>
+#import <QuartzCore/CARenderServer.h>
+#import <QuartzCore/QuartzCorePrivate.h>
 
 @interface UIScrollView (UIScrollViewInternal)
 - (void)_adjustForAutomaticKeyboardInfo:(NSDictionary*)info animated:(BOOL)animated lastAdjustment:(CGFloat*)lastAdjustment;
@@ -493,14 +497,22 @@ static CGFloat contentZoomScale(WKWebView* webView)
     }
 }
 
-- (RetainPtr<CGImageRef>)_takeViewSnapshot
+- (WebKit::ViewSnapshot)_takeViewSnapshot
 {
-    // FIXME: We should be able to use acquire an IOSurface directly, instead of going to CGImage here and back in ViewSnapshotStore.
-    UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, self.window.screen.scale);
-    [self drawViewHierarchyInRect:[self bounds] afterScreenUpdates:NO];
-    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-    return image.CGImage;
+    float deviceScale = wkGetScreenScaleFactor();
+    CGSize snapshotSize = self.bounds.size;
+    snapshotSize.width *= deviceScale;
+    snapshotSize.height *= deviceScale;
+
+    WebKit::ViewSnapshot snapshot;
+    snapshot.slotID = [WebKit::ViewSnapshotStore::snapshottingContext() createImageSlot:snapshotSize hasAlpha:YES];
+
+    CATransform3D transform = CATransform3DMakeScale(deviceScale, deviceScale, 1);
+    CARenderServerCaptureLayerWithTransform(MACH_PORT_NULL, self.layer.context.contextId, (uint64_t)self.layer, snapshot.slotID, 0, 0, &transform);
+
+    snapshot.imageSizeInBytes = snapshotSize.width * snapshotSize.height * 4;
+
+    return snapshot;
 }
 
 - (void)_zoomToPoint:(WebCore::FloatPoint)point atScale:(double)scale
index 5e669fa..61e733e 100644 (file)
@@ -46,6 +46,7 @@
 
 namespace WebKit {
 class WebPageProxy;
+struct ViewSnapshot;
 }
 
 @interface WKWebView () WK_WEB_VIEW_PROTOCOLS {
@@ -61,7 +62,7 @@ class WebPageProxy;
 
 - (void)_dynamicViewportUpdateChangedTargetToScale:(double)newScale position:(CGPoint)newScrollPosition;
 
-- (RetainPtr<CGImageRef>)_takeViewSnapshot;
+- (WebKit::ViewSnapshot)_takeViewSnapshot;
 
 - (void)_scrollToContentOffset:(WebCore::FloatPoint)contentOffset;
 - (BOOL)_scrollToRect:(WebCore::FloatRect)targetRect origin:(WebCore::FloatPoint)origin minimumScrollDistance:(float)minimumScrollDistance;
index 9dd9c92..f3488e7 100644 (file)
@@ -3025,12 +3025,27 @@ static void createSandboxExtensionsForFileUpload(NSPasteboard *pasteboard, Sandb
     return _data->_rootLayer.get();
 }
 
-- (RetainPtr<CGImageRef>)_takeViewSnapshot
+static RefPtr<IOSurface> createIOSurfaceFromImage(CGImageRef image)
+{
+    size_t width = CGImageGetWidth(image);
+    size_t height = CGImageGetHeight(image);
+
+    RefPtr<IOSurface> surface = IOSurface::create(IntSize(width, height), ColorSpaceDeviceRGB);
+    RetainPtr<CGContextRef> surfaceContext = surface->ensurePlatformContext();
+    CGContextDrawImage(surfaceContext.get(), CGRectMake(0, 0, width, height), image);
+    CGContextFlush(surfaceContext.get());
+
+    return surface;
+}
+
+- (ViewSnapshot)_takeViewSnapshot
 {
     NSWindow *window = self.window;
 
+    ViewSnapshot snapshot;
+
     if (![window windowNumber])
-        return nullptr;
+        return snapshot;
 
     // FIXME: This should use CGWindowListCreateImage once <rdar://problem/15709646> is resolved.
     CGSWindowID windowID = [window windowNumber];
@@ -3059,7 +3074,11 @@ static void createSandboxExtensionsForFileUpload(NSPasteboard *pasteboard, Sandb
     NSRect croppedImageRect = windowCaptureRect;
     croppedImageRect.origin.y = windowScreenRect.size.height - windowCaptureScreenRect.size.height - NSMinY(windowCaptureRect);
 
-    return adoptCF(CGImageCreateWithImageInRect(windowSnapshotImage.get(), NSRectToCGRect([window convertRectToBacking:croppedImageRect])));
+    auto croppedSnapshotImage = adoptCF(CGImageCreateWithImageInRect(windowSnapshotImage.get(), NSRectToCGRect([window convertRectToBacking:croppedImageRect])));
+
+    snapshot.surface = createIOSurfaceFromImage(croppedSnapshotImage.get());
+    snapshot.imageSizeInBytes = snapshot.surface->totalBytes();
+    return snapshot;
 }
 
 - (void)_wheelEventWasNotHandledByWebCore:(NSEvent *)event
index f8a63c9..31f2541 100644 (file)
 @class WKWebViewConfiguration;
 
 namespace IPC {
-    class DataReference;
+class DataReference;
 }
 
 namespace WebCore {
-    struct KeypressCommand;
-    class Image;
-    class SharedBuffer;
+class Image;
+class SharedBuffer;
+struct KeypressCommand;
 }
 
 namespace WebKit {
@@ -50,6 +50,7 @@ class LayerTreeContext;
 class WebContext;
 struct ColorSpaceData;
 struct EditorState;
+struct ViewSnapshot;
 struct WebPageConfiguration;
 }
 
@@ -82,7 +83,7 @@ struct WebPageConfiguration;
 - (void)_setAcceleratedCompositingModeRootLayer:(CALayer *)rootLayer;
 - (CALayer *)_acceleratedCompositingModeRootLayer;
 
-- (RetainPtr<CGImageRef>)_takeViewSnapshot;
+- (WebKit::ViewSnapshot)_takeViewSnapshot;
 - (void)_wheelEventWasNotHandledByWebCore:(NSEvent *)event;
 
 - (void)_setAccessibilityWebProcessToken:(NSData *)data;
index e21e6a9..1bd2371 100644 (file)
@@ -46,8 +46,8 @@ OBJC_CLASS NSTextAlternatives;
 #endif
 
 namespace WebCore {
-    class Cursor;
-    struct ViewportAttributes;
+class Cursor;
+struct ViewportAttributes;
 }
 
 namespace WebKit {
@@ -59,6 +59,7 @@ class RemoteLayerTreeTransaction;
 class WebContextMenuProxy;
 class WebEditCommandProxy;
 class WebPopupMenuProxy;
+struct ViewSnapshot;
 
 #if ENABLE(TOUCH_EVENTS)
 class NativeWebTouchEvent;
@@ -178,7 +179,7 @@ public:
     virtual void makeFirstResponder() = 0;
     virtual void setAcceleratedCompositingRootLayer(LayerOrView *) = 0;
     virtual LayerOrView *acceleratedCompositingRootLayer() const = 0;
-    virtual RetainPtr<CGImageRef> takeViewSnapshot() = 0;
+    virtual ViewSnapshot takeViewSnapshot() = 0;
     virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) = 0;
     virtual void clearCustomSwipeViews() = 0;
 #endif
index 9ffe6ea..465def3 100644 (file)
@@ -4758,7 +4758,7 @@ void WebPageProxy::dictationAlternatives(uint64_t dictationContext, Vector<Strin
 #endif // PLATFORM(MAC)
 
 #if PLATFORM(COCOA)
-RetainPtr<CGImageRef> WebPageProxy::takeViewSnapshot()
+ViewSnapshot WebPageProxy::takeViewSnapshot()
 {
     return m_pageClient.takeViewSnapshot();
 }
index d8de054..d59e207 100644 (file)
@@ -171,6 +171,7 @@ struct EditingRange;
 struct EditorState;
 struct PlatformPopupMenuData;
 struct PrintInfo;
+struct ViewSnapshot;
 struct WebPopupItem;
 
 #if ENABLE(VIBRATION)
@@ -1066,7 +1067,7 @@ public:
     void recordNavigationSnapshot();
 
 #if PLATFORM(COCOA)
-    RetainPtr<CGImageRef> takeViewSnapshot();
+    ViewSnapshot takeViewSnapshot();
 #endif
 
 #if ENABLE(SUBTLE_CRYPTO)
index fdd2478..5923ead 100644 (file)
@@ -102,7 +102,7 @@ private:
     virtual LayerOrView *acceleratedCompositingRootLayer() const override;
     virtual LayerHostingMode viewLayerHostingMode() override { return LayerHostingMode::OutOfProcess; }
 
-    virtual RetainPtr<CGImageRef> takeViewSnapshot() override;
+    virtual ViewSnapshot takeViewSnapshot() override;
     virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override;
     virtual void clearCustomSwipeViews() override;
 
index a32f2d1..e8429da 100644 (file)
@@ -34,6 +34,7 @@
 #import "FindIndicator.h"
 #import "NativeWebKeyboardEvent.h"
 #import "InteractionInformationAtPosition.h"
+#import "ViewSnapshotStore.h"
 #import "WKContentView.h"
 #import "WKContentViewInteraction.h"
 #import "WKWebViewInternal.h"
@@ -350,9 +351,9 @@ LayerOrView *PageClientImpl::acceleratedCompositingRootLayer() const
     return nullptr;
 }
 
-RetainPtr<CGImageRef> PageClientImpl::takeViewSnapshot()
+ViewSnapshot PageClientImpl::takeViewSnapshot()
 {
-    return [m_contentView _takeViewSnapshot];
+    return [m_webView _takeViewSnapshot];
 }
 
 void PageClientImpl::wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent& event)
index 186c342..f58989a 100644 (file)
@@ -37,7 +37,7 @@
 #import "WebPageProxy.h"
 #import "WebProcessProxy.h"
 #import <WebCore/IOSurface.h>
-#import <QuartzCore/QuartzCore.h>
+#import <QuartzCore/QuartzCorePrivate.h>
 #import <UIKit/UIScreenEdgePanGestureRecognizer.h>
 #import <UIKit/UIViewControllerTransitioning_Private.h>
 #import <UIKit/UIWebTouchEventsGestureRecognizer.h>
@@ -156,19 +156,12 @@ void ViewGestureController::beginSwipeGesture(_UINavigationInteractiveTransition
     RetainPtr<UIViewController> snapshotViewController = adoptNS([[UIViewController alloc] init]);
     m_snapshotView = adoptNS([[UIView alloc] initWithFrame:liveSwipeViewFrame]);
 
-    ViewSnapshotStore::Snapshot snapshot;
-    if (ViewSnapshotStore::shared().getSnapshot(targetItem, snapshot)) {
-#if USE(IOSURFACE)
-        if (snapshot.surface->setIsVolatile(false) == IOSurface::SurfaceState::Valid) {
-            [m_snapshotView layer].contents = (id)snapshot.surface->surface();
-            m_currentSwipeSnapshotSurface = snapshot.surface;
-        }
-#else
-        [m_snapshotView layer].contents = (id)snapshot.image.get();
-#endif
-    }
+    ViewSnapshot snapshot;
+    if (ViewSnapshotStore::shared().getSnapshot(targetItem, snapshot) && snapshot.hasImage())
+        [m_snapshotView layer].contents = [CAContext objectForSlot:snapshot.slotID];
+
     [m_snapshotView setBackgroundColor:[UIColor whiteColor]];
-    [m_snapshotView layer].contentsGravity = @"topLeft";
+    [m_snapshotView layer].contentsGravity = kCAGravityTopLeft;
     [m_snapshotView layer].contentsScale = m_liveSwipeView.window.screen.scale;
     [snapshotViewController setView:m_snapshotView.get()];
 
@@ -231,7 +224,7 @@ void ViewGestureController::endSwipeGesture(WebBackForwardListItem* targetItem,
         return;
     }
 
-    ViewSnapshotStore::Snapshot snapshot;
+    ViewSnapshot snapshot;
     m_targetRenderTreeSize = 0;
     if (ViewSnapshotStore::shared().getSnapshot(targetItem, snapshot))
         m_targetRenderTreeSize = snapshot.renderTreeSize * swipeSnapshotRemovalRenderTreeSizeTargetFraction;
index d452745..b38b104 100644 (file)
@@ -78,7 +78,6 @@ struct WebPageConfiguration;
 
 - (void)_decidePolicyForGeolocationRequestFromOrigin:(WebKit::WebSecurityOrigin&)origin frame:(WebKit::WebFrameProxy&)frame request:(WebKit::GeolocationPermissionRequestProxy&)permissionRequest;
 
-- (RetainPtr<CGImageRef>)_takeViewSnapshot;
 - (void)_setAccessibilityWebProcessToken:(NSData *)data;
 
 - (BOOL)_scrollToRect:(CGRect)targetRect withOrigin:(CGPoint)origin minimumScrollDistance:(CGFloat)minimumScrollDistance;
index d76eb4d..f50f1e7 100644 (file)
@@ -440,11 +440,6 @@ static inline FloatRect fixedPositionRectFromExposedRect(CGRect unobscuredRect,
     [[wrapper(_page->process().context()) _geolocationProvider] decidePolicyForGeolocationRequestFromOrigin:toAPI(&origin) frame:toAPI(&frame) request:toAPI(&permissionRequest) window:[self window]];
 }
 
-- (RetainPtr<CGImageRef>)_takeViewSnapshot
-{
-    return [_webView _takeViewSnapshot];
-}
-
 - (BOOL)_scrollToRect:(CGRect)targetRect withOrigin:(CGPoint)origin minimumScrollDistance:(CGFloat)minimumScrollDistance
 {
     return [_webView _scrollToRect:targetRect origin:origin minimumScrollDistance:minimumScrollDistance];
diff --git a/Source/WebKit2/UIProcess/ios/WebMemoryPressureHandlerIOS.cpp b/Source/WebKit2/UIProcess/ios/WebMemoryPressureHandlerIOS.cpp
new file mode 100644 (file)
index 0000000..ddbd1b0
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebMemoryPressureHandlerIOS.h"
+
+#if PLATFORM(IOS)
+
+#include "ViewSnapshotStore.h"
+#include <dispatch/private.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebMemoryPressureHandler& WebMemoryPressureHandler::shared()
+{
+    static NeverDestroyed<WebMemoryPressureHandler> memoryPressureHandler;
+    return memoryPressureHandler;
+}
+
+WebMemoryPressureHandler::WebMemoryPressureHandler()
+{
+    // FIXME: This should be able to share code with WebCore's MemoryPressureHandler (and be platform independent).
+    // Right now it cannot because WebKit1 and WebKit2 need to be able to coexist in the UI process,
+    // and you can only have one WebCore::MemoryPressureHandler.
+
+    dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYSTATUS, 0, DISPATCH_MEMORYSTATUS_PRESSURE_WARN, dispatch_get_main_queue());
+    dispatch_set_context(source, this);
+    dispatch_source_set_event_handler(source, ^{
+        ViewSnapshotStore::shared().discardSnapshots();
+    });
+    dispatch_resume(source);
+}
+
+} // namespace WebKit
+
+#endif
diff --git a/Source/WebKit2/UIProcess/ios/WebMemoryPressureHandlerIOS.h b/Source/WebKit2/UIProcess/ios/WebMemoryPressureHandlerIOS.h
new file mode 100644 (file)
index 0000000..7910faa
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebMemoryPressureHandler_h
+#define WebMemoryPressureHandler_h
+
+#if PLATFORM(IOS)
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WebKit {
+
+class WebMemoryPressureHandler {
+    friend class NeverDestroyed<WebMemoryPressureHandler>;
+public:
+    static WebMemoryPressureHandler& shared();
+
+private:
+    WebMemoryPressureHandler();
+};
+
+} // namespace WebKit
+
+#endif // PLATFORM(IOS)
+
+#endif // WebMemoryPressureHandler_h
index 460968a..7bdccac 100644 (file)
@@ -120,7 +120,7 @@ private:
     virtual void exitAcceleratedCompositingMode();
     virtual void updateAcceleratedCompositingMode(const LayerTreeContext&);
 
-    virtual RetainPtr<CGImageRef> takeViewSnapshot() override;
+    virtual ViewSnapshot takeViewSnapshot() override;
     virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override;
     virtual void clearCustomSwipeViews() override;
 
index 81c19c7..a84f94b 100644 (file)
@@ -38,6 +38,7 @@
 #import "NativeWebKeyboardEvent.h"
 #import "NativeWebWheelEvent.h"
 #import "StringUtilities.h"
+#import "ViewSnapshotStore.h"
 #import "WKAPICast.h"
 #import "WKFullScreenWindowController.h"
 #import "WKStringCF.h"
@@ -498,7 +499,7 @@ CALayer *PageClientImpl::acceleratedCompositingRootLayer() const
     return m_wkView._acceleratedCompositingModeRootLayer;
 }
 
-RetainPtr<CGImageRef> PageClientImpl::takeViewSnapshot()
+ViewSnapshot PageClientImpl::takeViewSnapshot()
 {
     return [m_wkView _takeViewSnapshot];
 }
index 556ae24..da42034 100644 (file)
@@ -453,7 +453,7 @@ CALayer *ViewGestureController::determineLayerAdjacentToSnapshotForParent(SwipeD
 
 IOSurface* ViewGestureController::retrieveSnapshotForItem(WebBackForwardListItem* targetItem, FloatSize swipeLayerSize, float topContentInset)
 {
-    ViewSnapshotStore::Snapshot snapshot;
+    ViewSnapshot snapshot;
     if (!ViewSnapshotStore::shared().getSnapshot(targetItem, snapshot))
         return nullptr;
 
@@ -632,7 +632,7 @@ void ViewGestureController::endSwipeGesture(WebBackForwardListItem* targetItem,
         return;
     }
 
-    ViewSnapshotStore::Snapshot snapshot;
+    ViewSnapshot snapshot;
     uint64_t renderTreeSize = 0;
     if (ViewSnapshotStore::shared().getSnapshot(targetItem, snapshot))
         renderTreeSize = snapshot.renderTreeSize;
index 807961c..784d42e 100644 (file)
 #include <wtf/RetainPtr.h>
 #include <wtf/text/WTFString.h>
 
+OBJC_CLASS CAContext;
+
 namespace WebKit {
 
 class WebBackForwardListItem;
 class WebPageProxy;
 
+struct ViewSnapshot {
+#if PLATFORM(MAC)
+    RefPtr<WebCore::IOSurface> surface;
+#endif
+#if PLATFORM(IOS)
+    uint32_t slotID = 0;
+#endif
+
+    std::chrono::steady_clock::time_point creationTime;
+    uint64_t renderTreeSize;
+    float deviceScaleFactor;
+    size_t imageSizeInBytes = 0;
+
+    void clearImage();
+    bool hasImage() const;
+};
+
 class ViewSnapshotStore {
     WTF_MAKE_NONCOPYABLE(ViewSnapshotStore);
 public:
@@ -46,34 +65,26 @@ public:
 
     static ViewSnapshotStore& shared();
 
-    struct Snapshot {
-#if USE(IOSURFACE)
-        RefPtr<WebCore::IOSurface> surface;
-#else
-        RetainPtr<CGImageRef> image;
-#endif
-
-        std::chrono::steady_clock::time_point creationTime;
-        uint64_t renderTreeSize;
-        float deviceScaleFactor;
-
-        void clearImage();
-        bool hasImage() const;
-    };
-
     void recordSnapshot(WebPageProxy&);
-    bool getSnapshot(WebBackForwardListItem*, Snapshot&);
+    bool getSnapshot(WebBackForwardListItem*, ViewSnapshot&);
 
     void disableSnapshotting() { m_enabled = false; }
     void enableSnapshotting() { m_enabled = true; }
 
+    void discardSnapshots();
+
+#if PLATFORM(IOS)
+    static CAContext *snapshottingContext();
+#endif
+
 private:
     void pruneSnapshots(WebPageProxy&);
+    void removeSnapshotImage(ViewSnapshot&);
 
-    HashMap<String, Snapshot> m_snapshotMap;
+    HashMap<String, ViewSnapshot> m_snapshotMap;
 
     bool m_enabled;
-    unsigned m_snapshotsWithImagesCount;
+    size_t m_snapshotCacheSize;
 };
 
 } // namespace WebKit
index 14daa6d..271a707 100644 (file)
 #import <WebCore/IOSurface.h>
 #import <WebCore/UUID.h>
 
+#if PLATFORM(IOS)
+#import <QuartzCore/QuartzCorePrivate.h>
+#endif
+
 using namespace WebCore;
 
-static const int maximumSnapshotCount = 20;
+#if PLATFORM(MAC)
+static const size_t maximumSnapshotCacheSize = 400 * (1024 * 1024);
+#elif PLATFORM(IOS)
+// Because snapshots are not purgeable, we should keep fewer around.
+static const size_t maximumSnapshotCacheSize = 50 * (1024 * 1024);
+#endif
 
 namespace WebKit {
 
 ViewSnapshotStore::ViewSnapshotStore()
     : m_enabled(true)
-    , m_snapshotsWithImagesCount(0)
+    , m_snapshotCacheSize(0)
 {
 }
 
 ViewSnapshotStore::~ViewSnapshotStore()
 {
+    discardSnapshots();
 }
 
 ViewSnapshotStore& ViewSnapshotStore::shared()
@@ -54,9 +64,36 @@ ViewSnapshotStore& ViewSnapshotStore::shared()
     return store;
 }
 
+#if PLATFORM(IOS)
+CAContext *ViewSnapshotStore::snapshottingContext()
+{
+    static CAContext *context;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        NSDictionary *options = @{
+            kCAContextDisplayName: @"WebKitSnapshotting",
+            kCAContextIgnoresHitTest: @YES,
+            kCAContextDisplayId : @20000
+        };
+        context = [[CAContext remoteContextWithOptions:options] retain];
+    });
+
+    return context;
+}
+#endif
+
+void ViewSnapshotStore::removeSnapshotImage(ViewSnapshot& snapshot)
+{
+    if (!snapshot.hasImage())
+        return;
+
+    m_snapshotCacheSize -= snapshot.imageSizeInBytes;
+    snapshot.clearImage();
+}
+
 void ViewSnapshotStore::pruneSnapshots(WebPageProxy& webPageProxy)
 {
-    if (m_snapshotsWithImagesCount <= maximumSnapshotCount)
+    if (m_snapshotCacheSize <= maximumSnapshotCacheSize)
         return;
 
     uint32_t currentIndex = webPageProxy.backForwardList().currentIndex();
@@ -89,8 +126,7 @@ void ViewSnapshotStore::pruneSnapshots(WebPageProxy& webPageProxy)
     }
 
     if (mostDistantSnapshotIter != m_snapshotMap.end()) {
-        mostDistantSnapshotIter->value.clearImage();
-        m_snapshotsWithImagesCount--;
+        removeSnapshotImage(mostDistantSnapshotIter->value);
         return;
     }
 
@@ -107,24 +143,8 @@ void ViewSnapshotStore::pruneSnapshots(WebPageProxy& webPageProxy)
     }
 
     const auto& snapshotIter = m_snapshotMap.find(oldestSnapshotUUID);
-    snapshotIter->value.clearImage();
-    m_snapshotsWithImagesCount--;
-}
-
-#if USE(IOSURFACE)
-static RefPtr<IOSurface> createIOSurfaceFromImage(CGImageRef image)
-{
-    size_t width = CGImageGetWidth(image);
-    size_t height = CGImageGetHeight(image);
-
-    RefPtr<IOSurface> surface = IOSurface::create(IntSize(width, height), ColorSpaceDeviceRGB);
-    RetainPtr<CGContextRef> surfaceContext = surface->ensurePlatformContext();
-    CGContextDrawImage(surfaceContext.get(), CGRectMake(0, 0, width, height), image);
-    CGContextFlush(surfaceContext.get());
-
-    return surface;
+    removeSnapshotImage(snapshotIter->value);
 }
-#endif
 
 void ViewSnapshotStore::recordSnapshot(WebPageProxy& webPageProxy)
 {
@@ -136,43 +156,29 @@ void ViewSnapshotStore::recordSnapshot(WebPageProxy& webPageProxy)
     if (!item)
         return;
 
-    RetainPtr<CGImageRef> snapshotImage = webPageProxy.takeViewSnapshot();
-    if (!snapshotImage)
-        return;
-
     pruneSnapshots(webPageProxy);
 
     String oldSnapshotUUID = item->snapshotUUID();
     if (!oldSnapshotUUID.isEmpty()) {
         const auto& oldSnapshotIter = m_snapshotMap.find(oldSnapshotUUID);
         if (oldSnapshotIter != m_snapshotMap.end()) {
-            if (oldSnapshotIter->value.hasImage())
-                m_snapshotsWithImagesCount--;
+            removeSnapshotImage(oldSnapshotIter->value);
             m_snapshotMap.remove(oldSnapshotIter);
         }
     }
 
     item->setSnapshotUUID(createCanonicalUUIDString());
-    
-    Snapshot snapshot;
+
+    ViewSnapshot snapshot = webPageProxy.takeViewSnapshot();
     snapshot.creationTime = std::chrono::steady_clock::now();
     snapshot.renderTreeSize = webPageProxy.renderTreeSize();
     snapshot.deviceScaleFactor = webPageProxy.deviceScaleFactor();
 
-#if USE(IOSURFACE)
-    snapshot.surface = createIOSurfaceFromImage(snapshotImage.get());
-    snapshot.surface->setIsVolatile(true);
-#else
-    snapshot.image = snapshotImage;
-#endif
-
     m_snapshotMap.add(item->snapshotUUID(), snapshot);
-
-    if (snapshot.hasImage())
-        m_snapshotsWithImagesCount++;
+    m_snapshotCacheSize += snapshot.imageSizeInBytes;
 }
 
-bool ViewSnapshotStore::getSnapshot(WebBackForwardListItem* item, ViewSnapshotStore::Snapshot& snapshot)
+bool ViewSnapshotStore::getSnapshot(WebBackForwardListItem* item, ViewSnapshot& snapshot)
 {
     if (item->snapshotUUID().isEmpty())
         return false;
@@ -184,22 +190,27 @@ bool ViewSnapshotStore::getSnapshot(WebBackForwardListItem* item, ViewSnapshotSt
     return true;
 }
 
-void ViewSnapshotStore::Snapshot::clearImage()
+void ViewSnapshotStore::discardSnapshots()
 {
-#if USE(IOSURFACE)
-    surface = nullptr;
-#else
-    image = nullptr;
-#endif
+    for (auto& snapshot : m_snapshotMap.values())
+        removeSnapshotImage(snapshot);
 }
 
-bool ViewSnapshotStore::Snapshot::hasImage() const
+bool ViewSnapshot::hasImage() const
 {
-#if USE(IOSURFACE)
-    return surface;
-#else
-    return image;
+    return imageSizeInBytes;
+}
+
+void ViewSnapshot::clearImage()
+{
+#if PLATFORM(MAC)
+    surface = nullptr;
+#elif PLATFORM(IOS)
+    if (slotID)
+        [ViewSnapshotStore::snapshottingContext() deleteSlot:slotID];
+    slotID = 0;
 #endif
+    imageSizeInBytes = 0;
 }
 
 } // namespace WebKit
index 6fb372c..c1cb770 100644 (file)
 #import "WKBrowsingContextControllerInternal.h"
 #import "WKBrowsingContextControllerInternal.h"
 #import "WebKitSystemInterface.h"
+#import "WebMemoryPressureHandlerIOS.h"
 #import "WebPageGroup.h"
 #import "WebProcessCreationParameters.h"
 #import "WebProcessMessages.h"
 #import "WindowServerConnection.h"
-#if !PLATFORM(IOS)
-#import <QuartzCore/CARemoteLayerServer.h>
-#endif
 #import <WebCore/Color.h>
 #import <WebCore/FileSystem.h>
 #import <WebCore/NotImplemented.h>
 #import "NetworkProcessProxy.h"
 #endif
 
+#if !PLATFORM(IOS)
+#import <QuartzCore/CARemoteLayerServer.h>
+#endif
+
 #if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
 
 #if __has_include(<CFNetwork/CFURLProtocolPriv.h>)
@@ -129,6 +131,10 @@ void WebContext::platformInitialize()
 {
     registerUserDefaultsIfNeeded();
     registerNotificationObservers();
+
+#if PLATFORM(IOS)
+    WebKit::WebMemoryPressureHandler::shared();
+#endif
 }
 
 String WebContext::platformDefaultApplicationCacheDirectory() const
index 71a6295..0838f7a 100644 (file)
                2D2ADF0916362DD500197E47 /* PDFPluginTextAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2ADF0616362DC700197E47 /* PDFPluginTextAnnotation.mm */; };
                2D2ADF0B16362DDB00197E47 /* PDFPluginAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2ADF031636243500197E47 /* PDFPluginAnnotation.mm */; };
                2D2ADF1016364D8200197E47 /* PDFPluginChoiceAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2ADF0E16364D8200197E47 /* PDFPluginChoiceAnnotation.mm */; };
+               2D3EF4421917646300034184 /* WebMemoryPressureHandlerIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D3EF4401917646300034184 /* WebMemoryPressureHandlerIOS.cpp */; };
+               2D3EF4431917646300034184 /* WebMemoryPressureHandlerIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D3EF4411917646300034184 /* WebMemoryPressureHandlerIOS.h */; };
                2D429BFD1721E2C700EC681F /* PDFPluginPasswordField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D429BFB1721E2BA00EC681F /* PDFPluginPasswordField.mm */; };
                2D47B56C1810714E003A3AEE /* RemoteLayerBackingStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D47B56A1810714E003A3AEE /* RemoteLayerBackingStore.mm */; };
                2D47B56D1810714E003A3AEE /* RemoteLayerBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D47B56B1810714E003A3AEE /* RemoteLayerBackingStore.h */; };
                2D2ADF0C16363DEC00197E47 /* PDFLayerControllerDetails.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PDFLayerControllerDetails.h; path = PDF/PDFLayerControllerDetails.h; sourceTree = "<group>"; };
                2D2ADF0D16364D8200197E47 /* PDFPluginChoiceAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDFPluginChoiceAnnotation.h; path = PDF/PDFPluginChoiceAnnotation.h; sourceTree = "<group>"; };
                2D2ADF0E16364D8200197E47 /* PDFPluginChoiceAnnotation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPluginChoiceAnnotation.mm; path = PDF/PDFPluginChoiceAnnotation.mm; sourceTree = "<group>"; };
+               2D3EF4401917646300034184 /* WebMemoryPressureHandlerIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebMemoryPressureHandlerIOS.cpp; path = ios/WebMemoryPressureHandlerIOS.cpp; sourceTree = "<group>"; };
+               2D3EF4411917646300034184 /* WebMemoryPressureHandlerIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebMemoryPressureHandlerIOS.h; path = ios/WebMemoryPressureHandlerIOS.h; sourceTree = "<group>"; };
                2D429BFA1721E2BA00EC681F /* PDFPluginPasswordField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDFPluginPasswordField.h; path = PDF/PDFPluginPasswordField.h; sourceTree = "<group>"; };
                2D429BFB1721E2BA00EC681F /* PDFPluginPasswordField.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPluginPasswordField.mm; path = PDF/PDFPluginPasswordField.mm; sourceTree = "<group>"; };
                2D47B56A1810714E003A3AEE /* RemoteLayerBackingStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RemoteLayerBackingStore.mm; sourceTree = "<group>"; };
                                2DAF06D518BD1A470081CEB1 /* SmartMagnificationController.mm */,
                                2DAF06D818BD23BA0081CEB1 /* SmartMagnificationController.messages.in */,
                                2DA944AA1884E9BA00ED86DB /* WebInspectorProxyIOS.mm */,
+                               2D3EF4401917646300034184 /* WebMemoryPressureHandlerIOS.cpp */,
+                               2D3EF4411917646300034184 /* WebMemoryPressureHandlerIOS.h */,
                                2DA944AB1884E9BA00ED86DB /* WebPageProxyIOS.mm */,
                                2DA944AC1884E9BA00ED86DB /* WebProcessProxyIOS.mm */,
                                3F889D12188778C900FEADAF /* WebVideoFullscreenManagerProxy.mm */,
                                514D9F5719119D35000063A7 /* ServicesController.h in Headers */,
                                CDC3830C17212282008A2FC3 /* CookieStorageShimLibrary.h in Headers */,
                                515E7730184015800007203F /* UniqueIDBDatabase.h in Headers */,
+                               2D3EF4431917646300034184 /* WebMemoryPressureHandlerIOS.h in Headers */,
                                B878B615133428DC006888E9 /* CorrectionPanel.h in Headers */,
                                2989A414167D184B004F96D2 /* CustomProtocolManager.h in Headers */,
                                371B32DE184D67490013E2B2 /* WKNSURLProtectionSpace.h in Headers */,
                                BC1BE1F312D54DBD0004A228 /* WebGeolocationProvider.cpp in Sources */,
                                7801C099142290C400FAF9AF /* WebHitTestResult.cpp in Sources */,
                                2684055218B86ED60022C38B /* ViewUpdateDispatcherMessageReceiver.cpp in Sources */,
+                               2D3EF4421917646300034184 /* WebMemoryPressureHandlerIOS.cpp in Sources */,
                                511B24AA132E097200065A0C /* WebIconDatabase.cpp in Sources */,
                                51834592134532E90092B696 /* WebIconDatabaseClient.cpp in Sources */,
                                51D02F64132EC5B900BEAA96 /* WebIconDatabaseMessageReceiver.cpp in Sources */,