Skip to content Skip to sidebar Skip to footer

Webglcontextcreationerror Event: Is It Triggered Synchronously?

Is the webglcontextcreationerror event triggered synchronously or asynchronously? For example does canvas.addEventListener('webglcontextcreationerror', function() { console.log('

Solution 1:

So one question is why do you care the order? getContext returns null on failure so if you want to know if it failed then you're done. webglcontextcreationerror's only point is for you to get the reason why it failed since getContext has no way to do that. So, you could structure your code such that it doesn't matter whether it's sync or async

var canvas = document.createElement('canvas')

functiondoSomethingWithStatusMessage(e) {
  log("context creation error: "+ e.statusMessage);
}

canvas.addEventListener("webglcontextcreationerror", doSomethingWithStatusMessage);

log("2d: " + canvas.getContext('2d'));
log("webgl: " + canvas.getContext("webgl"));
log("after creation");

functionlog(msg, color) {
  var div = document.createElement("pre");
  div.appendChild(document.createTextNode(msg));
  document.body.appendChild(div);
}

doSomethingWithStatus message could do anything you want. Assume based on getContext you display a dialog.

if (!canvas.getContext("webgl")) {
   g_dialog = newDialog("can't create context", g_reason);
}

Then you might have code like

var g_reason = "unknown";
var g_dialog;

functiondoSomethingWithStatusMessage(e) {
  if (g_dialog) {
    g_dialog.updateReason(e.statusMessage);
  } else {
    g_reason = g.statusMessage;
  }
}

functionDialog(msg, reason) {
  var div = document.createElement("div");
  div.appendChild(document.createTextNode(msg));
  var reasonNode = document.createTextNode("");
  div.appendChild(reasonNode);
  updateReason(reason);      

  functionupdateReason(reason) {
    reasonNode.nodeValue = reason;
  }
  this.updateReason = updateReason;
}

var g_reason = "unknown";
var g_dialog;

functiondoSomethingWithStatusMessage(e) {
  if (g_dialog) {
    g_dialog.updateReason(e.statusMessage);
  } else {
    g_reason = e.statusMessage;
  }
}

var canvas = document.createElement('canvas')

canvas.addEventListener("webglcontextcreationerror", doSomethingWithStatusMessage);

log("2d: " + canvas.getContext('2d'));
var gl = canvas.getContext("webgl");
log("webgl: " + gl);
log("after creation");

if (!gl) {
  newDialog("could not create WebGL context: ", g_reason);
}

functionlog(msg, color) {
  var div = document.createElement("pre");
  div.appendChild(document.createTextNode(msg));
  document.body.appendChild(div);
}

functionDialog(msg, reason) {
  var outer = document.createElement("div");
  outer.className = "dialog";
  var div = document.createElement("div");
  div.appendChild(document.createTextNode(msg));
  var reasonNode = document.createTextNode("");
  div.appendChild(reasonNode);
  outer.appendChild(div);
  updateReason(reason);      
  document.body.appendChild(outer);
  outer.addEventListener('click', close);

  functionupdateReason(reason) {
    reasonNode.nodeValue = reason;
  }
  
  functionclose() {
    document.body.removeChild(outer);
    outer.removeEventListener('click', close);
  }
  
  this.close = close;
  this.updateReason = updateReason;
}
.dialog {
  position: absolute;
  z-index: 2;
  background: rgba(0,0,0,0.8);
  color: red;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  
  display: flex;
  justify-content: center;
  align-content: center;
  align-items: center;
}

If instead you wanted to report the error to a server for example then just trigger it a few moments later to give the async message a chance to arrive.

if (!canvas.getContext("webgl")) {
   // give a moment for the async message to arrivesetTimeout(uploadReason, 1000);
}

The rest would just be

var g_reason = "unknown";

functiondoSomethingWithStatusMessage(e) {
  g_reason = e.statusMessage;
}

functionuploadReason() {
  .. XHR g_reason to server ..
}

Note: I file a bug on this part of the spec so you can follow up if you'd like.

Solution 2:

NB : This is not a per spec answer, but only from a single UA test, so it may be wrong, or at least true only to this UA, a.k.a Chrome.


In chrome, to force the error event, you can first request a 2dContext then a webgl one.

This way we can see that this UA does treat the event as an synchronous one. I just learn about these right-now...

var canvas = document.createElement('canvas')

canvas.addEventListener("webglcontextcreationerror", function() {
  snippet.log("Error");
});

canvas.getContext('2d')
canvas.getContext("webgl");

snippet.log("After creation");
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --><scriptsrc="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Post a Comment for "Webglcontextcreationerror Event: Is It Triggered Synchronously?"