Reputation: 41
I have a filter that isn't compatible with WebGL. Is there a way to skip writing a fragmentSource? I tried overriding fabric.Image.filters.BaseFilter applyTo on the filter subclass to only call this.applyTo2d(options);
but I'm not getting any image data.
applyTo: function(options) {
if (options.webgl) {
if (options.passes > 1 && this.isNeutralState(options)) {
// avoid doing something that we do not need
return;
}
this._setupFrameBuffer(options);
this.applyToWebGL(options);
this._swapTextures(options);
}
else if (!this.isNeutralState()) {
this.applyTo2d(options);
}
},
Upvotes: 1
Views: 454
Reputation: 41
I as able to accomplish this in a non-optimized way with minimal code in webgl_backend.class.js.
First, the webgl backend needs a fallback for non-webgl filters:
this.fallback2dBackend = new fabric.Canvas2dFilterBackend();
Then, instead of running all filters: fabric.filterBackend.applyFilters(filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey);
Do this:
var newSource = fabric.util.createCanvasElement();
newSource.width = sourceWidth;
newSource.height = sourceHeight;
var newSourceCtx = newSource.getContext('2d');
newSourceCtx.drawImage(this._originalElement, 0, 0, sourceWidth, sourceHeight);
filters.forEach(function(filter) {
if (!filter) {
return;
}
var backend = fabric.filterBackend;
if (filter.fragmentSource === null) {
backend = backend.fallback2dBackend;
}
backend.applyFilters(
[filter], newSource, sourceWidth, sourceHeight, this._element);
newSourceCtx.clearRect(0, 0, sourceWidth, sourceHeight);
newSourceCtx.drawImage(this._element, 0, 0, sourceWidth, sourceHeight);
}, this);
I've published a fork in case someone wants to refactor this into a PR.
Upvotes: 1