diff --git a/draftlogs/6084_change.md b/draftlogs/6084_change.md new file mode 100644 index 00000000000..2172e2e4172 --- /dev/null +++ b/draftlogs/6084_change.md @@ -0,0 +1,2 @@ + - Use the willReadFrequently 2d context creation attribute to optimize readback performance [[#6084](https://github.com/plotly/plotly.js/pull/6084)], + with thanks to @junov for the contribution! diff --git a/src/components/images/draw.js b/src/components/images/draw.js index b08cdebbd09..cd6dfeb698b 100644 --- a/src/components/images/draw.js +++ b/src/components/images/draw.js @@ -89,7 +89,7 @@ module.exports = function draw(gd) { canvas.width = this.width; canvas.height = this.height; - var ctx = canvas.getContext('2d'); + var ctx = canvas.getContext('2d', {willReadFrequently: true}); ctx.drawImage(this, 0, 0); var dataURL = canvas.toDataURL('image/png'); diff --git a/src/plots/gl2d/scene2d.js b/src/plots/gl2d/scene2d.js index 9df5db9618b..d988b9bbe12 100644 --- a/src/plots/gl2d/scene2d.js +++ b/src/plots/gl2d/scene2d.js @@ -211,7 +211,7 @@ proto.toImage = function(format) { canvas.width = w; canvas.height = h; - var context = canvas.getContext('2d'); + var context = canvas.getContext('2d', {willReadFrequently: true}); var imageData = context.createImageData(w, h); imageData.data.set(pixels); context.putImageData(imageData, 0, 0); diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 6bbae1c4aa8..78be9c070d0 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -1084,7 +1084,7 @@ proto.toImage = function(format) { var canvas = document.createElement('canvas'); canvas.width = w; canvas.height = h; - var context = canvas.getContext('2d'); + var context = canvas.getContext('2d', {willReadFrequently: true}); var imageData = context.createImageData(w, h); imageData.data.set(pixels); context.putImageData(imageData, 0, 0); diff --git a/src/snapshot/svgtoimg.js b/src/snapshot/svgtoimg.js index 51968b136f6..ee8ad39e695 100644 --- a/src/snapshot/svgtoimg.js +++ b/src/snapshot/svgtoimg.js @@ -33,7 +33,7 @@ function svgToImg(opts) { var w1 = scale * w0; var h1 = scale * h0; - var ctx = canvas.getContext('2d'); + var ctx = canvas.getContext('2d', {willReadFrequently: true}); var img = new Image(); var svgBlob, url; diff --git a/src/traces/image/hover.js b/src/traces/image/hover.js index 80977b7e76b..9b4e132d3dc 100644 --- a/src/traces/image/hover.js +++ b/src/traces/image/hover.js @@ -24,7 +24,7 @@ module.exports = function hoverPoints(pointData, xval, yval) { if(trace._hasZ) { pixel = cd0.z[ny][nx]; } else if(trace._hasSource) { - pixel = trace._canvas.el.getContext('2d').getImageData(nx, ny, 1, 1).data; + pixel = trace._canvas.el.getContext('2d', {willReadFrequently: true}).getImageData(nx, ny, 1, 1).data; } // return early if pixel is undefined diff --git a/src/traces/image/plot.js b/src/traces/image/plot.js index e182df8db81..a8a9e182fc7 100644 --- a/src/traces/image/plot.js +++ b/src/traces/image/plot.js @@ -92,7 +92,7 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { var canvas = document.createElement('canvas'); canvas.width = imageWidth; canvas.height = imageHeight; - var context = canvas.getContext('2d'); + var context = canvas.getContext('2d', {willReadFrequently: true}); var ipx = function(i) {return Lib.constrain(Math.round(xa.c2p(x0 + i * dx) - left), 0, imageWidth);}; var jpx = function(j) {return Lib.constrain(Math.round(ya.c2p(y0 + j * dy) - top), 0, imageHeight);}; @@ -167,7 +167,7 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { var canvas = document.createElement('canvas'); canvas.width = w; canvas.height = h; - var context = canvas.getContext('2d'); + var context = canvas.getContext('2d', {willReadFrequently: true}); trace._image = trace._image || new Image(); var image = trace._image; @@ -192,7 +192,7 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { if(realImage) { href = trace.source; } else { - var context = trace._canvas.el.getContext('2d'); + var context = trace._canvas.el.getContext('2d', {willReadFrequently: true}); var data = context.getImageData(0, 0, w, h).data; canvas = drawMagnifiedPixelsOnCanvas(function(i, j) { var index = 4 * (j * w + i);