Skip to content

Commit 35af715

Browse files
authored
Merge pull request #2939 from plotly/gl-context-vs-canvas-wrong-size
Replot when webgl buffer dims don't match canvas dims
2 parents a8dd8dd + 3879a41 commit 35af715

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

src/plot_api/plot_api.js

+23
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ exports.plot = function(gd, data, layout, config) {
199199

200200
// draw framework first so that margin-pushing
201201
// components can position themselves correctly
202+
var drawFrameworkCalls = 0;
202203
function drawFramework() {
203204
var basePlotModules = fullLayout._basePlotModules;
204205

@@ -242,6 +243,28 @@ exports.plot = function(gd, data, layout, config) {
242243
fullLayout._glcanvas
243244
.attr('width', fullLayout.width)
244245
.attr('height', fullLayout.height);
246+
247+
var regl = fullLayout._glcanvas.data()[0].regl;
248+
if(regl) {
249+
// Unfortunately, this can happen when relayouting to large
250+
// width/height on some browsers.
251+
if(fullLayout.width !== regl._gl.drawingBufferWidth ||
252+
fullLayout.height !== regl._gl.drawingBufferHeight
253+
) {
254+
var msg = 'WebGL context buffer and canvas dimensions do not match due to browser/WebGL bug.';
255+
if(drawFrameworkCalls) {
256+
Lib.error(msg);
257+
} else {
258+
Lib.log(msg + ' Clearing graph and plotting again.');
259+
Plots.cleanPlot([], {}, gd._fullData, fullLayout, gd.calcdata);
260+
Plots.supplyDefaults(gd);
261+
fullLayout = gd._fullLayout;
262+
Plots.doCalcdata(gd);
263+
drawFrameworkCalls++;
264+
return drawFramework();
265+
}
266+
}
267+
}
245268
}
246269

247270
return Plots.previousPromises(gd);

test/jasmine/tests/splom_test.js

+53
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,59 @@ describe('Test splom interactions:', function() {
682682
.catch(failTest)
683683
.then(done);
684684
});
685+
686+
it('@gl should clear graph and replot when canvas and WebGL context dimensions do not match', function(done) {
687+
var fig = Lib.extendDeep({}, require('@mocks/splom_iris.json'));
688+
689+
function assertDims(msg, w, h) {
690+
var canvas = gd._fullLayout._glcanvas;
691+
expect(canvas.node().width).toBe(w, msg);
692+
expect(canvas.node().height).toBe(h, msg);
693+
694+
var gl = canvas.data()[0].regl._gl;
695+
expect(gl.drawingBufferWidth).toBe(w, msg);
696+
expect(gl.drawingBufferHeight).toBe(h, msg);
697+
}
698+
699+
var methods = ['cleanPlot', 'supplyDefaults', 'doCalcdata'];
700+
701+
methods.forEach(function(m) { spyOn(Plots, m).and.callThrough(); });
702+
703+
function assetsFnCall(msg, exp) {
704+
methods.forEach(function(m) {
705+
expect(Plots[m]).toHaveBeenCalledTimes(exp[m], msg);
706+
Plots[m].calls.reset();
707+
});
708+
}
709+
710+
spyOn(Lib, 'log');
711+
712+
Plotly.plot(gd, fig).then(function() {
713+
assetsFnCall('base', {
714+
cleanPlot: 1, // called once from inside Plots.supplyDefaults
715+
supplyDefaults: 1,
716+
doCalcdata: 1
717+
});
718+
assertDims('base', 600, 500);
719+
expect(Lib.log).toHaveBeenCalledTimes(0);
720+
721+
spyOn(gd._fullData[0]._module, 'plot').and.callThrough();
722+
723+
return Plotly.relayout(gd, {width: 4810, height: 3656});
724+
})
725+
.then(function() {
726+
assetsFnCall('after', {
727+
cleanPlot: 4, // 3 three from supplyDefaults, once in drawFramework
728+
supplyDefaults: 3, // 1 from relayout, 1 from automargin, 1 in drawFramework
729+
doCalcdata: 1 // once in drawFramework
730+
});
731+
assertDims('after', 4810, 3656);
732+
expect(Lib.log)
733+
.toHaveBeenCalledWith('WebGL context buffer and canvas dimensions do not match due to browser/WebGL bug. Clearing graph and plotting again.');
734+
})
735+
.catch(failTest)
736+
.then(done);
737+
});
685738
});
686739

687740
describe('Test splom hover:', function() {

0 commit comments

Comments
 (0)