Diff
Modified: trunk/LayoutTests/ChangeLog (281979 => 281980)
--- trunk/LayoutTests/ChangeLog 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/LayoutTests/ChangeLog 2021-09-03 08:25:03 UTC (rev 281980)
@@ -1,3 +1,17 @@
+2021-09-03 Said Abou-Hallawa <s...@apple.com>
+
+ Add a layout test to detect memory leaks when drawing images to a detached canvas
+ https://bugs.webkit.org/show_bug.cgi?id=229790
+
+ Reviewed by Darin Adler.
+
+ Draw frames on an animated image to a detached canvas. Verify at the end
+ and after releasing all the image decoded frames that there are no remote
+ cached images.
+
+ * fast/canvas/canvas-drawImage-detached-leak-expected.txt: Added.
+ * fast/canvas/canvas-drawImage-detached-leak.html: Added.
+
2021-09-03 Frédéric Wang <fw...@igalia.com>
Use isRendererReplacedElement for SimplifiedBackwardsTextIterator
Added: trunk/LayoutTests/fast/canvas/canvas-drawImage-detached-leak-expected.txt (0 => 281980)
--- trunk/LayoutTests/fast/canvas/canvas-drawImage-detached-leak-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-drawImage-detached-leak-expected.txt 2021-09-03 08:25:03 UTC (rev 281980)
@@ -0,0 +1,10 @@
+Test drawImage() to a detached canvas won't leak the drawn images.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS internals.remoteImagesCountForTesting() is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/canvas/canvas-drawImage-detached-leak.html (0 => 281980)
--- trunk/LayoutTests/fast/canvas/canvas-drawImage-detached-leak.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-drawImage-detached-leak.html 2021-09-03 08:25:03 UTC (rev 281980)
@@ -0,0 +1,57 @@
+<head>
+ <script src=""
+</head>
+<body>
+ <script>
+ let canvas = document.createElement('canvas');
+
+ description("Test drawImage() to a detached canvas won't leak the drawn images.");
+ jsTestIsAsync = true;
+
+ if (window.internals) {
+ internals.clearMemoryCache();
+ internals.settings.setAnimatedImageDebugCanvasDrawingEnabled(true);
+ }
+
+ const drawFrame = (image) => {
+ return new Promise((resolve) => {
+ requestAnimationFrame(() => {
+ var ctx = canvas.getContext("2d");
+ ctx.drawImage(image, 0, 0);
+ setTimeout(() => {
+ resolve();
+ }, 30);
+ });
+ });
+ }
+
+ const drawImage = (image, frameCount) => {
+ let promise = drawFrame(image);
+ for (let frame = 1; frame < frameCount; ++frame) {
+ promise = promise.then(() => {
+ return drawFrame(image);
+ });
+ }
+ return promise;
+ }
+
+ const loadAndDrawImage = (src, frameCount) => {
+ return new Promise((resolve) => {
+ let image = new Image;
+ image._onload_ = (() => {
+ drawImage(image, frameCount).then(resolve);
+ });
+ image.src = ""
+ });
+ }
+
+ loadAndDrawImage("../images/resources/animated-red-green-blue-repeat-1.gif", 3).then(() => {
+ if (window.internals) {
+ internals.destroyDecodedDataForAllImages();
+ shouldBeZero("internals.remoteImagesCountForTesting()");
+ }
+ finishJSTest();
+ });
+ </script>
+ <script src=""
+</body>
Modified: trunk/Source/WebCore/ChangeLog (281979 => 281980)
--- trunk/Source/WebCore/ChangeLog 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebCore/ChangeLog 2021-09-03 08:25:03 UTC (rev 281980)
@@ -1,3 +1,24 @@
+2021-09-03 Said Abou-Hallawa <s...@apple.com>
+
+ Add a layout test to detect memory leaks when drawing images to a detached canvas
+ https://bugs.webkit.org/show_bug.cgi?id=229790
+
+ Reviewed by Darin Adler.
+
+ Add an internal API to return the number of remote images which are cached
+ by WebProcess and GPUProcess. It can be used after rendering update is
+ finished to verify that there are no images cached because they are
+ referenced in a DispalyList of a detached canvas.
+
+ Test: fast/canvas/canvas-drawImage-detached-leak.html
+
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::remoteImagesCountForTesting const):
+ * testing/Internals.cpp:
+ (WebCore::Internals::remoteImagesCountForTesting const):
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2021-09-03 Frédéric Wang <fw...@igalia.com>
Use isRendererReplacedElement for SimplifiedBackwardsTextIterator
Modified: trunk/Source/WebCore/page/ChromeClient.h (281979 => 281980)
--- trunk/Source/WebCore/page/ChromeClient.h 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebCore/page/ChromeClient.h 2021-09-03 08:25:03 UTC (rev 281980)
@@ -368,6 +368,8 @@
// Schedule a rendering update that coordinates with display refresh. Returns true if scheduled. (This is only used by SVGImageChromeClient.)
virtual bool scheduleRenderingUpdate() { return false; }
+ virtual unsigned remoteImagesCountForTesting() const { return 0; }
+
// Returns whether or not the client can render the composited layer,
// regardless of the settings.
virtual bool allowsAcceleratedCompositing() const { return true; }
Modified: trunk/Source/WebCore/testing/Internals.cpp (281979 => 281980)
--- trunk/Source/WebCore/testing/Internals.cpp 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebCore/testing/Internals.cpp 2021-09-03 08:25:03 UTC (rev 281980)
@@ -1007,6 +1007,15 @@
#endif
}
+unsigned Internals::remoteImagesCountForTesting() const
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return 0;
+
+ return document->page()->chrome().client().remoteImagesCountForTesting();
+}
+
void Internals::setLargeImageAsyncDecodingEnabledForTesting(HTMLImageElement& element, bool enabled)
{
if (auto* bitmapImage = bitmapImageFromImageElement(element))
Modified: trunk/Source/WebCore/testing/Internals.h (281979 => 281980)
--- trunk/Source/WebCore/testing/Internals.h 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebCore/testing/Internals.h 2021-09-03 08:25:03 UTC (rev 281980)
@@ -199,6 +199,7 @@
void setClearDecoderAfterAsyncFrameRequestForTesting(HTMLImageElement&, bool enabled);
unsigned imageDecodeCount(HTMLImageElement&);
unsigned pdfDocumentCachingCount(HTMLImageElement&);
+ unsigned remoteImagesCountForTesting() const;
void setLargeImageAsyncDecodingEnabledForTesting(HTMLImageElement&, bool enabled);
void setForceUpdateImageDataEnabledForTesting(HTMLImageElement&, bool enabled);
Modified: trunk/Source/WebCore/testing/Internals.idl (281979 => 281980)
--- trunk/Source/WebCore/testing/Internals.idl 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebCore/testing/Internals.idl 2021-09-03 08:25:03 UTC (rev 281980)
@@ -497,6 +497,7 @@
undefined setClearDecoderAfterAsyncFrameRequestForTesting(HTMLImageElement element, boolean enabled);
unsigned long imageDecodeCount(HTMLImageElement element);
unsigned long pdfDocumentCachingCount(HTMLImageElement element);
+ unsigned long remoteImagesCountForTesting();
undefined setLargeImageAsyncDecodingEnabledForTesting(HTMLImageElement element, boolean enabled);
undefined setForceUpdateImageDataEnabledForTesting(HTMLImageElement element, boolean enabled);
Modified: trunk/Source/WebKit/ChangeLog (281979 => 281980)
--- trunk/Source/WebKit/ChangeLog 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebKit/ChangeLog 2021-09-03 08:25:03 UTC (rev 281980)
@@ -1,3 +1,19 @@
+2021-09-03 Said Abou-Hallawa <s...@apple.com>
+
+ Add a layout test to detect memory leaks when drawing images to a detached canvas
+ https://bugs.webkit.org/show_bug.cgi?id=229790
+
+ Reviewed by Darin Adler.
+
+ * WebProcess/GPU/graphics/RemoteResourceCacheProxy.h:
+ (WebKit::RemoteResourceCacheProxy::imagesCount const):
+ * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+ (WebKit::WebChromeClient::remoteImagesCountForTesting const):
+ * WebProcess/WebCoreSupport/WebChromeClient.h:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::remoteImagesCountForTesting const):
+ * WebProcess/WebPage/WebPage.h:
+
2021-09-02 Wenson Hsieh <wenson_hs...@apple.com>
REGRESSION (r280767): Caret color is black after pasting rich text in Mail compose in dark mode
Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.h (281979 => 281980)
--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.h 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.h 2021-09-03 08:25:03 UTC (rev 281980)
@@ -59,6 +59,8 @@
void remoteResourceCacheWasDestroyed();
void releaseAllRemoteFonts();
void releaseMemory();
+
+ unsigned imagesCount() const { return m_nativeImages.size(); }
private:
struct ImageBufferState {
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (281979 => 281980)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp 2021-09-03 08:25:03 UTC (rev 281980)
@@ -988,6 +988,11 @@
m_page.drawingArea()->triggerRenderingUpdate();
}
+unsigned WebChromeClient::remoteImagesCountForTesting() const
+{
+ return m_page.remoteImagesCountForTesting();
+}
+
void WebChromeClient::contentRuleListNotification(const URL& url, const ContentRuleListResults& results)
{
#if ENABLE(CONTENT_EXTENSIONS)
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (281979 => 281980)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h 2021-09-03 08:25:03 UTC (rev 281980)
@@ -229,6 +229,7 @@
void setNeedsOneShotDrawingSynchronization() final;
bool shouldTriggerRenderingUpdate(unsigned rescheduledRenderingUpdateCount) const final;
void triggerRenderingUpdate() final;
+ unsigned remoteImagesCountForTesting() const final;
void contentRuleListNotification(const URL&, const WebCore::ContentRuleListResults&) final;
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (281979 => 281980)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-09-03 08:25:03 UTC (rev 281980)
@@ -4223,6 +4223,17 @@
#endif
}
+unsigned WebPage::remoteImagesCountForTesting() const
+{
+#if ENABLE(GPU_PROCESS)
+ if (!m_remoteRenderingBackendProxy)
+ return 0;
+ return m_remoteRenderingBackendProxy->remoteResourceCacheProxy().imagesCount();
+#else
+ return 0;
+#endif
+}
+
WebInspector* WebPage::inspector(LazyCreationPolicy behavior)
{
if (m_isClosed)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (281979 => 281980)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2021-09-03 07:25:34 UTC (rev 281979)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2021-09-03 08:25:03 UTC (rev 281980)
@@ -407,6 +407,8 @@
void releaseMemory(WTF::Critical);
+ unsigned remoteImagesCountForTesting() const;
+
enum class LazyCreationPolicy { UseExistingOnly, CreateIfNeeded };
WebInspector* inspector(LazyCreationPolicy = LazyCreationPolicy::CreateIfNeeded);