ericblade / quagga2

An advanced barcode-scanner written in Javascript and TypeScript - Continuation from https://github.com/serratus/quaggajs
MIT License
766 stars 85 forks source link

Multiple readback operations can be made faster. #459

Closed sam-the-programmer closed 1 year ago

sam-the-programmer commented 2 years ago

Hi there, just working on a Quagga2-based product, and came across this warning in the dev tools. Is there a reason that this is not changed/implemented for performance?

Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true. [quagga.min.js:3]
github-actions[bot] commented 2 years ago

Thank you for filing an issue! Please be patient. :-)

ericblade commented 2 years ago

I haven't ever seen that, and had no idea of it's existence.

A boolean value that indicates whether or not a lot of read-back operations are planned. This will force the use of a software (instead of hardware accelerated) 2D canvas and can save memory when calling [getImageData()](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData) frequently.

It does look like getImageData is used every frame grab, which might perhaps make a difference there, though it might be rather hard to quantify.

My guess would be that either that option didn't exist when this code was originally written, was not known by the original author, or was determined to not be helpful?

i real quick traced out the probably relevant getImageData triggering that to frame_grabber_browser .. not sure exactly where the relevant getContext('2d') call is though.

I'll try to take a deeper look at it next time i've got some time to work on this, i always like easy performance improvements :)

sam-the-programmer commented 2 years ago

Thanks

ghevge commented 2 years ago

I'm seeing the same warning on chrome

ericblade commented 2 years ago

Curious, I haven't seen it, but I also don't do a lot of chrome debugging with the camera, since my USB cameras don't read barcodes, so I'm usually doing things with my phone, which is a lot harder to hit with the dev tools.

Does it seem like there's any particular operation that causes it? When does the message occur?

I'm thinking it should be easy to just add a config flag, and have that passed along to getImageData, which would allow us to experiment with it without necessarily breaking anything.

ghevge commented 2 years ago

It shows up when you open the video stream. This is the error stack while using V 1.7.7 downloaded from here: https://cdn.jsdelivr.net/npm/@ericblade/quagga2@1.7.7/dist/quagga.js

this is the quagga.ts:223 line of code : if (this.context.framegrabber.grab()) {

frame_grabber_browser.js:107 Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true. See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently _that.grab @ frame_grabber_browser.js:107 (anonymous) @ quagga.ts:223 newFrame @ quagga.ts:248 requestAnimationFrame (async) newFrame @ quagga.ts:250 requestAnimationFrame (async) newFrame @ quagga.ts:250 requestAnimationFrame (async) newFrame @ quagga.ts:250 requestAnimationFrame (async) newFrame @ quagga.ts:250 startContinuousUpdate @ quagga.ts:254 start @ quagga.ts:259 start @ quagga.js:42 (anonymous) @ barcodeReader.js:43 ready @ quagga.ts:55 (anonymous) @ quagga.ts:93 adjustWorkerPool @ qworker.ts:165 (anonymous) @ quagga.ts:85 trigger @ input_stream_browser.ts:123 (anonymous) @ quagga.ts:107 Promise.then (async) initInputStream @ quagga.ts:107 init @ quagga.js:37 initQuagga @ barcodeReader.js:17 showScan @ barcodeReader.js:10 onclick @ index.html:1

ericblade commented 2 years ago

ooh! fantastic, thanks for the backtrace. I'll try to grab a few minutes this weekend to thread a setting you can put in init to toggle that, then, and we shall see what happens!

ericblade commented 2 years ago

did not get to this when i wanted to, have been super busy with work and family having covid :( but will try over the US holiday weekend :)

ericblade commented 1 year ago

working on threading this through... at least in the spot it occurs as mentioned above. There are other places where getContext is used, but they don't seem to have access to a configuration object easily... but in frame_grabber_browser should cover most of the usage, i think

ericblade commented 1 year ago

1.8.1 appears to correctly thread this through to the spots where it's used in most instances. Added willReadFrequently: boolean options to QuaggaJSResultCollector, QuaggaJSConfigObject.inputStream and QuaggaJSConfigObject.locator .

I'm pretty sure you want to add it to inputStream config, possibly also locator.

Probably in 2.0, it'll just be made the standard operation, but I don't want to break 1.x in unexpected fashions

ericblade commented 1 year ago

fwiw, it seems to work fine for my application, on my mobile. I saw a few other settings in that function that i'll probably wire up similarly