From: Robert Kaiser Date: Thu, 3 Jul 2014 19:32:17 +0000 (+0200) Subject: Merge branch 'master' of linz:/srv/git/lantea X-Git-Tag: producution~28 X-Git-Url: https://git-public.kairo.at/?p=lantea.git;a=commitdiff_plain;h=64dac5e1fc28b6084393c7e413b271c10cf21cfb;hp=-c Merge branch 'master' of linz:/srv/git/lantea --- 64dac5e1fc28b6084393c7e413b271c10cf21cfb diff --combined js/map.js index 9261776,ec9a05c..ff5112a --- a/js/map.js +++ b/js/map.js @@@ -72,11 -72,19 +72,19 @@@ function initMap() gGLMapCanvas.getContext("experimental-webgl", {depth: false}); } catch(e) {} - // If we don't have a GL context, give up now if (!gMap.gl) { + // If we don't have a GL context, give up now showGLWarningDialog(); gMap.gl = null; } + else { + // GL context can be lost at any time, handle that. + // See http://www.khronos.org/webgl/wiki/HandlingContextLost + gGLMapCanvas.addEventListener("webglcontextlost", + gMap.handleContextLost, false); + gGLMapCanvas.addEventListener("webglcontextrestored", + gMap.handleContextRestored, false); + } gTrackCanvas = document.getElementById("track"); gTrackContext = gTrackCanvas.getContext("2d"); if (!gMap.activeMap) @@@ -121,19 -129,15 +129,19 @@@ function loadPrefs(aEvent) document.getElementById("body").addEventListener("keydown", mapEvHandler, false); + console.log("Events added."); document.getElementById("copyright").innerHTML = gMapStyles[gMap.activeMap].copyright; + console.log("Init loading tile..."); gLoadingTile = new Image(); - gLoadingTile.src = "style/loading.png"; gLoadingTile.onload = function() { + console.log("Loading tile loaded."); var throwEv = new CustomEvent("prefload-done"); gAction.dispatchEvent(throwEv); }; + console.log("Set loading tile..."); + gLoadingTile.src = "style/loading.png"; } } else { @@@ -248,14 -252,12 +256,14 @@@ var gMap = initGL: function() { // When called from the event listener, the "this" reference doesn't work, so use the object name. + console.log("Initializing WebGL..."); if (gMap.gl) { gMap.gl.viewport(0, 0, gMap.gl.drawingBufferWidth, gMap.gl.drawingBufferHeight); gMap.gl.clearColor(0.0, 0.0, 0.0, 0.5); // Set clear color to black, fully opaque. gMap.gl.clear(gMap.gl.COLOR_BUFFER_BIT|gMap.gl.DEPTH_BUFFER_BIT); // Clear the color. // Create and initialize the shaders. + console.log("Create and compile shaders..."); var vertShader = gMap.gl.createShader(gMap.gl.VERTEX_SHADER); var fragShader = gMap.gl.createShader(gMap.gl.FRAGMENT_SHADER); gMap.gl.shaderSource(vertShader, gMap.getVertShaderSource()); @@@ -275,7 -277,6 +283,7 @@@ return null; } + console.log("Create and link shader program..."); gMap.glShaderProgram = gMap.gl.createProgram(); gMap.gl.attachShader(gMap.glShaderProgram, vertShader); gMap.gl.attachShader(gMap.glShaderProgram, fragShader); @@@ -290,7 -291,6 +298,7 @@@ gMap.glTextureCoordAttr = gMap.gl.getAttribLocation(gMap.glShaderProgram, "aTextureCoord"); gMap.glResolutionAttr = gMap.gl.getUniformLocation(gMap.glShaderProgram, "uResolution"); + console.log("Set up vertex buffer..."); var tileVerticesBuffer = gMap.gl.createBuffer(); gMap.gl.bindBuffer(gMap.gl.ARRAY_BUFFER, tileVerticesBuffer); // The vertices are the coordinates of the corner points of the square. @@@ -311,7 -311,6 +319,7 @@@ gMap.gl.uniform2f(gMap.glResolutionAttr, gGLMapCanvas.width, gGLMapCanvas.height); // Create a buffer for the position of the rectangle corners. + console.log("Set up coord buffer..."); var mapVerticesTextureCoordBuffer = gMap.gl.createBuffer(); gMap.gl.bindBuffer(gMap.gl.ARRAY_BUFFER, mapVerticesTextureCoordBuffer); gMap.gl.enableVertexAttribArray(gMap.glVertexPositionAttr); @@@ -321,8 -320,13 +329,13 @@@ gMap.glTxCleanIntervalID = window.setInterval(gMap.cleanTextures, 30 * 1000); } - var throwEv = new CustomEvent("mapinit-done"); - gAction.dispatchEvent(throwEv); + if (!gAppInitDone) { + // We may be called when context was lost and destroyed, + // only send event when we are in app startup + // (gAppInitDone is set to true right after we return this event). + var throwEv = new CustomEvent("mapinit-done"); + gAction.dispatchEvent(throwEv); + } }, draw: function() { @@@ -478,8 -482,8 +491,8 @@@ y: Math.ceil((gMap.pos.y + gMap.baseDim.ht / 2) / gMap.baseDim.tsize) + 1, z: gMap.pos.z}); console.log("In range: " + tMin.x + "," + tMin.y + "," + tMin.z + " - " + tMax.x + "," + tMax.y + "," + tMax.z); - for (aTileKey in gMap.glTextures) { - var keyMatches = aTileKey.match(/([^:]+)::(\d+),(\d+),(\d+)/); + for (var tileKey in gMap.glTextures) { + var keyMatches = tileKey.match(/([^:]+)::(\d+),(\d+),(\d+)/); if (keyMatches && keyMatches[1] != "loading") { var txData = { style: keyMatches[1], @@@ -506,15 -510,27 +519,27 @@@ } if (delTx) { // Delete texture from GL and from the array we are holding. - gMap.gl.deleteTexture(gMap.glTextures[aTileKey]); - delete gMap.glTextures[aTileKey]; + gMap.gl.deleteTexture(gMap.glTextures[tileKey]); + delete gMap.glTextures[tileKey]; } } } console.log("Cleaning complete, " + Object.keys(gMap.glTextures).length + " textures left)"); - //clearInterval(gMap.glTxCleanIntervalID); } }, + + handleContextLost: function(event) { + event.preventDefault(); + // GL context is gone, let's reset everything that depends on it. + clearInterval(gMap.glTxCleanIntervalID); + gMap.glTextures = {}; + }, + + handleContextRestored: function(event) { + // When GL context is back, init GL again and draw. + gMap.initGL(); + gMap.draw(); + }, } // Using scale(x, y) together with drawing old data on scaled canvas would be an improvement for zooming.