Split path IDs and Loop-Blinn data into separate VBOs

This commit is contained in:
Patrick Walton 2017-08-17 12:47:50 -07:00
parent 0a4d57580a
commit ec78a632dc
7 changed files with 160 additions and 125 deletions

View File

@ -14,10 +14,11 @@ const UINT32_SIZE: number = 4;
const B_POSITION_SIZE: number = 8;
const B_VERTEX_SIZE: number = 8;
const B_VERTEX_PATH_ID_OFFSET: number = 0;
const B_VERTEX_TEX_COORD_OFFSET: number = 4;
const B_VERTEX_SIGN_OFFSET: number = 6;
const B_PATH_INDEX_SIZE: number = 2;
const B_LOOP_BLINN_DATA_SIZE: number = 4;
const B_LOOP_BLINN_DATA_TEX_COORD_OFFSET: number = 0;
const B_LOOP_BLINN_DATA_SIGN_OFFSET: number = 2;
const IDENTITY: Matrix4D = [
1.0, 0.0, 0.0, 0.0,
@ -249,7 +250,8 @@ function initQuadVAO(view: PathfinderView, attributes: any) {
interface Meshes<T> {
readonly bQuads: T;
readonly bVertexPositions: T;
readonly bVertexInfo: T;
readonly bVertexPathIDs: T;
readonly bVertexLoopBlinnData: T;
readonly coverInteriorIndices: T;
readonly coverCurveIndices: T;
readonly edgeUpperLineIndices: T;
@ -258,18 +260,19 @@ interface Meshes<T> {
readonly edgeLowerCurveIndices: T;
}
type BufferType = number;
type BufferType = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER';
const BUFFER_TYPES: Meshes<BufferType> = {
bQuads: WebGLRenderingContext.ARRAY_BUFFER,
bVertexPositions: WebGLRenderingContext.ARRAY_BUFFER,
bVertexInfo: WebGLRenderingContext.ARRAY_BUFFER,
coverInteriorIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
coverCurveIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
edgeUpperLineIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
edgeUpperCurveIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
edgeLowerLineIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
edgeLowerCurveIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
bQuads: 'ARRAY_BUFFER',
bVertexPositions: 'ARRAY_BUFFER',
bVertexPathIDs: 'ARRAY_BUFFER',
bVertexLoopBlinnData: 'ARRAY_BUFFER',
coverInteriorIndices: 'ELEMENT_ARRAY_BUFFER',
coverCurveIndices: 'ELEMENT_ARRAY_BUFFER',
edgeUpperLineIndices: 'ELEMENT_ARRAY_BUFFER',
edgeUpperCurveIndices: 'ELEMENT_ARRAY_BUFFER',
edgeLowerLineIndices: 'ELEMENT_ARRAY_BUFFER',
edgeLowerCurveIndices: 'ELEMENT_ARRAY_BUFFER',
};
class PathfinderMeshData implements Meshes<ArrayBuffer> {
@ -284,7 +287,8 @@ class PathfinderMeshData implements Meshes<ArrayBuffer> {
readonly bQuads: ArrayBuffer;
readonly bVertexPositions: ArrayBuffer;
readonly bVertexInfo: ArrayBuffer;
readonly bVertexPathIDs: ArrayBuffer;
readonly bVertexLoopBlinnData: ArrayBuffer;
readonly coverInteriorIndices: ArrayBuffer;
readonly coverCurveIndices: ArrayBuffer;
readonly edgeUpperLineIndices: ArrayBuffer;
@ -296,7 +300,7 @@ class PathfinderMeshData implements Meshes<ArrayBuffer> {
class PathfinderMeshBuffers implements Meshes<WebGLBuffer> {
constructor(gl: WebGLRenderingContext, meshData: PathfinderMeshData) {
for (const bufferName of Object.keys(BUFFER_TYPES) as Array<keyof PathfinderMeshBuffers>) {
const bufferType = BUFFER_TYPES[bufferName];
const bufferType = gl[BUFFER_TYPES[bufferName]];
const buffer = expectNotNull(gl.createBuffer(), "Failed to create buffer!");
gl.bindBuffer(bufferType, buffer);
gl.bufferData(bufferType, meshData[bufferName], gl.STATIC_DRAW);
@ -306,7 +310,8 @@ class PathfinderMeshBuffers implements Meshes<WebGLBuffer> {
readonly bQuads: WebGLBuffer;
readonly bVertexPositions: WebGLBuffer;
readonly bVertexInfo: WebGLBuffer;
readonly bVertexPathIDs: WebGLBuffer;
readonly bVertexLoopBlinnData: WebGLBuffer;
readonly coverInteriorIndices: WebGLBuffer;
readonly coverCurveIndices: WebGLBuffer;
readonly edgeUpperLineIndices: WebGLBuffer;
@ -563,13 +568,13 @@ class PathfinderView {
false,
0,
0);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexInfo);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPathIDs);
this.gl.vertexAttribPointer(directInteriorProgram.attributes.aPathID,
1,
this.gl.UNSIGNED_SHORT, // FIXME(pcwalton)
this.gl.UNSIGNED_SHORT,
false,
B_VERTEX_SIZE,
B_VERTEX_PATH_ID_OFFSET);
0,
0);
this.gl.enableVertexAttribArray(directInteriorProgram.attributes.aPosition);
this.gl.enableVertexAttribArray(directInteriorProgram.attributes.aPathID);
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.meshes.coverInteriorIndices);
@ -605,25 +610,26 @@ class PathfinderView {
false,
0,
0);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexInfo);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPathIDs);
this.gl.vertexAttribPointer(directCurveProgram.attributes.aPathID,
1,
this.gl.UNSIGNED_SHORT,
false,
0,
0);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexLoopBlinnData);
this.gl.vertexAttribPointer(directCurveProgram.attributes.aTexCoord,
2,
this.gl.UNSIGNED_BYTE,
false,
B_VERTEX_SIZE,
B_VERTEX_TEX_COORD_OFFSET);
this.gl.vertexAttribPointer(directCurveProgram.attributes.aPathID,
1,
this.gl.UNSIGNED_SHORT, // FIXME(pcwalton)
false,
B_VERTEX_SIZE,
B_VERTEX_PATH_ID_OFFSET);
B_LOOP_BLINN_DATA_SIZE,
B_LOOP_BLINN_DATA_TEX_COORD_OFFSET);
this.gl.vertexAttribPointer(directCurveProgram.attributes.aSign,
1,
this.gl.BYTE,
false,
B_VERTEX_SIZE,
B_VERTEX_SIGN_OFFSET);
B_LOOP_BLINN_DATA_SIZE,
B_LOOP_BLINN_DATA_SIGN_OFFSET);
this.gl.enableVertexAttribArray(directCurveProgram.attributes.aPosition);
this.gl.enableVertexAttribArray(directCurveProgram.attributes.aTexCoord);
this.gl.enableVertexAttribArray(directCurveProgram.attributes.aPathID);

View File

@ -119,8 +119,10 @@ struct PartitionFontResponse {
bQuads: String,
// Base64-encoded `bincode`-encoded `Point2D<f32>`s.
bVertexPositions: String,
// Base64-encoded `bincode`-encoded `BVertexInfo`s.
bVertexInfo: String,
// Base64-encoded `bincode`-encoded `u16`s.
bVertexPathIDs: String,
// Base64-encoded `bincode`-encoded `BVertexLoopBlinnData`s.
bVertexLoopBlinnData: String,
// Base64-encoded `u32`s.
coverInteriorIndices: String,
// Base64-encoded `u32`s.
@ -195,7 +197,8 @@ fn partition_font(request: Json<PartitionFontRequest>)
// Partition the decoded glyph outlines.
let mut partitioner = Partitioner::new();
let (mut b_quads, mut b_vertex_positions, mut b_vertex_info) = (vec![], vec![], vec![]);
let (mut b_quads, mut b_vertex_positions) = (vec![], vec![]);
let (mut b_vertex_path_ids, mut b_vertex_loop_blinn_data) = (vec![], vec![]);
let (mut cover_interior_indices, mut cover_curve_indices) = (vec![], vec![]);
let (mut edge_upper_line_indices, mut edge_upper_curve_indices) = (vec![], vec![]);
let (mut edge_lower_line_indices, mut edge_lower_curve_indices) = (vec![], vec![]);
@ -224,27 +227,30 @@ fn partition_font(request: Json<PartitionFontRequest>)
}
};
partitioner.partition((path_index + 1) as u32,
partitioner.partition((path_index + 1) as u16,
decoded_outline_indices.subpath_indices.start as u32,
decoded_outline_indices.subpath_indices.end as u32);
let path_b_quads = partitioner.b_quads();
let path_b_vertex_positions = partitioner.b_vertex_positions();
let path_b_vertex_info = partitioner.b_vertex_info();
let path_b_vertex_path_ids = partitioner.b_vertex_path_ids();
let path_b_vertex_loop_blinn_data = partitioner.b_vertex_loop_blinn_data();
let cover_indices = partitioner.cover_indices();
let edge_indices = partitioner.edge_indices();
IndexRange::from_vector_append_and_serialization(&mut b_vertex_positions,
path_b_vertex_positions).unwrap();
IndexRange::from_vector_append_and_serialization(&mut b_vertex_path_ids,
path_b_vertex_path_ids).unwrap();
glyph_info.push(PartitionGlyphInfo {
id: glyph_id,
dimensions: dimensions,
bQuadIndices: IndexRange::from_vector_append_and_serialization(&mut b_quads,
path_b_quads).unwrap(),
bVertexIndices:
IndexRange::from_vector_append_and_serialization(&mut b_vertex_info,
path_b_vertex_info).unwrap(),
bVertexIndices: IndexRange::from_vector_append_and_serialization(
&mut b_vertex_loop_blinn_data,
path_b_vertex_loop_blinn_data).unwrap(),
coverInteriorIndices: IndexRange::from_vector_append_and_serialization(
&mut cover_interior_indices,
cover_indices.interior_indices).unwrap(),
@ -271,7 +277,8 @@ fn partition_font(request: Json<PartitionFontRequest>)
glyphInfo: glyph_info,
bQuads: base64::encode(&b_quads),
bVertexPositions: base64::encode(&b_vertex_positions),
bVertexInfo: base64::encode(&b_vertex_info),
bVertexPathIDs: base64::encode(&b_vertex_path_ids),
bVertexLoopBlinnData: base64::encode(&b_vertex_loop_blinn_data),
coverInteriorIndices: base64::encode(&cover_interior_indices),
coverCurveIndices: base64::encode(&cover_curve_indices),
edgeUpperLineIndices: base64::encode(&edge_upper_line_indices),

View File

@ -6,7 +6,7 @@ use legalizer::Legalizer;
use partitioner::Partitioner;
use std::mem;
use std::slice;
use {BQuad, BVertexInfo, CurveIndices, Endpoint, LineIndices, Subpath};
use {BQuad, BVertexLoopBlinnData, CurveIndices, Endpoint, LineIndices, Subpath};
#[derive(Clone, Copy)]
#[repr(C)]
@ -166,7 +166,7 @@ pub unsafe extern fn pf_partitioner_init<'a>(partitioner: *mut Partitioner<'a>,
#[no_mangle]
pub unsafe extern fn pf_partitioner_partition<'a>(partitioner: *mut Partitioner<'a>,
path_id: u32,
path_id: u16,
first_subpath_index: u32,
last_subpath_index: u32) {
(*partitioner).partition(path_id, first_subpath_index, last_subpath_index)
@ -195,14 +195,26 @@ pub unsafe extern fn pf_partitioner_b_vertex_positions<'a>(partitioner: *const P
}
#[no_mangle]
pub unsafe extern fn pf_partitioner_b_vertex_info<'a>(partitioner: *const Partitioner<'a>,
out_b_vertex_count: *mut u32)
-> *const BVertexInfo {
let b_vertex_info = (*partitioner).b_vertex_info();
pub unsafe extern fn pf_partitioner_b_vertex_path_ids<'a>(partitioner: *const Partitioner<'a>,
out_b_vertex_count: *mut u32)
-> *const u16 {
let b_vertex_path_ids = (*partitioner).b_vertex_path_ids();
if !out_b_vertex_count.is_null() {
*out_b_vertex_count = b_vertex_info.len() as u32
*out_b_vertex_count = b_vertex_path_ids.len() as u32
}
b_vertex_info.as_ptr() as *const BVertexInfo
b_vertex_path_ids.as_ptr() as *const u16
}
#[no_mangle]
pub unsafe extern fn pf_partitioner_b_vertex_loop_blinn_data<'a>(
partitioner: *const Partitioner<'a>,
out_b_vertex_count: *mut u32)
-> *const BVertexLoopBlinnData {
let b_vertex_loop_blinn_data = (*partitioner).b_vertex_loop_blinn_data();
if !out_b_vertex_count.is_null() {
*out_b_vertex_count = b_vertex_loop_blinn_data.len() as u32
}
b_vertex_loop_blinn_data.as_ptr() as *const BVertexLoopBlinnData
}
#[no_mangle]

View File

@ -91,24 +91,22 @@ pub(crate) enum BVertexKind {
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
#[repr(C)]
pub struct BVertexInfo {
pub path_id: u32,
pub struct BVertexLoopBlinnData {
pub tex_coord: [u8; 2],
pub sign: i8,
pad: u8,
}
impl BVertexInfo {
impl BVertexLoopBlinnData {
#[inline]
pub(crate) fn new(kind: BVertexKind, path_id: u32) -> BVertexInfo {
pub(crate) fn new(kind: BVertexKind) -> BVertexLoopBlinnData {
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,
BVertexLoopBlinnData {
tex_coord: tex_coord,
sign: sign,
pad: 0,
@ -118,9 +116,8 @@ impl BVertexInfo {
pub(crate) fn control_point(left_endpoint_position: &Point2D<f32>,
control_point_position: &Point2D<f32>,
right_endpoint_position: &Point2D<f32>,
path_id: u32,
bottom: bool)
-> BVertexInfo {
-> BVertexLoopBlinnData {
let control_point_vector = *control_point_position - *left_endpoint_position;
let right_vector = *right_endpoint_position - *left_endpoint_position;
let determinant = right_vector.cross(control_point_vector);
@ -129,7 +126,7 @@ impl BVertexInfo {
} else {
BVertexKind::ConcaveControlPoint
};
BVertexInfo::new(endpoint_kind, path_id)
BVertexLoopBlinnData::new(endpoint_kind)
}
}

View File

@ -6,15 +6,10 @@
#include <limits.h>
#include <stdint.h>
#define PF_ANTIALIASING_MODE_MSAA 0
#define PF_ANTIALIASING_MODE_ECAA 1
#ifdef __cplusplus
extern "C" {
#endif
typedef uint8_t pf_antialiasing_mode_t;
typedef uint16_t pf_float16_t;
struct pf_point2d_f32 {
@ -30,14 +25,13 @@ struct pf_matrix2d_f32 {
typedef struct pf_matrix2d_f32 pf_matrix2d_f32_t;
struct pf_b_vertex_info {
uint32_t path_id;
struct pf_b_vertex_loop_blinn_data {
uint8_t tex_coord[2];
int8_t sign;
uint8_t pad;
};
typedef struct pf_b_vertex_info pf_b_vertex_info_t;
typedef struct pf_b_vertex_loop_blinn_data pf_b_vertex_loop_blinn_data_t;
struct pf_cover_indices {
const uint32_t *interior_indices;
@ -154,7 +148,7 @@ void pf_partitioner_init(pf_partitioner_t *partitioner,
uint32_t subpath_count);
void pf_partitioner_partition(pf_partitioner_t *partitioner,
uint32_t path_id,
uint16_t path_id,
uint32_t first_subpath_index,
uint32_t last_subpath_index);
@ -164,8 +158,12 @@ const pf_b_quad_t *pf_partitioner_b_quads(const pf_partitioner_t *partitioner,
const pf_point2d_f32_t *pf_partitioner_b_vertex_positions(const pf_partitioner_t *partitioner,
uint32_t *out_b_vertex_count);
const pf_b_vertex_info_t *pf_partitioner_b_vertex_info(const pf_partitioner_t *partitioner,
uint32_t *out_b_vertex_count);
const uint16_t *pf_partitioner_b_vertex_path_ids(const pf_partitioner_t *partitioner,
uint32_t *out_b_vertex_count);
const pf_b_vertex_loop_blinn_data_t *pf_partitioner_b_vertex_loop_blinn_data(
const pf_partitioner_t *partitioner,
uint32_t *out_b_vertex_count);
const void pf_partitioner_cover_indices(const pf_partitioner_t *partitioner,
pf_cover_indices_t *out_cover_indices);

View File

@ -7,8 +7,9 @@ use log::LogLevel;
use std::collections::BinaryHeap;
use std::cmp::Ordering;
use std::f32;
use std::iter;
use std::u32;
use {BQuad, BVertexInfo, BVertexKind, CurveIndices, Endpoint, LineIndices, Subpath};
use {BQuad, BVertexLoopBlinnData, BVertexKind, CurveIndices, Endpoint, LineIndices, Subpath};
pub struct Partitioner<'a> {
endpoints: &'a [Endpoint],
@ -17,14 +18,15 @@ pub struct Partitioner<'a> {
b_quads: Vec<BQuad>,
b_vertex_positions: Vec<Point2D<f32>>,
b_vertex_info: Vec<BVertexInfo>,
b_vertex_path_ids: Vec<u16>,
b_vertex_loop_blinn_data: Vec<BVertexLoopBlinnData>,
cover_indices: CoverIndicesBuffer,
edge_indices: EdgeIndicesBuffer,
heap: BinaryHeap<Point>,
visited_points: BitVec,
active_edges: Vec<ActiveEdge>,
path_id: u32,
path_id: u16,
}
impl<'a> Partitioner<'a> {
@ -37,7 +39,8 @@ impl<'a> Partitioner<'a> {
b_quads: vec![],
b_vertex_positions: vec![],
b_vertex_info: vec![],
b_vertex_path_ids: vec![],
b_vertex_loop_blinn_data: vec![],
cover_indices: CoverIndicesBuffer::new(),
edge_indices: EdgeIndicesBuffer::new(),
@ -61,9 +64,10 @@ impl<'a> Partitioner<'a> {
self.visited_points = BitVec::from_elem(self.endpoints.len(), false);
}
pub fn partition(&mut self, path_id: u32, first_subpath_index: u32, last_subpath_index: u32) {
pub fn partition(&mut self, path_id: u16, first_subpath_index: u32, last_subpath_index: u32) {
self.b_quads.clear();
self.b_vertex_info.clear();
self.b_vertex_loop_blinn_data.clear();
self.b_vertex_path_ids.clear();
self.b_vertex_positions.clear();
self.cover_indices.clear();
self.edge_indices.clear();
@ -88,8 +92,13 @@ impl<'a> Partitioner<'a> {
}
#[inline]
pub fn b_vertex_info(&self) -> &[BVertexInfo] {
&self.b_vertex_info
pub fn b_vertex_path_ids(&self) -> &[u16] {
&self.b_vertex_path_ids
}
#[inline]
pub fn b_vertex_loop_blinn_data(&self) -> &[BVertexLoopBlinnData] {
&self.b_vertex_loop_blinn_data
}
#[inline]
@ -180,13 +189,15 @@ impl<'a> Partitioner<'a> {
{
let active_edge = &mut self.active_edges[active_edge_index as usize];
active_edge.left_vertex_index = self.b_vertex_info.len() as u32;
active_edge.left_vertex_index = self.b_vertex_loop_blinn_data.len() as u32;
active_edge.control_point_vertex_index = active_edge.left_vertex_index + 1;
let endpoint_position = self.endpoints[active_edge.right_endpoint_index as usize]
.position;
self.b_vertex_positions.push(endpoint_position);
self.b_vertex_info.push(BVertexInfo::new(active_edge.endpoint_kind(), self.path_id));
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(BVertexLoopBlinnData::new(
active_edge.endpoint_kind()));
active_edge.toggle_parity();
@ -214,19 +225,19 @@ impl<'a> Partitioner<'a> {
}
control_point_index => {
self.active_edges[active_edge_index as usize].control_point_vertex_index =
self.b_vertex_info.len() as u32;
self.b_vertex_loop_blinn_data.len() as u32;
let left_vertex_index = self.active_edges[active_edge_index as usize]
.left_vertex_index;
let control_point_position = &self.control_points[control_point_index as usize];
let control_point_b_vertex_info = BVertexInfo::control_point(
let control_point_b_vertex_loop_blinn_data = BVertexLoopBlinnData::control_point(
&self.b_vertex_positions[left_vertex_index as usize],
&control_point_position,
&new_point.position,
self.path_id,
bottom);
self.b_vertex_positions.push(*control_point_position);
self.b_vertex_info.push(control_point_b_vertex_info);
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
}
}
}
@ -280,13 +291,14 @@ impl<'a> Partitioner<'a> {
let new_active_edges = &mut self.active_edges[next_active_edge_index as usize..
next_active_edge_index as usize + 2];
let left_vertex_index = self.b_vertex_info.len() as u32;
let left_vertex_index = self.b_vertex_loop_blinn_data.len() as u32;
new_active_edges[0].left_vertex_index = left_vertex_index;
new_active_edges[1].left_vertex_index = left_vertex_index;
let position = self.endpoints[endpoint_index as usize].position;
self.b_vertex_positions.push(position);
self.b_vertex_info.push(BVertexInfo::new(BVertexKind::Endpoint0, self.path_id));
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(BVertexLoopBlinnData::new(BVertexKind::Endpoint0));
new_active_edges[0].toggle_parity();
new_active_edges[1].toggle_parity();
@ -322,40 +334,42 @@ impl<'a> Partitioner<'a> {
match upper_control_point_index {
u32::MAX => new_active_edges[0].control_point_vertex_index = u32::MAX,
upper_control_point_index => {
new_active_edges[0].control_point_vertex_index = self.b_vertex_info.len() as u32;
new_active_edges[0].control_point_vertex_index =
self.b_vertex_loop_blinn_data.len() as u32;
let control_point_position =
self.control_points[upper_control_point_index as usize];
let right_vertex_position =
self.endpoints[new_active_edges[0].right_endpoint_index as usize].position;
let control_point_b_vertex_info =
BVertexInfo::control_point(&position,
&control_point_position,
&right_vertex_position,
self.path_id,
false);
let control_point_b_vertex_loop_blinn_data =
BVertexLoopBlinnData::control_point(&position,
&control_point_position,
&right_vertex_position,
false);
self.b_vertex_positions.push(control_point_position);
self.b_vertex_info.push(control_point_b_vertex_info);
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
}
}
match lower_control_point_index {
u32::MAX => new_active_edges[1].control_point_vertex_index = u32::MAX,
lower_control_point_index => {
new_active_edges[1].control_point_vertex_index = self.b_vertex_info.len() as u32;
new_active_edges[1].control_point_vertex_index =
self.b_vertex_loop_blinn_data.len() as u32;
let control_point_position =
self.control_points[lower_control_point_index as usize];
let right_vertex_position =
self.endpoints[new_active_edges[1].right_endpoint_index as usize].position;
let control_point_b_vertex_info =
BVertexInfo::control_point(&position,
&control_point_position,
&right_vertex_position,
self.path_id,
true);
let control_point_b_vertex_loop_blinn_data =
BVertexLoopBlinnData::control_point(&position,
&control_point_position,
&right_vertex_position,
true);
self.b_vertex_positions.push(control_point_position);
self.b_vertex_info.push(control_point_b_vertex_info);
self.b_vertex_path_ids.push(self.path_id);
self.b_vertex_loop_blinn_data.push(control_point_b_vertex_loop_blinn_data);
}
}
}
@ -433,8 +447,8 @@ impl<'a> Partitioner<'a> {
// NB: Order is important here—we depend on the provoking vertex!
let upper_shape = upper_curve.shape(&self.b_vertex_info);
let lower_shape = lower_curve.shape(&self.b_vertex_info);
let upper_shape = upper_curve.shape(&self.b_vertex_loop_blinn_data);
let lower_shape = lower_curve.shape(&self.b_vertex_loop_blinn_data);
match upper_shape {
Shape::Flat => {
@ -757,15 +771,17 @@ impl<'a> Partitioner<'a> {
let left_curve_control_point_vertex_index;
match active_edge.control_point_vertex_index {
u32::MAX => {
let path_id = self.b_vertex_info[left_curve_left as usize].path_id;
let path_id = self.b_vertex_path_ids[left_curve_left as usize];
let left_point_position = self.b_vertex_positions[left_curve_left as usize];
let right_point = self.endpoints[active_edge.right_endpoint_index as usize]
.position;
let middle_point = left_point_position.to_vector().lerp(right_point.to_vector(), t);
active_edge.left_vertex_index = self.b_vertex_info.len() as u32;
active_edge.left_vertex_index = self.b_vertex_loop_blinn_data.len() as u32;
self.b_vertex_positions.push(middle_point.to_point());
self.b_vertex_info.push(BVertexInfo::new(active_edge.endpoint_kind(), path_id));
self.b_vertex_path_ids.push(path_id);
self.b_vertex_loop_blinn_data
.push(BVertexLoopBlinnData::new(active_edge.endpoint_kind()));
active_edge.toggle_parity();
@ -782,7 +798,7 @@ impl<'a> Partitioner<'a> {
&self.b_vertex_positions[active_edge.control_point_vertex_index as usize],
&right_endpoint_position);
left_curve_control_point_vertex_index = self.b_vertex_info.len() as u32;
left_curve_control_point_vertex_index = self.b_vertex_loop_blinn_data.len() as u32;
active_edge.left_vertex_index = left_curve_control_point_vertex_index + 1;
active_edge.control_point_vertex_index = left_curve_control_point_vertex_index + 2;
@ -791,18 +807,17 @@ impl<'a> Partitioner<'a> {
subdivided_quadratic_bezier.ap2bp0,
subdivided_quadratic_bezier.bp1,
].into_iter());
self.b_vertex_info.extend([
BVertexInfo::control_point(&left_endpoint_position,
&subdivided_quadratic_bezier.ap1,
&subdivided_quadratic_bezier.ap2bp0,
self.path_id,
bottom),
BVertexInfo::new(active_edge.endpoint_kind(), self.path_id),
BVertexInfo::control_point(&subdivided_quadratic_bezier.ap2bp0,
&subdivided_quadratic_bezier.bp1,
&right_endpoint_position,
self.path_id,
bottom),
self.b_vertex_path_ids.extend(iter::repeat(self.path_id).take(3));
self.b_vertex_loop_blinn_data.extend([
BVertexLoopBlinnData::control_point(&left_endpoint_position,
&subdivided_quadratic_bezier.ap1,
&subdivided_quadratic_bezier.ap2bp0,
bottom),
BVertexLoopBlinnData::new(active_edge.endpoint_kind()),
BVertexLoopBlinnData::control_point(&subdivided_quadratic_bezier.ap2bp0,
&subdivided_quadratic_bezier.bp1,
&right_endpoint_position,
bottom),
].into_iter());
active_edge.toggle_parity();
@ -1015,10 +1030,10 @@ struct SubdividedActiveEdge {
}
impl SubdividedActiveEdge {
fn shape(&self, b_vertex_info: &[BVertexInfo]) -> Shape {
fn shape(&self, b_vertex_loop_blinn_data: &[BVertexLoopBlinnData]) -> Shape {
if self.left_curve_control_point == u32::MAX {
Shape::Flat
} else if b_vertex_info[self.left_curve_control_point as usize].sign < 0 {
} else if b_vertex_loop_blinn_data[self.left_curve_control_point as usize].sign < 0 {
Shape::Convex
} else {
Shape::Concave

View File

@ -7,9 +7,9 @@ precision highp float;
uniform mat4 uTransform;
uniform ivec2 uFramebufferSize;
uniform ivec2 uBVertexPositionDimensions;
uniform ivec2 uBVertexInfoDimensions;
uniform ivec2 uBVertexPathIDDimensions;
uniform sampler2D uBVertexPosition;
uniform sampler2D uBVertexInfo;
uniform sampler2D uBVertexPathID;
attribute vec2 aQuadPosition;
attribute vec3 aUpperPointIndices;
@ -48,7 +48,7 @@ void main() {
vec4 roundedExtents = vec4(floor(extents.xy), ceil(extents.zw));
int pathID = fetchUInt16Data(uBVertexInfo, pointIndices.x, uBVertexInfoDimensions);
int pathID = fetchUInt16Data(uBVertexPathID, pointIndices.x, uBVertexPathIDDimensions);
vec2 position = mix(roundedExtents.xy, roundedExtents.zw, aQuadPosition);
position = convertScreenToClipSpace(position, uFramebufferSize);