⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 294742 in webkit


Ignore:
Timestamp:
May 24, 2022, 6:08:49 AM (4 years ago)
Author:
Jean-Yves Avenard
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

Location:
trunk/LayoutTests
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/fast/canvas/canvas-createPattern-video-loading.html

    r284439 r294742  
    44    <script src="../../resources/js-test-pre.js"></script>
    55    <script src="../../media/media-file.js"></script>
     6    <script src="../../media/utilities.js"></script>
    67    <script src="../../resources/platform-helper.js"></script>
    78</head>
     
    3334
    3435    var video = document.createElement("video");
    35     video.addEventListener("loadeddata", loadeddata);
    36     video.addEventListener("playing", playing);
    3736
    3837    shouldBeNull("document.createElement('canvas').getContext('2d').createPattern(video, 'repeat')");
    3938
     39    waitForVideoFrame(video, firstframe);
    4040    video.src = findMediaFile("video", "../../media/content/test");
     41
    4142
    4243    function checkPixels(context, x, y, r, g, b, tolerance)
     
    6465    }
    6566
    66     function loadeddata()
     67    async function firstframe()
    6768    {
    6869        drawImageToCanvasAndCheckPixels();
     
    7071        video.currentTime = 1;
    7172        video.play();
    72     }
    73 
    74     function playing()
    75     {
     73        await waitForVideoFrameUntil(video, 1);
    7674        video.pause();
    7775
  • trunk/LayoutTests/fast/canvas/canvas-createPattern-video-modify.html

    r284439 r294742  
    44    <script src="../../resources/js-test-pre.js"></script>
    55    <script src="../../media/media-file.js"></script>
     6    <script src="../../media/utilities.js"></script>
    67    <script src="../../resources/platform-helper.js"></script>
    78</head>
     
    1213    var buffer;
    1314    var canvas, context;
    14     var modified = false;
    1515    var expectedResults = [
    1616        // Each entry is formatted as [x, y, r, g, b].
     
    2222
    2323    var video = document.createElement("video");
    24     video.addEventListener("loadeddata", loadeddata);
     24
     25    waitForVideoFrame(video, firstframe);
    2526    video.src = findMediaFile("video", "../../media/content/test");
    2627
    27     function loadeddata()
     28    async function firstframe()
    2829    {
    29         if (!modified) {
    30             canvas = document.createElement("canvas");
    31             canvas.width = 2.5 * video.videoWidth;
    32             canvas.height = 2.5 * video.videoHeight;
    33             document.body.appendChild(canvas);
     30        canvas = document.createElement("canvas");
     31        canvas.width = 2.5 * video.videoWidth;
     32        canvas.height = 2.5 * video.videoHeight;
     33        document.body.appendChild(canvas);
    3434
    35             context = canvas.getContext("2d");
    36             context.fillStyle = context.createPattern(video, "repeat");
     35        context = canvas.getContext("2d");
     36        context.fillStyle = context.createPattern(video, "repeat");
    3737
    38             video.src = findMediaFile("video", "../../media/content/counting");
    39             modified = !modified;
    40         } else {
    41             context.fillRect(0, 0, canvas.width, canvas.height);
     38        video.src = findMediaFile("video", "../../media/content/counting");
    4239
    43             expectedResults.forEach(function(element) {
    44                 checkPixels(context, element[0], element[1], element[2], element[3], element[4], videoCanvasPixelComparisonTolerance());
    45             });
     40        await waitForVideoFrame(video);
    4641
    47             finishJSTest();
    48         }
     42        context.fillRect(0, 0, canvas.width, canvas.height);
     43        expectedResults.forEach(function(element) {
     44            checkPixels(context, element[0], element[1], element[2], element[3], element[4], videoCanvasPixelComparisonTolerance());
     45        });
     46
     47        finishJSTest();
    4948    }
    5049
  • trunk/LayoutTests/media/utilities.js

    r291216 r294742  
    55        }, { once: true });
    66    });
    7     if (cb) {
     7    if (cb)
    88        p.then(cb);
    9     }
    109    return p;
    1110}
     
    2221    });
    2322
    24     if (onLoadFunction) {
     23    if (onLoadFunction)
    2524        p.then(onLoadFunction);
    26     }
    2725
    2826    return p;
     
    4341    let buffers = {};
    4442    let fetches = [];
    45     for (var chunk of chunks) {
     43    for (var chunk of chunks)
    4644        fetches.push(fetchWithXHR(prefix + chunk + suffix).then(((c, x) => buffers[c] = x).bind(null, chunk)));
    47     }
    4845
    4946    // Load them in series, as required per spec.
    5047    return Promise.all(fetches).then(() => {
    5148        let rv = Promise.resolve();
    52         for (let chunk of chunks) {
     49        for (let chunk of chunks)
    5350            rv = rv.then(loadSegment.bind(null, sb, buffers[chunk]));
    54         }
    5551        return rv;
    5652    });
     
    5854
    5955const delay = ms => new Promise(res => setTimeout(res, ms));
     56
     57function waitForVideoFrame(video, cb) {
     58    const p = new Promise((resolve) => {
     59        video.requestVideoFrameCallback((now, metadata) => resolve(now, metadata));
     60    });
     61    if (cb)
     62        p.then(cb);
     63    return p;
     64}
     65
     66function waitForVideoFrameUntil(video, time, cb) {
     67    const p = new Promise(resolve => {
     68        const callback = ((now, metadata) => {
     69            if (metadata.mediaTime >= time) {
     70                resolve(now, metadata);
     71                return;
     72            }
     73            video.requestVideoFrameCallback(callback);
     74        });
     75        video.requestVideoFrameCallback(callback);
     76    });
     77    if (cb)
     78        p.then(cb);
     79    return p;
     80}
Note: See TracChangeset for help on using the changeset viewer.