Title: [294742] trunk/LayoutTests
Revision
294742
Author
[email protected]
Date
2022-05-24 06:08:49 -0700 (Tue, 24 May 2022)

Log Message

canvas-createPattern-video-modify.html is an intermittent failure
https://bugs.webkit.org/show_bug.cgi?id=240780
rdar://93731906

Reviewed by Youenn Fablet.

The tests relied on the event "loadeddata" to be fired to check if the first video frame got painted.
However, at present there's no guarantee that a frame would have been painted at the time this event is fired.
This issue is separately tracked in bug 240779

So instead we use the new requestVideoCallbackFrame API which is designed specifically for this case.
We also simplify the existing page, using more modern JS features.

* LayoutTests/fast/canvas/canvas-createPattern-video-loading.html:
* LayoutTests/fast/canvas/canvas-createPattern-video-modify.html:
* LayoutTests/media/utilities.js:
(once):
(fetchWithXHR):
(waitForVideoFrame):
(waitForVideoFrameUntil):

Canonical link: https://commits.webkit.org/250910@main

Modified Paths

Diff

Modified: trunk/LayoutTests/fast/canvas/canvas-createPattern-video-loading.html (294741 => 294742)


--- trunk/LayoutTests/fast/canvas/canvas-createPattern-video-loading.html	2022-05-24 08:17:38 UTC (rev 294741)
+++ trunk/LayoutTests/fast/canvas/canvas-createPattern-video-loading.html	2022-05-24 13:08:49 UTC (rev 294742)
@@ -3,6 +3,7 @@
 <head>
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
 </head>
 <body>
@@ -32,13 +33,13 @@
     document.body.appendChild(canvases);
 
     var video = document.createElement("video");
-    video.addEventListener("loadeddata", loadeddata);
-    video.addEventListener("playing", playing);
 
     shouldBeNull("document.createElement('canvas').getContext('2d').createPattern(video, 'repeat')");
 
+    waitForVideoFrame(video, firstframe);
     video.src = "" "../../media/content/test");
 
+
     function checkPixels(context, x, y, r, g, b, tolerance)
     {
         buffer = context.getImageData(x, y, 1, 1).data;
@@ -63,16 +64,13 @@
         });
     }
 
-    function loadeddata()
+    async function firstframe()
     {
         drawImageToCanvasAndCheckPixels();
 
         video.currentTime = 1;
         video.play();
-    }
-
-    function playing()
-    {
+        await waitForVideoFrameUntil(video, 1);
         video.pause();
 
         drawImageToCanvasAndCheckPixels();

Modified: trunk/LayoutTests/fast/canvas/canvas-createPattern-video-modify.html (294741 => 294742)


--- trunk/LayoutTests/fast/canvas/canvas-createPattern-video-modify.html	2022-05-24 08:17:38 UTC (rev 294741)
+++ trunk/LayoutTests/fast/canvas/canvas-createPattern-video-modify.html	2022-05-24 13:08:49 UTC (rev 294742)
@@ -3,6 +3,7 @@
 <head>
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
 </head>
 <body>
@@ -11,7 +12,6 @@
 
     var buffer;
     var canvas, context;
-    var modified = false;
     var expectedResults = [
         // Each entry is formatted as [x, y, r, g, b].
         [40, 165, 200, 200, 0], // Represents yellow north west tile.
@@ -21,31 +21,30 @@
     ];
 
     var video = document.createElement("video");
-    video.addEventListener("loadeddata", loadeddata);
+
+    waitForVideoFrame(video, firstframe);
     video.src = "" "../../media/content/test");
 
-    function loadeddata()
+    async function firstframe()
     {
-        if (!modified) {
-            canvas = document.createElement("canvas");
-            canvas.width = 2.5 * video.videoWidth;
-            canvas.height = 2.5 * video.videoHeight;
-            document.body.appendChild(canvas);
+        canvas = document.createElement("canvas");
+        canvas.width = 2.5 * video.videoWidth;
+        canvas.height = 2.5 * video.videoHeight;
+        document.body.appendChild(canvas);
 
-            context = canvas.getContext("2d");
-            context.fillStyle = context.createPattern(video, "repeat");
+        context = canvas.getContext("2d");
+        context.fillStyle = context.createPattern(video, "repeat");
 
-            video.src = "" "../../media/content/counting");
-            modified = !modified;
-        } else {
-            context.fillRect(0, 0, canvas.width, canvas.height);
+        video.src = "" "../../media/content/counting");
 
-            expectedResults.forEach(function(element) {
-                checkPixels(context, element[0], element[1], element[2], element[3], element[4], videoCanvasPixelComparisonTolerance());
-            });
+        await waitForVideoFrame(video);
 
-            finishJSTest();
-        }
+        context.fillRect(0, 0, canvas.width, canvas.height);
+        expectedResults.forEach(function(element) {
+            checkPixels(context, element[0], element[1], element[2], element[3], element[4], videoCanvasPixelComparisonTolerance());
+        });
+
+        finishJSTest();
     }
 
     function checkPixels(context, x, y, r, g, b, tolerance)

Modified: trunk/LayoutTests/media/utilities.js (294741 => 294742)


--- trunk/LayoutTests/media/utilities.js	2022-05-24 08:17:38 UTC (rev 294741)
+++ trunk/LayoutTests/media/utilities.js	2022-05-24 13:08:49 UTC (rev 294742)
@@ -4,9 +4,8 @@
             resolve(event);
         }, { once: true });
     });
-    if (cb) {
+    if (cb)
         p.then(cb);
-    }
     return p;
 }
 
@@ -21,9 +20,8 @@
         xhr.send();
     });
 
-    if (onLoadFunction) {
+    if (onLoadFunction)
         p.then(onLoadFunction);
-    }
 
     return p;
 };
@@ -42,18 +40,41 @@
     // Fetch the buffers in parallel.
     let buffers = {};
     let fetches = [];
-    for (var chunk of chunks) {
+    for (var chunk of chunks)
         fetches.push(fetchWithXHR(prefix + chunk + suffix).then(((c, x) => buffers[c] = x).bind(null, chunk)));
-    }
 
     // Load them in series, as required per spec.
     return Promise.all(fetches).then(() => {
         let rv = Promise.resolve();
-        for (let chunk of chunks) {
+        for (let chunk of chunks)
             rv = rv.then(loadSegment.bind(null, sb, buffers[chunk]));
-        }
         return rv;
     });
 }
 
 const delay = ms => new Promise(res => setTimeout(res, ms));
+
+function waitForVideoFrame(video, cb) {
+    const p = new Promise((resolve) => {
+        video.requestVideoFrameCallback((now, metadata) => resolve(now, metadata));
+    });
+    if (cb)
+        p.then(cb);
+    return p;
+}
+
+function waitForVideoFrameUntil(video, time, cb) {
+    const p = new Promise(resolve => {
+        const callback = ((now, metadata) => {
+            if (metadata.mediaTime >= time) {
+                resolve(now, metadata);
+                return;
+            }
+            video.requestVideoFrameCallback(callback);
+        });
+        video.requestVideoFrameCallback(callback);
+    });
+    if (cb)
+        p.then(cb);
+    return p;
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to