From e0bf7e215148148cc9287cfd3bc456427be0f06c Mon Sep 17 00:00:00 2001 From: p01 Date: Mon, 2 Jun 2014 14:54:40 +0200 Subject: [PATCH] Optimized genericComposeSMask Declaring the composition and backgdrop functions outside of genericComposeSMask is more efficient. --- src/display/canvas.js | 83 +++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/src/display/canvas.js b/src/display/canvas.js index ad0503485..a39601142 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -601,49 +601,54 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } } + function composeSMaskBackdrop(bytes, r0, g0, b0) { + var length = bytes.length; + for (var i = 3; i < length; i += 4) { + var alpha = bytes[i]; + if (alpha === 0) { + bytes[i - 3] = r0; + bytes[i - 2] = g0; + bytes[i - 1] = b0; + } else if (alpha < 255) { + var alpha_ = 255 - alpha; + bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) >> 8; + bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) >> 8; + bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) >> 8; + } + } + } + + function composeSMaskAlpha(maskData, layerData) { + var length = maskData.length; + var scale = 1 / 255; + for (var i = 3; i < length; i += 4) { + var alpha = maskData[i]; + layerData[i] = (layerData[i] * alpha * scale) | 0; + } + } + + function composeSMaskLuminosity(maskData, layerData) { + var length = maskData.length; + for (var i = 3; i < length; i += 4) { + var y = ((maskData[i - 3] * 77) + // * 0.3 / 255 * 0x10000 + (maskData[i - 2] * 152) + // * 0.59 .... + (maskData[i - 1] * 28)) | 0; // * 0.11 .... + layerData[i] = (layerData[i] * y) >> 16; + } + } + function genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop) { - var addBackdropFn; - if (backdrop) { - addBackdropFn = function (r0, g0, b0, bytes) { - var length = bytes.length; - for (var i = 3; i < length; i += 4) { - var alpha = bytes[i] / 255; - if (alpha === 0) { - bytes[i - 3] = r0; - bytes[i - 2] = g0; - bytes[i - 1] = b0; - } else if (alpha < 1) { - var alpha_ = 1 - alpha; - bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) | 0; - bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) | 0; - bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) | 0; - } - } - }.bind(null, backdrop[0], backdrop[1], backdrop[2]); - } else { - addBackdropFn = function () {}; - } + var hasBackdrop = backdrop !== undefined; + var r0 = hasBackdrop ? backdrop[0] : 0; + var g0 = hasBackdrop ? backdrop[1] : 0; + var b0 = hasBackdrop ? backdrop[2] : 0; var composeFn; if (subtype === 'Luminosity') { - composeFn = function (maskDataBytes, layerDataBytes) { - var length = maskDataBytes.length; - for (var i = 3; i < length; i += 4) { - var y = ((maskDataBytes[i - 3] * 77) + // * 0.3 / 255 * 0x10000 - (maskDataBytes[i - 2] * 152) + // * 0.59 .... - (maskDataBytes[i - 1] * 28)) | 0; // * 0.11 .... - layerDataBytes[i] = (layerDataBytes[i] * y) >> 16; - } - }; + composeFn = composeSMaskLuminosity; } else { - composeFn = function (maskDataBytes, layerDataBytes) { - var length = maskDataBytes.length; - for (var i = 3; i < length; i += 4) { - var alpha = maskDataBytes[i]; - layerDataBytes[i] = (layerDataBytes[i] * alpha / 255) | 0; - } - }; + composeFn = composeSMaskAlpha; } // processing image in chunks to save memory @@ -654,7 +659,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var maskData = maskCtx.getImageData(0, row, width, chunkHeight); var layerData = layerCtx.getImageData(0, row, width, chunkHeight); - addBackdropFn(maskData.data); + if (hasBackdrop) { + composeSMaskBackdrop(maskData.data, r0, g0, b0); + } composeFn(maskData.data, layerData.data); maskCtx.putImageData(layerData, 0, row);