<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="./resources/webgl-test.js"></script>
<script src="./resources/webgl-test-utils-full.js"></script>
</head>
<body>
<script>
var wtu = WebGLTestUtils;
var canvas;
var gl;
var WEBGL_lose_context;
var new_WEBGL_lose_context;
var allowRestore;
var contextLostEventFired;
var contextRestoredEventFired;
var OES_vertex_array_object;
var old_OES_vertex_array_object;
var OES_texture_float;
var newExtension;

async_test(function(t) {
    if (!setupTest()) {
        assert_true(false, 'Cannot initialize test');
        t.done();
    }

    canvas.addEventListener("webglcontextlost", t.step_func(function(e) {
        testLostContext(e);
        // restore the context after this event has exited.
        setTimeout(function() {
            // we didn't call prevent default so we should not be able to restore the context
            compareGLError(gl.INVALID_OPERATION, "WEBGL_lose_context.restoreContext()");
            testLosingAndRestoringContext(t);
        }, 0);
    }));
    canvas.addEventListener("webglcontextrestored", testShouldNotRestoreContext);
    allowRestore = false;
    contextLostEventFired = false;
    contextRestoredEventFired = false;

    testOriginalContext();
    WEBGL_lose_context.loseContext();
    // The context should be lost immediately.
    assert_true(gl.isContextLost());
    assert_equals(gl.getError(), gl.CONTEXT_LOST_WEBGL);
    assert_equals(gl.getError(), gl.NO_ERROR);
    // gl methods should be no-ops
    compareGLError(gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
    // but the event should not have been fired.
    assert_false(contextLostEventFired);
}, 'Test WebGL context restoration with OffscreenCanvas');

function compareGLError(glError, evalStr)
{
    var exception;
    try {
        eval(evalStr);
    } catch (e) {
        exception = e;
    }
    if (exception) {
        assert_true(false, evalStr + " threw exception " + exception);
    } else {
        assert_equals(gl.getError(), glError);
    }
}

function setupTest()
{
    canvas = new OffscreenCanvas(10, 10);
    gl = canvas.getContext('webgl');
    WEBGL_lose_context = getExtensionAndAddProperty(gl, "WEBGL_lose_context");
    if (!WEBGL_lose_context)
        return false;

    // Try to get a few extensions
    OES_vertex_array_object = getExtensionAndAddProperty(gl, "OES_vertex_array_object");
    OES_texture_float = getExtensionAndAddProperty(gl, "OES_texture_float");

    return true;
}

function getExtensionAndAddProperty(gl, name) {
  var ext = wtu.getExtensionWithKnownPrefixes(gl, name);
  if (ext) {
    ext.webglTestProperty = true;
  }
  return ext;
}

function reGetExtensionAndTestForProperty(gl, name, expectProperty) {
  newExtension = wtu.getExtensionWithKnownPrefixes(gl, name);
  // NOTE: while getting a extension after context lost/restored is allowed to fail
  // for the purpose the conformance tests it is not.
  //
  // Hypothetically the user can switch GPUs live. For example on Windows, install 2 GPUs,
  // then in the control panen enable 1, disable the others and visa versa. Since the GPUs
  // have different capabilities one or the other may not support a particlar extension.
  //
  // But, for the purpose of the conformance tests the context is expected to restore
  // on the same GPU and therefore the extensions that succeeded previously should
  // succeed on restore.
  assert_true(newExtension != null);
  if (expectProperty) {
    assert_true(newExtension.webglTestProperty === true);
  } else {
    assert_true(newExtension.webglTestProperty === undefined);
  }
  return newExtension;
}

function testLosingAndRestoringContext(t)
{
    if (!setupTest()) {
        assert_true(false, 'Cannot initialize test');
        t.done();
    }

    canvas.addEventListener("webglcontextlost", function(e) {
      testLostContext(e);
      // restore the context after this event has exited.
      setTimeout(function() {
        compareGLError(gl.NO_ERROR, "WEBGL_lose_context.restoreContext()");
        // The context should still be lost. It will not get restored until the
        // webglrestorecontext event is fired.
        assert_true(gl.isContextLost());
        assert_equals(gl.getError(), gl.NO_ERROR);
        // gl methods should still be no-ops
        compareGLError(gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
      }, 0);
    });
    canvas.addEventListener("webglcontextrestored", t.step_func_done(function() {
      testRestoredContext();
    }));
    allowRestore = true;
    contextLostEventFired = false;
    contextRestoredEventFired = false;

    testOriginalContext();
    WEBGL_lose_context.loseContext();
    // The context should be lost immediately.
    assert_true(gl.isContextLost());
    assert_equals(gl.getError(), gl.CONTEXT_LOST_WEBGL);
    assert_equals(gl.getError(), gl.NO_ERROR);
    // gl methods should be no-ops
    compareGLError(gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
    // but the event should not have been fired.
    assert_false(contextLostEventFired);
}

function testOriginalContext()
{
    assert_false(gl.isContextLost());
    assert_equals(gl.getError(), gl.NO_ERROR);
}

function testLostContext(e)
{
    assert_false(contextLostEventFired);
    contextLostEventFired = true;
    assert_true(gl.isContextLost());
    assert_equals(gl.getError(), gl.NO_ERROR);
    if (allowRestore)
      e.preventDefault();
}

function testShouldNotRestoreContext(e)
{
    assert_true(false, "Should not restore the context unless preventDefault is called on the context lost event");
}

function testOESTextureFloat() {
  if (OES_texture_float) {
    // Extension must still be lost.
    var tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex);
    compareGLError(gl.INVALID_ENUM, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
    // Try re-enabling extension
    OES_texture_float = reGetExtensionAndTestForProperty(gl, "OES_texture_float", false);
    compareGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
  }
}

function testOESVertexArrayObject() {
  if (OES_vertex_array_object) {
    // Extension must still be lost.
    assert_equals(OES_vertex_array_object.createVertexArrayOES(), null);
    // Try re-enabling extension

    old_OES_vertex_array_object = OES_vertex_array_object;
    OES_vertex_array_object = reGetExtensionAndTestForProperty(gl, "OES_vertex_array_object", false);
    assert_true(OES_vertex_array_object.createVertexArrayOES() != null);
    assert_true(old_OES_vertex_array_object.createVertexArrayOES() == null);
  }
}

function testExtensions() {
  testOESTextureFloat();
  testOESVertexArrayObject();
  // Only the WEBGL_lose_context extension should be the same object after context lost.
  new_WEBGL_lose_context = reGetExtensionAndTestForProperty(gl, "WEBGL_lose_context", true);
}

function testRestoredContext()
{
    assert_false(contextRestoredEventFired);
    contextRestoredEventFired = true;
    assert_false(gl.isContextLost());
    assert_equals(gl.getError(), gl.NO_ERROR);
    testExtensions();
}
</script>
</body>
</html>
