Improve performance of applyMaskImageData
- write some uint32 instead of uint8 to avoid the check before clamping; - unroll the loop to write data in the buffer - but keep a loop for the last element of a line: it likely doesn't hurt that much since it's executed only for one time for each line; - I tested on a macbook with an Apple chip, and on Firefox nightly the new code is almost 3.5x faster than before (~1.8x with Chrome).
This commit is contained in:
parent
08e1abe68e
commit
687c9a8710
@ -13,30 +13,42 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { FeatureTest } from "./util.js";
|
||||||
|
|
||||||
function applyMaskImageData({
|
function applyMaskImageData({
|
||||||
src,
|
src,
|
||||||
srcPos = 0,
|
srcPos = 0,
|
||||||
dest,
|
dest,
|
||||||
destPos = 3,
|
destPos = 0,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
inverseDecode = false,
|
inverseDecode = false,
|
||||||
}) {
|
}) {
|
||||||
const srcLength = src.byteLength;
|
const opaque = FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;
|
||||||
const zeroMapping = inverseDecode ? 0 : 255;
|
const [zeroMapping, oneMapping] = !inverseDecode ? [opaque, 0] : [0, opaque];
|
||||||
const oneMapping = inverseDecode ? 255 : 0;
|
const widthInSource = width >> 3;
|
||||||
|
const widthRemainder = width & 7;
|
||||||
|
const srcLength = src.length;
|
||||||
|
dest = new Uint32Array(dest.buffer);
|
||||||
|
|
||||||
for (let j = 0; j < height; j++) {
|
for (let i = 0; i < height; i++) {
|
||||||
let elem,
|
for (const max = srcPos + widthInSource; srcPos < max; srcPos++) {
|
||||||
mask = 0;
|
const elem = srcPos < srcLength ? src[srcPos] : 255;
|
||||||
for (let k = 0; k < width; k++) {
|
dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping;
|
||||||
if (mask === 0) {
|
dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping;
|
||||||
elem = srcPos < srcLength ? src[srcPos++] : 255;
|
dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping;
|
||||||
mask = 128;
|
dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping;
|
||||||
}
|
dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping;
|
||||||
dest[destPos] = elem & mask ? oneMapping : zeroMapping;
|
dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping;
|
||||||
destPos += 4;
|
dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping;
|
||||||
mask >>= 1;
|
dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping;
|
||||||
|
}
|
||||||
|
if (widthRemainder === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const elem = srcPos < srcLength ? src[srcPos++] : 255;
|
||||||
|
for (let j = 0; j < widthRemainder; j++) {
|
||||||
|
dest[destPos++] = elem & (1 << (7 - j)) ? oneMapping : zeroMapping;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user