Diff
Modified: trunk/Source/WebKit/ChangeLog (284785 => 284786)
--- trunk/Source/WebKit/ChangeLog 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/ChangeLog 2021-10-25 15:37:16 UTC (rev 284786)
@@ -1,3 +1,72 @@
+2021-10-25 Wenson Hsieh <[email protected]>
+
+ REGRESSION (r284079): Audio continues playing on hulu.com in private browsing mode after closing the tab
+ https://bugs.webkit.org/show_bug.cgi?id=232113
+ rdar://84399283
+
+ Reviewed by Chris Dumez.
+
+ I inadvertently introduced a ref-counting cycle between RemoteRenderingBackend and RemoteDisplayListRecorder
+ after IPC stream refactoring in r284079, since RemoteDisplayListRecorder directly strongly refs the rendering
+ backend, and the rendering backend indirectly holds on to RemoteDisplayListRecorders through remote image
+ buffers in the resource cache. Since RemoteRenderingBackend also strongly refs GPUConnectionToWebProcess as
+ well, this caused the entire GPUConnectionToWebProcess to leak after tearing down the connected web process, if
+ the web process ever installed a remote rendering backend for 2D canvas.
+
+ To avoid this cycle, turn RemoteDisplayListRecorder's `m_renderingBackend` into a RefPtr instead of a Ref, and
+ clear it out in `stopListeningForIPC()`. This also means that we no longer need a separate boolean flag to
+ ensure that `RemoteDisplayListRecorder::stopListeningForIPC()` is idempotent, so we also remove
+ `m_isListeningForIPC` altogether.
+
+ Test: GPUProcess.DoNotLeakConnectionAfterClosingWebPage
+
+ * GPUProcess/GPUConnectionToWebProcess.cpp:
+ (WebKit::GPUConnectionToWebProcess::GPUConnectionToWebProcess):
+ (WebKit::GPUConnectionToWebProcess::~GPUConnectionToWebProcess):
+ * GPUProcess/GPUConnectionToWebProcess.h:
+ (WebKit::GPUConnectionToWebProcess::objectCountForTesting):
+ * GPUProcess/GPUProcess.cpp:
+ (WebKit::GPUProcess::webProcessConnectionCountForTesting):
+
+ Add support for a testing-only SPI hook to ask for the live GPUConnectionToWebProcess count. This retrieves a
+ statically incremented/decremented count of the GPUConnectionToWebProcess instances that exist in the GPU
+ process; importantly, this is different from asking the GPUProcess for the number of connections in
+ `m_webProcessConnections`, since the latter will be 0 even when one or more GPUConnectionToWebProcesses are
+ still alive.
+
+ * GPUProcess/GPUProcess.h:
+ * GPUProcess/GPUProcess.messages.in:
+ * GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
+ (WebKit::RemoteDisplayListRecorder::RemoteDisplayListRecorder):
+
+ Also fix a leak caused by RemoteDisplayListRecorder and RemoteImageBuffer strongly reffing each other. Since
+ RemoteImageBuffer owns RemoteDisplayListRecorder, the backpointer from RemoteDisplayListRecorder to the image
+ buffer should be weak, not strong.
+
+ (WebKit::RemoteDisplayListRecorder::startListeningForIPC):
+ (WebKit::RemoteDisplayListRecorder::stopListeningForIPC):
+ (WebKit::RemoteDisplayListRecorder::paintFrameForMedia):
+ * GPUProcess/graphics/RemoteDisplayListRecorder.h:
+ (): Deleted.
+ * GPUProcess/graphics/RemoteRenderingBackend.cpp:
+ (WebKit::RemoteRenderingBackend::stopListeningForIPC):
+
+ Adjust this logic to ensure that we finish pending work and destroy cached resources *right before* we stop
+ listening for all stream IPC messages. Since RemoteDisplayListRecorder now clears out its pointer to the
+ rendering backend in `stopListeningForIPC()`, we'll need to ensure that any pending IPC stream messages that
+ might cause RemoteDisplayListRecorder to call into the back end are processed before we sever the IPC stream
+ connection for good by removing all receivers.
+
+ * UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
+
+ Add the new testing SPI (see above for more details).
+
+ * UIProcess/API/Cocoa/WKWebViewTesting.mm:
+ (-[WKWebView _gpuToWebProcessConnectionCountForTesting:]):
+ * UIProcess/GPU/GPUProcessProxy.cpp:
+ (WebKit::GPUProcessProxy::webProcessConnectionCountForTesting):
+ * UIProcess/GPU/GPUProcessProxy.h:
+
2021-10-25 Sam Sneddon <[email protected]>
[Python] rename assertEquals/assertNotEquals
Modified: trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp (284785 => 284786)
--- trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp 2021-10-25 15:37:16 UTC (rev 284786)
@@ -248,6 +248,8 @@
// reply from the GPU process, which would be unsafe.
m_connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true);
m_connection->open();
+
+ ++gObjectCountForTesting;
}
GPUConnectionToWebProcess::~GPUConnectionToWebProcess()
@@ -262,8 +264,12 @@
#if PLATFORM(COCOA) && USE(LIBWEBRTC)
m_libWebRTCCodecsProxy->close();
#endif
+
+ --gObjectCountForTesting;
}
+uint64_t GPUConnectionToWebProcess::gObjectCountForTesting = 0;
+
void GPUConnectionToWebProcess::didClose(IPC::Connection& connection)
{
#if ENABLE(ROUTING_ARBITRATION) && HAVE(AVAUDIO_ROUTING_ARBITER)
Modified: trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h (284785 => 284786)
--- trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h 2021-10-25 15:37:16 UTC (rev 284786)
@@ -170,6 +170,8 @@
void releaseGraphicsContextGLForTesting(GraphicsContextGLIdentifier);
#endif
+ static uint64_t objectCountForTesting() { return gObjectCountForTesting; }
+
using RemoteRenderingBackendMap = HashMap<RenderingBackendIdentifier, IPC::ScopedActiveMessageReceiveQueue<RemoteRenderingBackend>>;
const RemoteRenderingBackendMap& remoteRenderingBackendMap() const { return m_remoteRenderingBackendMap; }
@@ -242,6 +244,8 @@
void dispatchDisplayWasReconfigured();
#endif
+ static uint64_t gObjectCountForTesting;
+
RefPtr<Logger> m_logger;
Ref<IPC::Connection> m_connection;
Modified: trunk/Source/WebKit/GPUProcess/GPUProcess.cpp (284785 => 284786)
--- trunk/Source/WebKit/GPUProcess/GPUProcess.cpp 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/GPUProcess/GPUProcess.cpp 2021-10-25 15:37:16 UTC (rev 284786)
@@ -498,6 +498,11 @@
}
#endif
+void GPUProcess::webProcessConnectionCountForTesting(CompletionHandler<void(uint64_t)>&& completionHandler)
+{
+ completionHandler(GPUConnectionToWebProcess::objectCountForTesting());
+}
+
} // namespace WebKit
#endif // ENABLE(GPU_PROCESS)
Modified: trunk/Source/WebKit/GPUProcess/GPUProcess.h (284785 => 284786)
--- trunk/Source/WebKit/GPUProcess/GPUProcess.h 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/GPUProcess/GPUProcess.h 2021-10-25 15:37:16 UTC (rev 284786)
@@ -100,6 +100,8 @@
const String& applicationVisibleName() const { return m_applicationVisibleName; }
+ void webProcessConnectionCountForTesting(CompletionHandler<void(uint64_t)>&&);
+
private:
void lowMemoryHandler(Critical, Synchronous);
Modified: trunk/Source/WebKit/GPUProcess/GPUProcess.messages.in (284785 => 284786)
--- trunk/Source/WebKit/GPUProcess/GPUProcess.messages.in 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/GPUProcess/GPUProcess.messages.in 2021-10-25 15:37:16 UTC (rev 284786)
@@ -68,6 +68,8 @@
#if ENABLE(CFPREFS_DIRECT_MODE)
NotifyPreferencesChanged(String domain, String key, std::optional<String> encodedValue)
#endif
+
+ WebProcessConnectionCountForTesting() -> (uint64_t count) Async
}
#endif // ENABLE(GPU_PROCESS)
Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp (284785 => 284786)
--- trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp 2021-10-25 15:37:16 UTC (rev 284786)
@@ -37,7 +37,7 @@
: m_imageBuffer(imageBuffer)
, m_imageBufferIdentifier(imageBufferIdentifier)
, m_webProcessIdentifier(webProcessIdentifier)
- , m_renderingBackend(renderingBackend)
+ , m_renderingBackend(&renderingBackend)
{
}
@@ -53,18 +53,13 @@
void RemoteDisplayListRecorder::startListeningForIPC()
{
- ASSERT(!m_isListeningForIPC);
- m_isListeningForIPC = true;
m_renderingBackend->streamConnection().startReceivingMessages(*this, Messages::RemoteDisplayListRecorder::messageReceiverName(), m_imageBufferIdentifier.object().toUInt64());
}
void RemoteDisplayListRecorder::stopListeningForIPC()
{
- if (!m_isListeningForIPC)
- return;
-
- m_renderingBackend->streamConnection().stopReceivingMessages(Messages::RemoteDisplayListRecorder::messageReceiverName(), m_imageBufferIdentifier.object().toUInt64());
- m_isListeningForIPC = false;
+ if (auto renderingBackend = std::exchange(m_renderingBackend, { }))
+ renderingBackend->streamConnection().stopReceivingMessages(Messages::RemoteDisplayListRecorder::messageReceiverName(), m_imageBufferIdentifier.object().toUInt64());
}
void RemoteDisplayListRecorder::save()
@@ -426,7 +421,7 @@
void RemoteDisplayListRecorder::paintFrameForMedia(MediaPlayerIdentifier identifier, const FloatRect& destination)
{
- m_renderingBackend->performWithMediaPlayerOnMainThread(identifier, [imageBuffer = m_imageBuffer.copyRef(), destination](MediaPlayer& player) {
+ m_renderingBackend->performWithMediaPlayerOnMainThread(identifier, [imageBuffer = RefPtr { m_imageBuffer.get() }, destination](MediaPlayer& player) {
// It is currently not safe to call paintFrameForMedia() off the main thread.
imageBuffer->context().paintFrameForMedia(player, destination);
});
Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h (284785 => 284786)
--- trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h 2021-10-25 15:37:16 UTC (rev 284786)
@@ -149,12 +149,11 @@
void startListeningForIPC();
void didReceiveStreamMessage(IPC::StreamServerConnectionBase&, IPC::Decoder&) final;
- Ref<WebCore::ImageBuffer> m_imageBuffer;
+ WeakPtr<WebCore::ImageBuffer> m_imageBuffer;
QualifiedRenderingResourceIdentifier m_imageBufferIdentifier;
WebCore::ProcessIdentifier m_webProcessIdentifier;
- Ref<RemoteRenderingBackend> m_renderingBackend;
+ RefPtr<RemoteRenderingBackend> m_renderingBackend;
RefPtr<WebCore::ImageBuffer> m_maskImageBuffer;
- bool m_isListeningForIPC { false };
};
} // namespace WebKit
Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp (284785 => 284786)
--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp 2021-10-25 15:37:16 UTC (rev 284786)
@@ -108,6 +108,11 @@
void RemoteRenderingBackend::stopListeningForIPC()
{
ASSERT(RunLoop::isMain());
+ // Make sure we destroy the ResourceCache on the WorkQueue since it gets populated on the WorkQueue.
+ // Make sure rendering resource request is released after destroying the cache.
+ m_workQueue->dispatch([renderingResourcesRequest = WTFMove(m_renderingResourcesRequest), remoteResourceCache = WTFMove(m_remoteResourceCache)] { });
+ m_workQueue->stopAndWaitForCompletion();
+
m_streamConnection->stopReceivingMessages(Messages::RemoteRenderingBackend::messageReceiverName(), m_renderingBackendIdentifier.toUInt64());
m_streamConnection->stopReceivingMessages(Messages::RemoteDisplayListRecorder::messageReceiverName());
@@ -117,11 +122,6 @@
for (auto& remoteContext : std::exchange(m_remoteDisplayLists, { }))
remoteContext.value->stopListeningForIPC();
}
-
- // Make sure we destroy the ResourceCache on the WorkQueue since it gets populated on the WorkQueue.
- // Make sure rendering resource request is released after destroying the cache.
- m_workQueue->dispatch([renderingResourcesRequest = WTFMove(m_renderingResourcesRequest), remoteResourceCache = WTFMove(m_remoteResourceCache)] { });
- m_workQueue->stopAndWaitForCompletion();
}
void RemoteRenderingBackend::dispatch(Function<void()>&& task)
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h (284785 => 284786)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h 2021-10-25 15:37:16 UTC (rev 284786)
@@ -114,6 +114,7 @@
- (void)_clearAppPrivacyReportTestingData:(void(^)(void))completionHandler;
- (void)_createMediaSessionCoordinatorForTesting:(id <_WKMediaSessionCoordinator>)privateCoordinator completionHandler:(void(^)(BOOL))completionHandler;
+- (void)_gpuToWebProcessConnectionCountForTesting:(void(^)(NSUInteger))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
@end
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm (284785 => 284786)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm 2021-10-25 15:37:16 UTC (rev 284786)
@@ -27,6 +27,7 @@
#import "WKWebViewPrivateForTesting.h"
#import "AudioSessionRoutingArbitratorProxy.h"
+#import "GPUProcessProxy.h"
#import "MediaSessionCoordinatorProxyPrivate.h"
#import "PlaybackSessionManagerProxy.h"
#import "UserMediaProcessManager.h"
@@ -423,6 +424,19 @@
});
}
+- (void)_gpuToWebProcessConnectionCountForTesting:(void(^)(NSUInteger))completionHandler
+{
+ RefPtr gpuProcess = _page->process().processPool().gpuProcess();
+ if (!gpuProcess) {
+ completionHandler(0);
+ return;
+ }
+
+ gpuProcess->webProcessConnectionCountForTesting([completionHandler = makeBlockPtr(completionHandler)](uint64_t count) {
+ completionHandler(count);
+ });
+}
+
- (void)_createMediaSessionCoordinatorForTesting:(id <_WKMediaSessionCoordinator>)privateCoordinator completionHandler:(void(^)(BOOL))completionHandler
{
#if ENABLE(MEDIA_SESSION_COORDINATOR)
Modified: trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp (284785 => 284786)
--- trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp 2021-10-25 15:37:16 UTC (rev 284786)
@@ -399,6 +399,11 @@
processIsReadyToExit();
}
+void GPUProcessProxy::webProcessConnectionCountForTesting(CompletionHandler<void(uint64_t)>&& completionHandler)
+{
+ sendWithAsyncReply(Messages::GPUProcess::WebProcessConnectionCountForTesting(), WTFMove(completionHandler));
+}
+
void GPUProcessProxy::didClose(IPC::Connection&)
{
RELEASE_LOG_ERROR(Process, "%p - GPUProcessProxy::didClose:", this);
Modified: trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h (284785 => 284786)
--- trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h 2021-10-25 15:37:16 UTC (rev 284786)
@@ -94,6 +94,7 @@
void updatePreferences();
void terminateForTesting();
+ void webProcessConnectionCountForTesting(CompletionHandler<void(uint64_t)>&&);
private:
explicit GPUProcessProxy();
Modified: trunk/Tools/ChangeLog (284785 => 284786)
--- trunk/Tools/ChangeLog 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Tools/ChangeLog 2021-10-25 15:37:16 UTC (rev 284786)
@@ -1,3 +1,21 @@
+2021-10-25 Wenson Hsieh <[email protected]>
+
+ REGRESSION (r284079): Audio continues playing on hulu.com in private browsing mode after closing the tab
+ https://bugs.webkit.org/show_bug.cgi?id=232113
+ rdar://84399283
+
+ Reviewed by Chris Dumez.
+
+ Add a new API test to verify that the GPU to web prcoess connection isn't leaked in the GPU process. See WebKit
+ ChangeLog for more details.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm:
+ * TestWebKitAPI/Tests/WebKitCocoa/canvas-image-data.html: Added.
+ * TestWebKitAPI/cocoa/TestWKWebView.h:
+ * TestWebKitAPI/cocoa/TestWKWebView.mm:
+ (-[WKWebView gpuToWebProcessConnectionCount]):
+
2021-10-25 Simon Fraser <[email protected]>
webkitpy: have diff_image() return a ImageDiffResult
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (284785 => 284786)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-10-25 15:37:16 UTC (rev 284786)
@@ -1295,6 +1295,7 @@
F4E0A2B42122402B00AF7C7F /* image-and-file-upload.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E0A2B321223F2D00AF7C7F /* image-and-file-upload.html */; };
F4E0A2B82122847400AF7C7F /* TestFilePromiseReceiver.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4E0A2B72122847400AF7C7F /* TestFilePromiseReceiver.mm */; };
F4E3D80820F70BB9007B58C5 /* significant-text-milestone-article.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E3D80720F708E4007B58C5 /* significant-text-milestone-article.html */; };
+ F4E7A66327222CA900E74D36 /* canvas-image-data.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E7A66227222BB100E74D36 /* canvas-image-data.html */; };
F4EB4E912328AC3000574DAB /* NSItemProviderAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4EB4E902328AC3000574DAB /* NSItemProviderAdditions.mm */; };
F4EC8094260D30540010311D /* simple-image-overlay.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4EC8093260D2E620010311D /* simple-image-overlay.html */; };
F4F137921D9B683E002BEC57 /* large-video-test-now-playing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4F137911D9B6832002BEC57 /* large-video-test-now-playing.html */; };
@@ -1444,6 +1445,7 @@
2DE71B001D49C3ED00904094 /* blinking-div.html in Copy Resources */,
7C486BA11AA12567003F6F9B /* bundle-file.html in Copy Resources */,
26DF5A6315A2A27E003689C2 /* CancelLoadFromResourceLoadDelegate.html in Copy Resources */,
+ F4E7A66327222CA900E74D36 /* canvas-image-data.html in Copy Resources */,
2EFF06C51D8867760004BB30 /* change-video-source-on-click.html in Copy Resources */,
2EFF06C71D886A580004BB30 /* change-video-source-on-end.html in Copy Resources */,
9BD4239C1E04C01C00200395 /* chinese-character-with-image.html in Copy Resources */,
@@ -3187,6 +3189,7 @@
F4E0A2B62122847400AF7C7F /* TestFilePromiseReceiver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestFilePromiseReceiver.h; sourceTree = "<group>"; };
F4E0A2B72122847400AF7C7F /* TestFilePromiseReceiver.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestFilePromiseReceiver.mm; sourceTree = "<group>"; };
F4E3D80720F708E4007B58C5 /* significant-text-milestone-article.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "significant-text-milestone-article.html"; sourceTree = "<group>"; };
+ F4E7A66227222BB100E74D36 /* canvas-image-data.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "canvas-image-data.html"; sourceTree = "<group>"; };
F4EB4E8F2328AC3000574DAB /* NSItemProviderAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NSItemProviderAdditions.h; path = cocoa/NSItemProviderAdditions.h; sourceTree = SOURCE_ROOT; };
F4EB4E902328AC3000574DAB /* NSItemProviderAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = NSItemProviderAdditions.mm; path = cocoa/NSItemProviderAdditions.mm; sourceTree = SOURCE_ROOT; };
F4EC8093260D2E620010311D /* simple-image-overlay.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-image-overlay.html"; sourceTree = "<group>"; };
@@ -4050,6 +4053,7 @@
F41AB9971EF4692C0083FA08 /* background-image-link-and-input.html */,
464C764C230DF83200AFB020 /* BadServiceWorkerRegistrations-4.sqlite3 */,
2DE71AFF1D49C2F000904094 /* blinking-div.html */,
+ F4E7A66227222BB100E74D36 /* canvas-image-data.html */,
2EFF06C41D8867700004BB30 /* change-video-source-on-click.html */,
2EFF06C61D886A560004BB30 /* change-video-source-on-end.html */,
839AA35E21A26ACD00980DD6 /* client-side-redirect.html */,
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm (284785 => 284786)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm 2021-10-25 15:37:16 UTC (rev 284786)
@@ -282,6 +282,21 @@
EXPECT_EQ([configuration.get().processPool _gpuProcessIdentifier], 0);
}
+TEST(GPUProcess, DoNotLeakConnectionAfterClosingWebPage)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("UseGPUProcessForCanvasRenderingEnabled"));
+ WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], false, WKStringCreateWithUTF8CString("UseGPUProcessForDOMRenderingEnabled"));
+
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]);
+ [webView synchronouslyLoadTestPageNamed:@"canvas-image-data"];
+ EXPECT_EQ(1U, [webView gpuToWebProcessConnectionCount]);
+ [webView _close];
+
+ while ([webView gpuToWebProcessConnectionCount])
+ TestWebKitAPI::Util::sleep(0.1);
+}
+
#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
TEST(GPUProcess, LegacyCDM)
{
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/canvas-image-data.html (0 => 284786)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/canvas-image-data.html (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/canvas-image-data.html 2021-10-25 15:37:16 UTC (rev 284786)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+canvas {
+ width: 160px;
+ height: 160px;
+ display: block;
+}
+</style>
+</head>
+<body>
+<strong>Source</strong>
+<canvas id="source" width="320" height="320"></canvas>
+<strong>Destination</strong>
+<canvas id="destination" width="320" height="320"></canvas>
+<script>
+const sourceCanvas = document.getElementById("source");
+const sourceContext = sourceCanvas.getContext("2d");
+sourceContext.save();
+sourceContext.strokeStyle = "red";
+sourceContext.fillStyle = "rgba(200, 100, 100, 0.25)";
+sourceContext.lineWidth = 4;
+sourceContext.rect(40, 40, 240, 240);
+sourceContext.stroke();
+sourceContext.fill();
+sourceContext.restore();
+
+const imageData = sourceContext.getImageData(0, 0, 320, 320);
+const destinationCanvas = document.getElementById("destination");
+const destinationContext = destinationCanvas.getContext("2d");
+destinationContext.putImageData(imageData, 0, 0, 0, 0, 320, 320);
+</script>
+</body>
+</html>
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h (284785 => 284786)
--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h 2021-10-25 15:37:16 UTC (rev 284786)
@@ -53,6 +53,7 @@
@property (nonatomic, readonly) UIView <UITextInputPrivate, UITextInputInternal, UITextInputMultiDocument, UIWKInteractionViewProtocol, UITextInputTokenizer> *textInputContentView;
- (NSArray<_WKTextInputContext *> *)synchronouslyRequestTextInputContextsInRect:(CGRect)rect;
#endif
+@property (nonatomic, readonly) NSUInteger gpuToWebProcessConnectionCount;
@property (nonatomic, readonly) NSString *contentsAsString;
@property (nonatomic, readonly) NSArray<NSString *> *tagsInBody;
- (void)loadTestPageNamed:(NSString *)pageName;
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm (284785 => 284786)
--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm 2021-10-25 15:26:54 UTC (rev 284785)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm 2021-10-25 15:37:16 UTC (rev 284786)
@@ -154,6 +154,18 @@
#endif // PLATFORM(IOS_FAMILY)
+- (NSUInteger)gpuToWebProcessConnectionCount
+{
+ __block bool done = false;
+ __block NSUInteger count = 0;
+ [self _gpuToWebProcessConnectionCountForTesting:^(NSUInteger result) {
+ done = true;
+ count = result;
+ }];
+ TestWebKitAPI::Util::run(&done);
+ return count;
+}
+
- (NSString *)contentsAsString
{
__block bool done = false;