Split the ECAA shader into separate shaders for monochrome and multicolor

This commit is contained in:
Patrick Walton 2017-08-24 12:08:58 -07:00
parent ad565ffde7
commit 07d425dfb2
5 changed files with 89 additions and 22 deletions

View File

@ -65,9 +65,13 @@ const SHADER_URLS: ShaderMap<ShaderProgramURLs> = {
vertex: "/glsl/gles2/ecaa-curve.vs.glsl", vertex: "/glsl/gles2/ecaa-curve.vs.glsl",
fragment: "/glsl/gles2/ecaa-curve.fs.glsl", fragment: "/glsl/gles2/ecaa-curve.fs.glsl",
}, },
ecaaResolve: { ecaaMonoResolve: {
vertex: "/glsl/gles2/ecaa-resolve.vs.glsl", vertex: "/glsl/gles2/ecaa-mono-resolve.vs.glsl",
fragment: "/glsl/gles2/ecaa-resolve.fs.glsl", fragment: "/glsl/gles2/ecaa-mono-resolve.fs.glsl",
},
ecaaMultiResolve: {
vertex: "/glsl/gles2/ecaa-multi-resolve.vs.glsl",
fragment: "/glsl/gles2/ecaa-multi-resolve.fs.glsl",
}, },
}; };
@ -105,7 +109,8 @@ interface ShaderMap<T> {
ecaaCover: T; ecaaCover: T;
ecaaLine: T; ecaaLine: T;
ecaaCurve: T; ecaaCurve: T;
ecaaResolve: T; ecaaMonoResolve: T;
ecaaMultiResolve: T;
} }
interface UniformMap { interface UniformMap {
@ -1054,6 +1059,14 @@ class PathfinderView {
this.gl.drawElements(this.gl.TRIANGLES, this.textGlyphCount * 6, this.gl.UNSIGNED_INT, 0); this.gl.drawElements(this.gl.TRIANGLES, this.textGlyphCount * 6, this.gl.UNSIGNED_INT, 0);
} }
get bgColor(): glmatrix.vec4 {
return glmatrix.vec4.fromValues(1.0, 1.0, 1.0, 1.0);
}
get fgColor(): glmatrix.vec4 {
return glmatrix.vec4.fromValues(0.0, 0.0, 0.0, 1.0);
}
canvas: HTMLCanvasElement; canvas: HTMLCanvasElement;
gl: WebGLRenderingContext; gl: WebGLRenderingContext;
@ -1550,7 +1563,7 @@ abstract class ECAAStrategy implements AntialiasingStrategy {
this.resolveVAO = view.vertexArrayObjectExt.createVertexArrayOES(); this.resolveVAO = view.vertexArrayObjectExt.createVertexArrayOES();
view.vertexArrayObjectExt.bindVertexArrayOES(this.resolveVAO); view.vertexArrayObjectExt.bindVertexArrayOES(this.resolveVAO);
const resolveProgram = view.shaderPrograms.ecaaResolve; const resolveProgram = this.getResolveProgram(view);
view.gl.useProgram(resolveProgram.program); view.gl.useProgram(resolveProgram.program);
initQuadVAO(view, resolveProgram.attributes); initQuadVAO(view, resolveProgram.attributes);
@ -1711,24 +1724,20 @@ abstract class ECAAStrategy implements AntialiasingStrategy {
this.clearForResolve(view); this.clearForResolve(view);
// Resolve. // Resolve.
const resolveProgram = view.shaderPrograms.ecaaResolve; const resolveProgram = this.getResolveProgram(view);
view.gl.useProgram(resolveProgram.program); view.gl.useProgram(resolveProgram.program);
view.vertexArrayObjectExt.bindVertexArrayOES(this.resolveVAO); view.vertexArrayObjectExt.bindVertexArrayOES(this.resolveVAO);
view.setFramebufferSizeUniform(resolveProgram.uniforms); view.setFramebufferSizeUniform(resolveProgram.uniforms);
view.gl.activeTexture(view.gl.TEXTURE0); view.gl.activeTexture(view.gl.TEXTURE0);
view.gl.bindTexture(view.gl.TEXTURE_2D, this.bgColorTexture);
view.gl.uniform1i(resolveProgram.uniforms.uBGColor, 0);
view.gl.activeTexture(view.gl.TEXTURE1);
view.gl.bindTexture(view.gl.TEXTURE_2D, this.fgColorTexture);
view.gl.uniform1i(resolveProgram.uniforms.uFGColor, 1);
view.gl.activeTexture(view.gl.TEXTURE2);
view.gl.bindTexture(view.gl.TEXTURE_2D, this.aaAlphaTexture); view.gl.bindTexture(view.gl.TEXTURE_2D, this.aaAlphaTexture);
view.gl.uniform1i(resolveProgram.uniforms.uAAAlpha, 2); view.gl.uniform1i(resolveProgram.uniforms.uAAAlpha, 0);
this.setResolveUniforms(view, resolveProgram);
view.setTransformSTAndTexScaleUniformsForAtlas(resolveProgram.uniforms); view.setTransformSTAndTexScaleUniformsForAtlas(resolveProgram.uniforms);
view.gl.drawElements(view.gl.TRIANGLES, 6, view.gl.UNSIGNED_BYTE, 0); view.gl.drawElements(view.gl.TRIANGLES, 6, view.gl.UNSIGNED_BYTE, 0);
view.vertexArrayObjectExt.bindVertexArrayOES(null); view.vertexArrayObjectExt.bindVertexArrayOES(null);
} }
protected abstract getResolveProgram(view: PathfinderView): PathfinderShaderProgram;
protected abstract initEdgeDetectFramebuffer(view: PathfinderView): void; protected abstract initEdgeDetectFramebuffer(view: PathfinderView): void;
protected abstract createEdgeDetectVAO(view: PathfinderView): void; protected abstract createEdgeDetectVAO(view: PathfinderView): void;
protected abstract detectEdgesIfNecessary(view: PathfinderView): void; protected abstract detectEdgesIfNecessary(view: PathfinderView): void;
@ -1737,6 +1746,8 @@ abstract class ECAAStrategy implements AntialiasingStrategy {
protected abstract setAADepthState(view: PathfinderView): void; protected abstract setAADepthState(view: PathfinderView): void;
protected abstract clearForResolve(view: PathfinderView): void; protected abstract clearForResolve(view: PathfinderView): void;
protected abstract setResolveDepthState(view: PathfinderView): void; protected abstract setResolveDepthState(view: PathfinderView): void;
protected abstract setResolveUniforms(view: PathfinderView,
program: PathfinderShaderProgram): void;
abstract shouldRenderDirect: boolean; abstract shouldRenderDirect: boolean;
@ -1753,12 +1764,14 @@ abstract class ECAAStrategy implements AntialiasingStrategy {
protected directColorTexture: WebGLTexture; protected directColorTexture: WebGLTexture;
protected directPathIDTexture: WebGLTexture; protected directPathIDTexture: WebGLTexture;
protected bgColorTexture: WebGLTexture;
protected fgColorTexture: WebGLTexture;
protected framebufferSize: Size2D; protected framebufferSize: Size2D;
} }
class MonochromeECAAStrategy extends ECAAStrategy { class ECAAMonochromeStrategy extends ECAAStrategy {
protected getResolveProgram(view: PathfinderView): PathfinderShaderProgram {
return view.shaderPrograms.ecaaMonoResolve;
}
protected initEdgeDetectFramebuffer(view: PathfinderView) {} protected initEdgeDetectFramebuffer(view: PathfinderView) {}
protected createEdgeDetectVAO(view: PathfinderView) {} protected createEdgeDetectVAO(view: PathfinderView) {}
@ -1792,12 +1805,21 @@ class MonochromeECAAStrategy extends ECAAStrategy {
view.gl.clear(view.gl.COLOR_BUFFER_BIT); view.gl.clear(view.gl.COLOR_BUFFER_BIT);
} }
protected setResolveUniforms(view: PathfinderView, program: PathfinderShaderProgram) {
view.gl.uniform4fv(program.uniforms.uBGColor, view.bgColor);
view.gl.uniform4fv(program.uniforms.uFGColor, view.fgColor);
}
get shouldRenderDirect() { get shouldRenderDirect() {
return false; return false;
} }
} }
class MulticolorECAAStrategy extends ECAAStrategy { class ECAAMulticolorStrategy extends ECAAStrategy {
protected getResolveProgram(view: PathfinderView): PathfinderShaderProgram {
return view.shaderPrograms.ecaaMultiResolve;
}
protected initEdgeDetectFramebuffer(view: PathfinderView) { protected initEdgeDetectFramebuffer(view: PathfinderView) {
this.bgColorTexture = createFramebufferColorTexture(view.gl, this.framebufferSize); this.bgColorTexture = createFramebufferColorTexture(view.gl, this.framebufferSize);
this.fgColorTexture = createFramebufferColorTexture(view.gl, this.framebufferSize); this.fgColorTexture = createFramebufferColorTexture(view.gl, this.framebufferSize);
@ -1879,12 +1901,23 @@ class MulticolorECAAStrategy extends ECAAStrategy {
protected clearForResolve(view: PathfinderView) {} protected clearForResolve(view: PathfinderView) {}
protected setResolveUniforms(view: PathfinderView, program: PathfinderShaderProgram) {
view.gl.activeTexture(view.gl.TEXTURE1);
view.gl.bindTexture(view.gl.TEXTURE_2D, this.bgColorTexture);
view.gl.uniform1i(program.uniforms.uBGColor, 1);
view.gl.activeTexture(view.gl.TEXTURE2);
view.gl.bindTexture(view.gl.TEXTURE_2D, this.fgColorTexture);
view.gl.uniform1i(program.uniforms.uFGColor, 2);
}
get shouldRenderDirect() { get shouldRenderDirect() {
return true; return true;
} }
private edgeDetectFramebuffer: WebGLFramebuffer; private edgeDetectFramebuffer: WebGLFramebuffer;
private edgeDetectVAO: WebGLVertexArrayObject; private edgeDetectVAO: WebGLVertexArrayObject;
private bgColorTexture: WebGLTexture;
private fgColorTexture: WebGLTexture;
} }
interface AntialiasingStrategyTable { interface AntialiasingStrategyTable {
@ -1997,7 +2030,7 @@ class Atlas {
const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = { const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = {
none: NoAAStrategy, none: NoAAStrategy,
ssaa: SSAAStrategy, ssaa: SSAAStrategy,
ecaa: MonochromeECAAStrategy, ecaa: ECAAMonochromeStrategy,
}; };
function main() { function main() {

View File

@ -0,0 +1,16 @@
// pathfinder/shaders/gles2/ecaa-mono-resolve.fs.glsl
//
// Copyright (c) 2017 Mozilla Foundation
precision mediump float;
uniform vec4 uBGColor;
uniform vec4 uFGColor;
uniform sampler2D uAAAlpha;
varying vec2 vTexCoord;
void main() {
float alpha = clamp(texture2D(uAAAlpha, vTexCoord).r, 0.0, 1.0);
gl_FragColor = mix(uBGColor, uFGColor, alpha);
}

View File

@ -1,4 +1,4 @@
// pathfinder/shaders/gles2/ecaa-resolve.vs.glsl // pathfinder/shaders/gles2/ecaa-mono-resolve.vs.glsl
// //
// Copyright (c) 2017 Mozilla Foundation // Copyright (c) 2017 Mozilla Foundation

View File

@ -1,4 +1,4 @@
// pathfinder/shaders/gles2/ecaa-resolve.fs.glsl // pathfinder/shaders/gles2/ecaa-multi-resolve.fs.glsl
// //
// Copyright (c) 2017 Mozilla Foundation // Copyright (c) 2017 Mozilla Foundation
@ -11,8 +11,8 @@ uniform sampler2D uAAAlpha;
varying vec2 vTexCoord; varying vec2 vTexCoord;
void main() { void main() {
vec4 bgColor = vec4(1.0);//texture2D(uBGColor, vTexCoord); vec4 bgColor = texture2D(uBGColor, vTexCoord);
vec4 fgColor = vec4(vec3(0.0), 1.0);//texture2D(uFGColor, vTexCoord); vec4 fgColor = texture2D(uFGColor, vTexCoord);
float alpha = clamp(texture2D(uAAAlpha, vTexCoord).r, 0.0, 1.0); float alpha = clamp(texture2D(uAAAlpha, vTexCoord).r, 0.0, 1.0);
gl_FragColor = mix(bgColor, fgColor, alpha); gl_FragColor = mix(bgColor, fgColor, alpha);
} }

View File

@ -0,0 +1,18 @@
// pathfinder/shaders/gles2/ecaa-multi-resolve.vs.glsl
//
// Copyright (c) 2017 Mozilla Foundation
precision highp float;
uniform vec4 uTransformST;
uniform vec2 uTexScale;
attribute vec2 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
void main() {
gl_Position = vec4(transformVertexPositionST(aPosition, uTransformST), -1.0, 1.0);
vTexCoord = aTexCoord * uTexScale;
}