Diff
Modified: trunk/LayoutTests/ChangeLog (283034 => 283035)
--- trunk/LayoutTests/ChangeLog 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/LayoutTests/ChangeLog 2021-09-24 11:13:33 UTC (rev 283035)
@@ -1,5 +1,18 @@
2021-09-24 Youenn Fablet <[email protected]>
+ <video> element rendered incorrectly when provided with a portrait orientation stream in Safari 15
+ https://bugs.webkit.org/show_bug.cgi?id=229792
+ <rdar://problem/82776741>
+
+ Reviewed by Eric Carlson.
+
+ * fast/mediastream/video-rotation-expected.txt: Added.
+ * fast/mediastream/video-rotation.html: Added.
+ * platform/ios-simulator/fast/mediastream/video-rotation-expected.png: Added.
+ * platform/mac/fast/mediastream/video-rotation-expected.png: Added.
+
+2021-09-24 Youenn Fablet <[email protected]>
+
[IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
https://bugs.webkit.org/show_bug.cgi?id=230538
<rdar://problem/83355705>
Added: trunk/LayoutTests/fast/mediastream/video-rotation-expected.txt (0 => 283035)
--- trunk/LayoutTests/fast/mediastream/video-rotation-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/video-rotation-expected.txt 2021-09-24 11:13:33 UTC (rev 283035)
@@ -0,0 +1,2 @@
+
+PASS
Added: trunk/LayoutTests/fast/mediastream/video-rotation.html (0 => 283035)
--- trunk/LayoutTests/fast/mediastream/video-rotation.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/video-rotation.html 2021-09-24 11:13:33 UTC (rev 283035)
@@ -0,0 +1,109 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Testing video rotation</title>
+ </head>
+ <body>
+ <video style="z-index: 1; position: absolute; top: 0px; left: 0px;" id="video" autoplay playsInline></video>
+ <div style="z-index: 2; position: absolute; top: 5px; left: 0px; background-color:green; width:200px; height:390px"></div>
+ <image id='image'></image>
+ <canvas id='canvas'></canvas>
+ <div style="z-index: 3" id="log"></div>
+ <script>
+
+function getPixel(x, y, canvas, data)
+{
+ const position = 4 * (x * canvas.width + y);
+ return {r: data[position], g: data[position+1], b: data[position+2]};
+}
+
+function isPixelGreen(x, y, canvas, data)
+{
+ const pixel = getPixel(x, y, canvas, data);
+ return pixel.r === 0 && pixel.g === 128 && pixel.b === 0;
+}
+
+function isPixelWhite(x, y, canvas, data)
+{
+ const pixel = getPixel(x, y, canvas, data);
+ return pixel.r === 255 && pixel.g === 255 && pixel.b === 255;
+}
+
+async function validateSnapshot()
+{
+ const dataURL = await new Promise(resolve => testRunner.takeViewPortSnapshot(resolve));
+
+ const loadPromise = new Promise((resolve, reject) => {
+ image._onload_ = resolve;
+ image._onerror_ = reject;
+ setTimeout(() => reject("image load timed out"), 2000);
+ });
+ image.src = ""
+ await loadPromise;
+
+ canvas.width = image.width;
+ canvas.height = image.height;
+ canvas.getContext('2d').drawImage(image, 0, 0);
+ const data = "" 0, canvas.width, canvas.height).data;
+
+ document.body.appendChild(canvas);
+
+ // We expect to have a green horizontal line until getting some white.
+ let j = 100;
+ if (!isPixelGreen(100, j, canvas, data))
+ return Promise.reject("first pixel is not green");
+
+ while (isPixelGreen(100, ++j, canvas, data)) { };
+
+ // We then expect a vertical line until the end of the canvas.
+ j = j + 5;
+ if (!isPixelWhite(100, j, canvas, data))
+ return Promise.reject("did not find white pixel");
+
+ let i = 100;
+ while (++i < canvas.height && isPixelWhite(i, j, canvas, data)) { };
+
+ return i === canvas.height;
+}
+
+_onload_ = async () => {
+ try {
+ video.srcObject = await navigator.mediaDevices.getUserMedia({video: {width: 400, height: 200} });
+ await video.play();
+
+ if (!window.testRunner)
+ return;
+
+ testRunner.setMockCameraOrientation(90);
+ let counter = 0;
+ while (video.videoWidth !== 200 && ++counter < 100)
+ await new Promise(resolve => setTimeout(resolve, 50));
+
+ counter = 0;
+ let isValidSnapshot = false;
+ do {
+ await new Promise(resolve => setTimeout(resolve, 50));
+ isValidSnapshot = await validateSnapshot();
+ } while (++counter < 50 && !isValidSnapshot)
+
+ log.innerHTML = counter < 50 ? "PASS" : "FAIL";
+
+ if (counter < 50) {
+ document.body.removeChild(image);
+ document.body.removeChild(canvas);
+ }
+ } catch (e) {
+ console.log(e);
+ }
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+if (window.testRunner) {
+ testRunner.dumpAsText(true);
+ testRunner.waitUntilDone();
+}
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/platform/ios-simulator/fast/mediastream/video-rotation-expected.png
(Binary files differ)
Index: trunk/LayoutTests/platform/ios-simulator/fast/mediastream/video-rotation-expected.png
===================================================================
--- trunk/LayoutTests/platform/ios-simulator/fast/mediastream/video-rotation-expected.png 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/LayoutTests/platform/ios-simulator/fast/mediastream/video-rotation-expected.png 2021-09-24 11:13:33 UTC (rev 283035)
Property changes on: trunk/LayoutTests/platform/ios-simulator/fast/mediastream/video-rotation-expected.png
___________________________________________________________________
Added: svn:mime-type
+image/png
\ No newline at end of property
Added: trunk/LayoutTests/platform/mac/fast/mediastream/video-rotation-expected.png
(Binary files differ)
Index: trunk/LayoutTests/platform/mac/fast/mediastream/video-rotation-expected.png
===================================================================
--- trunk/LayoutTests/platform/mac/fast/mediastream/video-rotation-expected.png 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/LayoutTests/platform/mac/fast/mediastream/video-rotation-expected.png 2021-09-24 11:13:33 UTC (rev 283035)
Property changes on: trunk/LayoutTests/platform/mac/fast/mediastream/video-rotation-expected.png
___________________________________________________________________
Added: svn:mime-type
+image/png
\ No newline at end of property
Modified: trunk/Source/WebCore/ChangeLog (283034 => 283035)
--- trunk/Source/WebCore/ChangeLog 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Source/WebCore/ChangeLog 2021-09-24 11:13:33 UTC (rev 283035)
@@ -1,5 +1,25 @@
2021-09-24 Youenn Fablet <[email protected]>
+ <video> element rendered incorrectly when provided with a portrait orientation stream in Safari 15
+ https://bugs.webkit.org/show_bug.cgi?id=229792
+ <rdar://problem/82776741>
+
+ Reviewed by Eric Carlson.
+
+ We need to swap the bounds for both m_rootLayer and m_sampleBufferDisplayLayer if the sample is rotated by 90.
+ We also need to ompute m_sampleBufferDisplayLayer position based on m_rootLayer coordinates.
+ This means we swap root layer bounds width and height before computing m_sampleBufferDisplayLayer position based on it.
+
+ Test: fast/mediastream/video-rotation.html
+
+ * platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.h:
+ * platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.mm:
+ (WebCore::LocalSampleBufferDisplayLayer::setRootLayerBoundsAndPositions):
+ (WebCore::LocalSampleBufferDisplayLayer::updateRootLayerBoundsAndPosition):
+ * platform/graphics/cg/ImageBufferUtilitiesCG.h:
+
+2021-09-24 Youenn Fablet <[email protected]>
+
[IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
https://bugs.webkit.org/show_bug.cgi?id=230538
<rdar://problem/83355705>
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.h (283034 => 283035)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.h 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.h 2021-09-24 11:13:33 UTC (rev 283035)
@@ -88,6 +88,7 @@
void addSampleToPendingQueue(MediaSample&);
void requestNotificationWhenReadyForVideoData();
void enqueueSampleBuffer(MediaSample&);
+ void setRootLayerBoundsAndPositions(CGRect, MediaSample::VideoRotation);
#if !RELEASE_LOG_DISABLED
void onIrregularFrameRateNotification(MonotonicTime frameTime, MonotonicTime lastFrameTime);
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.mm (283034 => 283035)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.mm 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.mm 2021-09-24 11:13:33 UTC (rev 283035)
@@ -269,19 +269,27 @@
updateRootLayerBoundsAndPosition(bounds, rotation, ShouldUpdateRootLayer::No);
}
+void LocalSampleBufferDisplayLayer::setRootLayerBoundsAndPositions(CGRect bounds, MediaSample::VideoRotation rotation)
+{
+ CGPoint position = { bounds.size.width / 2, bounds.size.height / 2};
+ if (rotation == MediaSample::VideoRotation::Right || rotation == MediaSample::VideoRotation::Left)
+ std::swap(bounds.size.width, bounds.size.height);
+
+ m_rootLayer.get().position = position;
+ m_rootLayer.get().bounds = bounds;
+}
+
void LocalSampleBufferDisplayLayer::updateRootLayerBoundsAndPosition(CGRect bounds, MediaSample::VideoRotation rotation, ShouldUpdateRootLayer shouldUpdateRootLayer)
{
runWithoutAnimations([&] {
- CGPoint position = { bounds.size.width / 2, bounds.size.height / 2};
+ if (shouldUpdateRootLayer == ShouldUpdateRootLayer::Yes)
+ setRootLayerBoundsAndPositions(bounds, rotation);
- if (shouldUpdateRootLayer == ShouldUpdateRootLayer::Yes) {
- m_rootLayer.get().position = position;
- m_rootLayer.get().bounds = bounds;
- }
-
if (rotation == MediaSample::VideoRotation::Right || rotation == MediaSample::VideoRotation::Left)
std::swap(bounds.size.width, bounds.size.height);
+ CGPoint position = { bounds.size.width / 2, bounds.size.height / 2};
+
m_sampleBufferDisplayLayer.get().position = position;
m_sampleBufferDisplayLayer.get().bounds = bounds;
});
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h (283034 => 283035)
--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h 2021-09-24 11:13:33 UTC (rev 283035)
@@ -37,12 +37,12 @@
WEBCORE_EXPORT uint8_t verifyImageBufferIsBigEnough(const void* buffer, size_t bufferSize);
CFStringRef jpegUTI();
-RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String&);
+WEBCORE_EXPORT RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String&);
Vector<uint8_t> data(CGImageRef, CFStringRef destinationUTI, std::optional<double> quality);
Vector<uint8_t> data(const PixelBuffer&, const String& mimeType, std::optional<double> quality);
-String dataURL(CGImageRef, CFStringRef destinationUTI, const String& mimeType, std::optional<double> quality);
+WEBCORE_EXPORT String dataURL(CGImageRef, CFStringRef destinationUTI, const String& mimeType, std::optional<double> quality);
String dataURL(const PixelBuffer&, const String& mimeType, std::optional<double> quality);
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (283034 => 283035)
--- trunk/Source/WebKit/ChangeLog 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Source/WebKit/ChangeLog 2021-09-24 11:13:33 UTC (rev 283035)
@@ -1,5 +1,19 @@
2021-09-24 Youenn Fablet <[email protected]>
+ <video> element rendered incorrectly when provided with a portrait orientation stream in Safari 15
+ https://bugs.webkit.org/show_bug.cgi?id=229792
+ <rdar://problem/82776741>
+
+ Reviewed by Eric Carlson.
+
+ Helper routined used in WTR.
+
+ * Shared/API/c/cg/WKImageCG.cpp:
+ (WKImageCreateDataURLFromImage):
+ * Shared/API/c/cg/WKImageCG.h:
+
+2021-09-24 Youenn Fablet <[email protected]>
+
[IOS 15] Video track does not get unmuted in case of tab was inactive less than ~500 ms
https://bugs.webkit.org/show_bug.cgi?id=230538
<rdar://problem/83355705>
Modified: trunk/Source/WebKit/Shared/API/c/cg/WKImageCG.cpp (283034 => 283035)
--- trunk/Source/WebKit/Shared/API/c/cg/WKImageCG.cpp 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Source/WebKit/Shared/API/c/cg/WKImageCG.cpp 2021-09-24 11:13:33 UTC (rev 283035)
@@ -31,6 +31,7 @@
#include "WebImage.h"
#include <WebCore/ColorSpace.h>
#include <WebCore/GraphicsContext.h>
+#include <WebCore/ImageBufferUtilitiesCG.h>
#include <WebCore/NativeImage.h>
CGImageRef WKImageCreateCGImage(WKImageRef imageRef)
@@ -62,3 +63,10 @@
return toAPI(webImage.leakRef());
}
+WKStringRef WKImageCreateDataURLFromImage(CGImageRef imageRef)
+{
+ String mimeType { "image/png"_s };
+ auto destinationUTI = WebCore::utiFromImageBufferMIMEType(mimeType);
+ auto value = WebCore::dataURL(imageRef, destinationUTI.get(), mimeType, { });
+ return WKStringCreateWithUTF8CString(value.utf8().data());
+}
Modified: trunk/Source/WebKit/Shared/API/c/cg/WKImageCG.h (283034 => 283035)
--- trunk/Source/WebKit/Shared/API/c/cg/WKImageCG.h 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Source/WebKit/Shared/API/c/cg/WKImageCG.h 2021-09-24 11:13:33 UTC (rev 283035)
@@ -38,6 +38,8 @@
WK_EXPORT WKImageRef WKImageCreateFromCGImage(CGImageRef imageRef, WKImageOptions options);
+WK_EXPORT WKStringRef WKImageCreateDataURLFromImage(CGImageRef imageRef);
+
#ifdef __cplusplus
}
#endif
Modified: trunk/Tools/ChangeLog (283034 => 283035)
--- trunk/Tools/ChangeLog 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Tools/ChangeLog 2021-09-24 11:13:33 UTC (rev 283035)
@@ -1,3 +1,29 @@
+2021-09-24 Youenn Fablet <[email protected]>
+
+ <video> element rendered incorrectly when provided with a portrait orientation stream in Safari 15
+ https://bugs.webkit.org/show_bug.cgi?id=229792
+ <rdar://problem/82776741>
+
+ Reviewed by Eric Carlson.
+
+ Add testRunner API to take a view port snapshot as a PNG data URL.
+ We can then use this data URL to validate some rendered pixel values.
+
+ * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+ * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+ (WTR::InjectedBundle::didReceiveMessageToPage):
+ * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+ (WTR::TestRunner::takeViewPortSnapshot):
+ (WTR::TestRunner::viewPortSnapshotTaken):
+ * WebKitTestRunner/InjectedBundle/TestRunner.h:
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::takeViewPortSnapshot):
+ * WebKitTestRunner/TestController.h:
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+ * WebKitTestRunner/cocoa/TestControllerCocoa.mm:
+ (WTR::TestController::takeViewPortSnapshot):
+
2021-09-24 Philippe Normand <[email protected]>
REGRESSION(r282742): Broke IceCC builds
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (283034 => 283035)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2021-09-24 11:13:33 UTC (rev 283035)
@@ -421,4 +421,6 @@
// MediaKeySystem
undefined setIsMediaKeySystemPermissionGranted(boolean value);
+
+ undefined takeViewPortSnapshot(object callback);
};
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp (283034 => 283035)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp 2021-09-24 11:13:33 UTC (rev 283035)
@@ -481,6 +481,13 @@
return;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "ViewPortSnapshotTaken")) {
+ ASSERT(messageBody);
+ ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+ m_testRunner->viewPortSnapshotTaken(static_cast<WKStringRef>(messageBody));
+ return;
+ }
+
postPageMessage("Error", "Unknown");
}
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (283034 => 283035)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2021-09-24 11:13:33 UTC (rev 283035)
@@ -649,6 +649,7 @@
EnterFullscreenForElementCallbackID,
ExitFullscreenForElementCallbackID,
AppBoundRequestContextDataForDomainCallbackID,
+ TakeViewPortSnapshotCallbackID,
FirstUIScriptCallbackID = 100
};
@@ -2171,6 +2172,23 @@
postSynchronousPageMessage("SetIsMediaKeySystemPermissionGranted", granted);
}
+void TestRunner::takeViewPortSnapshot(JSValueRef callback)
+{
+ if (m_takeViewPortSnapshot)
+ return;
+
+ cacheTestRunnerCallback(TakeViewPortSnapshotCallbackID, callback);
+ postMessage("TakeViewPortSnapshot");
+ m_takeViewPortSnapshot = true;
+}
+
+void TestRunner::viewPortSnapshotTaken(WKStringRef value)
+{
+ auto jsValue = JSValueMakeString(mainFrameJSContext(), toJS(value).get());
+ callTestRunnerCallback(TakeViewPortSnapshotCallbackID, 1, &jsValue);
+ m_takeViewPortSnapshot = false;
+}
+
ALLOW_DEPRECATED_DECLARATIONS_END
} // namespace WTR
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (283034 => 283035)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2021-09-24 11:13:33 UTC (rev 283035)
@@ -537,6 +537,9 @@
void setIsMediaKeySystemPermissionGranted(bool);
+ void takeViewPortSnapshot(JSValueRef callback);
+ void viewPortSnapshotTaken(WKStringRef);
+
private:
TestRunner();
@@ -604,6 +607,7 @@
bool m_hasSetDowngradeReferrerCallback { false };
bool m_hasSetBlockThirdPartyCookiesCallback { false };
bool m_hasSetFirstPartyWebsiteDataRemovalModeCallback { false };
+ bool m_takeViewPortSnapshot { false };
};
} // namespace WTR
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (283034 => 283035)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2021-09-24 11:13:33 UTC (rev 283035)
@@ -3607,6 +3607,10 @@
{
}
+WKRetainPtr<WKStringRef> TestController::takeViewPortSnapshot()
+{
+ return adoptWK(WKStringCreateWithUTF8CString("not implemented"));
+}
#endif
void TestController::sendDisplayConfigurationChangedMessageForTesting()
Modified: trunk/Tools/WebKitTestRunner/TestController.h (283034 => 283035)
--- trunk/Tools/WebKitTestRunner/TestController.h 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Tools/WebKitTestRunner/TestController.h 2021-09-24 11:13:33 UTC (rev 283035)
@@ -364,6 +364,7 @@
void completeMediaKeySystemPermissionCheck(WKMediaKeySystemPermissionCallbackRef);
void setIsMediaKeySystemPermissionGranted(bool);
+ WKRetainPtr<WKStringRef> takeViewPortSnapshot();
private:
WKRetainPtr<WKPageConfigurationRef> generatePageConfiguration(const TestOptions&);
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (283034 => 283035)
--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2021-09-24 11:13:33 UTC (rev 283035)
@@ -744,6 +744,12 @@
TestController::singleton().setStatisticsFirstPartyWebsiteDataRemovalMode(booleanValue(messageBody));
return;
}
+
+ if (WKStringIsEqualToUTF8CString(messageName, "TakeViewPortSnapshot")) {
+ auto value = TestController::singleton().takeViewPortSnapshot();
+ postPageMessage("ViewPortSnapshotTaken", value.get());
+ return;
+ }
if (WKStringIsEqualToUTF8CString(messageName, "StatisticsSetToSameSiteStrictCookies")) {
TestController::singleton().setStatisticsToSameSiteStrictCookies(stringValue(messageBody));
Modified: trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm (283034 => 283035)
--- trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm 2021-09-24 10:07:45 UTC (rev 283034)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm 2021-09-24 11:13:33 UTC (rev 283035)
@@ -37,6 +37,7 @@
#import <Security/SecItem.h>
#import <WebKit/WKContextConfigurationRef.h>
#import <WebKit/WKContextPrivate.h>
+#import <WebKit/WKImageCG.h>
#import <WebKit/WKPreferencesRefPrivate.h>
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKStringCF.h>
@@ -571,4 +572,9 @@
configuration.defaultWebpagePreferences = webpagePreferences.get();
}
+WKRetainPtr<WKStringRef> TestController::takeViewPortSnapshot()
+{
+ return adoptWK(WKImageCreateDataURLFromImage(mainWebView()->windowSnapshotImage().get()));
+}
+
} // namespace WTR