1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121

content / test / data / gpu / pixel_offscreenCanvas_webgl_commit_main.html [blame]

<!DOCTYPE HTML>

<html>
<head>
<title>OffscreenCanvas webgl flow on main thread: Two Canvases</title>
<style type="text/css">
.nomargin {
  margin: 0px auto;
}
</style>
<script>
/* This pixel test checks the following:
    1. Whether submission of frames for multiple canvases happen about the same
       time for OffscreenCanvas that are invoked in the same JS task.
    2. Whether overdraw frame in one animation loop is handled well.
    3. Whether the drawn webgl image is position upright.

    Correct end result of this test: The left canvas shows a upright white
    triangle on a green background and the right canvas shows dark-blue fill.
*/

var g_swapsBeforeAck = 15;
var g_asyncCallbackNumber = 2;

function getOffscreenContext(htmlCanvasId) {
  return document.getElementById(htmlCanvasId).transferControlToOffscreen().getContext("webgl");
}

function startTest() {
  var ctx1 = getOffscreenContext("canvas1");
  var ctx2 = getOffscreenContext("canvas2");

  ctx1.clearColor(0, 1, 0, 1);
  ctx1.clear(ctx1.COLOR_BUFFER_BIT);

  requestAnimationFrame(() => {
    ctx2.clearColor(0, 0, 1, 1);
    ctx2.clear(ctx2.COLOR_BUFFER_BIT);
    if (--g_asyncCallbackNumber == 0) waitForFinish();
  });

  function drawTriangle(gl)
  {
    gl.clearColor(0, 1, 0, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);

    var prog = gl.createProgram();
    var vs = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vs, ['attribute vec2 pos;',
        'void main() {',
        '  gl_Position = vec4(pos, 0., 1.);',
        '}'].join('\n'));
    gl.compileShader(vs);
    if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
        throw 'failed to compiled shader';
    }
    gl.attachShader(prog, vs);

    var fs = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fs, ['void main() {',
        '  gl_FragColor = vec4(1.);',
        '}'].join('\n'));
    gl.compileShader(fs);
    if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
        throw 'failed to compiled shader';
    }
    gl.attachShader(prog, fs);

    gl.linkProgram(prog);
    if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
        throw "Could not link the shader program!";
    }
    gl.useProgram(prog);

    gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-.5,0, 0,.5, .5,0]), gl.STATIC_DRAW);
    var attr = gl.getAttribLocation(prog, 'pos');
    gl.enableVertexAttribArray(attr);
    gl.vertexAttribPointer(attr, 2, gl.FLOAT, false, 0, 0);

    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3);
  }

  // Do something complex to ctx2.
  drawTriangle(ctx2);
  // This ctx2 must be resolved at about the same time as the first
  // ctx1 above because they are in the same JS task, no matter how
  // complex the drawing operation is.
  requestAnimationFrame(() => {
    drawTriangle(ctx1);

    if (--g_asyncCallbackNumber == 0) waitForFinish();
  });

}

function main() {
  startTest();
}

function waitForFinish()
{
  if (g_swapsBeforeAck == 0) {
    domAutomationController.send("SUCCESS");
  } else {
    g_swapsBeforeAck--;
    document.getElementById('container').style.zIndex = g_swapsBeforeAck + 1;
    requestAnimationFrame(waitForFinish);
  }
}
</script>
</head>
<body onload="main()">
<div style="position:relative; width:360px; height:200px; background-color:white">
</div>
<div id="container" style="position:absolute; top:0px; left:0px">
<canvas id="canvas1" width="180" height="200" class="nomargin"></canvas>
<canvas id="canvas2" width="180" height="200" class="nomargin"></canvas>
</div>
</body>
</html>