Skip to content

Commit

Permalink
some performance tricks
Browse files Browse the repository at this point in the history
  • Loading branch information
andr83 committed Nov 4, 2014
1 parent f14f46c commit fc37867
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 62 deletions.
75 changes: 44 additions & 31 deletions example/glur.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ var blurCanvas = function (canvas, radius, callback) {
var src = imageData.data;

var data32 = new Uint32Array(src.buffer);
var res = glur.blur32(data32, canvas.width, canvas.height, radius);
glur.blur32(data32, canvas.width, canvas.height, radius);

imageData.data.set(res);
ctx.putImageData(imageData, 0, 0);

callback();
Expand All @@ -27,9 +26,8 @@ var fastBlurCanvas = function (canvas, radius, callback) {
var src = imageData.data;

var data32 = new Uint32Array(src.buffer);
var res = iir_gauss.blur32(data32, canvas.width, canvas.height, radius);
iir_gauss.blur32(data32, canvas.width, canvas.height, radius);

imageData.data.set(res);
ctx.putImageData(imageData, 0, 0);

callback();
Expand Down Expand Up @@ -110,13 +108,11 @@ var convolve = function (src, out, kernel, width, height, radius) {
};

var blur32 = function (src, width, height, radius) {
var buf = new ArrayBuffer(width * height * 4);
var out = new Uint32Array(buf);
var out = new Uint32Array(width * height * 4);
var kernel = buildKernel(radius);

convolve(src, out, kernel, width, height, radius);
convolve(out, src, kernel, height, width, radius);
return new Uint8ClampedArray(src.buffer);
};

exports.blur32 = blur32;
Expand Down Expand Up @@ -154,11 +150,16 @@ var gaussCoef = function (sigma) {
};


var convolve = function (src, out, tmp, coeff, width, height) {
var convolve32 = function (src, out, tmp, coeff, width, height) {
var x, y, rgb, r, g, b, a, out_index, y_offset, x_offset;
var r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2;

//console.time('convolve');
var coeff_b0 = coeff.b0;
var coeff_a0 = coeff.a0;
var coeff_a1 = coeff.a1;
var coeff_a2 = coeff.a2;

console.time('convolve');
for (y = 0; y < height; y++) {
out_index = y + height * width - 1;
y_offset = y * width;
Expand All @@ -184,18 +185,18 @@ var convolve = function (src, out, tmp, coeff, width, height) {
g2 = g1;
b2 = b1;

x_offset = 0;
for (x = 0; x < width; x++) {
rgb = src[y_offset + x];
a = (rgb >> 24) & 0xff;
r = (rgb >> 16) & 0xff;
g = (rgb >> 8) & 0xff;
b = rgb & 0xff;


a = coeff.b0 * a + (coeff.a0 * a0 + coeff.a1 * a1 + coeff.a2 * a2);
r = coeff.b0 * r + (coeff.a0 * r0 + coeff.a1 * r1 + coeff.a2 * r2);
g = coeff.b0 * g + (coeff.a0 * g0 + coeff.a1 * g1 + coeff.a2 * g2);
b = coeff.b0 * b + (coeff.a0 * b0 + coeff.a1 * b1 + coeff.a2 * b2);
a = coeff_b0 * a + (coeff_a0 * a0 + coeff_a1 * a1 + coeff_a2 * a2);
r = coeff_b0 * r + (coeff_a0 * r0 + coeff_a1 * r1 + coeff_a2 * r2);
g = coeff_b0 * g + (coeff_a0 * g0 + coeff_a1 * g1 + coeff_a2 * g2);
b = coeff_b0 * b + (coeff_a0 * b0 + coeff_a1 * b1 + coeff_a2 * b2);

a2 = a1;
r2 = r1;
Expand All @@ -212,25 +213,39 @@ var convolve = function (src, out, tmp, coeff, width, height) {
g0 = g;
b0 = b;

x_offset = x * 4;
tmp[x_offset] = a;
tmp[x_offset + 1] = r;
tmp[x_offset + 2] = g;
tmp[x_offset + 3] = b;
x_offset += 4;
}

for (x = width - 1; x >= 0; x--) {
a0 = a;
r0 = r;
g0 = g;
b0 = b;

a1 = a0;
r1 = r0;
g1 = g0;
b1 = b0;

x_offset = x * 4;
a2 = a1;
r2 = r1;
g2 = g1;
b2 = b1;

for (x = width - 1; x >= 0; x--) {
x_offset -= 4;
a = tmp[x_offset];
r = tmp[x_offset + 1];
g = tmp[x_offset + 2];
b = tmp[x_offset + 3];

a = coeff.b0 * a + (coeff.a0 * a0 + coeff.a1 * a1 + coeff.a2 * a2);
r = coeff.b0 * r + (coeff.a0 * r0 + coeff.a1 * r1 + coeff.a2 * r2);
g = coeff.b0 * g + (coeff.a0 * g0 + coeff.a1 * g1 + coeff.a2 * g2);
b = coeff.b0 * b + (coeff.a0 * b0 + coeff.a1 * b1 + coeff.a2 * b2);
a = coeff_b0 * a + (coeff_a0 * a0 + coeff_a1 * a1 + coeff_a2 * a2);
r = coeff_b0 * r + (coeff_a0 * r0 + coeff_a1 * r1 + coeff_a2 * r2);
g = coeff_b0 * g + (coeff_a0 * g0 + coeff_a1 * g1 + coeff_a2 * g2);
b = coeff_b0 * b + (coeff_a0 * b0 + coeff_a1 * b1 + coeff_a2 * b2);

a2 = a1;
r2 = r1;
Expand All @@ -247,29 +262,27 @@ var convolve = function (src, out, tmp, coeff, width, height) {
g0 = g;
b0 = b;

a = ((a > 255 ? 255 : a) + 0.5 | 0) & 0xff;
r = ((r > 255 ? 255 : r) + 0.5 | 0) & 0xff;
g = ((g > 255 ? 255 : g) + 0.5 | 0) & 0xff;
b = ((b > 255 ? 255 : b) + 0.5 | 0) & 0xff;
a = (a |0) & 0xff;
r = (r |0) & 0xff;
g = (g |0) & 0xff;
b = (b |0) & 0xff;

out_index -= height;
out[out_index] = (a << 24) | (r << 16) | (g << 8) | b;
}
}
//console.timeEnd('convolve');
console.timeEnd('convolve');
};


var blur32 = function (src, width, height, radius) {
var buf = new ArrayBuffer(width * height * 4);
var out = new Uint32Array(buf);
var out = new Uint32Array(width * height * 4);
var tmp = new Float32Array(width * 4);

var coeff = gaussCoef(radius);

convolve(src, out, tmp, coeff, width, height, radius);
convolve(out, src, tmp, coeff, height, width, radius);
return new Uint8ClampedArray(src.buffer);
convolve32(src, out, tmp, coeff, width, height, radius);
convolve32(out, src, tmp, coeff, height, width, radius);
};

exports.blur32 = blur32;
Expand Down
6 changes: 2 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ var blurCanvas = function (canvas, radius, callback) {
var src = imageData.data;

var data32 = new Uint32Array(src.buffer);
var res = glur.blur32(data32, canvas.width, canvas.height, radius);
glur.blur32(data32, canvas.width, canvas.height, radius);

imageData.data.set(res);
ctx.putImageData(imageData, 0, 0);

callback();
Expand All @@ -26,9 +25,8 @@ var fastBlurCanvas = function (canvas, radius, callback) {
var src = imageData.data;

var data32 = new Uint32Array(src.buffer);
var res = iir_gauss.blur32(data32, canvas.width, canvas.height, radius);
iir_gauss.blur32(data32, canvas.width, canvas.height, radius);

imageData.data.set(res);
ctx.putImageData(imageData, 0, 0);

callback();
Expand Down
4 changes: 1 addition & 3 deletions lib/gauss.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,11 @@ var convolve = function (src, out, kernel, width, height, radius) {
};

var blur32 = function (src, width, height, radius) {
var buf = new ArrayBuffer(width * height * 4);
var out = new Uint32Array(buf);
var out = new Uint32Array(width * height * 4);
var kernel = buildKernel(radius);

convolve(src, out, kernel, width, height, radius);
convolve(out, src, kernel, height, width, radius);
return new Uint8ClampedArray(src.buffer);
};

exports.blur32 = blur32;
65 changes: 41 additions & 24 deletions lib/iir_gauss.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ var gaussCoef = function (sigma) {
};


var convolve = function (src, out, tmp, coeff, width, height) {
var convolve32 = function (src, out, tmp, coeff, width, height) {
var x, y, rgb, r, g, b, a, out_index, y_offset, x_offset;
var r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2;

//console.time('convolve');
var coeff_b0 = coeff.b0;
var coeff_a0 = coeff.a0;
var coeff_a1 = coeff.a1;
var coeff_a2 = coeff.a2;

console.time('convolve');
for (y = 0; y < height; y++) {
out_index = y + height * width - 1;
y_offset = y * width;
Expand All @@ -60,18 +65,18 @@ var convolve = function (src, out, tmp, coeff, width, height) {
g2 = g1;
b2 = b1;

x_offset = 0;
for (x = 0; x < width; x++) {
rgb = src[y_offset + x];
a = (rgb >> 24) & 0xff;
r = (rgb >> 16) & 0xff;
g = (rgb >> 8) & 0xff;
b = rgb & 0xff;


a = coeff.b0 * a + (coeff.a0 * a0 + coeff.a1 * a1 + coeff.a2 * a2);
r = coeff.b0 * r + (coeff.a0 * r0 + coeff.a1 * r1 + coeff.a2 * r2);
g = coeff.b0 * g + (coeff.a0 * g0 + coeff.a1 * g1 + coeff.a2 * g2);
b = coeff.b0 * b + (coeff.a0 * b0 + coeff.a1 * b1 + coeff.a2 * b2);
a = coeff_b0 * a + (coeff_a0 * a0 + coeff_a1 * a1 + coeff_a2 * a2);
r = coeff_b0 * r + (coeff_a0 * r0 + coeff_a1 * r1 + coeff_a2 * r2);
g = coeff_b0 * g + (coeff_a0 * g0 + coeff_a1 * g1 + coeff_a2 * g2);
b = coeff_b0 * b + (coeff_a0 * b0 + coeff_a1 * b1 + coeff_a2 * b2);

a2 = a1;
r2 = r1;
Expand All @@ -88,25 +93,39 @@ var convolve = function (src, out, tmp, coeff, width, height) {
g0 = g;
b0 = b;

x_offset = x * 4;
tmp[x_offset] = a;
tmp[x_offset + 1] = r;
tmp[x_offset + 2] = g;
tmp[x_offset + 3] = b;
x_offset += 4;
}

for (x = width - 1; x >= 0; x--) {
a0 = a;
r0 = r;
g0 = g;
b0 = b;

a1 = a0;
r1 = r0;
g1 = g0;
b1 = b0;

x_offset = x * 4;
a2 = a1;
r2 = r1;
g2 = g1;
b2 = b1;

for (x = width - 1; x >= 0; x--) {
x_offset -= 4;
a = tmp[x_offset];
r = tmp[x_offset + 1];
g = tmp[x_offset + 2];
b = tmp[x_offset + 3];

a = coeff.b0 * a + (coeff.a0 * a0 + coeff.a1 * a1 + coeff.a2 * a2);
r = coeff.b0 * r + (coeff.a0 * r0 + coeff.a1 * r1 + coeff.a2 * r2);
g = coeff.b0 * g + (coeff.a0 * g0 + coeff.a1 * g1 + coeff.a2 * g2);
b = coeff.b0 * b + (coeff.a0 * b0 + coeff.a1 * b1 + coeff.a2 * b2);
a = coeff_b0 * a + (coeff_a0 * a0 + coeff_a1 * a1 + coeff_a2 * a2);
r = coeff_b0 * r + (coeff_a0 * r0 + coeff_a1 * r1 + coeff_a2 * r2);
g = coeff_b0 * g + (coeff_a0 * g0 + coeff_a1 * g1 + coeff_a2 * g2);
b = coeff_b0 * b + (coeff_a0 * b0 + coeff_a1 * b1 + coeff_a2 * b2);

a2 = a1;
r2 = r1;
Expand All @@ -123,29 +142,27 @@ var convolve = function (src, out, tmp, coeff, width, height) {
g0 = g;
b0 = b;

a = ((a > 255 ? 255 : a) + 0.5 | 0) & 0xff;
r = ((r > 255 ? 255 : r) + 0.5 | 0) & 0xff;
g = ((g > 255 ? 255 : g) + 0.5 | 0) & 0xff;
b = ((b > 255 ? 255 : b) + 0.5 | 0) & 0xff;
a = (a |0) & 0xff;
r = (r |0) & 0xff;
g = (g |0) & 0xff;
b = (b |0) & 0xff;

out_index -= height;
out[out_index] = (a << 24) | (r << 16) | (g << 8) | b;
}
}
//console.timeEnd('convolve');
console.timeEnd('convolve');
};


var blur32 = function (src, width, height, radius) {
var buf = new ArrayBuffer(width * height * 4);
var out = new Uint32Array(buf);
var out = new Uint32Array(width * height * 4);
var tmp = new Float32Array(width * 4);

var coeff = gaussCoef(radius);

convolve(src, out, tmp, coeff, width, height, radius);
convolve(out, src, tmp, coeff, height, width, radius);
return new Uint8ClampedArray(src.buffer);
convolve32(src, out, tmp, coeff, width, height, radius);
convolve32(out, src, tmp, coeff, height, width, radius);
};

exports.blur32 = blur32;

0 comments on commit fc37867

Please sign in to comment.