Changeset 170974 in webkit
- Timestamp:
- Jul 10, 2014, 1:33:05 PM (11 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r170972 r170974 1 2014-07-10 Tim Horton <timothy_horton@apple.com> 2 3 Store ViewSnapshots directly on the WebBackForwardListItem 4 https://bugs.webkit.org/show_bug.cgi?id=134667 5 <rdar://problem/17082639> 6 7 Reviewed by Dan Bernstein. 8 9 Make ViewSnapshot a refcounted class. Store it directly on the back-forward item 10 instead of in a side map referenced by UUID. Switch to a very simple LRU eviction model for now. 11 This fixes a ton of snapshot management bugs; for example, we would start throwing out snapshots 12 in the page that was actively being interacted with *first* when evicting snapshots, instead of 13 preferring older snapshots. Additionally, we would not throw away snapshots when back forward items 14 became unreachable. 15 16 There is definitely room for improvement of the eviction mechanism, but this is closer to a time-tested implementation. 17 18 * Shared/SessionState.h: 19 Keep a ViewSnapshot instead of a UUID on the BackForwardListItemState. 20 21 * Shared/WebBackForwardListItem.h: 22 Fix some indented namespace contents. 23 24 (WebKit::WebBackForwardListItem::snapshot): 25 (WebKit::WebBackForwardListItem::setSnapshot): 26 (WebKit::WebBackForwardListItem::setSnapshotUUID): Deleted. 27 (WebKit::WebBackForwardListItem::snapshotUUID): Deleted. 28 Switch the snapshot getter/setter to operate on ViewSnapshots instead of UUIDs. 29 30 * UIProcess/API/Cocoa/WKWebView.mm: 31 (-[WKWebView _takeViewSnapshot]): 32 * UIProcess/API/Cocoa/WKWebViewInternal.h: 33 * UIProcess/API/mac/WKView.mm: 34 (-[WKView _takeViewSnapshot]): 35 * UIProcess/API/mac/WKViewInternal.h: 36 * UIProcess/PageClient.h: 37 * UIProcess/WebPageProxy.cpp: 38 (WebKit::WebPageProxy::takeViewSnapshot): 39 * UIProcess/WebPageProxy.h: 40 * UIProcess/ios/PageClientImplIOS.h: 41 * UIProcess/ios/PageClientImplIOS.mm: 42 (WebKit::PageClientImpl::takeViewSnapshot): 43 * UIProcess/mac/PageClientImpl.h: 44 * UIProcess/mac/PageClientImpl.mm: 45 (WebKit::PageClientImpl::takeViewSnapshot): 46 Adopt ViewSnapshot::create, return a PassRefPtr, and class-ify ViewSnapshot. 47 48 * UIProcess/ios/ViewGestureControllerIOS.mm: 49 (WebKit::ViewGestureController::beginSwipeGesture): 50 (WebKit::ViewGestureController::endSwipeGesture): 51 * UIProcess/mac/ViewGestureController.h: 52 * UIProcess/mac/ViewGestureControllerMac.mm: 53 (WebKit::ViewGestureController::shouldUseSnapshotForSize): 54 (WebKit::ViewGestureController::beginSwipeGesture): 55 (WebKit::ViewGestureController::endSwipeGesture): 56 Grab the ViewSnapshot directly from the WebBackForwardListItem, and adopt the new functions. 57 58 * UIProcess/ios/WebMemoryPressureHandlerIOS.mm: 59 (WebKit::WebMemoryPressureHandler::WebMemoryPressureHandler): 60 Rename discardSnapshots to discardSnapshotImages, because we're really only discarding 61 the images; the render tree size/background color "snapshot" remains and is useful. 62 63 * UIProcess/mac/ViewSnapshotStore.h: 64 (WebKit::ViewSnapshot::setRenderTreeSize): 65 (WebKit::ViewSnapshot::renderTreeSize): 66 (WebKit::ViewSnapshot::setBackgroundColor): 67 (WebKit::ViewSnapshot::backgroundColor): 68 (WebKit::ViewSnapshot::setDeviceScaleFactor): 69 (WebKit::ViewSnapshot::deviceScaleFactor): 70 (WebKit::ViewSnapshot::imageSizeInBytes): 71 (WebKit::ViewSnapshot::surface): 72 (WebKit::ViewSnapshot::size): 73 (WebKit::ViewSnapshot::creationTime): 74 Make ViewSnapshot a refcounted class. 75 Add create functions which take an image (or slot ID), and relevant sizes. 76 It is expected that a ViewSnapshot is created with an image, and it is only possible 77 to remove that image, never to replace it. A new ViewSnapshot is required in that case. 78 Add setters for things that ViewSnapshotStore sets on the snapshot after the PageClient 79 retrieves it from the view. Add getters for things that the ViewGestureControllers need. 80 81 Remove removeSnapshotImage, getSnapshot, and the snapshot map. 82 83 * UIProcess/mac/ViewSnapshotStore.mm: 84 (WebKit::ViewSnapshotStore::~ViewSnapshotStore): 85 (WebKit::ViewSnapshotStore::didAddImageToSnapshot): 86 (WebKit::ViewSnapshotStore::willRemoveImageFromSnapshot): 87 Manage m_snapshotCacheSize and m_snapshotsWithImages via didAddImageToSnapshot and willRemoveImageFromSnapshot. 88 willRemoveImageFromSnapshot will -always- be called before the ViewSnapshot is destroyed. 89 90 (WebKit::ViewSnapshotStore::pruneSnapshots): 91 Switch to a simple LRU eviction model. As previously mentioned, it's possible to do better, but 92 this is much less broken than the previous implementation. 93 94 (WebKit::ViewSnapshotStore::recordSnapshot): 95 (WebKit::ViewSnapshotStore::discardSnapshotImages): 96 (WebKit::ViewSnapshot::create): 97 (WebKit::ViewSnapshot::ViewSnapshot): 98 (WebKit::ViewSnapshot::~ViewSnapshot): 99 (WebKit::ViewSnapshot::hasImage): 100 (WebKit::ViewSnapshot::clearImage): 101 (WebKit::ViewSnapshot::asLayerContents): 102 If a surface is Empty when it comes back from being volatile, throw away the surface 103 and notify the Store to remove it from m_snapshotCacheSize (via clearImage()). 104 105 (WebKit::ViewSnapshotStore::removeSnapshotImage): Deleted. 106 (WebKit::ViewSnapshotStore::getSnapshot): Deleted. 107 (WebKit::ViewSnapshotStore::discardSnapshots): Deleted. 108 1 109 2014-07-10 Beth Dakin <bdakin@apple.com> 2 110 -
trunk/Source/WebKit2/Shared/SessionState.h
r170722 r170974 27 27 #define SessionState_h 28 28 29 #include "ViewSnapshotStore.h" 29 30 #include <WebCore/FloatRect.h> 30 31 #include <WebCore/IntRect.h> … … 121 122 122 123 PageState pageState; 123 // FIXME: This should hold the snapshot itself, not its UUID. 124 String snapshotUUID; 124 RefPtr<ViewSnapshot> snapshot; 125 125 }; 126 126 -
trunk/Source/WebKit2/Shared/WebBackForwardListItem.h
r170902 r170974 37 37 38 38 namespace IPC { 39 40 39 class ArgumentDecoder; 40 class ArgumentEncoder; 41 41 } 42 42 … … 57 57 const String& url() const { return m_itemState.pageState.mainFrameState.urlString; } 58 58 const String& title() const { return m_itemState.pageState.title; } 59 60 void setSnapshotUUID(const String& uuid) { m_itemState.snapshotUUID = uuid; }61 const String& snapshotUUID() const { return m_itemState.snapshotUUID; }59 60 ViewSnapshot* snapshot() const { return m_itemState.snapshot.get(); } 61 void setSnapshot(PassRefPtr<ViewSnapshot> snapshot) { m_itemState.snapshot = snapshot; } 62 62 63 63 static uint64_t highedUsedItemID(); -
trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
r170945 r170974 900 900 } 901 901 902 - ( WebKit::ViewSnapshot)_takeViewSnapshot902 - (PassRefPtr<WebKit::ViewSnapshot>)_takeViewSnapshot 903 903 { 904 904 float deviceScale = WKGetScreenScaleFactor(); … … 907 907 snapshotSize.height *= deviceScale; 908 908 909 WebKit::ViewSnapshot snapshot; 910 snapshot.slotID = [WebKit::ViewSnapshotStore::snapshottingContext() createImageSlot:snapshotSize hasAlpha:YES]; 909 uint32_t slotID = [WebKit::ViewSnapshotStore::snapshottingContext() createImageSlot:snapshotSize hasAlpha:YES]; 910 911 if (!slotID) 912 return nullptr; 911 913 912 914 CATransform3D transform = CATransform3DMakeScale(deviceScale, deviceScale, 1); 913 CARenderServerCaptureLayerWithTransform(MACH_PORT_NULL, self.layer.context.contextId, (uint64_t)self.layer, snapshot.slotID, 0, 0, &transform); 914 915 snapshot.size = WebCore::expandedIntSize(WebCore::FloatSize(snapshotSize)); 916 snapshot.imageSizeInBytes = snapshotSize.width * snapshotSize.height * 4; 917 snapshot.backgroundColor = _page->pageExtendedBackgroundColor(); 918 919 return snapshot; 915 CARenderServerCaptureLayerWithTransform(MACH_PORT_NULL, self.layer.context.contextId, (uint64_t)self.layer, slotID, 0, 0, &transform); 916 917 WebCore::IntSize imageSize = WebCore::expandedIntSize(WebCore::FloatSize(snapshotSize)); 918 return WebKit::ViewSnapshot::create(slotID, imageSize, imageSize.width() * imageSize.height() * 4); 920 919 } 921 920 -
trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h
r170445 r170974 51 51 52 52 namespace WebKit { 53 class ViewSnapshot; 53 54 class WebPageProxy; 54 55 struct PrintInfo; 55 struct ViewSnapshot;56 56 } 57 57 … … 79 79 - (void)_restorePageStateToUnobscuredCenter:(WebCore::FloatPoint)center scale:(double)scale; 80 80 81 - ( WebKit::ViewSnapshot)_takeViewSnapshot;81 - (PassRefPtr<WebKit::ViewSnapshot>)_takeViewSnapshot; 82 82 83 83 - (void)_scrollToContentOffset:(WebCore::FloatPoint)contentOffset; -
trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm
r170963 r170974 3102 3102 } 3103 3103 3104 - ( ViewSnapshot)_takeViewSnapshot3104 - (PassRefPtr<ViewSnapshot>)_takeViewSnapshot 3105 3105 { 3106 3106 NSWindow *window = self.window; 3107 3108 ViewSnapshot snapshot;3109 3107 3110 3108 CGSWindowID windowID = (CGSWindowID)[window windowNumber]; 3111 3109 if (!windowID || ![window isVisible]) 3112 return snapshot;3110 return nullptr; 3113 3111 3114 3112 RetainPtr<CGImageRef> windowSnapshotImage = adoptCF(CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque)); … … 3142 3140 auto croppedSnapshotImage = adoptCF(CGImageCreateWithImageInRect(windowSnapshotImage.get(), NSRectToCGRect([window convertRectToBacking:croppedImageRect]))); 3143 3141 3144 snapshot.surface = IOSurface::createFromImage(croppedSnapshotImage.get()); 3145 snapshot.surface->setIsVolatile(true); 3146 3147 IntSize imageSize(CGImageGetWidth(croppedSnapshotImage.get()), CGImageGetHeight(croppedSnapshotImage.get())); 3148 snapshot.size = imageSize; 3149 snapshot.imageSizeInBytes = imageSize.width() * imageSize.height() * 4; 3150 snapshot.backgroundColor = _data->_page->pageExtendedBackgroundColor(); 3151 3152 return snapshot; 3142 auto surface = IOSurface::createFromImage(croppedSnapshotImage.get()); 3143 if (!surface) 3144 return nullptr; 3145 surface->setIsVolatile(true); 3146 3147 return ViewSnapshot::create(surface.get(), surface->size(), surface->totalBytes()); 3153 3148 } 3154 3149 -
trunk/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h
r168260 r170974 48 48 class FindIndicator; 49 49 class LayerTreeContext; 50 class ViewSnapshot; 50 51 class WebContext; 51 52 struct ColorSpaceData; 52 53 struct EditorState; 53 struct ViewSnapshot;54 54 struct WebPageConfiguration; 55 55 } … … 84 84 - (CALayer *)_acceleratedCompositingModeRootLayer; 85 85 86 - ( WebKit::ViewSnapshot)_takeViewSnapshot;86 - (PassRefPtr<WebKit::ViewSnapshot>)_takeViewSnapshot; 87 87 - (void)_wheelEventWasNotHandledByWebCore:(NSEvent *)event; 88 88 -
trunk/Source/WebKit2/UIProcess/PageClient.h
r170858 r170974 58 58 class NativeWebKeyboardEvent; 59 59 class RemoteLayerTreeTransaction; 60 class ViewSnapshot; 60 61 class WebContextMenuProxy; 61 62 class WebEditCommandProxy; 62 63 class WebPopupMenuProxy; 63 struct ViewSnapshot;64 64 65 65 #if ENABLE(TOUCH_EVENTS) … … 181 181 virtual void setAcceleratedCompositingRootLayer(LayerOrView *) = 0; 182 182 virtual LayerOrView *acceleratedCompositingRootLayer() const = 0; 183 virtual ViewSnapshottakeViewSnapshot() = 0;183 virtual PassRefPtr<ViewSnapshot> takeViewSnapshot() = 0; 184 184 virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) = 0; 185 185 virtual void clearCustomSwipeViews() = 0; -
trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp
r170943 r170974 4945 4945 4946 4946 #if PLATFORM(COCOA) 4947 ViewSnapshotWebPageProxy::takeViewSnapshot()4947 PassRefPtr<ViewSnapshot> WebPageProxy::takeViewSnapshot() 4948 4948 { 4949 4949 return m_pageClient.takeViewSnapshot(); -
trunk/Source/WebKit2/UIProcess/WebPageProxy.h
r170943 r170974 153 153 class RemoteScrollingCoordinatorProxy; 154 154 class StringPairVector; 155 class ViewSnapshot; 155 156 class VisitedLinkProvider; 156 157 class WebBackForwardList; … … 174 175 struct PlatformPopupMenuData; 175 176 struct PrintInfo; 176 struct ViewSnapshot;177 177 struct WebPopupItem; 178 178 … … 885 885 886 886 #if PLATFORM(COCOA) 887 ViewSnapshottakeViewSnapshot();887 PassRefPtr<ViewSnapshot> takeViewSnapshot(); 888 888 #endif 889 889 -
trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h
r170858 r170974 106 106 virtual LayerHostingMode viewLayerHostingMode() override { return LayerHostingMode::OutOfProcess; } 107 107 108 virtual ViewSnapshottakeViewSnapshot() override;108 virtual PassRefPtr<ViewSnapshot> takeViewSnapshot() override; 109 109 virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override; 110 110 virtual void clearCustomSwipeViews() override; -
trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm
r170858 r170974 471 471 } 472 472 473 ViewSnapshotPageClientImpl::takeViewSnapshot()473 PassRefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot() 474 474 { 475 475 return [m_webView _takeViewSnapshot]; -
trunk/Source/WebKit2/UIProcess/ios/ViewGestureControllerIOS.mm
r170761 r170974 169 169 170 170 RetainPtr<UIColor> backgroundColor = [UIColor whiteColor]; 171 ViewSnapshot snapshot; 172 if (ViewSnapshotStore::shared().getSnapshot(targetItem, snapshot)) { 171 if (ViewSnapshot* snapshot = targetItem->snapshot()) { 173 172 float deviceScaleFactor = m_webPageProxy.deviceScaleFactor(); 174 173 FloatSize swipeLayerSizeInDeviceCoordinates(liveSwipeViewFrame.size); 175 174 swipeLayerSizeInDeviceCoordinates.scale(deviceScaleFactor); 176 if (snapshot .hasImage() && snapshot.size == swipeLayerSizeInDeviceCoordinates && deviceScaleFactor == snapshot.deviceScaleFactor)177 [m_snapshotView layer].contents = snapshot .asLayerContents();178 Color coreColor = snapshot .backgroundColor;175 if (snapshot->hasImage() && snapshot->size() == swipeLayerSizeInDeviceCoordinates && deviceScaleFactor == snapshot->deviceScaleFactor()) 176 [m_snapshotView layer].contents = snapshot->asLayerContents(); 177 Color coreColor = snapshot->backgroundColor(); 179 178 if (coreColor.isValid()) 180 179 backgroundColor = adoptNS([[UIColor alloc] initWithCGColor:cachedCGColor(coreColor, ColorSpaceDeviceRGB)]); … … 245 244 } 246 245 247 ViewSnapshot snapshot;248 246 m_snapshotRemovalTargetRenderTreeSize = 0; 249 if (ViewSnapshot Store::shared().getSnapshot(targetItem, snapshot))250 m_snapshotRemovalTargetRenderTreeSize = snapshot .renderTreeSize* swipeSnapshotRemovalRenderTreeSizeTargetFraction;247 if (ViewSnapshot* snapshot = targetItem->snapshot()) 248 m_snapshotRemovalTargetRenderTreeSize = snapshot->renderTreeSize() * swipeSnapshotRemovalRenderTreeSizeTargetFraction; 251 249 252 250 // We don't want to replace the current back-forward item's snapshot -
trunk/Source/WebKit2/UIProcess/ios/WebMemoryPressureHandlerIOS.mm
r168739 r170974 49 49 dispatch_set_context(source, this); 50 50 dispatch_source_set_event_handler(source, ^{ 51 ViewSnapshotStore::shared().discardSnapshot s();51 ViewSnapshotStore::shared().discardSnapshotImages(); 52 52 }); 53 53 dispatch_resume(source); -
trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h
r170447 r170974 125 125 virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); 126 126 127 virtual ViewSnapshottakeViewSnapshot() override;127 virtual PassRefPtr<ViewSnapshot> takeViewSnapshot() override; 128 128 virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override; 129 129 virtual void clearCustomSwipeViews() override; -
trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm
r170447 r170974 508 508 } 509 509 510 ViewSnapshotPageClientImpl::takeViewSnapshot()510 PassRefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot() 511 511 { 512 512 return [m_wkView _takeViewSnapshot]; -
trunk/Source/WebKit2/UIProcess/mac/ViewGestureController.h
r170774 r170974 51 51 namespace WebKit { 52 52 53 structViewSnapshot;53 class ViewSnapshot; 54 54 class WebBackForwardListItem; 55 55 class WebPageProxy; -
trunk/Source/WebKit2/UIProcess/mac/ViewGestureControllerMac.mm
r170335 r170974 455 455 { 456 456 float deviceScaleFactor = m_webPageProxy.deviceScaleFactor(); 457 if (snapshot.deviceScaleFactor != deviceScaleFactor)457 if (snapshot.deviceScaleFactor() != deviceScaleFactor) 458 458 return false; 459 459 460 460 FloatSize unobscuredSwipeLayerSizeInDeviceCoordinates = swipeLayerSize - FloatSize(0, topContentInset); 461 461 unobscuredSwipeLayerSizeInDeviceCoordinates.scale(deviceScaleFactor); 462 if (snapshot.size != unobscuredSwipeLayerSizeInDeviceCoordinates)462 if (snapshot.size() != unobscuredSwipeLayerSizeInDeviceCoordinates) 463 463 return false; 464 464 … … 527 527 528 528 RetainPtr<CGColorRef> backgroundColor = CGColorGetConstantColor(kCGColorWhite); 529 ViewSnapshot snapshot; 530 if (ViewSnapshotStore::shared().getSnapshot(targetItem, snapshot)) { 531 if (shouldUseSnapshotForSize(snapshot, swipeArea.size(), topContentInset)) 532 [m_swipeSnapshotLayer setContents:snapshot.asLayerContents()]; 533 534 Color coreColor = snapshot.backgroundColor; 529 if (ViewSnapshot* snapshot = targetItem->snapshot()) { 530 if (shouldUseSnapshotForSize(*snapshot, swipeArea.size(), topContentInset)) 531 [m_swipeSnapshotLayer setContents:snapshot->asLayerContents()]; 532 533 Color coreColor = snapshot->backgroundColor(); 535 534 if (coreColor.isValid()) 536 535 backgroundColor = cachedCGColor(coreColor, ColorSpaceDeviceRGB); 537 536 #if USE_IOSURFACE_VIEW_SNAPSHOTS 538 m_currentSwipeSnapshotSurface = snapshot .surface;537 m_currentSwipeSnapshotSurface = snapshot->surface(); 539 538 #endif 540 539 } … … 631 630 } 632 631 633 ViewSnapshot snapshot;634 632 uint64_t renderTreeSize = 0; 635 if (ViewSnapshot Store::shared().getSnapshot(targetItem, snapshot))636 renderTreeSize = snapshot .renderTreeSize;633 if (ViewSnapshot* snapshot = targetItem->snapshot()) 634 renderTreeSize = snapshot->renderTreeSize(); 637 635 638 636 m_webPageProxy.process().send(Messages::ViewGestureGeometryCollector::SetRenderTreeSizeNotificationThreshold(renderTreeSize * swipeSnapshotRemovalRenderTreeSizeTargetFraction), m_webPageProxy.pageID()); -
trunk/Source/WebKit2/UIProcess/mac/ViewSnapshotStore.h
r170925 r170974 30 30 #include <WebCore/IntSize.h> 31 31 #include <WebCore/IOSurface.h> 32 #include <chrono> 33 #include <wtf/HashMap.h> 32 #include <wtf/ListHashSet.h> 34 33 #include <wtf/Noncopyable.h> 34 #include <wtf/RefCounted.h> 35 35 #include <wtf/RetainPtr.h> 36 36 #include <wtf/text/WTFString.h> … … 39 39 40 40 #if PLATFORM(MAC) 41 #define USE_IOSURFACE_VIEW_SNAPSHOTS true42 #define USE_RENDER_SERVER_VIEW_SNAPSHOTS false41 #define USE_IOSURFACE_VIEW_SNAPSHOTS 1 42 #define USE_RENDER_SERVER_VIEW_SNAPSHOTS 0 43 43 #else 44 #define USE_IOSURFACE_VIEW_SNAPSHOTS false45 #define USE_RENDER_SERVER_VIEW_SNAPSHOTS true44 #define USE_IOSURFACE_VIEW_SNAPSHOTS 0 45 #define USE_RENDER_SERVER_VIEW_SNAPSHOTS 1 46 46 #endif 47 48 namespace WebCore { 49 class IOSurface; 50 } 47 51 48 52 namespace WebKit { 49 53 54 class ViewSnapshotStore; 50 55 class WebBackForwardListItem; 51 56 class WebPageProxy; 52 57 53 struct ViewSnapshot { 58 class ViewSnapshot : public RefCounted<ViewSnapshot> { 59 public: 54 60 #if USE_IOSURFACE_VIEW_SNAPSHOTS 55 RefPtr<WebCore::IOSurface> surface; 56 #endif 57 #if USE_RENDER_SERVER_VIEW_SNAPSHOTS 58 uint32_t slotID = 0; 61 static PassRefPtr<ViewSnapshot> create(WebCore::IOSurface*, WebCore::IntSize, size_t imageSizeInBytes); 62 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 63 static PassRefPtr<ViewSnapshot> create(uint32_t slotID, WebCore::IntSize, size_t imageSizeInBytes); 59 64 #endif 60 65 61 std::chrono::steady_clock::time_point creationTime; 62 uint64_t renderTreeSize; 63 float deviceScaleFactor; 64 WebCore::IntSize size; 65 size_t imageSizeInBytes = 0; 66 WebCore::Color backgroundColor; 66 ~ViewSnapshot(); 67 67 68 68 void clearImage(); 69 69 bool hasImage() const; 70 70 id asLayerContents(); 71 72 void setRenderTreeSize(uint64_t renderTreeSize) { m_renderTreeSize = renderTreeSize; } 73 uint64_t renderTreeSize() const { return m_renderTreeSize; } 74 75 void setBackgroundColor(WebCore::Color color) { m_backgroundColor = color; } 76 WebCore::Color backgroundColor() const { return m_backgroundColor; } 77 78 void setDeviceScaleFactor(float deviceScaleFactor) { m_deviceScaleFactor = deviceScaleFactor; } 79 float deviceScaleFactor() const { return m_deviceScaleFactor; } 80 81 size_t imageSizeInBytes() const { return m_imageSizeInBytes; } 82 #if USE_IOSURFACE_VIEW_SNAPSHOTS 83 WebCore::IOSurface* surface() const { return m_surface.get(); } 84 #endif 85 WebCore::IntSize size() const { return m_size; } 86 87 private: 88 #if USE_IOSURFACE_VIEW_SNAPSHOTS 89 explicit ViewSnapshot(WebCore::IOSurface*, WebCore::IntSize, size_t imageSizeInBytes); 90 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 91 explicit ViewSnapshot(uint32_t slotID, WebCore::IntSize, size_t imageSizeInBytes); 92 #endif 93 94 #if USE_IOSURFACE_VIEW_SNAPSHOTS 95 RefPtr<WebCore::IOSurface> m_surface; 96 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 97 uint32_t m_slotID; 98 #endif 99 100 size_t m_imageSizeInBytes; 101 uint64_t m_renderTreeSize; 102 float m_deviceScaleFactor; 103 WebCore::IntSize m_size; 104 WebCore::Color m_backgroundColor; 71 105 }; 72 106 73 107 class ViewSnapshotStore { 74 108 WTF_MAKE_NONCOPYABLE(ViewSnapshotStore); 109 friend class ViewSnapshot; 75 110 public: 76 111 ViewSnapshotStore(); … … 80 115 81 116 void recordSnapshot(WebPageProxy&); 82 bool getSnapshot(WebBackForwardListItem*, ViewSnapshot&);83 117 84 118 void disableSnapshotting() { m_enabled = false; } 85 119 void enableSnapshotting() { m_enabled = true; } 86 120 87 void discardSnapshot s();121 void discardSnapshotImages(); 88 122 89 #if PLATFORM(IOS)123 #if USE_RENDER_SERVER_VIEW_SNAPSHOTS 90 124 static CAContext *snapshottingContext(); 91 125 #endif 92 126 93 127 private: 128 void didAddImageToSnapshot(ViewSnapshot&); 129 void willRemoveImageFromSnapshot(ViewSnapshot&); 94 130 void pruneSnapshots(WebPageProxy&); 95 void removeSnapshotImage(ViewSnapshot&);96 97 HashMap<String, ViewSnapshot> m_snapshotMap;98 131 99 132 bool m_enabled; 100 133 size_t m_snapshotCacheSize; 134 135 ListHashSet<ViewSnapshot*> m_snapshotsWithImages; 101 136 }; 102 137 -
trunk/Source/WebKit2/UIProcess/mac/ViewSnapshotStore.mm
r170925 r170974 31 31 #import <CoreGraphics/CoreGraphics.h> 32 32 #import <WebCore/IOSurface.h> 33 #import <WebCore/UUID.h>34 33 35 34 #if PLATFORM(IOS) … … 56 55 ViewSnapshotStore::~ViewSnapshotStore() 57 56 { 58 discardSnapshot s();57 discardSnapshotImages(); 59 58 } 60 59 … … 65 64 } 66 65 67 #if PLATFORM(IOS)66 #if USE_RENDER_SERVER_VIEW_SNAPSHOTS 68 67 CAContext *ViewSnapshotStore::snapshottingContext() 69 68 { … … 83 82 #endif 84 83 85 void ViewSnapshotStore::removeSnapshotImage(ViewSnapshot& snapshot) 86 { 87 if (!snapshot.hasImage()) 88 return; 89 90 m_snapshotCacheSize -= snapshot.imageSizeInBytes; 91 snapshot.clearImage(); 84 void ViewSnapshotStore::didAddImageToSnapshot(ViewSnapshot& snapshot) 85 { 86 bool isNewEntry = m_snapshotsWithImages.add(&snapshot).isNewEntry; 87 ASSERT_UNUSED(isNewEntry, isNewEntry); 88 m_snapshotCacheSize += snapshot.imageSizeInBytes(); 89 } 90 91 void ViewSnapshotStore::willRemoveImageFromSnapshot(ViewSnapshot& snapshot) 92 { 93 bool removed = m_snapshotsWithImages.remove(&snapshot); 94 ASSERT_UNUSED(removed, removed); 95 m_snapshotCacheSize -= snapshot.imageSizeInBytes(); 92 96 } 93 97 … … 97 101 return; 98 102 99 uint32_t currentIndex = webPageProxy.backForwardList().currentIndex(); 100 uint32_t maxDistance = 0; 101 auto mostDistantSnapshotIter = m_snapshotMap.end(); 102 auto backForwardEntries = webPageProxy.backForwardList().entries(); 103 104 // First, try to evict the snapshot for the page farthest from the current back-forward item. 105 for (uint32_t i = 0, entryCount = webPageProxy.backForwardList().entries().size(); i < entryCount; i++) { 106 uint32_t distance = std::max(currentIndex, i) - std::min(currentIndex, i); 107 108 if (i == currentIndex || distance < maxDistance) 109 continue; 110 111 WebBackForwardListItem* item = backForwardEntries[i].get(); 112 String snapshotUUID = item->snapshotUUID(); 113 if (snapshotUUID.isEmpty()) 114 continue; 115 116 const auto& snapshotIter = m_snapshotMap.find(snapshotUUID); 117 if (snapshotIter == m_snapshotMap.end()) 118 continue; 119 120 // We're only interested in evicting snapshots that still have images. 121 if (!snapshotIter->value.hasImage()) 122 continue; 123 124 mostDistantSnapshotIter = snapshotIter; 125 maxDistance = distance; 103 ASSERT(!m_snapshotsWithImages.isEmpty()); 104 105 // FIXME: We have enough information to do smarter-than-LRU eviction (making use of the back-forward lists, etc.) 106 107 m_snapshotsWithImages.first()->clearImage(); 108 } 109 110 void ViewSnapshotStore::recordSnapshot(WebPageProxy& webPageProxy) 111 { 112 WebBackForwardListItem* item = webPageProxy.backForwardList().currentItem(); 113 114 if (!m_enabled) 115 return; 116 117 if (!item) 118 return; 119 120 pruneSnapshots(webPageProxy); 121 122 RefPtr<ViewSnapshot> snapshot = webPageProxy.takeViewSnapshot(); 123 if (!snapshot || !snapshot->hasImage()) 124 return; 125 126 snapshot->setRenderTreeSize(webPageProxy.renderTreeSize()); 127 snapshot->setDeviceScaleFactor(webPageProxy.deviceScaleFactor()); 128 snapshot->setBackgroundColor(webPageProxy.pageExtendedBackgroundColor()); 129 130 item->setSnapshot(snapshot.release()); 131 } 132 133 void ViewSnapshotStore::discardSnapshotImages() 134 { 135 while (!m_snapshotsWithImages.isEmpty()) 136 m_snapshotsWithImages.first()->clearImage(); 137 } 138 139 140 #if USE_IOSURFACE_VIEW_SNAPSHOTS 141 PassRefPtr<ViewSnapshot> ViewSnapshot::create(IOSurface* surface, IntSize size, size_t imageSizeInBytes) 142 { 143 return adoptRef(new ViewSnapshot(surface, size, imageSizeInBytes)); 144 } 145 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 146 PassRefPtr<ViewSnapshot> ViewSnapshot::create(uint32_t slotID, IntSize size, size_t imageSizeInBytes) 147 { 148 return adoptRef(new ViewSnapshot(slotID, size, imageSizeInBytes)); 149 } 150 #endif 151 152 #if USE_IOSURFACE_VIEW_SNAPSHOTS 153 ViewSnapshot::ViewSnapshot(IOSurface* surface, IntSize size, size_t imageSizeInBytes) 154 : m_surface(surface) 155 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 156 ViewSnapshot::ViewSnapshot(uint32_t slotID, IntSize size, size_t imageSizeInBytes) 157 : m_slotID(slotID) 158 #endif 159 , m_imageSizeInBytes(imageSizeInBytes) 160 , m_size(size) 161 { 162 if (hasImage()) 163 ViewSnapshotStore::shared().didAddImageToSnapshot(*this); 164 } 165 166 ViewSnapshot::~ViewSnapshot() 167 { 168 clearImage(); 169 } 170 171 bool ViewSnapshot::hasImage() const 172 { 173 #if USE_IOSURFACE_VIEW_SNAPSHOTS 174 return m_surface; 175 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 176 return m_slotID; 177 #endif 178 } 179 180 void ViewSnapshot::clearImage() 181 { 182 if (!hasImage()) 183 return; 184 185 ViewSnapshotStore::shared().willRemoveImageFromSnapshot(*this); 186 187 #if USE_IOSURFACE_VIEW_SNAPSHOTS 188 m_surface = nullptr; 189 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 190 [ViewSnapshotStore::snapshottingContext() deleteSlot:m_slotID]; 191 m_slotID = 0; 192 #endif 193 m_imageSizeInBytes = 0; 194 } 195 196 id ViewSnapshot::asLayerContents() 197 { 198 #if USE_IOSURFACE_VIEW_SNAPSHOTS 199 if (!m_surface) 200 return nullptr; 201 202 if (m_surface->setIsVolatile(false) != IOSurface::SurfaceState::Valid) { 203 clearImage(); 204 return nullptr; 126 205 } 127 206 128 if (mostDistantSnapshotIter != m_snapshotMap.end()) { 129 removeSnapshotImage(mostDistantSnapshotIter->value); 130 return; 131 } 132 133 // If we can't find a most distant item (perhaps because all the snapshots are from 134 // a different WebPageProxy's back-forward list), we should evict the the oldest item. 135 std::chrono::steady_clock::time_point oldestSnapshotTime = std::chrono::steady_clock::time_point::max(); 136 String oldestSnapshotUUID; 137 138 for (const auto& uuidAndSnapshot : m_snapshotMap) { 139 if (uuidAndSnapshot.value.creationTime < oldestSnapshotTime && uuidAndSnapshot.value.hasImage()) { 140 oldestSnapshotTime = uuidAndSnapshot.value.creationTime; 141 oldestSnapshotUUID = uuidAndSnapshot.key; 142 } 143 } 144 145 const auto& snapshotIter = m_snapshotMap.find(oldestSnapshotUUID); 146 removeSnapshotImage(snapshotIter->value); 147 } 148 149 void ViewSnapshotStore::recordSnapshot(WebPageProxy& webPageProxy) 150 { 151 WebBackForwardListItem* item = webPageProxy.backForwardList().currentItem(); 152 153 if (!m_enabled) 154 return; 155 156 if (!item) 157 return; 158 159 pruneSnapshots(webPageProxy); 160 161 ViewSnapshot snapshot = webPageProxy.takeViewSnapshot(); 162 if (!snapshot.hasImage()) 163 return; 164 165 String oldSnapshotUUID = item->snapshotUUID(); 166 if (!oldSnapshotUUID.isEmpty()) { 167 const auto& oldSnapshotIter = m_snapshotMap.find(oldSnapshotUUID); 168 if (oldSnapshotIter != m_snapshotMap.end()) { 169 removeSnapshotImage(oldSnapshotIter->value); 170 m_snapshotMap.remove(oldSnapshotIter); 171 } 172 } 173 174 snapshot.creationTime = std::chrono::steady_clock::now(); 175 snapshot.renderTreeSize = webPageProxy.renderTreeSize(); 176 snapshot.deviceScaleFactor = webPageProxy.deviceScaleFactor(); 177 178 item->setSnapshotUUID(createCanonicalUUIDString()); 179 180 m_snapshotMap.add(item->snapshotUUID(), snapshot); 181 m_snapshotCacheSize += snapshot.imageSizeInBytes; 182 } 183 184 bool ViewSnapshotStore::getSnapshot(WebBackForwardListItem* item, ViewSnapshot& snapshot) 185 { 186 if (item->snapshotUUID().isEmpty()) 187 return false; 188 189 const auto& snapshotIterator = m_snapshotMap.find(item->snapshotUUID()); 190 if (snapshotIterator == m_snapshotMap.end()) 191 return false; 192 snapshot = snapshotIterator->value; 193 return true; 194 } 195 196 void ViewSnapshotStore::discardSnapshots() 197 { 198 for (auto& snapshot : m_snapshotMap.values()) 199 removeSnapshotImage(snapshot); 200 } 201 202 bool ViewSnapshot::hasImage() const 203 { 204 return imageSizeInBytes; 205 } 206 207 void ViewSnapshot::clearImage() 208 { 209 #if USE_IOSURFACE_VIEW_SNAPSHOTS 210 surface = nullptr; 211 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 212 if (slotID) 213 [ViewSnapshotStore::snapshottingContext() deleteSlot:slotID]; 214 slotID = 0; 215 #endif 216 imageSizeInBytes = 0; 217 } 218 219 id ViewSnapshot::asLayerContents() 220 { 221 #if USE_IOSURFACE_VIEW_SNAPSHOTS 222 if (!surface) 223 return nullptr; 224 225 // FIXME: This should destroy the surface and inform the ViewSnapshotStore to reduce m_snapshotCacheSize. 226 if (surface->setIsVolatile(false) != IOSurface::SurfaceState::Valid) 227 return nullptr; 228 229 return (id)surface->surface(); 230 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 231 return [CAContext objectForSlot:slotID]; 207 return (id)m_surface->surface(); 208 #elif USE_RENDER_SERVER_VIEW_SNAPSHOTS 209 return [CAContext objectForSlot:m_slotID]; 232 210 #endif 233 211 }
Note:
See TracChangeset
for help on using the changeset viewer.