We are attempting to integrate the OpenLayer library's vector tiles with webGL. The following warning appeared on the console when the data was loading and the marker was being drawn on the map.
`App:1 [.WebGL-0000371C047E9C00] GL_INVALID_OPERATION: Error: 0x00000502, in ....\third_party\angle\src\libANGLE\renderer\d3d\VertexDataManager.cpp, reserveSpaceForAttrib:520. Internal error: 0x00000502: Vertex buffer is not big enough for the draw call.
Debugging steps:
- Need to use webgl of openlayers library following this https://openlayers.org/workshop/en/webgl/points.html guide. (We didn't used clustering)
- We tried to render around 50000 markers at a time on the map.
- On Chrome, open the developer console.
- While the Ajax call finished we got the above mentioned warning.
- It is clearly stated that the error thrown by the ANGEL library which is used by Chrome to translates OpenGL ES calls to the underlying graphics API of the operating system.
- When we disable hardware acceleration (Settings -> Use hardware acceleration when available) (get the idea from this https://stackoverflow.com/a/71854516/8304287 comment), the warning disappears, but performance degrades significantly.
Sample sudo code (fetched from codebase)
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM
}),
],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([-97, 38.]),
maxZoom: 19,
minzoom: 2,
zoom: 4,
}),
});
map.on('postrender', function () {
setStartTime();
});
function setStartTime() {
startTime = new Date();
}
var vectorSourceNew = new ol.source.Vector({
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({ maxZoom: 20 })),
loader: function (extent, resolution, projection) {
var center = ol.proj.transform(ol.extent.getCenter(extent), 'EPSG:3857', 'EPSG:4326');
zoom = parseInt(map.getView().getZoom());
var tile = formatTile(center[0], center[1], zoom);
cntTriggerBackendNew++;
var url = `${baseUrl}/${tile[2]}/${tile[0]}/${tile[1]}?key=${key}&fleetType=${fleetTypes}&uId=${uId}`;
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
var onError = function () {
vectorSourceNew.removeLoadedExtent(extent);
}
xhr.onerror = onError;
xhr.onload = function () {
cntTriggerBackendNew--;
if (xhr.status == 200) {
const features = vectorSourceNew.getFormat().readFeatures(xhr.responseText);
vectorSourceNew.addFeatures(features);
} else {
onError();
}
}
xhr.send();
},
format: new ol.format.GeoJSON(),
wrapX: true
});
var vectorSourceOld = new ol.source.Vector({
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({ maxZoom: 20 })),
loader: function (extent, resolution, projection) {
var center = ol.proj.transform(ol.extent.getCenter(extent), 'EPSG:3857', 'EPSG:4326');
zoom = parseInt(map.getView().getZoom());
var tile = formatTile(center[0], center[1], zoom);
cntTriggerBackendOld++;
var url = `${baseUrl}/${tile[2]}/${tile[0]}/${tile[1]}?key=${key}&fleetType=${fleetTypes}&uId=${uId}`;
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
var onError = function () {
vectorSourceOld.removeLoadedExtent(extent);
}
xhr.onerror = onError;
xhr.onload = function () {
cntTriggerBackendOld--;
if (xhr.status == 200) {
const features = vectorSourceOld.getFormat().readFeatures(xhr.responseText);
vectorSourceOld.addFeatures(features);
} else {
onError();
}
}
xhr.send();
},
format: new ol.format.GeoJSON(),
wrapX: true
});
var vectorLayerNew = new ol.layer.WebGLPoints({
source: vectorSourceNew,
style: circleStyle
});
var vectorLayerOld = new ol.layer.WebGLPoints({
source: vectorSourceOld,
style: circleStyle
});
map.addLayer(vectorLayerNew);
function addNewLayer(layer) {
if (popup) {
map.removeOverlay(popup);
}
map.addLayer(layer);
}
function removeOldLayer(layer) {
map.removeLayer(layer);
}
function changeLayer() {
setTimeout(function () {
setStartTime();
if (toggle && cntTriggerBackendNew == 0) {
removeOldLayer(vectorLayerOld);
vectorLayerNew.visible = true;
toggle = false;
}
else if (!toggle && cntTriggerBackendOld == 0) {
removeOldLayer(vectorLayerNew);
vectorLayerOld.visible = true;
toggle = true;
}
else {
changeLayer();
}
}, 5000);
}
function updateVesselsData() {
setTimeout(function () {
var currentZoom = map.getView().getZoom();
endTime = new Date();
if (currentZoom >= 8 && (endTime - startTime) >= 240000) { // 240000 is equal to 4 minutes
setStartTime();
if (toggle) {
vectorLayerNew.getSource().refresh();
vectorLayerNew.visible = false;
addNewLayer(vectorLayerNew);
}
else {
vectorLayerOld.getSource().refresh();
vectorLayerOld.visible = false;
addNewLayer(vectorLayerOld);
}
changeLayer();
}
updateVesselsData();
}, 10000); // 10000 is equal to 10 seconds
}
updateVesselsData();
map.on('moveend', function () {
var currentZoom = map.getView().getZoom();
currentZoom = parseInt(currentZoom);
if (initialZoom != currentZoom) {
initialZoom = currentZoom;
vectorLayerNew.getSource().refresh();
}
});
function formatTile(lng, lat, zoom) {
var xTile = Math.floor((lng + 180) / 360 * Math.pow(2, zoom));
var yTile = Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom));
return wrapTile([xTile, yTile, zoom]);
}
function wrapTile(tile) {
var tx = tile[0]
var ty = tile[1]
var zoom = tile[2]
var maxTile = Math.pow(2, zoom)
tx = tx % maxTile
if (tx < 0) tx = tx + maxTile
return [tx, ty, zoom]
}
We only have this problem right now with Google Chrome. Can someone offer any solutions to repair it?