REGRESSION (r244239) Layout Test fast/canvas/canvas-too-large-to-draw.html is failing
https://bugs.webkit.org/show_bug.cgi?id=202870
Source/WebCore:

Reviewed by Simon Fraser.

Add an internal method to specify a fake limit of canvas pixel memory
so our tests produce reproducible results.

* html/HTMLCanvasElement.cpp:
(WebCore::maxActivePixelMemory):
(WebCore::HTMLCanvasElement::setMaxPixelMemoryForTesting):
* html/HTMLCanvasElement.h:
* testing/Internals.cpp:
(WebCore::Internals::setMaxCanvasPixelMemory):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

<rdar://51862629>

Reviewed by Simon Fraser.

The output from this test depends on the amount of RAM on the system, so
modify it to specify a limit for testing which will give reproducible results.

* fast/canvas/canvas-too-large-to-draw-expected.txt:
* fast/canvas/canvas-too-large-to-draw.html:
* platform/ios/fast/canvas/canvas-too-large-to-draw-expected.txt: Removed.
* platform/ipad/TestExpectations:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251032 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 1da793b..e29d3e2 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2019-10-11  Dean Jackson  <dino@apple.com>
+
+        REGRESSION (r244239) Layout Test fast/canvas/canvas-too-large-to-draw.html is failing
+        https://bugs.webkit.org/show_bug.cgi?id=202870
+        <rdar://51862629>
+
+        Reviewed by Simon Fraser.
+
+        The output from this test depends on the amount of RAM on the system, so
+        modify it to specify a limit for testing which will give reproducible results.
+
+        * fast/canvas/canvas-too-large-to-draw-expected.txt:
+        * fast/canvas/canvas-too-large-to-draw.html:
+        * platform/ios/fast/canvas/canvas-too-large-to-draw-expected.txt: Removed.
+        * platform/ipad/TestExpectations:
+
 2019-10-11  Peng Liu  <peng.liu6@apple.com>
 
         Layout Test media/W3C/audio/events/event_progress.html is flaky
diff --git a/LayoutTests/fast/canvas/canvas-too-large-to-draw-expected.txt b/LayoutTests/fast/canvas/canvas-too-large-to-draw-expected.txt
index 2c3e247..d93d61f 100644
--- a/LayoutTests/fast/canvas/canvas-too-large-to-draw-expected.txt
+++ b/LayoutTests/fast/canvas/canvas-too-large-to-draw-expected.txt
@@ -1,2 +1,4 @@
-CONSOLE MESSAGE: line 36: Canvas area exceeds the maximum limit (width * height > 268435456).
+CONSOLE MESSAGE: line 33: Total canvas memory use exceeds the maximum limit (15 MB).
+This test requires Internals.
+
  
diff --git a/LayoutTests/fast/canvas/canvas-too-large-to-draw.html b/LayoutTests/fast/canvas/canvas-too-large-to-draw.html
index 7d0fbe8..3a7fd20 100644
--- a/LayoutTests/fast/canvas/canvas-too-large-to-draw.html
+++ b/LayoutTests/fast/canvas/canvas-too-large-to-draw.html
@@ -10,30 +10,41 @@
   </style>
 </head>
 <body>
-  <canvas id="canvas1"></canvas>
-  <canvas id="canvas2"></canvas>
-  <script>
-    if (window.testRunner)
-      window.testRunner.dumpAsText();
+<p>This test requires Internals.</p>
+<canvas id="canvas1"></canvas>
+<canvas id="canvas2"></canvas>
+<script>
+    function run() {
+        if (!window.testRunner)
+            return;
 
-    var iOSPlatform = navigator.userAgent.search(/\b(iPhone OS|iPad)\b/) != -1;
-    var OSXYosemiteOrOlder = navigator.userAgent.search(/\bMac OS X 10_(8|9|10)(_[0-9]+)?\b/) != -1;
-    var MAX_WIDTH = iOSPlatform ? Math.pow(2, 12) : (OSXYosemiteOrOlder ? Math.pow(2, 13) : Math.pow(2, 14));
-    var MAX_HEIGHT = MAX_WIDTH;
+        window.testRunner.dumpAsText();
 
-    function fillCanvas(id, width, height) {
-      var canvas = document.getElementById(id);
-      canvas.width = width;
-      canvas.height = height;
+        const MAX_WIDTH = 2000;
+        const MAX_HEIGHT = MAX_WIDTH;
 
-      var ctx = canvas.getContext("2d");
+        window.internals.setMaxCanvasPixelMemory(MAX_WIDTH * MAX_HEIGHT * 4);
 
-      ctx.fillStyle = "lime";
-      ctx.fillRect(0, 0, width, height);
-    }
+        function fillCanvas(id, width, height) {
+            const canvas = document.getElementById(id);
+            canvas.width = width;
+            canvas.height = height;
+
+            const ctx = canvas.getContext("2d");
+            if (!ctx)
+                return;
+
+            ctx.fillStyle = "lime";
+            ctx.fillRect(0, 0, width, height);
+        }
     
-    fillCanvas("canvas1", MAX_WIDTH, MAX_HEIGHT);
-    fillCanvas("canvas2", MAX_WIDTH + 1, MAX_HEIGHT);
-  </script>
+        // This uses up all the available memory.
+        fillCanvas("canvas1", MAX_WIDTH, MAX_HEIGHT);
+
+        // Any new canvas from now on should exceed the memory limit.
+        fillCanvas("canvas2", 10, 10);
+    }
+    run();
+</script>
 </body>
 </html>
diff --git a/LayoutTests/platform/ios/fast/canvas/canvas-too-large-to-draw-expected.txt b/LayoutTests/platform/ios/fast/canvas/canvas-too-large-to-draw-expected.txt
deleted file mode 100644
index d9bb35d..0000000
--- a/LayoutTests/platform/ios/fast/canvas/canvas-too-large-to-draw-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-CONSOLE MESSAGE: line 36: Canvas area exceeds the maximum limit (width * height > 16777216).
- 
diff --git a/LayoutTests/platform/ipad/TestExpectations b/LayoutTests/platform/ipad/TestExpectations
index 77c95aa..a4cec26 100644
--- a/LayoutTests/platform/ipad/TestExpectations
+++ b/LayoutTests/platform/ipad/TestExpectations
@@ -55,9 +55,6 @@
 http/tests/paymentrequest/rejects_if_not_active.https.html [ Skip ]
 http/tests/paymentrequest/updateWith-method-pmi-handling.https.html [ Skip ]
 
-# <rdar://problem/51862629> REGRESSION (r244239) [ iPad Sim ] Layout Test fast/canvas/canvas-too-large-to-draw.html is failing
-fast/canvas/canvas-too-large-to-draw.html [ Failure ]
-
 # <rdar://problem/51863703> [ iPad Sim ] New Layout test fast/events/autoscroll-with-software-keyboard.html is failing on iOS 13 iPad Simulator testers
 fast/events/autoscroll-with-software-keyboard.html [ Failure ]
 
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index cf4d567..315710a 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2019-10-11  Dean Jackson  <dino@apple.com>
+
+        REGRESSION (r244239) Layout Test fast/canvas/canvas-too-large-to-draw.html is failing
+        https://bugs.webkit.org/show_bug.cgi?id=202870
+
+        Reviewed by Simon Fraser.
+
+        Add an internal method to specify a fake limit of canvas pixel memory
+        so our tests produce reproducible results.
+
+        * html/HTMLCanvasElement.cpp:
+        (WebCore::maxActivePixelMemory):
+        (WebCore::HTMLCanvasElement::setMaxPixelMemoryForTesting):
+        * html/HTMLCanvasElement.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::setMaxCanvasPixelMemory):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2019-10-11  Chris Dumez  <cdumez@apple.com>
 
         API Test TestWebKitAPI.WebKit.DefaultQuota is very flaky on High Sierra
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
index 9cfbdb8..996ba76 100644
--- a/Source/WebCore/html/HTMLCanvasElement.cpp
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -113,6 +113,7 @@
 #endif
 
 static size_t activePixelMemory = 0;
+static size_t maxActivePixelMemoryForTesting = 0;
 
 HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& document)
     : HTMLElement(tagName, document)
@@ -194,6 +195,9 @@
 
 static inline size_t maxActivePixelMemory()
 {
+    if (maxActivePixelMemoryForTesting)
+        return maxActivePixelMemoryForTesting;
+
     static size_t maxPixelMemory;
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
@@ -203,9 +207,15 @@
         maxPixelMemory = std::max(ramSize() / 4, 2151 * MB);
 #endif
     });
+
     return maxPixelMemory;
 }
 
+void HTMLCanvasElement::setMaxPixelMemoryForTesting(size_t size)
+{
+    maxActivePixelMemoryForTesting = size;
+}
+
 ExceptionOr<Optional<RenderingContext>> HTMLCanvasElement::getContext(JSC::ExecState& state, const String& contextId, Vector<JSC::Strong<JSC::Unknown>>&& arguments)
 {
     if (m_context) {
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
index 3124888..13a71a5 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -152,6 +152,8 @@
     // It would be better to have the contexts own the buffers.
     void setImageBufferAndMarkDirty(std::unique_ptr<ImageBuffer>&&);
 
+    WEBCORE_EXPORT static void setMaxPixelMemoryForTesting(size_t);
+
 private:
     HTMLCanvasElement(const QualifiedName&, Document&);
 
diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp
index f12249e..28b2063 100644
--- a/Source/WebCore/testing/Internals.cpp
+++ b/Source/WebCore/testing/Internals.cpp
@@ -5246,4 +5246,9 @@
 }
 #endif
 
+void Internals::setMaxCanvasPixelMemory(unsigned size)
+{
+    HTMLCanvasElement::setMaxPixelMemoryForTesting(size);
+}
+
 } // namespace WebCore
diff --git a/Source/WebCore/testing/Internals.h b/Source/WebCore/testing/Internals.h
index c134def..7fca656 100644
--- a/Source/WebCore/testing/Internals.h
+++ b/Source/WebCore/testing/Internals.h
@@ -304,6 +304,8 @@
     Vector<String> userPreferredAudioCharacteristics() const;
     void setUserPreferredAudioCharacteristic(const String&);
 
+    void setMaxCanvasPixelMemory(unsigned);
+
     ExceptionOr<unsigned> wheelEventHandlerCount();
     ExceptionOr<unsigned> touchEventHandlerCount();
 
diff --git a/Source/WebCore/testing/Internals.idl b/Source/WebCore/testing/Internals.idl
index 4e3a412..eafff68 100644
--- a/Source/WebCore/testing/Internals.idl
+++ b/Source/WebCore/testing/Internals.idl
@@ -754,6 +754,8 @@
     void postTask(VoidCallback callback);
     void markContextAsInsecure();
 
+    void setMaxCanvasPixelMemory(unsigned long size);
+
     [Conditional=VIDEO, MayThrowException] readonly attribute NowPlayingState nowPlayingState;
 
     [Conditional=VIDEO] HTMLMediaElement bestMediaElementForShowingPlaybackControlsManager(PlaybackControlsPurpose purpose);