Enable willReadFrequently for canvas 2D contexts

Adds the willReadFrequently: true option to all getContext('2d') calls on temporary canvases in Canvas, CanvasLayers, and SAMDetectorIntegration modules. This improves performance for frequent pixel data reads, addressing potential browser optimization issues.
This commit is contained in:
Dariusz L
2025-07-23 16:58:19 +02:00
parent 5235f7b961
commit bccb9da641
5 changed files with 17 additions and 15 deletions

View File

@@ -54,7 +54,8 @@ export class Canvas {
};
this.offscreenCanvas = document.createElement('canvas');
this.offscreenCtx = this.offscreenCanvas.getContext('2d', {
alpha: false
alpha: false,
willReadFrequently: true
});
this.dataInitialized = false;
this.pendingDataCheck = null;

View File

@@ -352,7 +352,7 @@ export class CanvasLayers {
async getLayerImageData(layer) {
try {
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx)
throw new Error("Could not create canvas context");
tempCanvas.width = layer.width;
@@ -593,7 +593,7 @@ export class CanvasLayers {
const tempCanvas = document.createElement('canvas');
tempCanvas.width = this.canvas.width;
tempCanvas.height = this.canvas.height;
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx) {
reject(new Error("Could not create canvas context"));
return;
@@ -606,7 +606,7 @@ export class CanvasLayers {
const tempMaskCanvas = document.createElement('canvas');
tempMaskCanvas.width = this.canvas.width;
tempMaskCanvas.height = this.canvas.height;
const tempMaskCtx = tempMaskCanvas.getContext('2d');
const tempMaskCtx = tempMaskCanvas.getContext('2d', { willReadFrequently: true });
if (!tempMaskCtx) {
reject(new Error("Could not create mask canvas context"));
return;
@@ -655,7 +655,7 @@ export class CanvasLayers {
const tempCanvas = document.createElement('canvas');
tempCanvas.width = this.canvas.width;
tempCanvas.height = this.canvas.height;
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx) {
reject(new Error("Could not create canvas context"));
return;
@@ -712,7 +712,7 @@ export class CanvasLayers {
const tempCanvas = document.createElement('canvas');
tempCanvas.width = newWidth;
tempCanvas.height = newHeight;
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx) {
reject(new Error("Could not create canvas context"));
return;
@@ -766,7 +766,7 @@ export class CanvasLayers {
const tempCanvas = document.createElement('canvas');
tempCanvas.width = fusedWidth;
tempCanvas.height = fusedHeight;
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx)
throw new Error("Could not create canvas context");
tempCtx.translate(-minX, -minY);

View File

@@ -98,7 +98,8 @@ export class Canvas {
this.offscreenCanvas = document.createElement('canvas');
this.offscreenCtx = this.offscreenCanvas.getContext('2d', {
alpha: false
alpha: false,
willReadFrequently: true
});
this.dataInitialized = false;

View File

@@ -410,7 +410,7 @@ export class CanvasLayers {
async getLayerImageData(layer: Layer): Promise<string> {
try {
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx) throw new Error("Could not create canvas context");
tempCanvas.width = layer.width;
@@ -687,7 +687,7 @@ export class CanvasLayers {
const tempCanvas = document.createElement('canvas');
tempCanvas.width = this.canvas.width;
tempCanvas.height = this.canvas.height;
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx) {
reject(new Error("Could not create canvas context"));
return;
@@ -703,7 +703,7 @@ export class CanvasLayers {
const tempMaskCanvas = document.createElement('canvas');
tempMaskCanvas.width = this.canvas.width;
tempMaskCanvas.height = this.canvas.height;
const tempMaskCtx = tempMaskCanvas.getContext('2d');
const tempMaskCtx = tempMaskCanvas.getContext('2d', { willReadFrequently: true });
if (!tempMaskCtx) {
reject(new Error("Could not create mask canvas context"));
return;
@@ -764,7 +764,7 @@ export class CanvasLayers {
const tempCanvas = document.createElement('canvas');
tempCanvas.width = this.canvas.width;
tempCanvas.height = this.canvas.height;
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx) {
reject(new Error("Could not create canvas context"));
return;
@@ -831,7 +831,7 @@ export class CanvasLayers {
const tempCanvas = document.createElement('canvas');
tempCanvas.width = newWidth;
tempCanvas.height = newHeight;
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx) {
reject(new Error("Could not create canvas context"));
return;
@@ -898,7 +898,7 @@ export class CanvasLayers {
const tempCanvas = document.createElement('canvas');
tempCanvas.width = fusedWidth;
tempCanvas.height = fusedHeight;
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (!tempCtx) throw new Error("Could not create canvas context");
tempCtx.translate(-minX, -minY);

View File

@@ -338,7 +338,7 @@ async function handleSAMDetectorResult(node: ComfyNode, resultImage: HTMLImageEl
const tempCanvas = document.createElement('canvas');
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;
const tempCtx = tempCanvas.getContext('2d', {willReadFrequently: true});
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
if (tempCtx) {
tempCtx.drawImage(resultImage, 0, 0, canvas.width, canvas.height);