So, is there one question, why do you care about the order? getContext returns null on failure, so if you want to find out if this failed, you are done. webglcontextcreationerror Only the point is for you to understand the reason why this failed, since getContext has no way to do this. That way, you can structure your code in such a way that it doesnβt matter if it will synchronize or asynchronously
var canvas = document.createElement('canvas') function doSomethingWithStatusMessage(e) { log("context creation error: "+ e.statusMessage); } canvas.addEventListener("webglcontextcreationerror", doSomethingWithStatusMessage); log("2d: " + canvas.getContext('2d')); log("webgl: " + canvas.getContext("webgl")); log("after creation"); function log(msg, color) { var div = document.createElement("pre"); div.appendChild(document.createTextNode(msg)); document.body.appendChild(div); }
doSomethingWithStatus message can do anything. Suppose a dialog is displayed based on getContext .
if (!canvas.getContext("webgl")) { g_dialog = new Dialog("can't create context", g_reason); }
Then you might have a code like
var g_reason = "unknown"; var g_dialog; function doSomethingWithStatusMessage(e) { if (g_dialog) { g_dialog.updateReason(e.statusMessage); } else { g_reason = g.statusMessage; } } function Dialog(msg, reason) { var div = document.createElement("div"); div.appendChild(document.createTextNode(msg)); var reasonNode = document.createTextNode(""); div.appendChild(reasonNode); updateReason(reason); function updateReason(reason) { reasonNode.nodeValue = reason; } this.updateReason = updateReason; }
var g_reason = "unknown"; var g_dialog; function doSomethingWithStatusMessage(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) { new Dialog("could not create WebGL context: ", g_reason); } function log(msg, color) { var div = document.createElement("pre"); div.appendChild(document.createTextNode(msg)); document.body.appendChild(div); } function Dialog(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); function updateReason(reason) { reasonNode.nodeValue = reason; } function close() { 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 want to report an error to the server, for example, just run it a few seconds later to allow the asynchronous message to arrive.
if (!canvas.getContext("webgl")) {
The rest will be easy
var g_reason = "unknown"; function doSomethingWithStatusMessage(e) { g_reason = e.statusMessage; } function uploadReason() { .. XHR g_reason to server .. }
Note: I will create an error in this part of the specification so that you can follow if you want.
source share