diff options
Diffstat (limited to 'image/test/mochitest/test_discardFinishedAnimatedImage.html')
-rw-r--r-- | image/test/mochitest/test_discardFinishedAnimatedImage.html | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/image/test/mochitest/test_discardFinishedAnimatedImage.html b/image/test/mochitest/test_discardFinishedAnimatedImage.html new file mode 100644 index 0000000000..190cb1d1a0 --- /dev/null +++ b/image/test/mochitest/test_discardFinishedAnimatedImage.html @@ -0,0 +1,144 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that img.decode works on finished, discarded animated images</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="text/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1629490">Mozilla Bug 1629490</a> +<div id="container"> + <img id="finitepng" src="finite-apng.png"> +</div> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +window.onload = runTest; + +let discardCallback = undefined; +let frameUpdateCallback = undefined; + +async function runTest() { + const kUsingWebRender = SpecialPowers.DOMWindowUtils.layerManagerType.startsWith("WebRender"); + + let img = document.getElementById("finitepng"); + + await img.decode(); + + while (!isItGreen(img)) { + // We hit an optimized path in WebRender that doesn't cause a repaint on the + // main thread and doesn't seem to send MozAfterPaints. + // + // https://searchfox.org/mozilla-central/rev/b7f3977978922d44c7d92ae01c0d4cc2baca7bc2/layout/style/ImageLoader.cpp#553 + await new Promise(resolve => { + if (kUsingWebRender) { + requestAnimationFrame(() => { + requestAnimationFrame(resolve); + }); + } else { + window.addEventListener("MozAfterPaint", resolve, { once: true }); + } + }); + } + + addCallbacks(img); + + let iterationsLeft = 26; + while (iterationsLeft > 0) { + + let discardPromise = new Promise(resolve => { + discardCallback = resolve; + }); + + document.getElementById("container").style.display = "none"; + document.documentElement.offsetLeft; // force that style to take effect + requestDiscard(img); + + await new Promise(resolve => {requestAnimationFrame(() => { requestAnimationFrame(resolve); }); }); + + await discardPromise; + await new Promise(resolve => {requestAnimationFrame(() => { requestAnimationFrame(resolve); }); }); + + let waitForFrameUpdate = new Promise(resolve => { + frameUpdateCallback = resolve; + }); + + document.getElementById("container").style.display = ""; + document.documentElement.offsetLeft; // force that style to take effect + + await img.decode(); + + await new Promise(resolve => requestAnimationFrame(resolve)); + + await waitForFrameUpdate; + + ok(isItGreen(img), "should be green"); + + iterationsLeft--; + await new Promise(resolve => {requestAnimationFrame(() => { requestAnimationFrame(resolve); }); }); + + } + + removeObserver(img); + SimpleTest.finish(); +} + +function isItGreen(img) { + let rect = img.getBoundingClientRect(); + let r = {left: rect.left + 5, top: rect.top + 5, width: 5, height: 5}; + let c = SpecialPowers.snapshotWindowWithOptions(window, r); + let d = c.getContext('2d').getImageData(0,0,5,5).data; + let isGreen = true; + for (let i = 0; i < 5*5; i++) { + if (d[4*i] != 0 || d[4*i + 1] != 128 || d[4*i + 2] != 0 || d[4*i + 3] != 255) { + isGreen = false; + } + } + return isGreen; +} + + +let scriptedObserver = undefined; +let imgLoadingContent = undefined; +function addCallbacks(anImage) { + var observer = new ImageDecoderObserverStub(); + observer.discard = function () { + if (discardCallback != undefined) { + let localDiscardCallback = discardCallback; + discardCallback = undefined; + setTimeout(localDiscardCallback, 0); + } + }; + observer.frameUpdate = function () { + if (frameUpdateCallback != undefined) { + let localFrameUpdateCallback = frameUpdateCallback; + frameUpdateCallback = undefined; + setTimeout(localFrameUpdateCallback, 0); + } + }; + observer = SpecialPowers.wrapCallbackObject(observer); + + scriptedObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"] + .getService(SpecialPowers.Ci.imgITools) + .createScriptedObserver(observer); + + imgLoadingContent = SpecialPowers.wrap(anImage); + imgLoadingContent.addObserver(scriptedObserver); +} + +function removeObserver(anImage) { + imgLoadingContent.removeObserver(scriptedObserver); +} + +function requestDiscard(anImage) { + var request = SpecialPowers.wrap(anImage) + .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST); + setTimeout(() => request.requestDiscard(), 0); +} + +</script> +</body> +</html> |