Skip to content

Commit

Permalink
Ab webgl filter for resize (fabricjs#4426)
Browse files Browse the repository at this point in the history
* test another version

* a working webgl resize

* broke blur"

* broke blur"

* a working webgl resize

* better cache shader

* no dist

* better

* better2

* fixed tests

* linting
  • Loading branch information
asturur authored Nov 4, 2017
1 parent a7c5fc6 commit a700bd1
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 135 deletions.
53 changes: 30 additions & 23 deletions src/filters/base_filter.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
*/
type: 'BaseFilter',

/**
* Array of attributes to send with buffers. do not modify
* @private
*/

vertexSource: 'attribute vec2 aPosition;\n' +
'attribute vec2 aTexCoord;\n' +
'varying vec2 vTexCoord;\n' +
'void main() {\n' +
'vTexCoord = aTexCoord;\n' +
'vTexCoord = aPosition;\n' +
'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' +
'}',

Expand Down Expand Up @@ -63,13 +67,12 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
* @param {String} vertexSource vertexShader source for compilation
*/
createProgram: function(gl, fragmentSource, vertexSource) {
if (!this.vertexSource || !this.fragmentSource) {
return;
}
if(fabric.webGlPrecision !== 'highp'){
fragmentSource = fragmentSource.replace(/precision highp float/g, 'precision ' + fabric.webGlPrecision + ' float');
if (fabric.webGlPrecision !== 'highp'){
fragmentSource = fragmentSource.replace(
/precision highp float/g,
'precision ' + fabric.webGlPrecision + ' float'
);
}

var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexSource || this.vertexSource);
gl.compileShader(vertexShader);
Expand Down Expand Up @@ -125,7 +128,6 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
getAttributeLocations: function(gl, program) {
return {
aPosition: gl.getAttribLocation(program, 'aPosition'),
aTexCoord: gl.getAttribLocation(program, 'aTexCoord'),
};
},

Expand All @@ -139,7 +141,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
* @returns {Object} A map of uniform names to uniform locations.
*/
getUniformLocations: function (/* gl, program */) {
// Intentionally left blank, override me in subclasses.
// in case i do not need any special uniform i need to return an empty object
return { };
},

/**
Expand All @@ -148,20 +151,24 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
* @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.
* @param {Object} attributeLocations A map of shader attribute names to their locations.
*/
sendAttributeData: function(gl, attributeLocations, squareVertices) {
['aPosition', 'aTexCoord'].forEach(function(attribute) {
var attributeLocation = attributeLocations[attribute];
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(attributeLocation);
gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, squareVertices, gl.STATIC_DRAW);
});
sendAttributeData: function(gl, attributeLocations, aPositionData) {
var attributeLocation = attributeLocations.aPostion;
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(attributeLocation);
gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);
},

_setupFrameBuffer: function(options) {
var gl = options.context;
var gl = options.context, width, height;
if (options.passes > 1) {
width = options.destinationWidth;
height = options.destinationHeight;
if (options.sourceWidth !== width || options.sourceHeight !== height) {
gl.deleteTexture(options.targetTexture);
options.targetTexture = options.filterBackend.createTexture(gl, width, height);
}
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,
options.targetTexture, 0);
}
Expand Down Expand Up @@ -211,7 +218,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
this.applyToWebGL(options);
this._swapTextures(options);
}
else {
else if (!this.isNeutralState()) {
this.applyTo2d(options);
}
},
Expand Down Expand Up @@ -251,13 +258,13 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);
}
gl.useProgram(shader.program);
this.sendAttributeData(gl, shader.attributeLocations, options.squareVertices);
this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);

gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);
gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);

this.sendUniformData(gl, shader.uniformLocations);
gl.viewport(0, 0, options.sourceWidth, options.sourceHeight);
gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
},

Expand Down
14 changes: 14 additions & 0 deletions src/filters/colormatrix_filter.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@
this.matrix = this.matrix.slice(0);
},

/**
* Intentionally left blank, to be overridden in custom filters
* @param {Object} options
**/
isNeutralState: function(/* options */) {
var _class = filters.ColorMatrix;
for (var i = 20; i--;) {
if (this.matrix[i] !== _class.prototype.matrix[i]) {
return false;
}
}
return true;
},

/**
* Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.
*
Expand Down
7 changes: 7 additions & 0 deletions src/filters/pixelate_filter.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@
}
},

/**
* Indicate when the filter is not gonna apply changes to the image
**/
isNeutralState: function() {
return this.blocksize === 1;
},

/**
* Return WebGL uniform locations for this filter's shader.
*
Expand Down
Loading

0 comments on commit a700bd1

Please sign in to comment.