Fix compile errors in shaders

This commit is contained in:
Patrick Walton 2017-08-13 13:39:51 -07:00
parent d0dd883ddf
commit 5f89f7ba50
10 changed files with 107 additions and 81 deletions

View File

@ -8,6 +8,8 @@ const FONT_SIZE: number = 16.0;
const PARTITION_FONT_ENDPOINT_URL: string = "/partition-font";
const COMMON_SHADER_URL: string = '/glsl/gles2/common.inc.glsl';
const SHADER_URLS: ShaderURLMap = {
directCurve: {
vertex: "/glsl/gles2/direct-curve.vs.glsl",
@ -20,7 +22,7 @@ const SHADER_URLS: ShaderURLMap = {
};
interface ShaderURLMap {
[shaderName: string]: { 'vertex': string, 'fragment': string }
[shaderName: string]: { 'vertex': string, 'fragment': string };
}
interface ShaderMap {
@ -37,15 +39,21 @@ type ShaderTypeName = 'vertex' | 'fragment';
function expect<T>(value: T | null, message: string): T {
if (value == null)
throw new Error(message);
throw new PathfinderError(message);
return value;
}
class PathfinderError extends Error {
constructor(message?: string | undefined) {
super(message);
}
}
class PathfinderMeshes {
constructor(encodedResponse: string) {
const response = JSON.parse(encodedResponse);
if (!('Ok' in response))
throw new Error("Failed to partition the font!");
throw new PathfinderError("Failed to partition the font!");
const meshes = response.Ok;
this.bQuadPositions = base64js.toByteArray(meshes.bQuadPositions);
this.bQuadInfo = base64js.toByteArray(meshes.bQuadInfo);
@ -80,7 +88,7 @@ class AppController {
fontLoaded() {
this.font = opentype.parse(this.fontData);
if (!this.font.supported)
throw new Error("The font type is unsupported.");
throw new PathfinderError("The font type is unsupported.");
const glyphIDs = this.font.stringToGlyphs(TEXT).map((glyph: any) => glyph.index);
@ -120,7 +128,7 @@ class PathfinderView {
this.initContext();
this.loadShaders().then(shaders => this.shaderProgramsPromise = this.linkShaders(shaders));
this.shaderProgramsPromise = this.loadShaders().then(shaders => this.linkShaders(shaders));
window.addEventListener('resize', () => this.resizeToFit(), false);
this.resizeToFit();
@ -137,38 +145,65 @@ class PathfinderView {
loadShaders(): Promise<ShaderMap> {
let shaders: ShaderMap = {};
const shaderKeys = Object.keys(SHADER_URLS);
return window.fetch(COMMON_SHADER_URL)
.then((response) => response.text())
.then((commonSource) => {
const shaderKeys = Object.keys(SHADER_URLS);
let promises = [];
for (const shaderKey of shaderKeys) {
for (const typeName of ['vertex', 'fragment'] as Array<ShaderTypeName>) {
const type = {
vertex: this.gl.VERTEX_SHADER,
fragment: this.gl.FRAGMENT_SHADER,
}[typeName];
let promises = [];
for (const shaderKey of shaderKeys) {
for (const typeName of ['vertex', 'fragment'] as Array<ShaderTypeName>) {
const type = {
vertex: this.gl.VERTEX_SHADER,
fragment: this.gl.FRAGMENT_SHADER,
}[typeName];
const url = SHADER_URLS[shaderKey][typeName];
promises.push(window.fetch(url).then((response) => {
return response.text().then((source) => {
const url = SHADER_URLS[shaderKey][typeName];
promises.push(window.fetch(url)
.then(response => response.text())
.then(source => {
const shader = this.gl.createShader(type);
if (shader == null)
throw new Error("Failed to create shader!");
this.gl.shaderSource(shader, source);
throw new PathfinderError("Failed to create shader!");
this.gl.shaderSource(shader, commonSource + "\n#line 1\n" + source);
this.gl.compileShader(shader);
if (this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS) == 0) {
const infoLog = this.gl.getShaderInfoLog(shader);
throw new PathfinderError(`Failed to compile ${typeName} shader ` +
`"${shaderKey}":\n${infoLog}`);
}
if (!(shaderKey in shaders))
shaders[shaderKey] = {};
shaders[shaderKey][type] = shader;
});
}));
}));
}
}
}
return Promise.all(promises).then(() => shaders);
return Promise.all(promises);
}).then(() => shaders);
}
linkShaders(shaders: ShaderMap): Promise<ShaderProgramMap> {
// TODO(pcwalton)
throw new Error("TODO");
return new Promise((resolve, reject) => {
let shaderProgramMap: ShaderProgramMap = {};
for (const shaderKey of Object.keys(shaders)) {
const program = expect(this.gl.createProgram(), "Failed to create shader program!");
const compiledShaders = shaders[shaderKey];
for (const compiledShader of Object.values(compiledShaders))
this.gl.attachShader(program, compiledShader);
this.gl.linkProgram(program);
if (this.gl.getProgramParameter(program, this.gl.LINK_STATUS) == 0) {
const infoLog = this.gl.getProgramInfoLog(program);
throw new PathfinderError(`Failed to link program "${program}":\n${infoLog}`);
}
shaderProgramMap[shaderKey] = program;
}
resolve(shaderProgramMap);
});
}
resizeToFit() {
@ -182,7 +217,7 @@ class PathfinderView {
}
class PathfinderShaderProgram {
constructor(vertexShaderSource: string, fragmentShaderSource: string) {
constructor(vertexShader: WebGLShader, fragmentShader: WebGLShader) {
// TODO(pcwalton)
}
}

View File

@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es6",
"target": "ES2017",
"module": "commonjs",
"types": [
"node"

View File

@ -80,13 +80,13 @@ pub enum AntialiasingMode {
Ecaa = 1,
}
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(u8)]
pub enum BVertexKind {
Endpoint0 = 0,
Endpoint1 = 1,
ConvexControlPoint = 2,
ConcaveControlPoint = 3,
pub(crate) enum BVertexKind {
Endpoint0,
Endpoint1,
ConvexControlPoint,
ConcaveControlPoint,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
@ -94,22 +94,23 @@ pub enum BVertexKind {
pub struct BVertexInfo {
pub path_id: u32,
pub tex_coord: [u8; 2],
pub kind: BVertexKind,
pub sign: i8,
pad: u8,
}
impl BVertexInfo {
#[inline]
pub fn new(kind: BVertexKind, path_id: u32) -> BVertexInfo {
let tex_coord = match kind {
BVertexKind::Endpoint0 => [0, 0],
BVertexKind::Endpoint1 => [2, 2],
BVertexKind::ConcaveControlPoint | BVertexKind::ConvexControlPoint => [1, 0],
pub(crate) fn new(kind: BVertexKind, path_id: u32) -> BVertexInfo {
let (tex_coord, sign) = match kind {
BVertexKind::Endpoint0 => ([0, 0], 0),
BVertexKind::Endpoint1 => ([2, 2], 0),
BVertexKind::ConcaveControlPoint => ([1, 0], 1),
BVertexKind::ConvexControlPoint => ([1, 0], -1),
};
BVertexInfo {
path_id: path_id,
tex_coord: tex_coord,
kind: kind,
sign: sign,
pad: 0,
}
}

View File

@ -9,11 +9,6 @@
#define PF_ANTIALIASING_MODE_MSAA 0
#define PF_ANTIALIASING_MODE_ECAA 1
#define PF_B_VERTEX_KIND_ENDPOINT_0 0
#define PF_B_VERTEX_KIND_ENDPOINT_1 1
#define PF_B_VERTEX_KIND_CONVEX_CONTROL_POINT 2
#define PF_B_VERTEX_KIND_CONCAVE_CONTROL_POINT 3
#ifdef __cplusplus
extern "C" {
#endif
@ -22,8 +17,6 @@ typedef uint8_t pf_antialiasing_mode_t;
typedef uint16_t pf_float16_t;
typedef uint8_t pf_b_vertex_kind_t;
struct pf_point2d_f32 {
float x, y;
};
@ -40,7 +33,7 @@ typedef struct pf_matrix2d_f32 pf_matrix2d_f32_t;
struct pf_b_vertex_info {
uint32_t path_id;
uint8_t tex_coord[2];
pf_b_vertex_kind_t kind;
int8_t sign;
uint8_t pad;
};

View File

@ -1017,11 +1017,11 @@ struct SubdividedActiveEdge {
impl SubdividedActiveEdge {
fn shape(&self, b_vertex_info: &[BVertexInfo]) -> Shape {
if self.left_curve_control_point == u32::MAX {
return Shape::Flat
}
match b_vertex_info[self.left_curve_control_point as usize].kind {
BVertexKind::ConvexControlPoint => Shape::Convex,
_ => Shape::Concave,
Shape::Flat
} else if b_vertex_info[self.left_curve_control_point as usize].sign < 0 {
Shape::Convex
} else {
Shape::Concave
}
}
}

View File

@ -2,8 +2,19 @@
//
// Copyright (c) 2017 Mozilla Foundation
#version 100
#define MAX_PATHS 65536
precision highp float;
// https://stackoverflow.com/a/36078859
int imod(int ia, int ib) {
float a = float(ia), b = float(ib);
float m = a - floor((a + 0.5) / b) * b;
return int(floor(m + 0.5));
}
vec2 transformVertexPosition(vec2 position, mat4 transform) {
return (transform * vec4(position, 0.0, 1.0)).xy;
}
@ -17,5 +28,10 @@ float convertPathIndexToDepthValue(int pathIndex) {
}
vec4 fetchFloat4Data(sampler2D dataTexture, int index, ivec2 dimensions) {
return texture2D(dataTexture, (float(index) + 0.5) / vec2(dimensions));
ivec2 pixelCoord = ivec2(imod(index, dimensions.x), index / dimensions.x);
return texture2D(dataTexture, (vec2(pixelCoord) + 0.5) / vec2(dimensions));
}
vec4 fetchFloat4NormIndexedData(sampler2D dataTexture, float normIndex, ivec2 dimensions) {
return fetchFloat4Data(dataTexture, int(normIndex * float(dimensions.x)), dimensions);
}

View File

@ -6,8 +6,6 @@
// It is therefore unsuitable for ECAA, but it's fast (specifically, preserving early Z) and
// compatible with OpenGL ES 2.0.
#version 100
precision highp float;
varying vec4 vColor;

View File

@ -2,8 +2,6 @@
//
// Copyright (c) 2017 Mozilla Foundation
#version 100
precision highp float;
uniform mat4 uTransform;
@ -12,8 +10,9 @@ uniform ivec2 uPathColorsDimensions;
uniform sampler2D uPathColors;
attribute vec2 aPosition;
attribute ivec2 aTexCoord;
attribute int aKind;
attribute vec2 aTexCoord;
attribute float aPathDepth;
attribute float aSign;
varying vec4 vColor;
varying vec2 vTexCoord;
@ -22,20 +21,9 @@ varying float vSign;
void main() {
vec2 position = transformVertexPosition(aPosition, uTransform);
position = convertScreenToClipSpace(position, uFramebufferSize);
float depth = convertPathIndexToDepthValue(aPathIndex);
gl_Position = vec4(position, depth, 1.0);
gl_Position = vec4(position, aPathDepth, 1.0);
vColor = fetchFloat4Data(uPathColors, aPathIndex, uPathColorsDimensions);
vColor = fetchFloat4NormIndexedData(uPathColors, aPathDepth, uPathColorsDimensions);
vTexCoord = vec2(aTexCoord) / 2.0;
switch (aKind) {
case PF_B_VERTEX_KIND_CONVEX_CONTROL_POINT:
vSign = -1.0;
break;
case PF_B_VERTEX_KIND_CONCAVE_CONTROL_POINT:
vSign = 1.0;
break;
default:
vSign = 0.0;
}
vSign = aSign;
}

View File

@ -2,8 +2,6 @@
//
// Copyright (c) 2017 Mozilla Foundation
#version 100
precision highp float;
varying vec4 vColor;

View File

@ -2,8 +2,6 @@
//
// Copyright (c) 2017 Mozilla Foundation
#version 100
precision highp float;
uniform mat4 uTransform;
@ -13,15 +11,14 @@ uniform ivec2 uPathColorsDimensions;
uniform sampler2D uPathColors;
attribute vec2 aPosition;
attribute int aPathIndex;
attribute float aPathDepth;
varying vec4 vColor;
void main() {
vec2 position = transformVertexPosition(aPosition, uTransform);
position = convertScreenToClipSpace(position, uFramebufferSize);
float depth = convertPathIndexToDepthValue(aPathIndex);
gl_Position = vec4(position, depth, 1.0);
gl_Position = vec4(position, aPathDepth, 1.0);
vColor = fetchFloat4Data(uPathColors, aPathIndex, uPathColorsDimensions);
vColor = fetchFloat4NormIndexedData(uPathColors, aPathDepth, uPathColorsDimensions);
}