Skip to content

Commit

Permalink
Merge pull request mapbox#1 from CartoDB/webgl-layer2
Browse files Browse the repository at this point in the history
Using `setCustomWebGLDrawCallback` for custom-webgl layers
  • Loading branch information
David M authored Feb 8, 2018
2 parents 470c7ec + 0822443 commit 398591a
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 21 deletions.
25 changes: 15 additions & 10 deletions debug/custom_webgl_layer.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<title>Mapbox GL JS debug page</title>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel='stylesheet' href='/dist/mapbox-gl.css' />
<style>
body { margin: 0; padding: 0; }
Expand All @@ -18,7 +18,7 @@
<script src='/debug/access_token_generated.js'></script>
<script>

var map = window.map = new mapboxgl.Map({
var map = new mapboxgl.Map({
container: 'map',
zoom: 3,
center: [-77.01866, 38.888],
Expand All @@ -29,18 +29,23 @@
map.addControl(new mapboxgl.NavigationControl());
map.addControl(new mapboxgl.GeolocateControl());

window.callback = (gl)=>{
gl.clearColor(0, 0.5, 0, 1);
map.setCustomWebGLDrawCallback('externallayer0', (gl, invalidate) => {
gl.clearColor(0, 1, 0, 0.1);
gl.clear(gl.COLOR_BUFFER_BIT);
}
});
map.setCustomWebGLDrawCallback('externallayer1', (gl, invalidate) => {
gl.clearColor(1, 1, 1, 0.1);
gl.clear(gl.COLOR_BUFFER_BIT);
});

map.on('load', function() {
map.addLayer({
"id": "externalwebgl",
"type": "custom-webgl",
"layout": {
"callback": "callback",
}
"id": "externallayer0",
"type": "custom-webgl"
}, "marine-label-sm-ln");
map.addLayer({
"id": "externallayer1",
"type": "custom-webgl"
}, "marine-label-sm-ln");
});

Expand Down
25 changes: 14 additions & 11 deletions src/render/draw_custom_webgl.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
// @flow

const pattern = require('./pattern');
const StencilMode = require('../gl/stencil_mode');
const DepthMode = require('../gl/depth_mode');

import type Painter from './painter';
import type SourceCache from '../source/source_cache';
import type WebGLLayer from '../style/style_layer/custom_webgl_layer';
Expand All @@ -20,15 +16,22 @@ function drawCustomWebGL(painter: Painter, sourceCache: SourceCache, layer: WebG
For example, if the external renderer receives some data from an AJAX request,
it can upload data to the WebGL context asynchronously (regarding Mapbox GL rendering,
it would synchronous respect WebGL) and call invalidateCurrentWebGLState afterwards
to ensure that in the next Mapbox GL rendering pass the WebGL tracked is not stale (which would produce rendering artifacts).
to ensure that in the next Mapbox GL rendering pass the WebGL tracked is not stale (which would produce rendering artifacts).
*/
const invalidateCurrentWebGLState = () => {
const names = Object.keys(painter.context).filter(name => painter.context[name].current !== undefined);
names.map((name, index) => painter.context[name].current = {});
Object.keys(this.context).forEach((key) => {
if (this.context[key].current !== undefined) {
this.context[key].current = {};
}
});
};
const callback = window[layer.layout._values.callback];
if (callback) {
callback(painter.context.gl, invalidateCurrentWebGLState);
invalidateCurrentWebGLState();

const drawCallbacks = painter.customWebGLDrawCallbacks;
if (drawCallbacks.hasOwnProperty(layer.id)) {
const callback = drawCallbacks[layer.id];
if (callback) {
callback(painter.context.gl, invalidateCurrentWebGLState);
invalidateCurrentWebGLState();
}
}
}
12 changes: 12 additions & 0 deletions src/render/painter.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class Painter {
this.context = new Context(gl);
this.transform = transform;
this._tileTextures = {};
this.customWebGLDrawCallbacks = {};

this.setup();

Expand Down Expand Up @@ -471,6 +472,17 @@ class Painter {

return nextProgram;
}

/**
* Store a DrawCallback used by a `custom-webgl` layer.
* This callback will be called by the function renderLayer -> drawWebGL.
*
* @param {string} id The ID of the `custom-webgl` layer.
* @param {Function} callback The callback to be stored.
*/
setCustomWebGLDrawCallback(id: string, callback: Function) {
this.customWebGLDrawCallbacks[id] = callback;
}
}

module.exports = Painter;
10 changes: 10 additions & 0 deletions src/ui/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,16 @@ class Map extends Camera {
}
}

/**
* Store a DrawCallback used by a `custom-webgl` layer in the `painter`.
*
* @param {string} id The ID of the `custom-webgl` layer.
* @param {Function} callback The callback to be stored.
*/
setCustomWebGLDrawCallback(id: string, callback: Function) {
this.painter.setCustomWebGLDrawCallback(id, callback);
}

/**
* Gets and sets a Boolean indicating whether the map will render an outline
* around each tile. These tile boundaries are useful for debugging.
Expand Down

0 comments on commit 398591a

Please sign in to comment.