<!DOCTYPE html>
<html>
<head>
<script src="./resources/webgl-test-utils-full.js"></script>
<script src="./resources/tex-image-and-sub-image-utils.js"></script>
<script src="../../../resources/js-test.js"></script>
</head>

<script id='myWorker' type='text/worker'>
self.onmessage = function(e) {
    var canvas = new OffscreenCanvas(128, 128);
    var gl = canvas.getContext('webgl');
    gl.clearColor(1.0, 1.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    var image = canvas.transferToImageBitmap();
    self.postMessage({bitmap: image}, [image]);
};
</script>

<script>
window.jsTestIsAsync = true;

var wtu = WebGLTestUtils;
var tiu = TexImageUtils;
var internalFormat = "RGBA";
var pixelFormat = "RGBA";
var pixelType = "UNSIGNED_BYTE";
var blob = new Blob([document.getElementById('myWorker').textContent]);
var worker = new Worker(URL.createObjectURL(blob));
var bitmap;

var canvas = document.createElement("canvas");
canvas.width = 128;
canvas.height = 128;
var ctx = canvas.getContext('bitmaprenderer');

var width = 32;
var height = 32;
var canvas2d = document.createElement("canvas");
canvas2d.width = width;
canvas2d.height = height;
var gl = canvas2d.getContext('webgl');
gl.clearColor(0,0,0,1);
gl.clearDepth(1);
gl.disable(gl.BLEND);

function checkCanvas(buf, width, height)
{
    for (var i = 0; i < width * height; i++) {
        if (buf[i * 4] != 255 || buf[i * 4 + 1] != 255 ||
            buf[i * 4 + 2] != 0 || buf[i * 4 + 3] != 255) {
            testFailed("This pixel should be red, but it is: [" + buf[i * 4] + ", " +
                buf[i * 4 + 1] + ", " + buf[i * 4 + 2] + ", " + buf[i * 4 + 3] + "].");
            finishJSTest();
        }
    }
}

function runTestOnBindingTarget(bindingTarget, program, bitmap)
{
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    // Enable writes to the RGBA channels
    gl.colorMask(1, 1, 1, 0);
    var texture = gl.createTexture();
    // Bind the texture to texture unit 0
    gl.bindTexture(bindingTarget, texture);
    // Set up texture parameters
    gl.texParameteri(bindingTarget, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(bindingTarget, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

    var targets = [gl.TEXTURE_2D];
    // Upload the image into the texture
    for (var tt = 0; tt < targets.length; ++tt) {
        gl.texImage2D(targets[tt], 0, gl[internalFormat], gl[pixelFormat], gl[pixelType], bitmap);
    }
    for (var tt = 0; tt < targets.length; ++tt) {
        // Draw the triangles
        gl.clearColor(0, 0, 0, 1);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        gl.drawArrays(gl.TRIANGLES, 0, 6);

        var buf = new Uint8Array(width * height * 4);
        gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
        checkCanvas(buf, width, height);
    }
}

worker.onmessage = function(msg) {
    bitmap = msg.data.bitmap;
    var program = tiu.setupTexturedQuad(gl, internalFormat);
    runTestOnBindingTarget(gl.TEXTURE_2D, program, bitmap);
    testPassed("This test passed");
    finishJSTest();
}
worker.postMessage("");

</script>
</html>
