chromium/third_party/blink/web_tests/fast/canvas/color-space/canvas-drawImage-offscreenCanvas.html

<!DOCTYPE HTML>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script>

function initializeBlankCanvas(canvasColorSpace, canvasPixelFormat)
{
    var testCanvas = document.createElement("canvas");
    testCanvas.width = 4;
    testCanvas.height = 4;
    var testCtx = testCanvas.getContext('2d',
        {colorSpace: canvasColorSpace, pixelFormat:canvasPixelFormat});
    return testCtx;
}

function initializeCanvas(canvasColorSpace, canvasPixelFormat)
{
    var testCanvas = document.createElement("canvas");
    testCanvas.width = 4;
    testCanvas.height = 4;
    var testCtx = testCanvas.getContext('2d',
        {colorSpace: canvasColorSpace, pixelFormat:canvasPixelFormat});
    testCtx.fillStyle = "rgba(155, 27, 27, 1)";
    testCtx.fillRect(0, 0, 2, 2);
    testCtx.fillStyle = "rgba(27, 155, 27, 1)";
    testCtx.fillRect(2, 0, 2, 2);
    testCtx.fillStyle = "rgba(27, 27, 155, 1)";
    testCtx.fillRect(0, 2, 2, 2);
    testCtx.fillStyle = "rgba(27, 27, 27, 1)";
    testCtx.fillRect(2, 2, 2, 2);
    return testCtx;
}

function initializeCanvasTransparent(canvasColorSpace, canvasPixelFormat)
{
    var testCanvas = document.createElement("canvas");
    testCanvas.width = 4;
    testCanvas.height = 4;
    var testCtx = testCanvas.getContext('2d',
        {colorSpace: canvasColorSpace, pixelFormat:canvasPixelFormat});
    testCtx.fillStyle = "rgba(155, 27, 27, 0.5)";
    testCtx.fillRect(0, 0, 2, 2);
    testCtx.fillStyle = "rgba(27, 155, 27, 0.5)";
    testCtx.fillRect(2, 0, 2, 2);
    testCtx.fillStyle = "rgba(27, 27, 155, 0.5)";
    testCtx.fillRect(0, 2, 2, 2);
    testCtx.fillStyle = "rgba(27, 27, 27, 0.5)";
    testCtx.fillRect(2, 2, 2, 2);
    return testCtx;
}


function initializeOffscreenCanvas(canvasColorSpace, canvasPixelFormat)
{
    var canvas = document.createElement("canvas");
    canvas.width = 4;
    canvas.height = 4;
    var offscreen = canvas.transferControlToOffscreen();
    var ctx = offscreen.getContext('2d',
        {colorSpace: canvasColorSpace, pixelFormat:canvasPixelFormat});
    ctx.fillStyle = "rgba(155, 27, 27, 1)";
    ctx.fillRect(0, 0, 2, 2);
    ctx.fillStyle = "rgba(27, 155, 27, 1)";
    ctx.fillRect(2, 0, 2, 2);
    ctx.fillStyle = "rgba(27, 27, 155, 1)";
    ctx.fillRect(0, 2, 2, 2);
    ctx.fillStyle = "rgba(27, 27, 27, 1)";
    ctx.fillRect(2, 2, 2, 2);
    return offscreen;
}

function initializeOffscreenCanvasTransparent(canvasColorSpace, canvasPixelFormat)
{
    var canvas = document.createElement("canvas");
    canvas.width = 4;
    canvas.height = 4;
    var offscreen = canvas.transferControlToOffscreen();
    var ctx = offscreen.getContext('2d',
        {colorSpace: canvasColorSpace, pixelFormat:canvasPixelFormat});
    ctx.fillStyle = "rgba(155, 27, 27, 0.5)";
    ctx.fillRect(0, 0, 2, 2);
    ctx.fillStyle = "rgba(27, 155, 27, 0.5)";
    ctx.fillRect(2, 0, 2, 2);
    ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
    ctx.fillRect(0, 2, 2, 2);
    ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
    ctx.fillRect(2, 2, 2, 2);
    return offscreen;
}

function testPixels(testCtx, refCtx, pixelFormat, isTrnasparent, imageSetting)
{
    var actual = testCtx.getImageData(0, 0, 4, 4, imageSetting).data;
    var expected = refCtx.getImageData(0, 0, 4, 4, imageSetting).data;

    var tolerance = 4;
    if (pixelFormat === 'float16')
        tolerance = 0.02;
    if (isTrnasparent)
        tolerance = tolerance * 2;
    assert_array_approx_equals(actual, expected, tolerance);
}


function runDrawOffscreenCanvasTestOpaque(testScenario) {
    var canvas_ctx_opaque = initializeCanvas(
        testScenario.canvasColorSpace, testScenario.canvasPixelFormat);

    var canvas_ctx_blank = initializeBlankCanvas(
        testScenario.canvasColorSpace, testScenario.canvasPixelFormat);
    var offscreen_canvas_opaque = initializeOffscreenCanvas(
        testScenario.imageColorSpace, testScenario.imagePixelFormat);
    canvas_ctx_blank.drawImage(offscreen_canvas_opaque, 0, 0);
    testPixels(canvas_ctx_blank, canvas_ctx_opaque,
               testScenario.canvasPixelFormat, false,
               {colorSpace: testScenario.canvasColorSpace,
                storageFormat: testScenario.imageStorageFormat});
}

function runDrawOffscreenCanvasTestTransparent(testScenario) {
    var canvas_ctx_transparent = initializeCanvasTransparent(
        testScenario.canvasColorSpace, testScenario.canvasPixelFormat);

    var canvas_ctx_blank = initializeBlankCanvas(
        testScenario.canvasColorSpace, testScenario.canvasPixelFormat);
    var offscreen_canvas_transparent = initializeOffscreenCanvasTransparent(
        testScenario.imageColorSpace, testScenario.imagePixelFormat);
    canvas_ctx_blank.drawImage(offscreen_canvas_transparent, 0, 0);
    testPixels(canvas_ctx_blank, canvas_ctx_transparent,
               testScenario.canvasPixelFormat, true,
               {colorSpace: testScenario.canvasColorSpace,
                storageFormat: testScenario.imageStorageFormat});
}

function runAllTests() {
    var canvasColorSpaces = ['srgb', 'display-p3', 'rec2020'];
    var canvasPixelFormats = ['uint8', 'float16'];
    var imageStorageFormat = ['uint8', 'float32']
    var testScenarioSet = [];
    for (var i = 0; i < canvasColorSpaces.length; i++) {
        for (var j = 0; j < canvasPixelFormats.length; j++) {
            var canvas_color_space = canvasColorSpaces[i];
            var canvas_pixel_format = canvasPixelFormats[j];
            for (var k = 0; k < canvasColorSpaces.length; k++) {
                for (var m = 0; m < canvasPixelFormats.length; m++) {
                    var image_host_color_space = canvasColorSpaces[k];
                    var image_host_pixel_format = canvasPixelFormats[m];

                    var testScenario = {};
                    testScenario.canvasColorSpace = canvas_color_space;
                    testScenario.canvasPixelFormat = canvas_pixel_format;
                    testScenario.imageColorSpace = image_host_color_space;
                    testScenario.imagePixelFormat = image_host_pixel_format;
                    testScenario.imageStorageFormat = imageStorageFormat[j];
                    testScenarioSet.push(testScenario);
                }
            }
        }
    }

    for (var i = 0; i < testScenarioSet.length; i++) {
        test(function(t) {
            runDrawOffscreenCanvasTestOpaque(testScenarioSet[i]);
            runDrawOffscreenCanvasTestTransparent(testScenarioSet[i]);
        }, testScenarioToString(testScenarioSet[i]));
    }
}

function testScenarioToString(testScenario) {
    var str = "Test drawing color managed OffscreenCanvas: " +
        "Canvas color params: " +
        testScenario.canvasColorSpace + ", " +
        testScenario.canvasPixelFormat +
        ";  OffscreenCanvas color params: " +
        testScenario.imageColorSpace + ", " +
        testScenario.imagePixelFormat;
    return str;
}

runAllTests();
</script>