Fix compile errors in shaders
This commit is contained in:
parent
d0dd883ddf
commit
5f89f7ba50
|
@ -8,6 +8,8 @@ const FONT_SIZE: number = 16.0;
|
||||||
|
|
||||||
const PARTITION_FONT_ENDPOINT_URL: string = "/partition-font";
|
const PARTITION_FONT_ENDPOINT_URL: string = "/partition-font";
|
||||||
|
|
||||||
|
const COMMON_SHADER_URL: string = '/glsl/gles2/common.inc.glsl';
|
||||||
|
|
||||||
const SHADER_URLS: ShaderURLMap = {
|
const SHADER_URLS: ShaderURLMap = {
|
||||||
directCurve: {
|
directCurve: {
|
||||||
vertex: "/glsl/gles2/direct-curve.vs.glsl",
|
vertex: "/glsl/gles2/direct-curve.vs.glsl",
|
||||||
|
@ -20,7 +22,7 @@ const SHADER_URLS: ShaderURLMap = {
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ShaderURLMap {
|
interface ShaderURLMap {
|
||||||
[shaderName: string]: { 'vertex': string, 'fragment': string }
|
[shaderName: string]: { 'vertex': string, 'fragment': string };
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ShaderMap {
|
interface ShaderMap {
|
||||||
|
@ -37,15 +39,21 @@ type ShaderTypeName = 'vertex' | 'fragment';
|
||||||
|
|
||||||
function expect<T>(value: T | null, message: string): T {
|
function expect<T>(value: T | null, message: string): T {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
throw new Error(message);
|
throw new PathfinderError(message);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PathfinderError extends Error {
|
||||||
|
constructor(message?: string | undefined) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class PathfinderMeshes {
|
class PathfinderMeshes {
|
||||||
constructor(encodedResponse: string) {
|
constructor(encodedResponse: string) {
|
||||||
const response = JSON.parse(encodedResponse);
|
const response = JSON.parse(encodedResponse);
|
||||||
if (!('Ok' in response))
|
if (!('Ok' in response))
|
||||||
throw new Error("Failed to partition the font!");
|
throw new PathfinderError("Failed to partition the font!");
|
||||||
const meshes = response.Ok;
|
const meshes = response.Ok;
|
||||||
this.bQuadPositions = base64js.toByteArray(meshes.bQuadPositions);
|
this.bQuadPositions = base64js.toByteArray(meshes.bQuadPositions);
|
||||||
this.bQuadInfo = base64js.toByteArray(meshes.bQuadInfo);
|
this.bQuadInfo = base64js.toByteArray(meshes.bQuadInfo);
|
||||||
|
@ -80,7 +88,7 @@ class AppController {
|
||||||
fontLoaded() {
|
fontLoaded() {
|
||||||
this.font = opentype.parse(this.fontData);
|
this.font = opentype.parse(this.fontData);
|
||||||
if (!this.font.supported)
|
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);
|
const glyphIDs = this.font.stringToGlyphs(TEXT).map((glyph: any) => glyph.index);
|
||||||
|
|
||||||
|
@ -120,7 +128,7 @@ class PathfinderView {
|
||||||
|
|
||||||
this.initContext();
|
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);
|
window.addEventListener('resize', () => this.resizeToFit(), false);
|
||||||
this.resizeToFit();
|
this.resizeToFit();
|
||||||
|
@ -137,38 +145,65 @@ class PathfinderView {
|
||||||
|
|
||||||
loadShaders(): Promise<ShaderMap> {
|
loadShaders(): Promise<ShaderMap> {
|
||||||
let shaders: 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 = [];
|
let promises = [];
|
||||||
for (const shaderKey of shaderKeys) {
|
for (const shaderKey of shaderKeys) {
|
||||||
for (const typeName of ['vertex', 'fragment'] as Array<ShaderTypeName>) {
|
for (const typeName of ['vertex', 'fragment'] as Array<ShaderTypeName>) {
|
||||||
const type = {
|
const type = {
|
||||||
vertex: this.gl.VERTEX_SHADER,
|
vertex: this.gl.VERTEX_SHADER,
|
||||||
fragment: this.gl.FRAGMENT_SHADER,
|
fragment: this.gl.FRAGMENT_SHADER,
|
||||||
}[typeName];
|
}[typeName];
|
||||||
|
|
||||||
const url = SHADER_URLS[shaderKey][typeName];
|
const url = SHADER_URLS[shaderKey][typeName];
|
||||||
promises.push(window.fetch(url).then((response) => {
|
promises.push(window.fetch(url)
|
||||||
return response.text().then((source) => {
|
.then(response => response.text())
|
||||||
|
.then(source => {
|
||||||
const shader = this.gl.createShader(type);
|
const shader = this.gl.createShader(type);
|
||||||
if (shader == null)
|
if (shader == null)
|
||||||
throw new Error("Failed to create shader!");
|
throw new PathfinderError("Failed to create shader!");
|
||||||
this.gl.shaderSource(shader, source);
|
this.gl.shaderSource(shader, commonSource + "\n#line 1\n" + source);
|
||||||
this.gl.compileShader(shader);
|
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))
|
if (!(shaderKey in shaders))
|
||||||
shaders[shaderKey] = {};
|
shaders[shaderKey] = {};
|
||||||
shaders[shaderKey][type] = shader;
|
shaders[shaderKey][type] = shader;
|
||||||
});
|
}));
|
||||||
}));
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.all(promises).then(() => shaders);
|
return Promise.all(promises);
|
||||||
|
}).then(() => shaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
linkShaders(shaders: ShaderMap): Promise<ShaderProgramMap> {
|
linkShaders(shaders: ShaderMap): Promise<ShaderProgramMap> {
|
||||||
// TODO(pcwalton)
|
return new Promise((resolve, reject) => {
|
||||||
throw new Error("TODO");
|
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() {
|
resizeToFit() {
|
||||||
|
@ -182,7 +217,7 @@ class PathfinderView {
|
||||||
}
|
}
|
||||||
|
|
||||||
class PathfinderShaderProgram {
|
class PathfinderShaderProgram {
|
||||||
constructor(vertexShaderSource: string, fragmentShaderSource: string) {
|
constructor(vertexShader: WebGLShader, fragmentShader: WebGLShader) {
|
||||||
// TODO(pcwalton)
|
// TODO(pcwalton)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es6",
|
"target": "ES2017",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"types": [
|
"types": [
|
||||||
"node"
|
"node"
|
||||||
|
|
|
@ -80,13 +80,13 @@ pub enum AntialiasingMode {
|
||||||
Ecaa = 1,
|
Ecaa = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum BVertexKind {
|
pub(crate) enum BVertexKind {
|
||||||
Endpoint0 = 0,
|
Endpoint0,
|
||||||
Endpoint1 = 1,
|
Endpoint1,
|
||||||
ConvexControlPoint = 2,
|
ConvexControlPoint,
|
||||||
ConcaveControlPoint = 3,
|
ConcaveControlPoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
|
@ -94,22 +94,23 @@ pub enum BVertexKind {
|
||||||
pub struct BVertexInfo {
|
pub struct BVertexInfo {
|
||||||
pub path_id: u32,
|
pub path_id: u32,
|
||||||
pub tex_coord: [u8; 2],
|
pub tex_coord: [u8; 2],
|
||||||
pub kind: BVertexKind,
|
pub sign: i8,
|
||||||
pad: u8,
|
pad: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BVertexInfo {
|
impl BVertexInfo {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(kind: BVertexKind, path_id: u32) -> BVertexInfo {
|
pub(crate) fn new(kind: BVertexKind, path_id: u32) -> BVertexInfo {
|
||||||
let tex_coord = match kind {
|
let (tex_coord, sign) = match kind {
|
||||||
BVertexKind::Endpoint0 => [0, 0],
|
BVertexKind::Endpoint0 => ([0, 0], 0),
|
||||||
BVertexKind::Endpoint1 => [2, 2],
|
BVertexKind::Endpoint1 => ([2, 2], 0),
|
||||||
BVertexKind::ConcaveControlPoint | BVertexKind::ConvexControlPoint => [1, 0],
|
BVertexKind::ConcaveControlPoint => ([1, 0], 1),
|
||||||
|
BVertexKind::ConvexControlPoint => ([1, 0], -1),
|
||||||
};
|
};
|
||||||
BVertexInfo {
|
BVertexInfo {
|
||||||
path_id: path_id,
|
path_id: path_id,
|
||||||
tex_coord: tex_coord,
|
tex_coord: tex_coord,
|
||||||
kind: kind,
|
sign: sign,
|
||||||
pad: 0,
|
pad: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,6 @@
|
||||||
#define PF_ANTIALIASING_MODE_MSAA 0
|
#define PF_ANTIALIASING_MODE_MSAA 0
|
||||||
#define PF_ANTIALIASING_MODE_ECAA 1
|
#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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,8 +17,6 @@ typedef uint8_t pf_antialiasing_mode_t;
|
||||||
|
|
||||||
typedef uint16_t pf_float16_t;
|
typedef uint16_t pf_float16_t;
|
||||||
|
|
||||||
typedef uint8_t pf_b_vertex_kind_t;
|
|
||||||
|
|
||||||
struct pf_point2d_f32 {
|
struct pf_point2d_f32 {
|
||||||
float x, y;
|
float x, y;
|
||||||
};
|
};
|
||||||
|
@ -40,7 +33,7 @@ typedef struct pf_matrix2d_f32 pf_matrix2d_f32_t;
|
||||||
struct pf_b_vertex_info {
|
struct pf_b_vertex_info {
|
||||||
uint32_t path_id;
|
uint32_t path_id;
|
||||||
uint8_t tex_coord[2];
|
uint8_t tex_coord[2];
|
||||||
pf_b_vertex_kind_t kind;
|
int8_t sign;
|
||||||
uint8_t pad;
|
uint8_t pad;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1017,11 +1017,11 @@ struct SubdividedActiveEdge {
|
||||||
impl SubdividedActiveEdge {
|
impl SubdividedActiveEdge {
|
||||||
fn shape(&self, b_vertex_info: &[BVertexInfo]) -> Shape {
|
fn shape(&self, b_vertex_info: &[BVertexInfo]) -> Shape {
|
||||||
if self.left_curve_control_point == u32::MAX {
|
if self.left_curve_control_point == u32::MAX {
|
||||||
return Shape::Flat
|
Shape::Flat
|
||||||
}
|
} else if b_vertex_info[self.left_curve_control_point as usize].sign < 0 {
|
||||||
match b_vertex_info[self.left_curve_control_point as usize].kind {
|
Shape::Convex
|
||||||
BVertexKind::ConvexControlPoint => Shape::Convex,
|
} else {
|
||||||
_ => Shape::Concave,
|
Shape::Concave
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,19 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2017 Mozilla Foundation
|
// Copyright (c) 2017 Mozilla Foundation
|
||||||
|
|
||||||
|
#version 100
|
||||||
|
|
||||||
#define MAX_PATHS 65536
|
#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) {
|
vec2 transformVertexPosition(vec2 position, mat4 transform) {
|
||||||
return (transform * vec4(position, 0.0, 1.0)).xy;
|
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) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
// It is therefore unsuitable for ECAA, but it's fast (specifically, preserving early Z) and
|
// It is therefore unsuitable for ECAA, but it's fast (specifically, preserving early Z) and
|
||||||
// compatible with OpenGL ES 2.0.
|
// compatible with OpenGL ES 2.0.
|
||||||
|
|
||||||
#version 100
|
|
||||||
|
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
varying vec4 vColor;
|
varying vec4 vColor;
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2017 Mozilla Foundation
|
// Copyright (c) 2017 Mozilla Foundation
|
||||||
|
|
||||||
#version 100
|
|
||||||
|
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
uniform mat4 uTransform;
|
uniform mat4 uTransform;
|
||||||
|
@ -12,8 +10,9 @@ uniform ivec2 uPathColorsDimensions;
|
||||||
uniform sampler2D uPathColors;
|
uniform sampler2D uPathColors;
|
||||||
|
|
||||||
attribute vec2 aPosition;
|
attribute vec2 aPosition;
|
||||||
attribute ivec2 aTexCoord;
|
attribute vec2 aTexCoord;
|
||||||
attribute int aKind;
|
attribute float aPathDepth;
|
||||||
|
attribute float aSign;
|
||||||
|
|
||||||
varying vec4 vColor;
|
varying vec4 vColor;
|
||||||
varying vec2 vTexCoord;
|
varying vec2 vTexCoord;
|
||||||
|
@ -22,20 +21,9 @@ varying float vSign;
|
||||||
void main() {
|
void main() {
|
||||||
vec2 position = transformVertexPosition(aPosition, uTransform);
|
vec2 position = transformVertexPosition(aPosition, uTransform);
|
||||||
position = convertScreenToClipSpace(position, uFramebufferSize);
|
position = convertScreenToClipSpace(position, uFramebufferSize);
|
||||||
float depth = convertPathIndexToDepthValue(aPathIndex);
|
gl_Position = vec4(position, aPathDepth, 1.0);
|
||||||
gl_Position = vec4(position, depth, 1.0);
|
|
||||||
|
|
||||||
vColor = fetchFloat4Data(uPathColors, aPathIndex, uPathColorsDimensions);
|
vColor = fetchFloat4NormIndexedData(uPathColors, aPathDepth, uPathColorsDimensions);
|
||||||
vTexCoord = vec2(aTexCoord) / 2.0;
|
vTexCoord = vec2(aTexCoord) / 2.0;
|
||||||
|
vSign = aSign;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2017 Mozilla Foundation
|
// Copyright (c) 2017 Mozilla Foundation
|
||||||
|
|
||||||
#version 100
|
|
||||||
|
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
varying vec4 vColor;
|
varying vec4 vColor;
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2017 Mozilla Foundation
|
// Copyright (c) 2017 Mozilla Foundation
|
||||||
|
|
||||||
#version 100
|
|
||||||
|
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
uniform mat4 uTransform;
|
uniform mat4 uTransform;
|
||||||
|
@ -13,15 +11,14 @@ uniform ivec2 uPathColorsDimensions;
|
||||||
uniform sampler2D uPathColors;
|
uniform sampler2D uPathColors;
|
||||||
|
|
||||||
attribute vec2 aPosition;
|
attribute vec2 aPosition;
|
||||||
attribute int aPathIndex;
|
attribute float aPathDepth;
|
||||||
|
|
||||||
varying vec4 vColor;
|
varying vec4 vColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 position = transformVertexPosition(aPosition, uTransform);
|
vec2 position = transformVertexPosition(aPosition, uTransform);
|
||||||
position = convertScreenToClipSpace(position, uFramebufferSize);
|
position = convertScreenToClipSpace(position, uFramebufferSize);
|
||||||
float depth = convertPathIndexToDepthValue(aPathIndex);
|
gl_Position = vec4(position, aPathDepth, 1.0);
|
||||||
gl_Position = vec4(position, depth, 1.0);
|
|
||||||
|
|
||||||
vColor = fetchFloat4Data(uPathColors, aPathIndex, uPathColorsDimensions);
|
vColor = fetchFloat4NormIndexedData(uPathColors, aPathDepth, uPathColorsDimensions);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue