diff --git a/Cargo.lock b/Cargo.lock index 8e28591d4..e0b2f2219 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1592,6 +1592,11 @@ dependencies = [ "objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "once_cell" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ordered-float" version = "1.0.2" @@ -1861,6 +1866,7 @@ dependencies = [ "hashbrown 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "instant 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "pathfinder_color 0.5.0", "pathfinder_content 0.5.0", "pathfinder_geometry 0.5.1", @@ -3207,6 +3213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" "checksum objc_exception 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" "checksum objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +"checksum once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" "checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" "checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" "checksum parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" diff --git a/geometry/Cargo.toml b/geometry/Cargo.toml index 1ed81d50a..b05e92997 100644 --- a/geometry/Cargo.toml +++ b/geometry/Cargo.toml @@ -8,6 +8,9 @@ license = "MIT/Apache-2.0" repository = "https://github.com/servo/pathfinder" homepage = "https://github.com/servo/pathfinder" +[features] +shader_alignment_32_bits = [] + [dependencies] [dependencies.log] diff --git a/geometry/src/alignment.rs b/geometry/src/alignment.rs new file mode 100644 index 000000000..44db8652b --- /dev/null +++ b/geometry/src/alignment.rs @@ -0,0 +1,19 @@ +#[cfg(feature = "shader_alignment_32_bits")] +pub type AlignedU8 = u32; +#[cfg(not(feature = "shader_alignment_32_bits"))] +pub type AlignedU8 = u8; + +#[cfg(feature = "shader_alignment_32_bits")] +pub type AlignedU16 = u32; +#[cfg(not(feature = "shader_alignment_32_bits"))] +pub type AlignedU16 = u16; + +#[cfg(feature = "shader_alignment_32_bits")] +pub type AlignedI8 = i32; +#[cfg(not(feature = "shader_alignment_32_bits"))] +pub type AlignedI8 = i8; + +#[cfg(feature = "shader_alignment_32_bits")] +pub type AlignedI16 = i32; +#[cfg(not(feature = "shader_alignment_32_bits"))] +pub type AlignedI16 = i16; \ No newline at end of file diff --git a/geometry/src/lib.rs b/geometry/src/lib.rs index 59d04061f..44d88cc2a 100644 --- a/geometry/src/lib.rs +++ b/geometry/src/lib.rs @@ -18,3 +18,4 @@ pub mod transform3d; pub mod unit_vector; pub mod util; pub mod vector; +pub mod alignment; diff --git a/geometry/src/line_segment.rs b/geometry/src/line_segment.rs index 56707a4c4..1fb0a7cd6 100644 --- a/geometry/src/line_segment.rs +++ b/geometry/src/line_segment.rs @@ -11,8 +11,9 @@ //! Line segment types, optimized with SIMD. use crate::transform2d::Matrix2x2F; -use crate::vector::{Vector2F, vec2f}; +use crate::alignment::AlignedU8; use crate::util; +use crate::vector::{vec2f, Vector2F}; use pathfinder_simd::default::F32x4; use std::ops::{Add, Mul, MulAssign, Sub}; @@ -294,8 +295,8 @@ impl MulAssign for LineSegment2F { #[derive(Clone, Copy, Debug, Default)] #[repr(C)] pub struct LineSegmentU4 { - pub from: u8, - pub to: u8, + pub from: AlignedU8, + pub to: AlignedU8, } #[derive(Clone, Copy, Debug, Default)] diff --git a/gl/src/lib.rs b/gl/src/lib.rs index dabfec0ca..d11fb0d6e 100644 --- a/gl/src/lib.rs +++ b/gl/src/lib.rs @@ -1329,8 +1329,10 @@ impl VertexAttrTypeExt for VertexAttrType { fn to_gl_type(self) -> GLuint { match self { VertexAttrType::F32 => gl::FLOAT, + VertexAttrType::I32 => gl::INT, VertexAttrType::I16 => gl::SHORT, VertexAttrType::I8 => gl::BYTE, + VertexAttrType::U32 => gl::UNSIGNED_INT, VertexAttrType::U16 => gl::UNSIGNED_SHORT, VertexAttrType::U8 => gl::UNSIGNED_BYTE, } diff --git a/gpu/Cargo.toml b/gpu/Cargo.toml index d95858196..80a178692 100644 --- a/gpu/Cargo.toml +++ b/gpu/Cargo.toml @@ -8,6 +8,9 @@ license = "MIT/Apache-2.0" repository = "https://github.com/servo/pathfinder" homepage = "https://github.com/servo/pathfinder" +[features] +shader_alignment_32_bits = ["pathfinder_geometry/shader_alignment_32_bits"] + [dependencies] bitflags = "1.0" half = "1.5" diff --git a/gpu/src/lib.rs b/gpu/src/lib.rs index 50a7116f3..77a1b5f55 100644 --- a/gpu/src/lib.rs +++ b/gpu/src/lib.rs @@ -175,15 +175,51 @@ pub enum TextureFormat { RGBA32F, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum VertexAttrType { F32, + I32, I16, I8, + U32, U16, U8, } +impl VertexAttrType { + pub fn get_size(&self) -> usize { + match *self { + VertexAttrType::F32 => 4, + VertexAttrType::I32 => 4, + VertexAttrType::I16 => 2, + VertexAttrType::I8 => 1, + VertexAttrType::U32 => 4, + VertexAttrType::U16 => 2, + VertexAttrType::U8 => 1, + } + } +} + +#[cfg(feature = "shader_alignment_32_bits")] +pub const ALIGNED_U8_ATTR: VertexAttrType = VertexAttrType::U32; +#[cfg(not(feature = "shader_alignment_32_bits"))] +pub const ALIGNED_U8_ATTR: VertexAttrType = VertexAttrType::U8; + +#[cfg(feature = "shader_alignment_32_bits")] +pub const ALIGNED_U16_ATTR: VertexAttrType = VertexAttrType::U32; +#[cfg(not(feature = "shader_alignment_32_bits"))] +pub const ALIGNED_U16_ATTR: VertexAttrType = VertexAttrType::U16; + +#[cfg(feature = "shader_alignment_32_bits")] +pub const ALIGNED_I8_ATTR: VertexAttrType = VertexAttrType::I32; +#[cfg(not(feature = "shader_alignment_32_bits"))] +pub const ALIGNED_I8_ATTR: VertexAttrType = VertexAttrType::I8; + +#[cfg(feature = "shader_alignment_32_bits")] +pub const ALIGNED_I16_ATTR: VertexAttrType = VertexAttrType::I32; +#[cfg(not(feature = "shader_alignment_32_bits"))] +pub const ALIGNED_I16_ATTR: VertexAttrType = VertexAttrType::I16; + #[derive(Clone, Copy, Debug)] pub enum BufferData<'a, T> { Uninitialized(usize), @@ -420,7 +456,7 @@ impl UniformData { } } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct VertexAttrDescriptor { pub size: usize, pub class: VertexAttrClass, @@ -431,7 +467,49 @@ pub struct VertexAttrDescriptor { pub buffer_index: u32, } -#[derive(Clone, Copy, Debug, PartialEq)] +impl VertexAttrDescriptor { + pub const fn datatype_only(class: VertexAttrClass, attr_type: VertexAttrType, size: usize) -> Self { + VertexAttrDescriptor { + size, + class, + attr_type, + divisor: 0, + buffer_index: 0, + stride: 0, + offset: 0, + } + } +} + +pub struct VertexBufferDescriptor { + pub index: u32, + pub divisor: u32, + pub vertex_attrs: Vec, +} + +impl VertexBufferDescriptor { + pub fn update_attrs(&mut self) { + let mut offset = 0; + for attr in self.vertex_attrs.iter_mut() { + attr.buffer_index = self.index; + attr.divisor = self.divisor; + attr.offset = offset; + offset += attr.size * attr.attr_type.get_size(); + } + + for attr in self.vertex_attrs.iter_mut() { + attr.stride = offset; + } + } + + pub fn configure_vertex_attrs(&self, device: &D, vertex_array: &D::VertexArray, attrs: &[D::VertexAttr]) { + for (attr, descriptor) in attrs.iter().zip(self.vertex_attrs.iter()) { + device.configure_vertex_attr(vertex_array, attr, &descriptor); + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum VertexAttrClass { Float, FloatNorm, diff --git a/metal/src/lib.rs b/metal/src/lib.rs index 6e85722b0..b503baec0 100644 --- a/metal/src/lib.rs +++ b/metal/src/lib.rs @@ -474,6 +474,8 @@ impl Device for MetalDevice { } (VertexAttrClass::Int, VertexAttrType::I16, 1) => MTLVertexFormat::Short, (VertexAttrClass::Int, VertexAttrType::U16, 1) => MTLVertexFormat::UShort, + (VertexAttrClass::Int, VertexAttrType::I32, 1) => MTLVertexFormat::Int, + (VertexAttrClass::Int, VertexAttrType::U32, 1) => MTLVertexFormat::UInt, (VertexAttrClass::FloatNorm, VertexAttrType::U16, 1) => { MTLVertexFormat::UShortNormalized } diff --git a/renderer/Cargo.toml b/renderer/Cargo.toml index 0bac653e8..282794e57 100644 --- a/renderer/Cargo.toml +++ b/renderer/Cargo.toml @@ -12,6 +12,7 @@ homepage = "https://github.com/servo/pathfinder" bitflags = "1.0" byteorder = "1.2" crossbeam-channel = "0.4" +once_cell = "1.3.1" fxhash = "0.2" half = "1.5" hashbrown = "0.7" diff --git a/renderer/src/builder.rs b/renderer/src/builder.rs index 344438e8d..61e98d645 100644 --- a/renderer/src/builder.rs +++ b/renderer/src/builder.rs @@ -26,6 +26,7 @@ use crate::z_buffer::{DepthMetadata, ZBuffer}; use pathfinder_content::effects::{BlendMode, Filter}; use pathfinder_content::fill::FillRule; use pathfinder_content::render_target::RenderTargetId; +use pathfinder_geometry::alignment::{AlignedI16, AlignedU8, AlignedU16, AlignedI8}; use pathfinder_geometry::line_segment::{LineSegment2F, LineSegmentU4, LineSegmentU8}; use pathfinder_geometry::rect::{RectF, RectI}; use pathfinder_geometry::transform2d::Transform2F; @@ -648,14 +649,14 @@ impl ObjectBuilder { self.fills.push(FillBatchEntry { page: alpha_tile_id.page(), fill: Fill { - px: LineSegmentU4 { from: px[0] as u8, to: px[2] as u8 }, + px: LineSegmentU4 { from: px[0] as AlignedU8, to: px[2] as AlignedU8 }, subpx: LineSegmentU8 { from_x: from_x as u8, from_y: from_y as u8, to_x: to_x as u8, to_y: to_y as u8, }, - alpha_tile_index: alpha_tile_id.tile(), + alpha_tile_index: alpha_tile_id.tile() as AlignedU16, }, }); } @@ -841,14 +842,14 @@ impl Tile { } Tile { - tile_x: tile_origin.x() as i16, - tile_y: tile_origin.y() as i16, - mask_0_u: mask_0_uv.x() as u8, - mask_0_v: mask_0_uv.y() as u8, - mask_0_backdrop: draw_tile_backdrop, - ctrl: ctrl as u16, + tile_x: tile_origin.x() as AlignedI16, + tile_y: tile_origin.y() as AlignedI16, + mask_0_u: mask_0_uv.x() as AlignedU8, + mask_0_v: mask_0_uv.y() as AlignedU8, + mask_0_backdrop: draw_tile_backdrop as AlignedI8, + ctrl: ctrl as AlignedU16, pad: 0, - color: draw_tiling_path_info.paint_id.0, + color: draw_tiling_path_info.paint_id.0 as AlignedU16, } } @@ -864,11 +865,11 @@ impl Clip { let dest_uv = calculate_mask_uv(dest_tile_index); let src_uv = calculate_mask_uv(src_tile_index); Clip { - dest_u: dest_uv.x() as u8, - dest_v: dest_uv.y() as u8, - src_u: src_uv.x() as u8, - src_v: src_uv.y() as u8, - backdrop: src_backdrop, + dest_u: dest_uv.x() as AlignedU8, + dest_v: dest_uv.y() as AlignedU8, + src_u: src_uv.x() as AlignedU8, + src_v: src_uv.y() as AlignedU8, + backdrop: src_backdrop as AlignedI8, pad_0: 0, pad_1: 0, } diff --git a/renderer/src/gpu/renderer.rs b/renderer/src/gpu/renderer.rs index 20419f52b..8fd5b27f3 100644 --- a/renderer/src/gpu/renderer.rs +++ b/renderer/src/gpu/renderer.rs @@ -31,7 +31,7 @@ use pathfinder_geometry::line_segment::LineSegment2F; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::transform3d::Transform4F; use pathfinder_geometry::util; -use pathfinder_geometry::vector::{Vector2F, Vector2I, Vector4F, vec2f, vec2i}; +use pathfinder_geometry::{alignment::AlignedU16, vector::{Vector2F, Vector2I, Vector4F, vec2f, vec2i}}; use pathfinder_gpu::{BlendFactor, BlendOp, BlendState, BufferData, BufferTarget, BufferUploadMode}; use pathfinder_gpu::{ClearOps, ComputeDimensions, ComputeState, DepthFunc, DepthState, Device}; use pathfinder_gpu::{ImageAccess, ImageBinding, Primitive, RenderOptions, RenderState}; @@ -47,7 +47,7 @@ use std::ops::{Add, Div}; use std::time::Duration; use std::u32; -static QUAD_VERTEX_POSITIONS: [u16; 8] = [0, 0, 1, 0, 1, 1, 0, 1]; +static QUAD_VERTEX_POSITIONS: [AlignedU16; 8] = [0, 0, 1, 0, 1, 1, 0, 1]; static QUAD_VERTEX_INDICES: [u32; 6] = [0, 1, 3, 1, 2, 3]; pub(crate) const MASK_TILES_ACROSS: u32 = 256; diff --git a/renderer/src/gpu/shaders.rs b/renderer/src/gpu/shaders.rs index 06f419d1e..827276af5 100644 --- a/renderer/src/gpu/shaders.rs +++ b/renderer/src/gpu/shaders.rs @@ -11,14 +11,11 @@ use crate::gpu::options::RendererOptions; use crate::gpu::renderer::{MASK_TILES_ACROSS, MASK_TILES_DOWN}; use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; -use pathfinder_gpu::{BufferTarget, BufferUploadMode, ComputeDimensions, Device, FeatureLevel}; -use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; +use pathfinder_gpu::{BufferTarget, BufferUploadMode, ComputeDimensions, Device, FeatureLevel, VertexAttrClass}; +use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType, VertexBufferDescriptor}; +use pathfinder_gpu::{ALIGNED_I16_ATTR, ALIGNED_I8_ATTR, ALIGNED_U8_ATTR, ALIGNED_U16_ATTR}; use pathfinder_resources::ResourceLoader; - -// TODO(pcwalton): Replace with `mem::size_of` calls? -pub(crate) const TILE_INSTANCE_SIZE: usize = 12; -const FILL_INSTANCE_SIZE: usize = 8; -const CLIP_TILE_INSTANCE_SIZE: usize = 8; +use once_cell::sync::Lazy; pub const MAX_FILLS_PER_BATCH: usize = 0x10000; pub const MAX_TILES_PER_BATCH: usize = MASK_TILES_ACROSS as usize * MASK_TILES_DOWN as usize; @@ -34,18 +31,24 @@ impl BlitVertexArray where D: Device { quad_vertex_indices_buffer: &D::Buffer) -> BlitVertexArray { let vertex_array = device.create_vertex_array(); - let position_attr = device.get_vertex_attr(&blit_program.program, "Position").unwrap(); + let position_attrs= &[ + device.get_vertex_attr(&blit_program.program, "Position").unwrap(), + ]; + + static POSITION_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor{ + index: 0, + divisor: 0, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I16_ATTR, 2), + ] + }; + descriptor.update_attrs(); + descriptor + }); device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); + POSITION_BUFFER.configure_vertex_attrs(device, &vertex_array, position_attrs); device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); BlitVertexArray { vertex_array } @@ -63,18 +66,24 @@ impl ClearVertexArray where D: Device { quad_vertex_indices_buffer: &D::Buffer) -> ClearVertexArray { let vertex_array = device.create_vertex_array(); - let position_attr = device.get_vertex_attr(&clear_program.program, "Position").unwrap(); + let position_attrs= &[ + device.get_vertex_attr(&clear_program.program, "Position").unwrap(), + ]; + + static POSITION_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor{ + index: 0, + divisor: 0, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I16_ATTR, 2), + ] + }; + descriptor.update_attrs(); + descriptor + }); device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); + POSITION_BUFFER.configure_vertex_attrs(device, &vertex_array, position_attrs); device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); ClearVertexArray { vertex_array } @@ -98,69 +107,50 @@ where ) -> FillVertexArray { let vertex_array = device.create_vertex_array(); - let tess_coord_attr = device.get_vertex_attr(&fill_program.program, "TessCoord").unwrap(); - let from_px_attr = device.get_vertex_attr(&fill_program.program, "FromPx").unwrap(); - let to_px_attr = device.get_vertex_attr(&fill_program.program, "ToPx").unwrap(); - let from_subpx_attr = device.get_vertex_attr(&fill_program.program, "FromSubpx").unwrap(); - let to_subpx_attr = device.get_vertex_attr(&fill_program.program, "ToSubpx").unwrap(); - let tile_index_attr = device.get_vertex_attr(&fill_program.program, "TileIndex").unwrap(); + let tess_coord_attrs= &[ + device.get_vertex_attr(&fill_program.program, "TessCoord").unwrap() + ]; + + static TESS_COORD_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor{ + index: 0, + divisor: 0, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_U16_ATTR, 2), + ] + }; + descriptor.update_attrs(); + descriptor + }); - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tess_coord_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, + let fill_attrs= &[ + device.get_vertex_attr(&fill_program.program, "FromSubpx").unwrap(), + device.get_vertex_attr(&fill_program.program, "ToSubpx").unwrap(), + device.get_vertex_attr(&fill_program.program, "FromPx").unwrap(), + device.get_vertex_attr(&fill_program.program, "ToPx").unwrap(), + device.get_vertex_attr(&fill_program.program, "TileIndex").unwrap(), + ]; + + static FILL_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor{ + index: 1, + divisor: 1, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::FloatNorm, VertexAttrType::U8, 2), + VertexAttrDescriptor::datatype_only(VertexAttrClass::FloatNorm, VertexAttrType::U8, 2), + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_U8_ATTR, 1), + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_U8_ATTR, 1), + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_U16_ATTR, 1), + ] + }; + descriptor.update_attrs(); + descriptor }); + + device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); + TESS_COORD_BUFFER.configure_vertex_attrs(device, &vertex_array, tess_coord_attrs); device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &from_subpx_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::FloatNorm, - attr_type: VertexAttrType::U8, - stride: FILL_INSTANCE_SIZE, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &to_subpx_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::FloatNorm, - attr_type: VertexAttrType::U8, - stride: FILL_INSTANCE_SIZE, - offset: 2, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &from_px_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: FILL_INSTANCE_SIZE, - offset: 4, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &to_px_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: FILL_INSTANCE_SIZE, - offset: 5, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U16, - stride: FILL_INSTANCE_SIZE, - offset: 6, - divisor: 1, - buffer_index: 1, - }); + FILL_BUFFER.configure_vertex_attrs(device, &vertex_array, fill_attrs); device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); FillVertexArray { vertex_array } @@ -180,73 +170,51 @@ impl TileVertexArray where D: Device { -> TileVertexArray { let vertex_array = device.create_vertex_array(); - let tile_offset_attr = - device.get_vertex_attr(&tile_program.program, "TileOffset").unwrap(); - let tile_origin_attr = - device.get_vertex_attr(&tile_program.program, "TileOrigin").unwrap(); - let mask_0_tex_coord_attr = - device.get_vertex_attr(&tile_program.program, "MaskTexCoord0").unwrap(); - let mask_backdrop_attr = - device.get_vertex_attr(&tile_program.program, "MaskBackdrop").unwrap(); - let color_attr = device.get_vertex_attr(&tile_program.program, "Color").unwrap(); - let tile_ctrl_attr = device.get_vertex_attr(&tile_program.program, "TileCtrl").unwrap(); + let tile_offset_attrs = &[ + device.get_vertex_attr(&tile_program.program, "TileOffset").unwrap(), + ]; + + static TILE_OFFSET_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor{ + index: 0, + divisor: 0, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_U16_ATTR, 2), + ] + }; + descriptor.update_attrs(); + descriptor + }); + + let tile_buffer_attrs = &[ + device.get_vertex_attr(&tile_program.program, "TileOrigin").unwrap(), + device.get_vertex_attr(&tile_program.program, "MaskTexCoord0").unwrap(), + device.get_vertex_attr(&tile_program.program, "MaskBackdrop").unwrap(), + device.get_vertex_attr(&tile_program.program, "Color").unwrap(), + device.get_vertex_attr(&tile_program.program, "TileCtrl").unwrap(), + ]; + + static TILE_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor{ + index: 1, + divisor: 1, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I16_ATTR, 2), + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_U8_ATTR, 2), + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I8_ATTR, 2), + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I16_ATTR, 1), + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I16_ATTR, 1), + ] + }; + descriptor.update_attrs(); + descriptor - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, }); + + device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); + TILE_OFFSET_BUFFER.configure_vertex_attrs(device, &vertex_array, tile_offset_attrs); device.bind_buffer(&vertex_array, tile_vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_origin_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &mask_0_tex_coord_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: TILE_INSTANCE_SIZE, - offset: 4, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &mask_backdrop_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I8, - stride: TILE_INSTANCE_SIZE, - offset: 6, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &color_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 8, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &tile_ctrl_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 10, - divisor: 1, - buffer_index: 1, - }); + TILE_BUFFER.configure_vertex_attrs(device, &vertex_array, tile_buffer_attrs); device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); TileVertexArray { vertex_array } @@ -266,19 +234,24 @@ impl CopyTileVertexArray where D: Device { ) -> CopyTileVertexArray { let vertex_array = device.create_vertex_array(); - let tile_position_attr = - device.get_vertex_attr(©_tile_program.program, "TilePosition").unwrap(); + let copy_tile_attrs = &[ + device.get_vertex_attr(©_tile_program.program, "TilePosition").unwrap(), + ]; + + static COPY_TILE_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor { + index: 0, + divisor: 0, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I16_ATTR, 2), + ], + }; + descriptor.update_attrs(); + descriptor + }); device.bind_buffer(&vertex_array, copy_tile_vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 0, - divisor: 0, - buffer_index: 0, - }); + COPY_TILE_BUFFER.configure_vertex_attrs(device, &vertex_array, copy_tile_attrs); device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index); CopyTileVertexArray { vertex_array } @@ -298,54 +271,46 @@ impl ClipTileVertexArray where D: Device { -> ClipTileVertexArray { let vertex_array = device.create_vertex_array(); let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic); + let tile_offset_attrs = &[ + device.get_vertex_attr(&clip_tile_program.program, "TileOffset").unwrap(), + ]; + + static TILE_OFFSET_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor{ + index: 0, + divisor: 0, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I16_ATTR, 2), + ], + }; + descriptor.update_attrs(); + descriptor + }); - let tile_offset_attr = - device.get_vertex_attr(&clip_tile_program.program, "TileOffset").unwrap(); - let dest_tile_origin_attr = - device.get_vertex_attr(&clip_tile_program.program, "DestTileOrigin").unwrap(); - let src_tile_origin_attr = - device.get_vertex_attr(&clip_tile_program.program, "SrcTileOrigin").unwrap(); - let src_backdrop_attr = - device.get_vertex_attr(&clip_tile_program.program, "SrcBackdrop").unwrap(); + let clip_tile_attrs = &[ + device.get_vertex_attr(&clip_tile_program.program, "DestTileOrigin").unwrap(), + device.get_vertex_attr(&clip_tile_program.program, "SrcTileOrigin").unwrap(), + device.get_vertex_attr(&clip_tile_program.program, "SrcBackdrop").unwrap(), + ]; + + static CLIP_TILE_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor{ + index: 1, + divisor: 1, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_U8_ATTR, 2), + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_U8_ATTR, 2), + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I8_ATTR, 1), + ], + }; + descriptor.update_attrs(); + descriptor + }); device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); + TILE_OFFSET_BUFFER.configure_vertex_attrs(device, &vertex_array, tile_offset_attrs); device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &dest_tile_origin_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &src_tile_origin_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 2, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &src_backdrop_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I8, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 4, - divisor: 1, - buffer_index: 1, - }); + CLIP_TILE_BUFFER.configure_vertex_attrs(device, &vertex_array, clip_tile_attrs); device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); ClipTileVertexArray { vertex_array, vertex_buffer } @@ -658,19 +623,24 @@ where quad_vertex_indices_buffer: &D::Buffer, ) -> ReprojectionVertexArray { let vertex_array = device.create_vertex_array(); - let position_attr = device.get_vertex_attr(&reprojection_program.program, "Position") - .unwrap(); + let position_attrs = &[ + device.get_vertex_attr(&reprojection_program.program, "Position") + .unwrap(), + ]; + static POSITION_BUFFER: Lazy = Lazy::new(|| { + let mut descriptor = VertexBufferDescriptor{ + index: 0, + divisor: 0, + vertex_attrs: vec![ + VertexAttrDescriptor::datatype_only(VertexAttrClass::Int, ALIGNED_I16_ATTR, 2), + ] + }; + descriptor.update_attrs(); + descriptor + }); device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); + POSITION_BUFFER.configure_vertex_attrs(device, &vertex_array, position_attrs); device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); ReprojectionVertexArray { vertex_array } diff --git a/renderer/src/gpu_data.rs b/renderer/src/gpu_data.rs index 2282df5e9..fe5ae10d7 100644 --- a/renderer/src/gpu_data.rs +++ b/renderer/src/gpu_data.rs @@ -16,6 +16,7 @@ use crate::paint::PaintCompositeOp; use pathfinder_color::ColorU; use pathfinder_content::effects::{BlendMode, Filter}; use pathfinder_content::render_target::RenderTargetId; +use pathfinder_geometry::alignment::{AlignedI8, AlignedU8, AlignedI16, AlignedU16}; use pathfinder_geometry::line_segment::{LineSegmentU4, LineSegmentU8}; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::transform2d::Transform2F; @@ -152,7 +153,7 @@ pub struct FillBatchEntry { pub struct Fill { pub subpx: LineSegmentU8, pub px: LineSegmentU4, - pub alpha_tile_index: u16, + pub alpha_tile_index: AlignedU16, } #[derive(Clone, Debug)] @@ -178,26 +179,26 @@ pub enum ClipBatchKind { #[derive(Clone, Copy, Debug, Default)] #[repr(C)] pub struct Clip { - pub dest_u: u8, - pub dest_v: u8, - pub src_u: u8, - pub src_v: u8, - pub backdrop: i8, - pub pad_0: u8, - pub pad_1: u16, + pub dest_u: AlignedU8, + pub dest_v: AlignedU8, + pub src_u: AlignedU8, + pub src_v: AlignedU8, + pub backdrop: AlignedI8, + pub pad_0: AlignedU8, + pub pad_1: AlignedU16, } #[derive(Clone, Copy, Debug, Default)] #[repr(C)] pub struct Tile { - pub tile_x: i16, - pub tile_y: i16, - pub mask_0_u: u8, - pub mask_0_v: u8, - pub mask_0_backdrop: i8, - pub pad: u8, - pub color: u16, - pub ctrl: u16, + pub tile_x: AlignedI16, + pub tile_y: AlignedI16, + pub mask_0_u: AlignedU8, + pub mask_0_v: AlignedU8, + pub mask_0_backdrop: AlignedI8, + pub pad: AlignedU8, + pub color: AlignedU16, + pub ctrl: AlignedU16, } #[derive(Clone, Copy, PartialEq, Debug)] diff --git a/renderer/src/z_buffer.rs b/renderer/src/z_buffer.rs index ce67e29dc..291ffafc3 100644 --- a/renderer/src/z_buffer.rs +++ b/renderer/src/z_buffer.rs @@ -16,6 +16,7 @@ use crate::paint::{PaintId, PaintMetadata}; use crate::tile_map::DenseTileMap; use crate::tiles; use pathfinder_content::effects::BlendMode; +use pathfinder_geometry::alignment::{AlignedU16, AlignedI16}; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::Vector2I; use vec_map::VecMap; @@ -109,14 +110,14 @@ impl ZBuffer { impl Tile { pub(crate) fn new_solid_from_paint_id(tile_origin: Vector2I, paint_id: PaintId) -> Tile { Tile { - tile_x: tile_origin.x() as i16, - tile_y: tile_origin.y() as i16, + tile_x: tile_origin.x() as AlignedI16, + tile_y: tile_origin.y() as AlignedI16, mask_0_backdrop: 0, mask_0_u: 0, mask_0_v: 0, ctrl: 0, pad: 0, - color: paint_id.0, + color: paint_id.0 as AlignedU16, } } } diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 237092cfd..21e747a95 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -19,6 +19,7 @@ extern crate serde_derive; use hashbrown::HashMap; use pathfinder_color::ColorU; use pathfinder_geometry::rect::RectI; +use pathfinder_geometry::alignment::{AlignedU16, AlignedI16}; use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2i}; use pathfinder_gpu::{BlendFactor, BlendState, BufferData, BufferTarget, BufferUploadMode, Device}; use pathfinder_gpu::{Primitive, RenderOptions, RenderState, RenderTarget, TextureFormat}; @@ -679,19 +680,19 @@ impl DebugSolidProgram where D: Device { #[allow(dead_code)] #[repr(C)] struct DebugTextureVertex { - position_x: i16, - position_y: i16, - tex_coord_x: u16, - tex_coord_y: u16, + position_x: AlignedI16, + position_y: AlignedI16, + tex_coord_x: AlignedU16, + tex_coord_y: AlignedU16, } impl DebugTextureVertex { fn new(position: Vector2I, tex_coord: Vector2I) -> DebugTextureVertex { DebugTextureVertex { - position_x: position.x() as i16, - position_y: position.y() as i16, - tex_coord_x: tex_coord.x() as u16, - tex_coord_y: tex_coord.y() as u16, + position_x: position.x() as AlignedI16, + position_y: position.y() as AlignedI16, + tex_coord_x: tex_coord.x() as AlignedU16, + tex_coord_y: tex_coord.y() as AlignedU16, } } } @@ -700,13 +701,13 @@ impl DebugTextureVertex { #[allow(dead_code)] #[repr(C)] struct DebugSolidVertex { - position_x: i16, - position_y: i16, + position_x: AlignedI16, + position_y: AlignedI16, } impl DebugSolidVertex { fn new(position: Vector2I) -> DebugSolidVertex { - DebugSolidVertex { position_x: position.x() as i16, position_y: position.y() as i16 } + DebugSolidVertex { position_x: position.x() as AlignedI16, position_y: position.y() as AlignedI16 } } } diff --git a/webgl/src/lib.rs b/webgl/src/lib.rs index ed3ddf593..da1548cb7 100644 --- a/webgl/src/lib.rs +++ b/webgl/src/lib.rs @@ -1129,8 +1129,10 @@ impl VertexAttrTypeExt for VertexAttrType { fn to_gl_type(self) -> u32 { match self { VertexAttrType::F32 => WebGl::FLOAT, + VertexAttrType::I32 => WebGl::INT, VertexAttrType::I16 => WebGl::SHORT, VertexAttrType::I8 => WebGl::BYTE, + VertexAttrType::U32 => WebGl::UNSIGNED_INT, VertexAttrType::U16 => WebGl::UNSIGNED_SHORT, VertexAttrType::U8 => WebGl::UNSIGNED_BYTE, }