Long pause under _takeViewSnapshot when screen updates are disabled
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Apr 2015 23:25:00 +0000 (23:25 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Apr 2015 23:25:00 +0000 (23:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144017
<rdar://problem/20548397>

Reviewed by Simon Fraser.

* UIProcess/API/mac/WKView.mm:
(-[WKView _takeViewSnapshot]):
Use CGSHWCaptureWindowList, for snapshotting that doesn't block on
the next commit, and can succeed while screen updates are disabled
without blocking.

* platform/spi/cg/CoreGraphicsSPI.h:
Add some SPI.

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

Source/WebCore/ChangeLog
Source/WebCore/platform/spi/cg/CoreGraphicsSPI.h
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/mac/WKView.mm

index 335e4ba..cd25a09 100644 (file)
@@ -1,3 +1,14 @@
+2015-04-21  Tim Horton  <timothy_horton@apple.com>
+
+        Long pause under _takeViewSnapshot when screen updates are disabled
+        https://bugs.webkit.org/show_bug.cgi?id=144017
+        <rdar://problem/20548397>
+
+        Reviewed by Simon Fraser.
+
+        * platform/spi/cg/CoreGraphicsSPI.h:
+        Add some SPI.
+
 2015-04-21  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r183077.
index bce8a8d..0c7ae89 100644 (file)
@@ -113,6 +113,17 @@ static inline CGFloat CGFloatMin(CGFloat a, CGFloat b) { return isnan(a) ? b : (
 
 typedef struct CGFontCache CGFontCache;
 
+typedef uint32_t CGSConnectionID;
+typedef uint32_t CGSWindowID;
+typedef uint32_t CGSWindowCount;
+typedef CGSWindowID *CGSWindowIDList;
+
+enum {
+    kCGSWindowCaptureNominalResolution = 0x0200,
+    kCGSCaptureIgnoreGlobalClipShape = 0x0800,
+};
+typedef uint32_t CGSWindowCaptureOptions;
+
 #endif // USE(APPLE_INTERNAL_SDK)
 
 WTF_EXTERN_C_BEGIN
@@ -162,6 +173,9 @@ void CGFontCacheSetShouldAutoExpire(CGFontCache*, bool);
 void CGFontCacheSetMaxSize(CGFontCache*, size_t);
 #endif
 
+CGSConnectionID CGSMainConnectionID(void);
+CFArrayRef CGSHWCaptureWindowList(CGSConnectionID cid, CGSWindowIDList windowList, CGSWindowCount windowCount, CGSWindowCaptureOptions options);
+
 WTF_EXTERN_C_END
 
 #endif // CoreGraphicsSPI_h
index 13fb868..a175870 100644 (file)
@@ -1,3 +1,17 @@
+2015-04-21  Tim Horton  <timothy_horton@apple.com>
+
+        Long pause under _takeViewSnapshot when screen updates are disabled
+        https://bugs.webkit.org/show_bug.cgi?id=144017
+        <rdar://problem/20548397>
+
+        Reviewed by Simon Fraser.
+
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView _takeViewSnapshot]):
+        Use CGSHWCaptureWindowList, for snapshotting that doesn't block on
+        the next commit, and can succeed while screen updates are disabled
+        without blocking.
+
 2015-04-21  Chris Dumez  <cdumez@apple.com>
 
         [WK2][NetworkCache] Better account of resource revalidations in efficacy logging
index ec0257d..98219a6 100644 (file)
@@ -3370,12 +3370,22 @@ static void* keyValueObservingContext = &keyValueObservingContext;
     if (!windowID || ![window isVisible])
         return nullptr;
 
-    RetainPtr<CGImageRef> windowSnapshotImage = adoptCF(CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque));
+    CGSWindowCaptureOptions options = kCGSCaptureIgnoreGlobalClipShape;
+    RetainPtr<CFArrayRef> windowSnapshotImages = adoptCF(CGSHWCaptureWindowList(CGSMainConnectionID(), &windowID, 1, options));
+    if (!CFArrayGetCount(windowSnapshotImages.get()))
+        return nullptr;
+
+    RetainPtr<CGImageRef> windowSnapshotImage = (CGImageRef)CFArrayGetValueAtIndex(windowSnapshotImages.get(), 0);
 
     // Work around <rdar://problem/17084993>; re-request the snapshot at kCGWindowImageNominalResolution if it was captured at the wrong scale.
     CGFloat desiredSnapshotWidth = window.frame.size.width * window.screen.backingScaleFactor;
-    if (CGImageGetWidth(windowSnapshotImage.get()) != desiredSnapshotWidth)
-        windowSnapshotImage = adoptCF(CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque | kCGWindowImageNominalResolution));
+    if (CGImageGetWidth(windowSnapshotImage.get()) != desiredSnapshotWidth) {
+        options |= kCGSWindowCaptureNominalResolution;
+        windowSnapshotImages = adoptCF(CGSHWCaptureWindowList(CGSMainConnectionID(), &windowID, 1, options));
+        if (!CFArrayGetCount(windowSnapshotImages.get()))
+            return nullptr;
+        windowSnapshotImage = (CGImageRef)CFArrayGetValueAtIndex(windowSnapshotImages.get(), 0);
+    }
 
     [self _ensureGestureController];