diff --git a/.vscode/launch.json b/.vscode/launch.json index ecf8958b14..4ba6f16f5e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -819,25 +819,6 @@ "args": [], "cwd": "${workspaceFolder}" }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in library 'bevy_pathfinder'", - "cargo": { - "args": [ - "test", - "--no-run", - "--lib", - "--package=bevy_pathfinder" - ], - "filter": { - "name": "bevy_pathfinder", - "kind": "lib" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, { "type": "lldb", "request": "launch", @@ -989,43 +970,6 @@ "args": [], "cwd": "${workspaceFolder}" }, - { - "type": "lldb", - "request": "launch", - "name": "Debug example 'pathfinder'", - "cargo": { - "args": [ - "build", - "--example=pathfinder", - "--package=bevy" - ], - "filter": { - "name": "pathfinder", - "kind": "example" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in example 'pathfinder'", - "cargo": { - "args": [ - "test", - "--no-run", - "--example=pathfinder", - "--package=bevy" - ], - "filter": { - "name": "pathfinder", - "kind": "example" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, { "type": "lldb", "request": "launch", diff --git a/Cargo.toml b/Cargo.toml index caaba26720..ec42aca9e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,14 +6,13 @@ edition = "2018" [features] default = ["headless", "wgpu", "winit"] -headless = ["asset", "core", "derive", "diagnostic", "gltf", "input", "pathfinder", "pbr", "render", "serialization", "transform", "ui", "window"] +headless = ["asset", "core", "derive", "diagnostic", "gltf", "input", "pbr", "render", "serialization", "transform", "ui", "window"] asset = ["bevy_asset"] core = ["bevy_core"] derive = ["bevy_derive"] diagnostic = ["bevy_diagnostic"] gltf = ["bevy_gltf"] input = ["bevy_input"] -pathfinder = ["bevy_pathfinder"] pbr = ["bevy_pbr"] render = ["bevy_render"] serialization = ["bevy_serialization"] @@ -29,10 +28,6 @@ members = [ "crates/*", "examples/app/dynamic_plugin_loading/example_plugin" ] -exclude = [ - "crates/pathfinder" -] - [dependencies] # bevy @@ -43,7 +38,6 @@ bevy_derive = { path = "crates/bevy_derive", optional = true } bevy_diagnostic = { path = "crates/bevy_diagnostic", optional = true } bevy_gltf = { path = "crates/bevy_gltf", optional = true } bevy_input = { path = "crates/bevy_input", optional = true } -bevy_pathfinder = { path = "crates/bevy_pathfinder", optional = true } bevy_pbr = { path = "crates/bevy_pbr", optional = true } bevy_render = { path = "crates/bevy_render", optional = true } bevy_serialization = { path = "crates/bevy_serialization", optional = true } @@ -71,10 +65,6 @@ opt-level = 3 name = "hello_world" path = "examples/hello_world.rs" -[[example]] -name = "pathfinder" -path = "examples/2d/pathfinder.rs" - [[example]] name = "sprite" path = "examples/2d/sprite.rs" diff --git a/crates/bevy_pathfinder/Cargo.toml b/crates/bevy_pathfinder/Cargo.toml deleted file mode 100644 index 97bee67c6a..0000000000 --- a/crates/bevy_pathfinder/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "bevy_pathfinder" -version = "0.1.0" -authors = ["Carter Anderson "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bevy_app = { path = "../bevy_app" } -bevy_asset = { path = "../bevy_asset" } -bevy_render = { path = "../bevy_render" } -legion = { path = "../bevy_legion" } - -pathfinder_geometry = { path = "../pathfinder/geometry", features = ["shader_alignment_32_bits"] } -pathfinder_gpu = { path = "../pathfinder/gpu", features = ["shader_alignment_32_bits"] } -pathfinder_renderer = { path = "../pathfinder/renderer" } -pathfinder_simd = { path = "../pathfinder/simd" } -pathfinder_resources = { path = "../pathfinder/resources" } -pathfinder_color = { path = "../pathfinder/color" } -pathfinder_canvas = { path = "../pathfinder/canvas" } - -zerocopy = "0.3.0" -byteorder = "1.3" diff --git a/crates/bevy_pathfinder/src/device.rs b/crates/bevy_pathfinder/src/device.rs deleted file mode 100644 index 4dc7750c5d..0000000000 --- a/crates/bevy_pathfinder/src/device.rs +++ /dev/null @@ -1,1274 +0,0 @@ -use bevy_asset::{AssetStorage, Handle}; -use bevy_render::{ - pass::{ - LoadOp, PassDescriptor, RenderPass, RenderPassColorAttachmentDescriptor, - RenderPassDepthStencilAttachmentDescriptor, StoreOp, TextureAttachment, - }, - pipeline::{ - state_descriptors::{ - BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite, - CompareFunction, DepthStencilStateDescriptor, IndexFormat, PrimitiveTopology, - RasterizationStateDescriptor, StencilOperation, StencilStateFaceDescriptor, - }, - BindType, InputStepMode, PipelineDescriptor, VertexAttributeDescriptor, - VertexBufferDescriptor, VertexFormat, - }, - render_resource::{ - BufferInfo, BufferUsage, RenderResource, RenderResourceAssignment, - RenderResourceAssignments, ResourceInfo, - }, - renderer::RenderContext, - shader::{Shader, ShaderSource, ShaderStage, ShaderStages}, - texture::{ - AddressMode, Extent3d, FilterMode, SamplerDescriptor, TextureDescriptor, TextureDimension, - TextureFormat, TextureUsage, - }, - Color, -}; -use byteorder::{NativeEndian, WriteBytesExt}; -use pathfinder_canvas::vec2i; -use pathfinder_geometry::{rect::RectI, vector::Vector2I}; -use pathfinder_gpu::{ - BufferData, BufferTarget, BufferUploadMode, Device, FeatureLevel, ProgramKind, RenderState, - RenderTarget, ShaderKind, TextureData, TextureDataRef, TextureSamplingFlags, UniformData, - VertexAttrClass, VertexAttrDescriptor, VertexAttrType, -}; -use pathfinder_resources::ResourceLoader; -use std::{borrow::Cow, cell::RefCell, collections::HashMap, mem, rc::Rc}; - -pub struct BevyPathfinderDevice<'a> { - render_context: RefCell<&'a mut dyn RenderContext>, - shaders: RefCell<&'a mut AssetStorage>, - samplers: RefCell>, - main_color_texture: RenderResource, - main_depth_stencil_texture: RenderResource, - default_sampler: RenderResource, - default_uniform_texture: RenderResource, - default_buffer: RenderResource, -} - -impl<'a> BevyPathfinderDevice<'a> { - pub fn new( - render_context: &'a mut dyn RenderContext, - shaders: &'a mut AssetStorage, - main_color_texture: RenderResource, - main_depth_stencil_texture: RenderResource, - ) -> Self { - let default_sampler = render_context - .resources() - .create_sampler(&SamplerDescriptor::default()); - let default_texture = render_context - .resources() - .create_texture(TextureDescriptor { - dimension: TextureDimension::D2, - format: TextureFormat::Bgra8UnormSrgb, - mip_level_count: 1, - sample_count: 1, - size: Extent3d { - width: 32, - height: 32, - depth: 1, - }, - usage: TextureUsage::COPY_DST | TextureUsage::SAMPLED, - }); - let default_uniform_buffer = render_context.resources().create_buffer_with_data( - BufferInfo { - buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, - ..Default::default() - }, - &[0; 16], - ); - BevyPathfinderDevice { - render_context: RefCell::new(render_context), - shaders: RefCell::new(shaders), - samplers: RefCell::new(HashMap::new()), - main_color_texture, - main_depth_stencil_texture, - default_sampler, - default_uniform_texture: default_texture, - default_buffer: default_uniform_buffer, - } - } - - pub fn setup_uniforms( - &self, - render_state: &RenderState, - render_resource_assignments: &mut RenderResourceAssignments, - ) { - let mut uniform_buffer_data = Vec::new(); - let mut uniform_buffer_ranges = Vec::new(); - for (bevy_uniform, uniform_data) in render_state.uniforms.iter() { - let start_index = uniform_buffer_data.len(); - match *uniform_data { - UniformData::Float(value) => uniform_buffer_data - .write_f32::(value) - .unwrap(), - UniformData::IVec2(vector) => { - uniform_buffer_data - .write_i32::(vector.x()) - .unwrap(); - uniform_buffer_data - .write_i32::(vector.y()) - .unwrap(); - } - UniformData::IVec3(values) => { - uniform_buffer_data - .write_i32::(values[0]) - .unwrap(); - uniform_buffer_data - .write_i32::(values[1]) - .unwrap(); - uniform_buffer_data - .write_i32::(values[2]) - .unwrap(); - } - UniformData::Int(value) => uniform_buffer_data - .write_i32::(value) - .unwrap(), - UniformData::Mat2(matrix) => { - uniform_buffer_data - .write_f32::(matrix.x()) - .unwrap(); - uniform_buffer_data - .write_f32::(matrix.y()) - .unwrap(); - uniform_buffer_data - .write_f32::(matrix.z()) - .unwrap(); - uniform_buffer_data - .write_f32::(matrix.w()) - .unwrap(); - } - UniformData::Mat4(matrix) => { - for column in &matrix { - uniform_buffer_data - .write_f32::(column.x()) - .unwrap(); - uniform_buffer_data - .write_f32::(column.y()) - .unwrap(); - uniform_buffer_data - .write_f32::(column.z()) - .unwrap(); - uniform_buffer_data - .write_f32::(column.w()) - .unwrap(); - } - } - UniformData::Vec2(vector) => { - uniform_buffer_data - .write_f32::(vector.x()) - .unwrap(); - uniform_buffer_data - .write_f32::(vector.y()) - .unwrap(); - } - UniformData::Vec3(array) => { - uniform_buffer_data - .write_f32::(array[0]) - .unwrap(); - uniform_buffer_data - .write_f32::(array[1]) - .unwrap(); - uniform_buffer_data - .write_f32::(array[2]) - .unwrap(); - } - UniformData::Vec4(vector) => { - uniform_buffer_data - .write_f32::(vector.x()) - .unwrap(); - uniform_buffer_data - .write_f32::(vector.y()) - .unwrap(); - uniform_buffer_data - .write_f32::(vector.z()) - .unwrap(); - uniform_buffer_data - .write_f32::(vector.w()) - .unwrap(); - } - UniformData::TextureUnit(index) => { - let texture = &render_state.textures[index as usize]; - render_resource_assignments.set( - &bevy_uniform.name, - RenderResourceAssignment::Texture(texture.handle), - ); - let sampler_resource = - if let Some(sampler_resource) = *texture.sampler_resource.borrow() { - // NOTE: this assumes theres is only one sampler - // TODO: see if we need more than one sampler - sampler_resource - } else { - self.default_sampler - }; - - render_resource_assignments.set( - "uSampler", - RenderResourceAssignment::Sampler(sampler_resource), - ); - - uniform_buffer_ranges.push(None); - - continue; - } - UniformData::ImageUnit(_) => panic!("image unit not currently supported"), - } - let end_index = uniform_buffer_data.len(); - while uniform_buffer_data.len() % 256 != 0 { - uniform_buffer_data.push(0); - } - uniform_buffer_ranges.push(Some(start_index..end_index)); - } - - let buffer_resource = self - .render_context - .borrow() - .resources() - .create_buffer_with_data( - BufferInfo { - buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, - ..Default::default() - }, - &uniform_buffer_data, - ); - - for ((bevy_uniform, _data), range) in render_state - .uniforms - .iter() - .zip(uniform_buffer_ranges.iter()) - { - if let Some(range) = range { - render_resource_assignments.set( - &bevy_uniform.name, - RenderResourceAssignment::Buffer { - dynamic_index: None, - range: range.start as u64..range.end as u64, - resource: buffer_resource, - }, - ) - } - } - } - - pub fn fill_in_missing_uniforms( - &self, - render_resource_assignments: &mut RenderResourceAssignments, - pipeline_descriptor: &PipelineDescriptor, - ) { - for bind_group in pipeline_descriptor.get_layout().unwrap().bind_groups.iter() { - for binding in bind_group.bindings.iter() { - if render_resource_assignments.get(&binding.name).is_none() { - match binding.bind_type { - BindType::SampledTexture { .. } => { - render_resource_assignments.set( - &binding.name, - RenderResourceAssignment::Texture(self.default_uniform_texture), - ); - } - BindType::Buffer { .. } => { - render_resource_assignments.set( - &binding.name, - RenderResourceAssignment::Buffer { - resource: self.default_buffer, - range: 0..binding.bind_type.get_uniform_size().unwrap(), - dynamic_index: None, - }, - ); - } - BindType::Uniform { .. } => { - render_resource_assignments.set( - &binding.name, - RenderResourceAssignment::Buffer { - resource: self.default_buffer, - range: 0..binding.bind_type.get_uniform_size().unwrap(), - dynamic_index: None, - }, - ); - } - BindType::Sampler { .. } => { - render_resource_assignments.set( - &binding.name, - RenderResourceAssignment::Sampler(self.default_sampler), - ); - } - _ => panic!( - "no defaults available for bind type {:?}", - binding.bind_type - ), - } - } - } - } - } - - pub fn setup_vertex_buffers( - &self, - render_state: &RenderState, - render_resource_assignments: &mut RenderResourceAssignments, - ) { - for (i, vertex_buffer) in render_state - .vertex_array - .vertex_buffers - .borrow() - .iter() - .enumerate() - { - let resource = vertex_buffer.handle.borrow().unwrap(); - let mut indices_resource = None; - if i == 0 { - if let Some(ref index_buffer) = *render_state.vertex_array.index_buffer.borrow() { - indices_resource = Some(index_buffer.handle.borrow().unwrap()); - } - } - render_resource_assignments.set_vertex_buffer( - get_vertex_buffer_name(i), - resource, - indices_resource, - ); - } - } - - pub fn setup_bind_groups( - &self, - pipeline_descriptor: &PipelineDescriptor, - render_resource_assignments: &mut RenderResourceAssignments, - ) { - let bind_groups = &pipeline_descriptor.get_layout().unwrap().bind_groups; - let render_context = self.render_context.borrow(); - let render_resources = render_context.resources(); - for bind_group in bind_groups.iter() { - render_resource_assignments.update_render_resource_set_id(bind_group); - } - render_resources.setup_bind_groups(pipeline_descriptor, &render_resource_assignments); - } - - pub fn draw(&self, render_state: &RenderState, draw_func: F) - where - F: Fn(&mut dyn RenderPass), - { - // TODO: maybe sync textures here? - let pass_descriptor = self.create_pass_descriptor(render_state); - self.setup_pipline_descriptor( - render_state, - &pass_descriptor, - &render_state.vertex_array.requested_descriptors.borrow(), - ); - let mut render_resource_assignments = RenderResourceAssignments::default(); - self.setup_uniforms(render_state, &mut render_resource_assignments); - self.fill_in_missing_uniforms( - &mut render_resource_assignments, - &render_state.program.pipeline_descriptor.borrow(), - ); - self.setup_bind_groups( - &render_state.program.pipeline_descriptor.borrow(), - &mut render_resource_assignments, - ); - self.setup_vertex_buffers(render_state, &mut render_resource_assignments); - self.render_context.borrow_mut().begin_pass( - &pass_descriptor, - &render_resource_assignments, - &mut |pass| { - let viewport = render_state.viewport; - pass.set_viewport( - viewport.origin().x() as f32, - viewport.origin().y() as f32, - viewport.size().x() as f32, - viewport.size().y() as f32, - 0.0, - 1.0, - ); - pass.set_pipeline(render_state.program.pipeline_handle); - - if let Some(stencil_state) = render_state.options.stencil { - pass.set_stencil_reference(stencil_state.reference); - } - - let pipeline_descriptor = render_state.program.pipeline_descriptor.borrow(); - pass.set_render_resources(&pipeline_descriptor, &render_resource_assignments); - draw_func(pass); - }, - ) - } - - fn get_texture_format(&self, render_resource: RenderResource) -> Option { - // TODO: add swap chain resource info so this isnt necessary - let mut texture_format = Some(TextureFormat::Bgra8UnormSrgb); - self.render_context - .borrow() - .resources() - .get_resource_info(render_resource, &mut |info| { - if let Some(ResourceInfo::Texture(descriptor)) = info { - texture_format = Some(descriptor.format) - } - }); - texture_format - } - - // v - pub fn setup_pipline_descriptor( - &self, - render_state: &RenderState, - pass_descriptor: &PassDescriptor, - requested_vertex_descriptors: &HashMap, - ) { - // TODO: only create pipelines once - // if self - // .render_context - // .borrow() - // .resources() - // .get_asset_resource(render_state.program.pipeline_handle, 0) - // .is_some() - // { - // return; - // } - - let mut pipeline_descriptor = render_state.program.pipeline_descriptor.borrow_mut(); - pipeline_descriptor.primitive_topology = match render_state.primitive { - pathfinder_gpu::Primitive::Triangles => PrimitiveTopology::TriangleList, - pathfinder_gpu::Primitive::Lines => PrimitiveTopology::LineList, - }; - pipeline_descriptor.rasterization_state = Some(RasterizationStateDescriptor::default()); - { - let mut layout = pipeline_descriptor.get_layout_mut().unwrap(); - let mut i = 0; - let mut descriptors = Vec::with_capacity(requested_vertex_descriptors.len()); - loop { - if let Some(descriptor) = requested_vertex_descriptors.get(&i) { - let mut descriptor = descriptor.clone(); - descriptor.attributes.sort_by_key(|a| a.shader_location); - descriptors.push(descriptor); - i += 1; - } else { - break; - } - } - layout.vertex_buffer_descriptors = descriptors; - } - - let color_texture_format = if let TextureAttachment::RenderResource(texture_resource) = - pass_descriptor - .color_attachments - .first() - .unwrap() - .attachment - { - self.get_texture_format(texture_resource) - .expect("expected color attachment RenderResource to have a texture format") - } else { - panic!("expected a RenderResource color attachment"); - }; - - // TODO: make sure colors render correctly - let mut color_state = ColorStateDescriptor { - format: color_texture_format, - color_blend: BlendDescriptor { - src_factor: BlendFactor::SrcAlpha, - dst_factor: BlendFactor::OneMinusSrcAlpha, - operation: BlendOperation::Add, - }, - alpha_blend: BlendDescriptor { - src_factor: BlendFactor::One, - dst_factor: BlendFactor::One, - operation: BlendOperation::Add, - }, - write_mask: if render_state.options.color_mask { - ColorWrite::all() - } else { - ColorWrite::empty() - }, - }; - - if let Some(blend_state) = render_state.options.blend { - let blend_op = blend_state.op.to_bevy_blend_op(); - color_state.color_blend.src_factor = blend_state.src_rgb_factor.to_bevy_blend_factor(); - color_state.color_blend.dst_factor = blend_state.dest_rgb_factor.to_bevy_blend_factor(); - color_state.color_blend.operation = blend_op; - - color_state.alpha_blend.src_factor = - blend_state.src_alpha_factor.to_bevy_blend_factor(); - color_state.alpha_blend.dst_factor = - blend_state.dest_alpha_factor.to_bevy_blend_factor(); - color_state.color_blend.operation = blend_op; - } - - pipeline_descriptor.color_states.push(color_state); - - if let Some(ref pass_depth_stencil_descriptor) = pass_descriptor.depth_stencil_attachment { - // TODO: maybe we need a stencil-type depth format? TextureFormat::Depth24PlusStencil8 - let format = self - .get_texture_format( - pass_depth_stencil_descriptor - .attachment - .get_resource() - .expect("Expected attachment to be a resource"), - ) - .expect("expected a texture format"); - let mut descriptor = DepthStencilStateDescriptor { - format, - depth_write_enabled: false, - depth_compare: CompareFunction::Less, - stencil_front: StencilStateFaceDescriptor::IGNORE, - stencil_back: StencilStateFaceDescriptor::IGNORE, - stencil_read_mask: 0, - stencil_write_mask: 0, - }; - - if let Some(depth_state) = render_state.options.depth { - let compare_function = depth_state.func.to_bevy_compare_function(); - descriptor.depth_compare = compare_function; - descriptor.depth_write_enabled = true; - } - - if let Some(stencil_state) = render_state.options.stencil { - let compare = stencil_state.func.to_bevy_compare_function(); - let (pass_op, write_mask) = if stencil_state.write { - (StencilOperation::Replace, stencil_state.mask) - } else { - (StencilOperation::Keep, 0) - }; - - let stencil_descriptor = StencilStateFaceDescriptor { - compare, - pass_op, - depth_fail_op: StencilOperation::Keep, - fail_op: StencilOperation::Keep, - }; - - descriptor.stencil_write_mask = write_mask; - descriptor.stencil_front = stencil_descriptor.clone(); - descriptor.stencil_back = stencil_descriptor; - } - pipeline_descriptor.depth_stencil_state = Some(descriptor); - } - - self.render_context - .borrow() - .resources() - .create_render_pipeline( - render_state.program.pipeline_handle, - &pipeline_descriptor, - &self.shaders.borrow(), - ); - } - - pub fn create_pass_descriptor( - &self, - render_state: &RenderState, - ) -> PassDescriptor { - let mut depth_texture = None; - let color_texture = match render_state.target { - RenderTarget::Default { .. } => { - depth_texture = Some(self.main_depth_stencil_texture); - self.main_color_texture - } - RenderTarget::Framebuffer(framebuffer) => framebuffer.handle, - }; - - let mut color_attachment = RenderPassColorAttachmentDescriptor { - attachment: TextureAttachment::RenderResource(color_texture), - clear_color: Color::WHITE, - load_op: LoadOp::Load, - store_op: StoreOp::Store, - resolve_target: None, - }; - - if let Some(color) = render_state.options.clear_ops.color { - color_attachment.clear_color = Color::rgba(color.r(), color.g(), color.b(), color.a()); - color_attachment.load_op = LoadOp::Clear; - } - - let depth_stencil_attachment = if let Some(depth_texture) = depth_texture { - let mut descriptor = RenderPassDepthStencilAttachmentDescriptor { - attachment: TextureAttachment::RenderResource(depth_texture), - depth_load_op: LoadOp::Load, - depth_store_op: StoreOp::Store, - stencil_load_op: LoadOp::Load, - stencil_store_op: StoreOp::Store, - clear_depth: 1.0, - clear_stencil: 0, - }; - - if let Some(depth) = render_state.options.clear_ops.depth { - descriptor.clear_depth = depth; - descriptor.depth_load_op = LoadOp::Clear; - } - - if let Some(value) = render_state.options.clear_ops.stencil { - descriptor.clear_stencil = value as u32; - descriptor.stencil_load_op = LoadOp::Clear; - } - - Some(descriptor) - } else { - None - }; - - PassDescriptor { - color_attachments: vec![color_attachment], - depth_stencil_attachment, - sample_count: 1, - } - } -} - -pub struct BevyTimerQuery {} -pub struct BevyTextureDataReceiver {} -pub struct BevyUniform { - pub name: String, -} - -pub struct BevyVertexAttr { - attr: RefCell, -} - -#[derive(Debug)] -pub struct BevyVertexArray { - requested_descriptors: RefCell>, - vertex_buffers: RefCell>, - index_buffer: RefCell>, -} - -pub struct BevyProgram { - pipeline_descriptor: RefCell, - pipeline_handle: Handle, -} - -pub struct BevyTexture { - handle: RenderResource, - texture_descriptor: TextureDescriptor, - sampler_resource: RefCell>, -} - -#[derive(Debug, Clone)] -pub struct BevyBuffer { - handle: Rc>>, - mode: BufferUploadMode, -} - -impl<'a> Device for BevyPathfinderDevice<'a> { - type Buffer = BevyBuffer; - type Fence = (); - type Framebuffer = BevyTexture; - type Program = BevyProgram; - type Shader = Handle; - type StorageBuffer = (); - type Texture = BevyTexture; - type TextureDataReceiver = BevyTextureDataReceiver; - type TimerQuery = BevyTimerQuery; - type Uniform = BevyUniform; - type VertexArray = BevyVertexArray; - type VertexAttr = BevyVertexAttr; - - fn create_texture( - &self, - format: pathfinder_gpu::TextureFormat, - size: Vector2I, - ) -> Self::Texture { - let descriptor = TextureDescriptor { - size: Extent3d { - depth: 1, - width: size.x() as u32, - height: size.y() as u32, - }, - mip_level_count: 1, - sample_count: 1, - dimension: TextureDimension::D2, - format: match format { - pathfinder_gpu::TextureFormat::R8 => TextureFormat::R8Unorm, - pathfinder_gpu::TextureFormat::R16F => TextureFormat::R16Float, - pathfinder_gpu::TextureFormat::RGBA8 => TextureFormat::Rgba8Unorm, - pathfinder_gpu::TextureFormat::RGBA16F => TextureFormat::Rgba16Float, - pathfinder_gpu::TextureFormat::RGBA32F => TextureFormat::Rgba32Float, - }, - usage: TextureUsage::WRITE_ALL | TextureUsage::SAMPLED, // TODO: this might be overly safe - }; - BevyTexture { - handle: self - .render_context - .borrow() - .resources() - .create_texture(descriptor), - texture_descriptor: descriptor, - sampler_resource: RefCell::new(None), - } - } - fn create_texture_from_data( - &self, - format: pathfinder_gpu::TextureFormat, - size: Vector2I, - data: TextureDataRef, - ) -> Self::Texture { - let texture = self.create_texture(format, size); - self.upload_to_texture(&texture, RectI::new(Vector2I::default(), size), data); - texture - } - fn create_shader( - &self, - resources: &dyn ResourceLoader, - name: &str, - kind: ShaderKind, - ) -> Self::Shader { - let suffix = match kind { - ShaderKind::Vertex => 'v', - ShaderKind::Fragment => 'f', - ShaderKind::Compute => 'c', - }; - let path = format!("shaders/vulkan/{}.{}s.spv", name, suffix); - let bytes = resources.slurp(&path).unwrap(); - - self.create_shader_from_source(name, &bytes, kind) - } - fn create_shader_from_source( - &self, - _name: &str, - source: &[u8], - kind: ShaderKind, - ) -> Self::Shader { - let stage = match kind { - ShaderKind::Fragment => ShaderStage::Fragment, - ShaderKind::Vertex => ShaderStage::Vertex, - ShaderKind::Compute => panic!("bevy does not currently support compute shaders"), - }; - let shader = Shader::new(stage, ShaderSource::spirv_from_bytes(source)); - let mut shaders = self.shaders.borrow_mut(); - let handle = shaders.add(shader); - self.render_context - .borrow() - .resources() - .create_shader_module(handle, &mut shaders); - handle - } - - fn create_vertex_array(&self) -> Self::VertexArray { - BevyVertexArray { - requested_descriptors: RefCell::new(HashMap::new()), - index_buffer: RefCell::new(None), - vertex_buffers: RefCell::new(Vec::new()), - } - } - fn create_program_from_shaders( - &self, - _resources: &dyn ResourceLoader, - _name: &str, - shaders: ProgramKind>, - ) -> BevyProgram { - match shaders { - ProgramKind::Compute(_) => panic!("bevy does not currently support compute shaders"), - ProgramKind::Raster { vertex, fragment } => { - let mut descriptor = PipelineDescriptor::new(ShaderStages { - vertex, - fragment: Some(fragment), - }); - descriptor.index_format = IndexFormat::Uint32; - descriptor.reflect_layout(&self.shaders.borrow(), false, None, None); - BevyProgram { - pipeline_descriptor: RefCell::new(descriptor), - pipeline_handle: Handle::new(), - } - } - } - } - fn get_vertex_attr(&self, program: &BevyProgram, name: &str) -> Option { - // TODO: this probably isn't actually used for anything. try to optimize - let pipeline_descriptor = program.pipeline_descriptor.borrow(); - let layout = pipeline_descriptor.get_layout().unwrap(); - let attribute_name = format!("a{}", name); - for buffer_descriptor in layout.vertex_buffer_descriptors.iter() { - let attribute = buffer_descriptor - .attributes - .iter() - .find(|a| a.name == attribute_name) - .cloned(); - if attribute.is_some() { - return attribute.map(|a| BevyVertexAttr { - attr: RefCell::new(a), - }); - } - } - - None - } - fn get_uniform(&self, _program: &BevyProgram, name: &str) -> Self::Uniform { - BevyUniform { - name: format!("u{}", name), - } - } - fn bind_buffer( - &self, - vertex_array: &BevyVertexArray, - buffer: &BevyBuffer, - target: BufferTarget, - ) { - match target { - BufferTarget::Vertex => vertex_array - .vertex_buffers - .borrow_mut() - .push(buffer.clone()), - BufferTarget::Index => *vertex_array.index_buffer.borrow_mut() = Some(buffer.clone()), - _ => panic!("Buffers bound to vertex arrays must be vertex or index buffers!"), - } - } - fn configure_vertex_attr( - &self, - vertex_array: &BevyVertexArray, - bevy_attr: &BevyVertexAttr, - descriptor: &VertexAttrDescriptor, - ) { - // println!("configure: {:?} {:?}") - let format = match (descriptor.class, descriptor.attr_type, descriptor.size) { - (VertexAttrClass::Int, VertexAttrType::I8, 2) => VertexFormat::Char2, - // (VertexAttrClass::Int, VertexAttrType::I8, 3) => VertexFormat::Char3, - (VertexAttrClass::Int, VertexAttrType::I8, 4) => VertexFormat::Char4, - (VertexAttrClass::Int, VertexAttrType::U8, 2) => VertexFormat::Uchar2, - // (VertexAttrClass::Int, VertexAttrType::U8, 3) => VertexFormat::Uchar3, - (VertexAttrClass::Int, VertexAttrType::U8, 4) => VertexFormat::Uchar4, - (VertexAttrClass::FloatNorm, VertexAttrType::U8, 2) => VertexFormat::Uchar2Norm, - // (VertexAttrClass::FloatNorm, VertexAttrType::U8, 3) => { - // VertexFormat::UChar3Normalized - // } - (VertexAttrClass::FloatNorm, VertexAttrType::U8, 4) => VertexFormat::Uchar4Norm, - (VertexAttrClass::FloatNorm, VertexAttrType::I8, 2) => VertexFormat::Char2Norm, - // (VertexAttrClass::FloatNorm, VertexAttrType::I8, 3) => { - // VertexFormat::Char3Norm - // } - (VertexAttrClass::FloatNorm, VertexAttrType::I8, 4) => VertexFormat::Char4Norm, - (VertexAttrClass::Int, VertexAttrType::I16, 2) => VertexFormat::Short2, - // (VertexAttrClass::Int, VertexAttrType::I16, 3) => VertexFormat::Short3, - (VertexAttrClass::Int, VertexAttrType::I16, 4) => VertexFormat::Short4, - (VertexAttrClass::Int, VertexAttrType::U16, 2) => VertexFormat::Ushort2, - // (VertexAttrClass::Int, VertexAttrType::U16, 3) => VertexFormat::UShort3, - (VertexAttrClass::Int, VertexAttrType::U16, 4) => VertexFormat::Ushort4, - (VertexAttrClass::FloatNorm, VertexAttrType::U16, 2) => VertexFormat::Ushort2Norm, - // (VertexAttrClass::FloatNorm, VertexAttrType::U16, 3) => { - // VertexFormat::UShort3Normalized - // } - (VertexAttrClass::FloatNorm, VertexAttrType::U16, 4) => VertexFormat::Ushort4Norm, - (VertexAttrClass::FloatNorm, VertexAttrType::I16, 2) => VertexFormat::Short2Norm, - // (VertexAttrClass::FloatNorm, VertexAttrType::I16, 3) => { - // VertexFormat::Short3Normalized - // } - (VertexAttrClass::FloatNorm, VertexAttrType::I16, 4) => VertexFormat::Short4Norm, - (VertexAttrClass::Int, VertexAttrType::I32, 1) => VertexFormat::Int, - (VertexAttrClass::Int, VertexAttrType::I32, 2) => VertexFormat::Int2, - (VertexAttrClass::Int, VertexAttrType::I32, 3) => VertexFormat::Int3, - (VertexAttrClass::Int, VertexAttrType::I32, 4) => VertexFormat::Int4, - (VertexAttrClass::Int, VertexAttrType::U32, 1) => VertexFormat::Uint, - (VertexAttrClass::Int, VertexAttrType::U32, 2) => VertexFormat::Uint2, - (VertexAttrClass::Int, VertexAttrType::U32, 3) => VertexFormat::Uint3, - (VertexAttrClass::Int, VertexAttrType::U32, 4) => VertexFormat::Uint4, - (VertexAttrClass::Float, VertexAttrType::F32, 1) => VertexFormat::Float, - (VertexAttrClass::Float, VertexAttrType::F32, 2) => VertexFormat::Float2, - (VertexAttrClass::Float, VertexAttrType::F32, 3) => VertexFormat::Float3, - (VertexAttrClass::Float, VertexAttrType::F32, 4) => VertexFormat::Float4, - // (VertexAttrClass::Int, VertexAttrType::I8, 1) => VertexFormat::Char, - // (VertexAttrClass::Int, VertexAttrType::U8, 1) => VertexFormat::UChar, - // (VertexAttrClass::FloatNorm, VertexAttrType::I8, 1) => VertexFormat::CharNormalized, - // (VertexAttrClass::FloatNorm, VertexAttrType::U8, 1) => { - // VertexFormat::UCharNormalized - // } - // (VertexAttrClass::Int, VertexAttrType::I16, 1) => VertexFormat::Short, - // (VertexAttrClass::Int, VertexAttrType::U16, 1) => VertexFormat::UShort, - // (VertexAttrClass::FloatNorm, VertexAttrType::U16, 1) => { - // VertexFormat::UShortNormalized - // } - // (VertexAttrClass::FloatNorm, VertexAttrType::I16, 1) => { - // VertexFormat::ShortNormalized - // } - (attr_class, attr_type, attr_size) => panic!( - "Unsupported vertex class/type/size combination: {:?}/{:?}/{}!", - attr_class, attr_type, attr_size - ), - }; - - let mut requested_descriptors = vertex_array.requested_descriptors.borrow_mut(); - let buffer_index = descriptor.buffer_index; - let step_mode = if descriptor.divisor == 0 { - InputStepMode::Vertex - } else { - InputStepMode::Instance - }; - - assert!( - descriptor.divisor <= 1, - "instanced step size greater than 1 not supported" - ); - - let vertex_buffer_descriptor = - requested_descriptors - .entry(buffer_index) - .or_insert_with(|| VertexBufferDescriptor { - name: Cow::Borrowed(get_vertex_buffer_name(buffer_index as usize)), - attributes: Vec::new(), - step_mode, - stride: descriptor.stride as u64, - }); - - let mut attr = bevy_attr.attr.borrow_mut(); - attr.format = format; - attr.offset = descriptor.offset as u64; - - vertex_buffer_descriptor.attributes.push(attr.clone()); - } - - fn create_framebuffer(&self, texture: BevyTexture) -> BevyTexture { - texture - } - - fn create_buffer(&self, mode: BufferUploadMode) -> Self::Buffer { - BevyBuffer { - handle: Rc::new(RefCell::new(None)), - mode, - } - } - - fn allocate_buffer(&self, buffer: &BevyBuffer, data: BufferData, target: BufferTarget) { - let usage = match target { - BufferTarget::Vertex => BufferUsage::VERTEX, - BufferTarget::Index => BufferUsage::INDEX, - BufferTarget::Storage => BufferUsage::empty(), - }; - - let buffer_usage = match buffer.mode { - BufferUploadMode::Dynamic => BufferUsage::WRITE_ALL | usage, - BufferUploadMode::Static => BufferUsage::COPY_DST | usage, - }; - match data { - BufferData::Uninitialized(size) => { - let size = size * mem::size_of::(); - let new_buffer = - self.render_context - .borrow() - .resources() - .create_buffer(BufferInfo { - size, - buffer_usage, - ..Default::default() - }); - *buffer.handle.borrow_mut() = Some(new_buffer); - } - BufferData::Memory(slice) => { - let new_buffer = self - .render_context - .borrow() - .resources() - .create_buffer_with_data( - BufferInfo { - buffer_usage, - ..Default::default() - }, - slice_to_u8(slice), - ); - *buffer.handle.borrow_mut() = Some(new_buffer); - } - } - } - - fn framebuffer_texture<'f>(&self, framebuffer: &'f BevyTexture) -> &'f BevyTexture { - framebuffer - } - - fn destroy_framebuffer(&self, framebuffer: BevyTexture) -> BevyTexture { - // TODO: should this deallocate the bevy texture? - framebuffer - } - - fn texture_format(&self, texture: &BevyTexture) -> pathfinder_gpu::TextureFormat { - match texture.texture_descriptor.format { - TextureFormat::R8Unorm => pathfinder_gpu::TextureFormat::R8, - TextureFormat::R16Float => pathfinder_gpu::TextureFormat::R16F, - TextureFormat::Rgba8Unorm => pathfinder_gpu::TextureFormat::RGBA8, - TextureFormat::Rgba16Float => pathfinder_gpu::TextureFormat::RGBA16F, - TextureFormat::Rgba32Float => pathfinder_gpu::TextureFormat::RGBA32F, - _ => panic!( - "unexpected texture format {:?}", - texture.texture_descriptor.format - ), - } - } - - fn texture_size(&self, texture: &BevyTexture) -> Vector2I { - vec2i( - texture.texture_descriptor.size.width as i32, - texture.texture_descriptor.size.height as i32, - ) - } - - fn set_texture_sampling_mode(&self, texture: &BevyTexture, flags: TextureSamplingFlags) { - let mut samplers = self.samplers.borrow_mut(); - let resource = samplers.entry(flags.bits()).or_insert_with(|| { - let descriptor = SamplerDescriptor { - address_mode_u: if flags.contains(TextureSamplingFlags::REPEAT_U) { - AddressMode::Repeat - } else { - AddressMode::ClampToEdge - }, - address_mode_v: if flags.contains(TextureSamplingFlags::REPEAT_V) { - AddressMode::Repeat - } else { - AddressMode::ClampToEdge - }, - address_mode_w: AddressMode::ClampToEdge, - mag_filter: if flags.contains(TextureSamplingFlags::NEAREST_MAG) { - FilterMode::Nearest - } else { - FilterMode::Linear - }, - min_filter: if flags.contains(TextureSamplingFlags::NEAREST_MIN) { - FilterMode::Nearest - } else { - FilterMode::Linear - }, - mipmap_filter: FilterMode::Nearest, - lod_min_clamp: -100.0, - lod_max_clamp: 100.0, - compare_function: CompareFunction::Always, - }; - self.render_context - .borrow_mut() - .resources() - .create_sampler(&descriptor) - }); - *texture.sampler_resource.borrow_mut() = Some(*resource); - } - - fn upload_to_texture(&self, texture: &BevyTexture, rect: RectI, data: TextureDataRef) { - let texture_size = self.texture_size(texture); - assert!(rect.size().x() >= 0); - assert!(rect.size().y() >= 0); - assert!(rect.max_x() <= texture_size.x()); - assert!(rect.max_y() <= texture_size.y()); - - let format = self.texture_format(&texture); - let width = rect.size().x() as u32; - let height = rect.size().y() as u32; - let origin = [rect.origin().x() as u32, rect.origin().y() as u32, 0]; - let bytes_per_pixel = format.bytes_per_pixel() as u32; - - let staging_buffer = self - .render_context - .borrow() - .resources() - .create_buffer_with_data( - BufferInfo { - buffer_usage: BufferUsage::COPY_SRC, - ..Default::default() - }, - get_texture_bytes(&data), - ); - - let stride = bytes_per_pixel * width; - - self.render_context.borrow_mut().copy_buffer_to_texture( - staging_buffer, - 0, - stride, - texture.handle, - origin, - 0, - 0, - Extent3d { - width, - height, - depth: 1, - }, - ) - } - fn read_pixels( - &self, - _target: &RenderTarget, - _viewport: RectI, - ) -> Self::TextureDataReceiver { - // TODO: this might actually be optional, which is great because otherwise this requires a command buffer sync - todo!() - } - fn begin_commands(&self) { - // NOTE: the Bevy Render Graph handles command buffer creation - } - fn end_commands(&self) { - // NOTE: the Bevy Render Graph handles command buffer submission - } - fn draw_arrays(&self, index_count: u32, render_state: &RenderState) { - self.draw(render_state, |pass| { - pass.draw(0..index_count, 0..1); - }); - } - fn draw_elements(&self, index_count: u32, render_state: &RenderState) { - self.draw(render_state, |pass| { - pass.draw_indexed(0..index_count, 0, 0..1); - }); - } - fn draw_elements_instanced( - &self, - index_count: u32, - instance_count: u32, - render_state: &RenderState, - ) { - self.draw(render_state, |pass| { - pass.draw_indexed(0..index_count, 0, 0..instance_count); - }); - } - fn create_timer_query(&self) -> Self::TimerQuery { - // TODO: maybe not needed - BevyTimerQuery {} - } - fn begin_timer_query(&self, _query: &Self::TimerQuery) {} - fn end_timer_query(&self, _query: &Self::TimerQuery) {} - fn try_recv_timer_query(&self, _query: &Self::TimerQuery) -> Option { - todo!() - } - fn recv_timer_query(&self, _query: &Self::TimerQuery) -> std::time::Duration { - todo!() - } - fn try_recv_texture_data(&self, _receiver: &Self::TextureDataReceiver) -> Option { - todo!() - } - fn recv_texture_data(&self, _receiver: &Self::TextureDataReceiver) -> TextureData { - todo!() - } - fn feature_level(&self) -> pathfinder_gpu::FeatureLevel { - // TODO: change to 11 when compute is added - FeatureLevel::D3D10 - } - fn set_compute_program_local_size( - &self, - _program: &mut Self::Program, - _local_size: pathfinder_gpu::ComputeDimensions, - ) { - todo!() - } - fn get_storage_buffer( - &self, - _program: &Self::Program, - _name: &str, - _binding: u32, - ) -> Self::StorageBuffer { - panic!("Compute shader is unsupported in Bevy!"); - } - fn upload_to_buffer( - &self, - buffer: &BevyBuffer, - position: usize, - data: &[T], - _target: BufferTarget, - ) { - let temp_buffer = self - .render_context - .borrow() - .resources() - .create_buffer_with_data( - BufferInfo { - buffer_usage: BufferUsage::COPY_SRC | BufferUsage::COPY_DST, - ..Default::default() - }, - slice_to_u8(data), - ); - let buffer_handle = buffer.handle.borrow().unwrap(); - self.render_context.borrow_mut().copy_buffer_to_buffer( - temp_buffer, - 0, - buffer_handle, - (position * mem::size_of::()) as u64, - (data.len() * mem::size_of::()) as u64, - ) - } - fn dispatch_compute( - &self, - _dimensions: pathfinder_gpu::ComputeDimensions, - _state: &pathfinder_gpu::ComputeState, - ) { - panic!("Compute shader is unsupported in Bevy!"); - } - fn add_fence(&self) -> Self::Fence {} - fn wait_for_fence(&self, _fence: &Self::Fence) {} -} - -fn get_texture_bytes<'a>(data_ref: &'a TextureDataRef) -> &'a [u8] { - match data_ref { - TextureDataRef::U8(data) => slice_to_u8(data), - TextureDataRef::F16(data) => slice_to_u8(data), - TextureDataRef::F32(data) => slice_to_u8(data), - } -} - -fn slice_to_u8(slice: &[T]) -> &[u8] { - unsafe { - std::slice::from_raw_parts( - slice.as_ptr() as *const u8, - slice.len() * mem::size_of::(), - ) - } -} - -trait ToBevyBlendOp { - fn to_bevy_blend_op(self) -> BlendOperation; -} - -impl ToBevyBlendOp for pathfinder_gpu::BlendOp { - #[inline] - fn to_bevy_blend_op(self) -> BlendOperation { - match self { - pathfinder_gpu::BlendOp::Add => BlendOperation::Add, - pathfinder_gpu::BlendOp::Subtract => BlendOperation::Subtract, - pathfinder_gpu::BlendOp::ReverseSubtract => BlendOperation::ReverseSubtract, - pathfinder_gpu::BlendOp::Min => BlendOperation::Min, - pathfinder_gpu::BlendOp::Max => BlendOperation::Max, - } - } -} - -trait ToBevyBlendFactor { - fn to_bevy_blend_factor(self) -> BlendFactor; -} - -impl ToBevyBlendFactor for pathfinder_gpu::BlendFactor { - #[inline] - fn to_bevy_blend_factor(self) -> BlendFactor { - match self { - pathfinder_gpu::BlendFactor::Zero => BlendFactor::Zero, - pathfinder_gpu::BlendFactor::One => BlendFactor::One, - pathfinder_gpu::BlendFactor::SrcAlpha => BlendFactor::SrcAlpha, - pathfinder_gpu::BlendFactor::OneMinusSrcAlpha => BlendFactor::OneMinusSrcAlpha, - pathfinder_gpu::BlendFactor::DestAlpha => BlendFactor::DstAlpha, - pathfinder_gpu::BlendFactor::OneMinusDestAlpha => BlendFactor::OneMinusDstAlpha, - pathfinder_gpu::BlendFactor::DestColor => BlendFactor::DstColor, - } - } -} - -trait ToBevyCompareFunction { - fn to_bevy_compare_function(self) -> CompareFunction; -} - -impl ToBevyCompareFunction for pathfinder_gpu::DepthFunc { - fn to_bevy_compare_function(self) -> CompareFunction { - match self { - pathfinder_gpu::DepthFunc::Always => CompareFunction::Always, - pathfinder_gpu::DepthFunc::Less => CompareFunction::Less, - } - } -} - -impl ToBevyCompareFunction for pathfinder_gpu::StencilFunc { - fn to_bevy_compare_function(self) -> CompareFunction { - match self { - pathfinder_gpu::StencilFunc::Always => CompareFunction::Always, - pathfinder_gpu::StencilFunc::Equal => CompareFunction::Equal, - } - } -} - -pub const PATHFINDER_VERTEX_BUFFER_0: &'static str = "P0"; -pub const PATHFINDER_VERTEX_BUFFER_1: &'static str = "P1"; -pub const PATHFINDER_VERTEX_BUFFER_2: &'static str = "P2"; -pub const PATHFINDER_VERTEX_BUFFER_3: &'static str = "P3"; - -pub fn get_vertex_buffer_name(index: usize) -> &'static str { - match index { - 0 => PATHFINDER_VERTEX_BUFFER_0, - 1 => PATHFINDER_VERTEX_BUFFER_1, - 2 => PATHFINDER_VERTEX_BUFFER_2, - 3 => PATHFINDER_VERTEX_BUFFER_3, - _ => panic!("encountered unknown vertex buffer index"), - } -} diff --git a/crates/bevy_pathfinder/src/lib.rs b/crates/bevy_pathfinder/src/lib.rs deleted file mode 100644 index 38054039d5..0000000000 --- a/crates/bevy_pathfinder/src/lib.rs +++ /dev/null @@ -1,39 +0,0 @@ -mod device; -mod pathfinder_node; -use bevy_app::{AppBuilder, AppPlugin}; -pub use device::*; - -use bevy_render::{ - base_render_graph, - render_graph::{ - nodes::{WindowSwapChainNode, WindowTextureNode}, - RenderGraph, - }, -}; -use pathfinder_node::PathfinderNode; - -#[derive(Default)] -pub struct PathfinderPlugin; - -impl AppPlugin for PathfinderPlugin { - fn build(&self, app: &mut AppBuilder) { - let mut render_graph = app.resources().get_mut::().unwrap(); - render_graph.add_node_named("pathfinder", PathfinderNode::default()); - render_graph - .add_slot_edge( - base_render_graph::node::PRIMARY_SWAP_CHAIN, - WindowSwapChainNode::OUT_TEXTURE, - "pathfinder", - PathfinderNode::IN_COLOR_TEXTURE, - ) - .unwrap(); - render_graph - .add_slot_edge( - base_render_graph::node::MAIN_DEPTH_TEXTURE, - WindowTextureNode::OUT_TEXTURE, - "pathfinder", - PathfinderNode::IN_DEPTH_STENCIL_TEXTURE, - ) - .unwrap(); - } -} diff --git a/crates/bevy_pathfinder/src/pathfinder_node.rs b/crates/bevy_pathfinder/src/pathfinder_node.rs deleted file mode 100644 index a6390b5144..0000000000 --- a/crates/bevy_pathfinder/src/pathfinder_node.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::BevyPathfinderDevice; -use bevy_asset::AssetStorage; -use bevy_render::{ - render_graph::{Node, ResourceSlotInfo, ResourceSlots}, - render_resource::ResourceInfo, - renderer::RenderContext, - shader::{FieldBindType, Shader}, -}; -use legion::prelude::{Resources, World}; -use pathfinder_canvas::{vec2f, Canvas, CanvasFontContext, ColorF, Path2D, RectF, Vector2I}; -use pathfinder_renderer::{ - concurrent::{rayon::RayonExecutor, scene_proxy::SceneProxy}, - gpu::{ - options::{DestFramebuffer, RendererOptions}, - renderer::Renderer, - }, - options::BuildOptions, -}; -use pathfinder_resources::embedded::EmbeddedResourceLoader; -use std::borrow::Cow; - -#[derive(Default)] -pub struct PathfinderNode; - -impl PathfinderNode { - pub const IN_COLOR_TEXTURE: &'static str = "color"; - pub const IN_DEPTH_STENCIL_TEXTURE: &'static str = "depth_stencil"; -} - -impl Node for PathfinderNode { - fn input(&self) -> &[ResourceSlotInfo] { - static INPUT: &[ResourceSlotInfo] = &[ - ResourceSlotInfo { - name: Cow::Borrowed(PathfinderNode::IN_COLOR_TEXTURE), - resource_type: FieldBindType::Texture, - }, - ResourceSlotInfo { - name: Cow::Borrowed(PathfinderNode::IN_DEPTH_STENCIL_TEXTURE), - resource_type: FieldBindType::Texture, - }, - ]; - INPUT - } - fn update( - &mut self, - _world: &World, - resources: &Resources, - render_context: &mut dyn RenderContext, - input: &ResourceSlots, - _output: &mut ResourceSlots, - ) { - let mut shaders = resources.get_mut::>().unwrap(); - let color_texture = input.get(PathfinderNode::IN_COLOR_TEXTURE).unwrap(); - let depth_stencil_texture = input.get(PathfinderNode::IN_DEPTH_STENCIL_TEXTURE).unwrap(); - let device = BevyPathfinderDevice::new( - render_context, - &mut shaders, - color_texture, - depth_stencil_texture, - ); - let window_size = Vector2I::new(1280 as i32, 720 as i32); - let mut renderer = Renderer::new( - device, - &EmbeddedResourceLoader::new(), - DestFramebuffer::full_window(window_size), - RendererOptions { - background_color: Some(ColorF::white()), - ..Default::default() - }, - ); - - // Make a canvas. We're going to draw a house. - let mut canvas = Canvas::new(window_size.to_f32()) - .get_context_2d(CanvasFontContext::from_system_source()); - - // Set line width. - canvas.set_line_width(10.0); - - // Draw walls. - canvas.stroke_rect(RectF::new(vec2f(75.0, 140.0), vec2f(150.0, 110.0))); - - // Draw door. - canvas.fill_rect(RectF::new(vec2f(130.0, 190.0), vec2f(40.0, 60.0))); - - // Draw roof. - let mut path = Path2D::new(); - path.move_to(vec2f(50.0, 140.0)); - path.line_to(vec2f(150.0, 60.0)); - path.line_to(vec2f(250.0, 140.0)); - path.close_path(); - canvas.stroke_path(path); - - // Render the canvas to screen. - let scene = SceneProxy::from_scene(canvas.into_canvas().into_scene(), RayonExecutor); - scene.build_and_render(&mut renderer, BuildOptions::default()); - // TODO: submit command buffers? - } -} diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 5d95d60004..72032f20ad 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -314,7 +314,6 @@ mod tests { use super::RenderGraph; use crate::{ render_graph::{Edge, Node, NodeId, RenderGraphError, ResourceSlotInfo, ResourceSlots}, - render_resource::ResourceInfo, renderer::RenderContext, shader::FieldBindType, }; use legion::prelude::{Resources, World}; diff --git a/crates/bevy_render/src/render_graph/node_slot.rs b/crates/bevy_render/src/render_graph/node_slot.rs index 383ec9cf26..bd4bc68e86 100644 --- a/crates/bevy_render/src/render_graph/node_slot.rs +++ b/crates/bevy_render/src/render_graph/node_slot.rs @@ -1,5 +1,5 @@ use super::RenderGraphError; -use crate::{shader::FieldBindType, render_resource::{RenderResource, ResourceInfo}}; +use crate::{render_resource::RenderResource, shader::FieldBindType}; use std::borrow::Cow; #[derive(Debug, Clone)] diff --git a/crates/bevy_render/src/render_graph/nodes/pass_node.rs b/crates/bevy_render/src/render_graph/nodes/pass_node.rs index db1744a0dd..fb30856d28 100644 --- a/crates/bevy_render/src/render_graph/nodes/pass_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/pass_node.rs @@ -3,7 +3,7 @@ use crate::{ pass::{PassDescriptor, TextureAttachment}, pipeline::{PipelineCompiler, PipelineDescriptor}, render_graph::{Node, ResourceSlotInfo, ResourceSlots}, - render_resource::{RenderResourceAssignments, ResourceInfo}, + render_resource::RenderResourceAssignments, renderer::RenderContext, shader::{FieldBindType, Shader}, }; diff --git a/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs b/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs index f67f44a458..ed7d8c0cc1 100644 --- a/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs @@ -1,6 +1,5 @@ use crate::{ render_graph::{Node, ResourceSlotInfo, ResourceSlots}, - render_resource::ResourceInfo, renderer::RenderContext, shader::FieldBindType, }; use bevy_app::{EventReader, Events}; diff --git a/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs b/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs index 9924c63e9a..48dd797796 100644 --- a/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs @@ -1,6 +1,5 @@ use crate::{ render_graph::{Node, ResourceSlotInfo, ResourceSlots}, - render_resource::ResourceInfo, renderer::RenderContext, texture::TextureDescriptor, shader::FieldBindType, }; diff --git a/crates/bevy_render/src/render_graph/schedule.rs b/crates/bevy_render/src/render_graph/schedule.rs index c30e4e8bcb..d996b93863 100644 --- a/crates/bevy_render/src/render_graph/schedule.rs +++ b/crates/bevy_render/src/render_graph/schedule.rs @@ -264,7 +264,6 @@ mod tests { use super::{DependentNodeStager, OrderedJob, RenderGraphStager, Stage}; use crate::{ render_graph::{Node, NodeId, RenderGraph, ResourceSlotInfo, ResourceSlots}, - render_resource::ResourceInfo, renderer::RenderContext, shader::FieldBindType, }; use legion::prelude::{Resources, World}; diff --git a/crates/pathfinder/Cargo.toml b/crates/pathfinder/Cargo.toml deleted file mode 100644 index db37ef4dcc..0000000000 --- a/crates/pathfinder/Cargo.toml +++ /dev/null @@ -1,70 +0,0 @@ -[workspace] -members = [ - "c", - "canvas", - "color", - "content", - "demo/android/rust", - "demo/common", - "demo/magicleap", - "demo/native", - "examples/canvas_glutin_minimal", - "examples/canvas_metal_minimal", - "examples/canvas_minimal", - "examples/canvas_moire", - "examples/canvas_nanovg", - "examples/canvas_text", - "examples/lottie_basic", - "examples/swf_basic", - "geometry", - "gl", - "gpu", - "lottie", - "export", - "metal", - "renderer", - "resources", - "simd", - "svg", - "swf", - "text", - "ui", - "utils/area-lut", - "utils/gamma-lut", - "utils/svg-to-skia", - "utils/convert", - "webgl", -] - -default-members = [ - "c", - "canvas", - "content", - "demo/common", - "demo/native", - "examples/canvas_glutin_minimal", - "examples/canvas_minimal", - "examples/canvas_moire", - "examples/canvas_text", - "examples/lottie_basic", - "examples/swf_basic", - "geometry", - "gl", - "gpu", - "lottie", - "export", - "renderer", - "simd", - "svg", - "swf", - "text", - "ui", - "utils/area-lut", - "utils/gamma-lut", - "utils/svg-to-skia", - "utils/convert", -] - -[patch.crates-io] -pathfinder_geometry = { path = "geometry" } -pathfinder_simd = { path = "simd" } diff --git a/crates/pathfinder/LICENSE-APACHE b/crates/pathfinder/LICENSE-APACHE deleted file mode 100644 index 16fe87b06e..0000000000 --- a/crates/pathfinder/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/crates/pathfinder/LICENSE-MIT b/crates/pathfinder/LICENSE-MIT deleted file mode 100644 index 25597d5838..0000000000 --- a/crates/pathfinder/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2010 The Rust Project Developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/crates/pathfinder/README.md b/crates/pathfinder/README.md deleted file mode 100644 index fc5b25e8da..0000000000 --- a/crates/pathfinder/README.md +++ /dev/null @@ -1,109 +0,0 @@ -# Pathfinder 3 - -![Logo](https://github.com/servo/pathfinder/raw/master/resources/textures/pathfinder-logo.png) - -Pathfinder 3 is a fast, practical, GPU-based rasterizer for fonts and vector graphics using OpenGL -3.0+, OpenGL ES 3.0+, WebGL 2, and Metal. - -Please note that Pathfinder is under heavy development and is incomplete in various areas. - -## Quick start - -Pathfinder contains a library that implements a subset of the -[HTML canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API). You can quickly add -vector rendering to any Rust app with it. The library is available on `crates.io`. See -`examples/canvas_minimal` for a small example of usage. - -### Demos - -Demo app sources are available in [demo/](https://github.com/servo/pathfinder/tree/master/demo). A prebuilt package for Magic Leap can be found in [releases](https://github.com/servo/pathfinder/releases). - -## Features - -The project features: - -* High quality antialiasing. Pathfinder can compute exact fractional trapezoidal area coverage on a - per-pixel basis for the highest-quality antialiasing possible (effectively 256xAA). - -* Fast CPU setup, making full use of parallelism. Pathfinder 3 uses the Rayon library to quickly - perform a CPU tiling prepass to prepare vector scenes for the GPU. This prepass can be pipelined - with the GPU to hide its latency. - -* Fast GPU rendering, even at small pixel sizes. Even on lower-end GPUs, Pathfinder typically - matches or exceeds the performance of the best CPU rasterizers. The difference is particularly - pronounced at large sizes, where Pathfinder regularly achieves multi-factor speedups. - -* GPU compute-based rendering, where available. Pathfinder can optionally use compute shaders to - achieve better performance than what the built-in GPU rasterization hardware can provide. Compute - shader capability is not required, and all features are available without it. - -* Advanced font rendering. Pathfinder can render fonts with slight hinting and can perform subpixel - antialiasing on LCD screens. It can do stem darkening/font dilation like macOS and FreeType in - order to make text easier to read at small sizes. The library also has support for gamma - correction. - -* Support for SVG. Pathfinder 3 is designed to efficiently handle workloads that consist of many - overlapping vector paths, such as those commonly found in SVG and PDF files. It can perform - occlusion culling, which often results in dramatic performance wins over typical software - renderers that use the painter's algorithm. A simple loader that leverages the `resvg` library - to render a subset of SVG is included, so it's easy to get started. - -* 3D capability. Pathfinder can render fonts and vector paths in 3D environments without any loss - in quality. This is intended to be useful for vector-graphics-based user interfaces in VR, for - example. - -* Lightweight. Unlike large vector graphics packages that mix and match many different algorithms, - Pathfinder 3 uses a single, simple technique. It consists of a set of modular crates, so - applications can pick and choose only the components that are necessary to minimize dependencies. - -* Portability to most GPUs manufactured in the last decade, including integrated and mobile GPUs. - Geometry, tessellation, and compute shader functionality is not required. - -## Building - -Pathfinder 3 is a set of modular packages, allowing you to choose which parts of the library you -need. An SVG rendering demo, written in Rust, is included, so you can try Pathfinder out right -away. It also provides an example of how to use the library. (Note that, like the rest of -Pathfinder, the demo is under heavy development and has known bugs.) - -Running the demo is as simple as: - - $ cd demo/native - $ cargo run --release - -Running examples (e.g. `canvas_nanovg`) can be done with: - - $ cd examples/canvas_nanovg - $ cargo run --release - -Pathfinder libraries are available on `crates.io` with the `pathfinder_` prefix (e.g. -`pathfinder_canvas`), but you may wish to use the `master` branch for the latest features and bug -fixes. - -## Community - -There's a Matrix chat room available at -[`#pathfinder:mozilla.org`](https://matrix.to/#/!XiDASQfNTTMrJbXHTw:mozilla.org?via=mozilla.org). -If you're on the Mozilla Matrix server, you can search for Pathfinder to find it. For more -information on connecting to the Matrix network, see -[this `wiki.mozilla.org` page](https://wiki.mozilla.org/Matrix). - -The entire Pathfinder community, including the chat room and GitHub project, is expected to abide -by the same Code of Conduct that the Rust project itself follows. - -## Build status - -[![Build Status](https://travis-ci.org/servo/pathfinder.svg?branch=master)](https://travis-ci.org/servo/pathfinder) - -## Authors - -The primary author is Patrick Walton (@pcwalton), with contributions from the Servo development -community. - -The logo was designed by Jay Vining. - -## License - -Pathfinder is licensed under the same terms as Rust itself. See `LICENSE-APACHE` and `LICENSE-MIT`. - -Material Design icons are copyright Google Inc. and licensed under the Apache 2.0 license. diff --git a/crates/pathfinder/canvas/Cargo.toml b/crates/pathfinder/canvas/Cargo.toml deleted file mode 100644 index b247fcd6b5..0000000000 --- a/crates/pathfinder/canvas/Cargo.toml +++ /dev/null @@ -1,44 +0,0 @@ -[package] -name = "pathfinder_canvas" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -description = "A GPU-accelerated vector graphics renderer that works like HTML canvas" -license = "MIT/Apache-2.0" -repository = "https://github.com/servo/pathfinder" -homepage = "https://github.com/servo/pathfinder" -keywords = ["pathfinder", "canvas", "vector", "graphics", "gpu"] - -[lib] -crate-type = ["rlib", "staticlib"] - -[dependencies] -font-kit = { version = "0.6", optional = true } - -[dependencies.pathfinder_color] -path = "../color" -version = "0.5" - -[dependencies.pathfinder_content] -path = "../content" -version = "0.5" - -[dependencies.pathfinder_geometry] -path = "../geometry" -version = "0.5" - -[dependencies.pathfinder_renderer] -path = "../renderer" -version = "0.5" - -[dependencies.pathfinder_text] -path = "../text" -version = "0.5" -optional = true - -[dependencies.skribo] -version = "0.1" -optional = true - -[features] -pf-text = ["pathfinder_text", "skribo", "font-kit"] diff --git a/crates/pathfinder/canvas/src/lib.rs b/crates/pathfinder/canvas/src/lib.rs deleted file mode 100644 index 4de6a02899..0000000000 --- a/crates/pathfinder/canvas/src/lib.rs +++ /dev/null @@ -1,959 +0,0 @@ -// pathfinder/canvas/src/lib.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A simple API for Pathfinder that mirrors a subset of HTML canvas. - -pub use pathfinder_color::{ColorF, ColorU, rgbaf, rgbau, rgbf, rgbu}; -pub use pathfinder_color::{color_slice_to_u8_slice, u8_slice_to_color_slice, u8_vec_to_color_vec}; -pub use pathfinder_content::fill::FillRule; -pub use pathfinder_content::stroke::LineCap; -pub use pathfinder_content::outline::ArcDirection; -pub use pathfinder_geometry::rect::{RectF, RectI}; -pub use pathfinder_geometry::transform2d::Transform2F; -pub use pathfinder_geometry::vector::{IntoVector2F, Vector2F, Vector2I, vec2f, vec2i}; - -use pathfinder_content::dash::OutlineDash; -use pathfinder_content::effects::{BlendMode, BlurDirection, PatternFilter}; -use pathfinder_content::gradient::Gradient; -use pathfinder_content::outline::{Contour, Outline}; -use pathfinder_content::pattern::Pattern; -use pathfinder_content::render_target::RenderTargetId; -use pathfinder_content::stroke::{LineJoin as StrokeLineJoin}; -use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle}; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_renderer::paint::{Paint, PaintCompositeOp}; -use pathfinder_renderer::scene::{ClipPath, ClipPathId, DrawPath, RenderTarget, Scene}; -use std::borrow::Cow; -use std::default::Default; -use std::f32::consts::PI; -use std::f32; -use std::fmt::{Debug, Error as FmtError, Formatter}; -use std::mem; -use std::sync::Arc; - -pub use text::CanvasFontContext; - -#[cfg(feature = "pf-text")] -use skribo::FontCollection; -#[cfg(not(feature = "pf-text"))] -use crate::text::FontCollection; - -#[cfg(feature = "pf-text")] -pub use text::TextMetrics; - -const HAIRLINE_STROKE_WIDTH: f32 = 0.0333; -const DEFAULT_FONT_SIZE: f32 = 10.0; - -#[cfg(feature = "pf-text")] -mod text; - -// For users who don't want text capability, include a tiny convenience stub. -#[cfg(not(feature = "pf-text"))] -mod text { - #[derive(Clone)] - pub struct CanvasFontContext; - - impl CanvasFontContext { - pub fn from_system_source() -> Self { - CanvasFontContext - } - } - - pub struct FontCollection; -} - -#[cfg(test)] -mod tests; - -pub struct Canvas { - scene: Scene, -} - -impl Canvas { - #[inline] - pub fn new(size: Vector2F) -> Canvas { - let mut scene = Scene::new(); - scene.set_view_box(RectF::new(Vector2F::zero(), size)); - Canvas::from_scene(scene) - } - - #[inline] - pub fn from_scene(scene: Scene) -> Canvas { - Canvas { scene } - } - - #[inline] - pub fn into_scene(self) -> Scene { - self.scene - } - - pub fn get_context_2d(self, canvas_font_context: CanvasFontContext) - -> CanvasRenderingContext2D { - #[cfg(feature = "pf-text")] - let default_font_collection = - canvas_font_context.0.borrow().default_font_collection.clone(); - #[cfg(not(feature = "pf-text"))] - let default_font_collection = Arc::new(FontCollection); - CanvasRenderingContext2D { - canvas: self, - current_state: State::default(default_font_collection), - saved_states: vec![], - canvas_font_context, - } - } - - #[inline] - pub fn size(&self) -> Vector2I { - self.scene.view_box().size().ceil().to_i32() - } -} - -pub struct CanvasRenderingContext2D { - canvas: Canvas, - current_state: State, - saved_states: Vec, - #[allow(dead_code)] - canvas_font_context: CanvasFontContext, -} - -impl CanvasRenderingContext2D { - // Canvas accessors - - #[inline] - pub fn canvas(&self) -> &Canvas { - &self.canvas - } - - #[inline] - pub fn into_canvas(self) -> Canvas { - self.canvas - } - - // Drawing rectangles - - #[inline] - pub fn fill_rect(&mut self, rect: RectF) { - let mut path = Path2D::new(); - path.rect(rect); - self.fill_path(path, FillRule::Winding); - } - - #[inline] - pub fn stroke_rect(&mut self, rect: RectF) { - let mut path = Path2D::new(); - path.rect(rect); - self.stroke_path(path); - } - - pub fn clear_rect(&mut self, rect: RectF) { - let mut path = Path2D::new(); - path.rect(rect); - - let paint = Paint::transparent_black(); - let paint = self.current_state.resolve_paint(&paint); - let paint_id = self.canvas.scene.push_paint(&paint); - - let mut outline = path.into_outline(); - outline.transform(&self.current_state.transform); - - let mut path = DrawPath::new(outline, paint_id); - path.set_blend_mode(BlendMode::Clear); - self.canvas.scene.push_path(path); - } - - // Line styles - - #[inline] - pub fn set_line_width(&mut self, new_line_width: f32) { - self.current_state.line_width = new_line_width - } - - #[inline] - pub fn set_line_cap(&mut self, new_line_cap: LineCap) { - self.current_state.line_cap = new_line_cap - } - - #[inline] - pub fn set_line_join(&mut self, new_line_join: LineJoin) { - self.current_state.line_join = new_line_join - } - - #[inline] - pub fn set_miter_limit(&mut self, new_miter_limit: f32) { - self.current_state.miter_limit = new_miter_limit - } - - #[inline] - pub fn set_line_dash(&mut self, mut new_line_dash: Vec) { - // Duplicate and concatenate if an odd number of dashes are present. - if new_line_dash.len() % 2 == 1 { - let mut real_line_dash = new_line_dash.clone(); - real_line_dash.extend(new_line_dash.into_iter()); - new_line_dash = real_line_dash; - } - - self.current_state.line_dash = new_line_dash - } - - #[inline] - pub fn set_line_dash_offset(&mut self, new_line_dash_offset: f32) { - self.current_state.line_dash_offset = new_line_dash_offset - } - - // Fill and stroke styles - - #[inline] - pub fn set_fill_style(&mut self, new_fill_style: FS) where FS: Into { - self.current_state.fill_paint = new_fill_style.into().into_paint(); - } - - #[inline] - pub fn set_stroke_style(&mut self, new_stroke_style: FS) where FS: Into { - self.current_state.stroke_paint = new_stroke_style.into().into_paint(); - } - - // Shadows - - #[inline] - pub fn shadow_blur(&self) -> f32 { - self.current_state.shadow_blur - } - - #[inline] - pub fn set_shadow_blur(&mut self, new_shadow_blur: f32) { - self.current_state.shadow_blur = new_shadow_blur; - } - - #[inline] - pub fn shadow_color(&self) -> ColorU { - self.current_state.shadow_color - } - - #[inline] - pub fn set_shadow_color(&mut self, new_shadow_color: ColorU) { - self.current_state.shadow_color = new_shadow_color; - } - - #[inline] - pub fn shadow_offset(&self) -> Vector2F { - self.current_state.shadow_offset - } - - #[inline] - pub fn set_shadow_offset(&mut self, new_shadow_offset: Vector2F) { - self.current_state.shadow_offset = new_shadow_offset; - } - - // Drawing paths - - #[inline] - pub fn fill_path(&mut self, path: Path2D, fill_rule: FillRule) { - self.push_path(path.into_outline(), PathOp::Fill, fill_rule); - } - - #[inline] - pub fn stroke_path(&mut self, path: Path2D) { - let mut stroke_style = self.current_state.resolve_stroke_style(); - - // The smaller scale is relevant here, as we multiply by it and want to ensure it is always - // bigger than `HAIRLINE_STROKE_WIDTH`. - let transform_scales = self.current_state.transform.extract_scale(); - let transform_scale = f32::min(transform_scales.x(), transform_scales.y()); - - // Avoid the division in the normal case of sufficient thickness. - if stroke_style.line_width * transform_scale < HAIRLINE_STROKE_WIDTH { - stroke_style.line_width = HAIRLINE_STROKE_WIDTH / transform_scale; - } - - let mut outline = path.into_outline(); - if !self.current_state.line_dash.is_empty() { - let mut dash = OutlineDash::new(&outline, - &self.current_state.line_dash, - self.current_state.line_dash_offset); - dash.dash(); - outline = dash.into_outline(); - } - - let mut stroke_to_fill = OutlineStrokeToFill::new(&outline, stroke_style); - stroke_to_fill.offset(); - outline = stroke_to_fill.into_outline(); - - self.push_path(outline, PathOp::Stroke, FillRule::Winding); - } - - pub fn clip_path(&mut self, path: Path2D, fill_rule: FillRule) { - let mut outline = path.into_outline(); - outline.transform(&self.current_state.transform); - - let mut clip_path = ClipPath::new(outline); - clip_path.set_fill_rule(fill_rule); - let clip_path_id = self.canvas.scene.push_clip_path(clip_path); - - self.current_state.clip_path = Some(clip_path_id); - } - - fn push_path(&mut self, mut outline: Outline, path_op: PathOp, fill_rule: FillRule) { - let paint = self.current_state.resolve_paint(match path_op { - PathOp::Fill => &self.current_state.fill_paint, - PathOp::Stroke => &self.current_state.stroke_paint, - }); - let paint_id = self.canvas.scene.push_paint(&paint); - - let transform = self.current_state.transform; - let clip_path = self.current_state.clip_path; - let blend_mode = self.current_state.global_composite_operation.to_blend_mode(); - - outline.transform(&transform); - - if !self.current_state.shadow_color.is_fully_transparent() { - let mut outline = outline.clone(); - outline.transform(&Transform2F::from_translation(self.current_state.shadow_offset)); - - let shadow_blur_info = - push_shadow_blur_render_targets_if_needed(&mut self.canvas.scene, - &self.current_state, - outline.bounds()); - - if let Some(ref shadow_blur_info) = shadow_blur_info { - outline.transform(&Transform2F::from_translation(-shadow_blur_info.bounds - .origin() - .to_f32())); - } - - // Per spec the shadow must respect the alpha of the shadowed path, but otherwise have - // the color of the shadow paint. - let mut shadow_paint = (*paint).clone(); - let shadow_base_alpha = shadow_paint.base_color().a; - let mut shadow_color = self.current_state.shadow_color.to_f32(); - shadow_color.set_a(shadow_color.a() * shadow_base_alpha as f32 / 255.0); - shadow_paint.set_base_color(shadow_color.to_u8()); - if let &mut Some(ref mut shadow_paint_overlay) = shadow_paint.overlay_mut() { - shadow_paint_overlay.set_composite_op(PaintCompositeOp::DestIn); - } - let shadow_paint_id = self.canvas.scene.push_paint(&shadow_paint); - - let mut path = DrawPath::new(outline, shadow_paint_id); - if shadow_blur_info.is_none() { - path.set_clip_path(clip_path); - } - path.set_fill_rule(fill_rule); - path.set_blend_mode(blend_mode); - self.canvas.scene.push_path(path); - - composite_shadow_blur_render_targets_if_needed(&mut self.canvas.scene, - shadow_blur_info, - clip_path); - } - - let mut path = DrawPath::new(outline, paint_id); - path.set_clip_path(clip_path); - path.set_fill_rule(fill_rule); - path.set_blend_mode(blend_mode); - self.canvas.scene.push_path(path); - - fn push_shadow_blur_render_targets_if_needed(scene: &mut Scene, - current_state: &State, - outline_bounds: RectF) - -> Option { - if current_state.shadow_blur == 0.0 { - return None; - } - - let sigma = current_state.shadow_blur * 0.5; - let bounds = outline_bounds.dilate(sigma * 3.0).round_out().to_i32(); - - let render_target_y = RenderTarget::new(bounds.size(), String::new()); - let render_target_id_y = scene.push_render_target(render_target_y); - let render_target_x = RenderTarget::new(bounds.size(), String::new()); - let render_target_id_x = scene.push_render_target(render_target_x); - - Some(ShadowBlurRenderTargetInfo { - id_x: render_target_id_x, - id_y: render_target_id_y, - bounds, - sigma, - }) - } - - fn composite_shadow_blur_render_targets_if_needed(scene: &mut Scene, - info: Option, - clip_path: Option) { - let info = match info { - None => return, - Some(info) => info, - }; - - let mut paint_x = Pattern::from_render_target(info.id_x, info.bounds.size()); - let mut paint_y = Pattern::from_render_target(info.id_y, info.bounds.size()); - paint_y.apply_transform(Transform2F::from_translation(info.bounds.origin().to_f32())); - - let sigma = info.sigma; - paint_x.set_filter(Some(PatternFilter::Blur { direction: BlurDirection::X, sigma })); - paint_y.set_filter(Some(PatternFilter::Blur { direction: BlurDirection::Y, sigma })); - - let paint_id_x = scene.push_paint(&Paint::from_pattern(paint_x)); - let paint_id_y = scene.push_paint(&Paint::from_pattern(paint_y)); - - // TODO(pcwalton): Apply clip as necessary. - let outline_x = Outline::from_rect(RectF::new(vec2f(0.0, 0.0), - info.bounds.size().to_f32())); - let path_x = DrawPath::new(outline_x, paint_id_x); - let outline_y = Outline::from_rect(info.bounds.to_f32()); - let mut path_y = DrawPath::new(outline_y, paint_id_y); - path_y.set_clip_path(clip_path); - - scene.pop_render_target(); - scene.push_path(path_x); - scene.pop_render_target(); - scene.push_path(path_y); - } - - } - - // Transformations - - #[inline] - pub fn rotate(&mut self, angle: f32) { - self.current_state.transform *= Transform2F::from_rotation(angle) - } - - #[inline] - pub fn scale(&mut self, scale: S) where S: IntoVector2F { - self.current_state.transform *= Transform2F::from_scale(scale) - } - - #[inline] - pub fn translate(&mut self, offset: Vector2F) { - self.current_state.transform *= Transform2F::from_translation(offset) - } - - #[inline] - pub fn transform(&self) -> Transform2F { - self.current_state.transform - } - - #[inline] - pub fn set_transform(&mut self, new_transform: &Transform2F) { - self.current_state.transform = *new_transform; - } - - #[inline] - pub fn reset_transform(&mut self) { - self.current_state.transform = Transform2F::default(); - } - - // Compositing - - #[inline] - pub fn global_alpha(&self) -> f32 { - self.current_state.global_alpha - } - - #[inline] - pub fn set_global_alpha(&mut self, new_global_alpha: f32) { - self.current_state.global_alpha = new_global_alpha; - } - - #[inline] - pub fn global_composite_operation(&self) -> CompositeOperation { - self.current_state.global_composite_operation - } - - #[inline] - pub fn set_global_composite_operation(&mut self, new_composite_operation: CompositeOperation) { - self.current_state.global_composite_operation = new_composite_operation; - } - - // Drawing images - - #[inline] - pub fn draw_image(&mut self, image: I, dest_location: L) - where I: CanvasImageSource, L: CanvasImageDestLocation { - let pattern = image.to_pattern(self, Transform2F::default()); - let src_rect = RectF::new(vec2f(0.0, 0.0), pattern.size().to_f32()); - self.draw_subimage(pattern, src_rect, dest_location) - } - - pub fn draw_subimage(&mut self, image: I, src_location: RectF, dest_location: L) - where I: CanvasImageSource, L: CanvasImageDestLocation { - let dest_size = dest_location.size().unwrap_or(src_location.size()); - let scale = dest_size / src_location.size(); - let offset = dest_location.origin() - src_location.origin(); - let transform = Transform2F::from_scale(scale).translate(offset); - - let pattern = image.to_pattern(self, transform); - let old_fill_paint = self.current_state.fill_paint.clone(); - self.set_fill_style(pattern); - self.fill_rect(RectF::new(dest_location.origin(), dest_size)); - self.current_state.fill_paint = old_fill_paint; - } - - // Image smoothing - - #[inline] - pub fn image_smoothing_enabled(&self) -> bool { - self.current_state.image_smoothing_enabled - } - - #[inline] - pub fn set_image_smoothing_enabled(&mut self, enabled: bool) { - self.current_state.image_smoothing_enabled = enabled - } - - #[inline] - pub fn image_smoothing_quality(&self) -> ImageSmoothingQuality { - self.current_state.image_smoothing_quality - } - - #[inline] - pub fn set_image_smoothing_quality(&mut self, new_quality: ImageSmoothingQuality) { - self.current_state.image_smoothing_quality = new_quality - } - - // The canvas state - - #[inline] - pub fn save(&mut self) { - self.saved_states.push(self.current_state.clone()); - } - - #[inline] - pub fn restore(&mut self) { - if let Some(state) = self.saved_states.pop() { - self.current_state = state; - } - } - - // Extensions - - pub fn create_pattern_from_canvas(&mut self, canvas: Canvas, transform: Transform2F) - -> Pattern { - let subscene_size = canvas.size(); - let subscene = canvas.into_scene(); - let render_target = RenderTarget::new(subscene_size, String::new()); - let render_target_id = self.canvas.scene.push_render_target(render_target); - self.canvas.scene.append_scene(subscene); - self.canvas.scene.pop_render_target(); - - let mut pattern = Pattern::from_render_target(render_target_id, subscene_size); - pattern.apply_transform(transform); - pattern - } -} - -#[derive(Clone)] -struct State { - transform: Transform2F, - font_collection: Arc, - font_size: f32, - line_width: f32, - line_cap: LineCap, - line_join: LineJoin, - miter_limit: f32, - line_dash: Vec, - line_dash_offset: f32, - fill_paint: Paint, - stroke_paint: Paint, - shadow_color: ColorU, - shadow_blur: f32, - shadow_offset: Vector2F, - text_align: TextAlign, - text_baseline: TextBaseline, - image_smoothing_enabled: bool, - image_smoothing_quality: ImageSmoothingQuality, - global_alpha: f32, - global_composite_operation: CompositeOperation, - clip_path: Option, -} - -impl State { - fn default(default_font_collection: Arc) -> State { - State { - transform: Transform2F::default(), - font_collection: default_font_collection, - font_size: DEFAULT_FONT_SIZE, - line_width: 1.0, - line_cap: LineCap::Butt, - line_join: LineJoin::Miter, - miter_limit: 10.0, - line_dash: vec![], - line_dash_offset: 0.0, - fill_paint: Paint::black(), - stroke_paint: Paint::black(), - shadow_color: ColorU::transparent_black(), - shadow_blur: 0.0, - shadow_offset: Vector2F::zero(), - text_align: TextAlign::Left, - text_baseline: TextBaseline::Alphabetic, - image_smoothing_enabled: true, - image_smoothing_quality: ImageSmoothingQuality::Low, - global_alpha: 1.0, - global_composite_operation: CompositeOperation::SourceOver, - clip_path: None, - } - } - - fn resolve_paint<'a>(&self, paint: &'a Paint) -> Cow<'a, Paint> { - let mut must_copy = !self.transform.is_identity() || self.global_alpha < 1.0; - if !must_copy { - if let Some(ref pattern) = paint.pattern() { - must_copy = self.image_smoothing_enabled != pattern.smoothing_enabled() - } - } - - if !must_copy { - return Cow::Borrowed(paint); - } - - let mut paint = (*paint).clone(); - paint.apply_transform(&self.transform); - - let mut base_color = paint.base_color().to_f32(); - base_color.set_a(base_color.a() * self.global_alpha); - paint.set_base_color(base_color.to_u8()); - - if let Some(ref mut pattern) = paint.pattern_mut() { - pattern.set_smoothing_enabled(self.image_smoothing_enabled); - } - Cow::Owned(paint) - } - - fn resolve_stroke_style(&self) -> StrokeStyle { - StrokeStyle { - line_width: self.line_width, - line_cap: self.line_cap, - line_join: match self.line_join { - LineJoin::Miter => StrokeLineJoin::Miter(self.miter_limit), - LineJoin::Bevel => StrokeLineJoin::Bevel, - LineJoin::Round => StrokeLineJoin::Round, - }, - } - } -} - -#[derive(Clone)] -pub struct Path2D { - outline: Outline, - current_contour: Contour, -} - -impl Path2D { - #[inline] - pub fn new() -> Path2D { - Path2D { outline: Outline::new(), current_contour: Contour::new() } - } - - #[inline] - pub fn close_path(&mut self) { - self.current_contour.close(); - } - - #[inline] - pub fn move_to(&mut self, to: Vector2F) { - // TODO(pcwalton): Cull degenerate contours. - self.flush_current_contour(); - self.current_contour.push_endpoint(to); - } - - #[inline] - pub fn line_to(&mut self, to: Vector2F) { - self.current_contour.push_endpoint(to); - } - - #[inline] - pub fn quadratic_curve_to(&mut self, ctrl: Vector2F, to: Vector2F) { - self.current_contour.push_quadratic(ctrl, to); - } - - #[inline] - pub fn bezier_curve_to(&mut self, ctrl0: Vector2F, ctrl1: Vector2F, to: Vector2F) { - self.current_contour.push_cubic(ctrl0, ctrl1, to); - } - - #[inline] - pub fn arc(&mut self, - center: Vector2F, - radius: f32, - start_angle: f32, - end_angle: f32, - direction: ArcDirection) { - let transform = Transform2F::from_scale(radius).translate(center); - self.current_contour.push_arc(&transform, start_angle, end_angle, direction); - } - - #[inline] - pub fn arc_to(&mut self, ctrl: Vector2F, to: Vector2F, radius: f32) { - // FIXME(pcwalton): What should we do if there's no initial point? - let from = self.current_contour.last_position().unwrap_or_default(); - let (v0, v1) = (from - ctrl, to - ctrl); - let (vu0, vu1) = (v0.normalize(), v1.normalize()); - let hypot = radius / f32::sqrt(0.5 * (1.0 - vu0.dot(vu1))); - let bisector = vu0 + vu1; - let center = ctrl + bisector * (hypot / bisector.length()); - - let transform = Transform2F::from_scale(radius).translate(center); - let chord = LineSegment2F::new(vu0.yx() * vec2f(-1.0, 1.0), vu1.yx() * vec2f( 1.0, -1.0)); - - // FIXME(pcwalton): Is clockwise direction correct? - self.current_contour.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW); - } - - pub fn rect(&mut self, rect: RectF) { - self.flush_current_contour(); - self.current_contour.push_endpoint(rect.origin()); - self.current_contour.push_endpoint(rect.upper_right()); - self.current_contour.push_endpoint(rect.lower_right()); - self.current_contour.push_endpoint(rect.lower_left()); - self.current_contour.close(); - } - - pub fn ellipse(&mut self, - center: Vector2F, - axes: A, - rotation: f32, - start_angle: f32, - end_angle: f32) - where A: IntoVector2F { - self.flush_current_contour(); - - let transform = Transform2F::from_scale(axes).rotate(rotation).translate(center); - self.current_contour.push_arc(&transform, start_angle, end_angle, ArcDirection::CW); - - if end_angle - start_angle >= 2.0 * PI { - self.current_contour.close(); - } - } - - // https://html.spec.whatwg.org/multipage/canvas.html#dom-path2d-addpath - pub fn add_path(&mut self, mut path: Path2D, transform: &Transform2F) { - self.flush_current_contour(); - path.flush_current_contour(); - path.outline.transform(transform); - let last_contour = path.outline.pop_contour(); - for contour in path.outline.into_contours() { - self.outline.push_contour(contour); - } - self.current_contour = last_contour.unwrap_or_else(Contour::new); - } - - pub fn into_outline(mut self) -> Outline { - self.flush_current_contour(); - self.outline - } - - fn flush_current_contour(&mut self) { - if !self.current_contour.is_empty() { - self.outline.push_contour(mem::replace(&mut self.current_contour, Contour::new())); - } - } -} - -#[derive(Clone)] -pub enum FillStyle { - Color(ColorU), - Gradient(Gradient), - Pattern(Pattern), -} - -impl FillStyle { - fn into_paint(self) -> Paint { - match self { - FillStyle::Color(color) => Paint::from_color(color), - FillStyle::Gradient(gradient) => Paint::from_gradient(gradient), - FillStyle::Pattern(pattern) => Paint::from_pattern(pattern), - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum TextAlign { - Left, - Right, - Center, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum TextBaseline { - Alphabetic, - Top, - Hanging, - Middle, - Ideographic, - Bottom, -} - -// We duplicate `pathfinder_content::stroke::LineJoin` here because the HTML canvas API treats the -// miter limit as part of the canvas state, while the native Pathfinder API treats the miter limit -// as part of the line join. Pathfinder's choice is more logical, because the miter limit is -// specific to miter joins. In this API, however, for compatibility we go with the HTML canvas -// semantics. -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum LineJoin { - Miter, - Bevel, - Round, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum CompositeOperation { - SourceOver, - SourceIn, - SourceOut, - SourceAtop, - DestinationOver, - DestinationIn, - DestinationOut, - DestinationAtop, - Lighter, - Copy, - Xor, - Multiply, - Screen, - Overlay, - Darken, - Lighten, - ColorDodge, - ColorBurn, - HardLight, - SoftLight, - Difference, - Exclusion, - Hue, - Saturation, - Color, - Luminosity, -} - -impl CompositeOperation { - fn to_blend_mode(self) -> BlendMode { - match self { - CompositeOperation::Copy => BlendMode::Copy, - CompositeOperation::SourceAtop => BlendMode::SrcAtop, - CompositeOperation::DestinationOver => BlendMode::DestOver, - CompositeOperation::DestinationOut => BlendMode::DestOut, - CompositeOperation::Xor => BlendMode::Xor, - CompositeOperation::Lighter => BlendMode::Lighter, - CompositeOperation::Multiply => BlendMode::Multiply, - CompositeOperation::Screen => BlendMode::Screen, - CompositeOperation::Overlay => BlendMode::Overlay, - CompositeOperation::Darken => BlendMode::Darken, - CompositeOperation::Lighten => BlendMode::Lighten, - CompositeOperation::ColorDodge => BlendMode::ColorDodge, - CompositeOperation::ColorBurn => BlendMode::ColorBurn, - CompositeOperation::HardLight => BlendMode::HardLight, - CompositeOperation::SoftLight => BlendMode::SoftLight, - CompositeOperation::Difference => BlendMode::Difference, - CompositeOperation::Exclusion => BlendMode::Exclusion, - CompositeOperation::Hue => BlendMode::Hue, - CompositeOperation::Saturation => BlendMode::Saturation, - CompositeOperation::Color => BlendMode::Color, - CompositeOperation::Luminosity => BlendMode::Luminosity, - CompositeOperation::SourceOver => BlendMode::SrcOver, - CompositeOperation::SourceIn => BlendMode::SrcIn, - CompositeOperation::SourceOut => BlendMode::SrcOut, - CompositeOperation::DestinationIn => BlendMode::DestIn, - CompositeOperation::DestinationAtop => BlendMode::DestAtop, - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum ImageSmoothingQuality { - Low, - Medium, - High, -} - -pub trait CanvasImageSource { - fn to_pattern(self, dest_context: &mut CanvasRenderingContext2D, transform: Transform2F) - -> Pattern; -} - -pub trait CanvasImageDestLocation { - fn origin(&self) -> Vector2F; - fn size(&self) -> Option; -} - -impl CanvasImageSource for Pattern { - #[inline] - fn to_pattern(mut self, _: &mut CanvasRenderingContext2D, transform: Transform2F) -> Pattern { - self.apply_transform(transform); - self - } -} - -impl CanvasImageSource for Canvas { - #[inline] - fn to_pattern(self, dest_context: &mut CanvasRenderingContext2D, transform: Transform2F) - -> Pattern { - dest_context.create_pattern_from_canvas(self, transform) - } -} - -impl CanvasImageDestLocation for RectF { - #[inline] - fn origin(&self) -> Vector2F { - RectF::origin(*self) - } - #[inline] - fn size(&self) -> Option { - Some(RectF::size(*self)) - } -} - -impl CanvasImageDestLocation for Vector2F { - #[inline] - fn origin(&self) -> Vector2F { - *self - } - #[inline] - fn size(&self) -> Option { - None - } -} - -impl Debug for Path2D { - fn fmt(&self, formatter: &mut Formatter) -> Result<(), FmtError> { - self.clone().into_outline().fmt(formatter) - } -} - -impl From for FillStyle { - #[inline] - fn from(color: ColorU) -> FillStyle { - FillStyle::Color(color) - } -} - -impl From for FillStyle { - #[inline] - fn from(gradient: Gradient) -> FillStyle { - FillStyle::Gradient(gradient) - } -} - -impl From for FillStyle { - #[inline] - fn from(pattern: Pattern) -> FillStyle { - FillStyle::Pattern(pattern) - } -} - -struct ShadowBlurRenderTargetInfo { - id_x: RenderTargetId, - id_y: RenderTargetId, - bounds: RectI, - sigma: f32, -} - -enum PathOp { - Fill, - Stroke, -} diff --git a/crates/pathfinder/canvas/src/tests.rs b/crates/pathfinder/canvas/src/tests.rs deleted file mode 100644 index 6aad48183a..0000000000 --- a/crates/pathfinder/canvas/src/tests.rs +++ /dev/null @@ -1,19 +0,0 @@ -// pathfinder/canvas/src/tests.rs -// -// For this file only, any copyright is dedicated to the Public Domain. -// https://creativecommons.org/publicdomain/zero/1.0/ - -use pathfinder_geometry::vector::{Vector2F, vec2f}; -use super::Path2D; - -#[test] -pub fn test_path2d_formatting() { - let mut path = Path2D::new(); - path.move_to(vec2f(0.0, 1.0)); - path.line_to(vec2f(2.0, 3.0)); - assert_eq!(format!("{:?}", path), "M 0 1 L 2 3"); - path.line_to(vec2f(4.0, 5.0)); - assert_eq!(format!("{:?}", path), "M 0 1 L 2 3 L 4 5"); - path.close_path(); - assert_eq!(format!("{:?}", path), "M 0 1 L 2 3 L 4 5 z"); -} diff --git a/crates/pathfinder/canvas/src/text.rs b/crates/pathfinder/canvas/src/text.rs deleted file mode 100644 index 44af8a19d2..0000000000 --- a/crates/pathfinder/canvas/src/text.rs +++ /dev/null @@ -1,507 +0,0 @@ -// pathfinder/canvas/src/text.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::{CanvasRenderingContext2D, State, TextAlign, TextBaseline}; -use font_kit::canvas::RasterizationOptions; -use font_kit::family_name::FamilyName; -use font_kit::handle::Handle; -use font_kit::hinting::HintingOptions; -use font_kit::loaders::default::Font; -use font_kit::properties::Properties; -use font_kit::source::{Source, SystemSource}; -use font_kit::sources::mem::MemSource; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::util; -use pathfinder_geometry::vector::{Vector2F, vec2f}; -use pathfinder_renderer::paint::PaintId; -use pathfinder_text::{FontContext, FontRenderOptions, TextRenderMode}; -use skribo::{FontCollection, FontFamily, FontRef, Layout, TextStyle}; -use std::cell::RefCell; -use std::rc::Rc; -use std::sync::Arc; - -impl CanvasRenderingContext2D { - pub fn fill_text(&mut self, string: &str, position: Vector2F) { - let paint = self.current_state.resolve_paint(&self.current_state.fill_paint); - let paint_id = self.canvas.scene.push_paint(&paint); - self.fill_or_stroke_text(string, position, paint_id, TextRenderMode::Fill); - } - - pub fn stroke_text(&mut self, string: &str, position: Vector2F) { - let paint = self.current_state.resolve_paint(&self.current_state.stroke_paint); - let paint_id = self.canvas.scene.push_paint(&paint); - let render_mode = TextRenderMode::Stroke(self.current_state.resolve_stroke_style()); - self.fill_or_stroke_text(string, position, paint_id, render_mode); - } - - pub fn measure_text(&self, string: &str) -> TextMetrics { - let mut metrics = self.layout_text(string).metrics(); - metrics.make_origin_relative(&self.current_state); - metrics - } - - pub fn fill_layout(&mut self, layout: &Layout, transform: Transform2F) { - let paint_id = self.canvas.scene.push_paint(&self.current_state.fill_paint); - - let clip_path = self.current_state.clip_path; - let blend_mode = self.current_state.global_composite_operation.to_blend_mode(); - - // TODO(pcwalton): Report errors. - drop(self.canvas_font_context - .0 - .borrow_mut() - .font_context - .push_layout(&mut self.canvas.scene, - &layout, - &TextStyle { size: self.current_state.font_size }, - &FontRenderOptions { - transform: transform * self.current_state.transform, - render_mode: TextRenderMode::Fill, - hinting_options: HintingOptions::None, - clip_path, - blend_mode, - paint_id, - })); - } - - fn fill_or_stroke_text(&mut self, - string: &str, - mut position: Vector2F, - paint_id: PaintId, - render_mode: TextRenderMode) { - let layout = self.layout_text(string); - - let clip_path = self.current_state.clip_path; - let blend_mode = self.current_state.global_composite_operation.to_blend_mode(); - - position += layout.metrics().text_origin(&self.current_state); - let transform = self.current_state.transform * Transform2F::from_translation(position); - - // TODO(pcwalton): Report errors. - drop(self.canvas_font_context - .0 - .borrow_mut() - .font_context - .push_layout(&mut self.canvas.scene, - &layout, - &TextStyle { size: self.current_state.font_size }, - &FontRenderOptions { - transform, - render_mode, - hinting_options: HintingOptions::None, - clip_path, - blend_mode, - paint_id, - })); - } - - fn layout_text(&self, string: &str) -> Layout { - skribo::layout(&TextStyle { size: self.current_state.font_size }, - &self.current_state.font_collection, - string) - } - - // Text styles - - #[inline] - pub fn font(&self) -> Arc { - self.current_state.font_collection.clone() - } - - #[inline] - pub fn set_font(&mut self, font_collection: FC) where FC: IntoFontCollection { - let font_collection = font_collection.into_font_collection(&self.canvas_font_context); - self.current_state.font_collection = font_collection; - } - - #[inline] - pub fn font_size(&self) -> f32 { - self.current_state.font_size - } - - #[inline] - pub fn set_font_size(&mut self, new_font_size: f32) { - self.current_state.font_size = new_font_size; - } - - #[inline] - pub fn text_align(&self) -> TextAlign { - self.current_state.text_align - } - - #[inline] - pub fn set_text_align(&mut self, new_text_align: TextAlign) { - self.current_state.text_align = new_text_align; - } - - #[inline] - pub fn text_baseline(&self) -> TextBaseline { - self.current_state.text_baseline - } - - #[inline] - pub fn set_text_baseline(&mut self, new_text_baseline: TextBaseline) { - self.current_state.text_baseline = new_text_baseline; - } -} - -/// Represents the dimensions of a piece of text in the canvas. -#[derive(Clone, Copy, Debug)] -pub struct TextMetrics { - /// The calculated width of a segment of inline text in pixels. - pub width: f32, - /// The distance from the alignment point given by the `text_align` state to the left side of - /// the bounding rectangle of the given text, in pixels. The distance is measured parallel to - /// the baseline. - pub actual_bounding_box_left: f32, - /// The distance from the alignment point given by the `text_align` state to the right side of - /// the bounding rectangle of the given text, in pixels. The distance is measured parallel to - /// the baseline. - pub actual_bounding_box_right: f32, - /// The distance from the horizontal line indicated by the `text_baseline` state to the top of - /// the highest bounding rectangle of all the fonts used to render the text, in pixels. - pub font_bounding_box_ascent: f32, - /// The distance from the horizontal line indicated by the `text_baseline` state to the bottom - /// of the highest bounding rectangle of all the fonts used to render the text, in pixels. - pub font_bounding_box_descent: f32, - /// The distance from the horizontal line indicated by the `text_baseline` state to the top of - /// the bounding rectangle used to render the text, in pixels. - pub actual_bounding_box_ascent: f32, - /// The distance from the horizontal line indicated by the `text_baseline` state to the bottom - /// of the bounding rectangle used to render the text, in pixels. - pub actual_bounding_box_descent: f32, - /// The distance from the horizontal line indicated by the `text_baseline` state to the top of - /// the em square in the line box, in pixels. - pub em_height_ascent: f32, - /// The distance from the horizontal line indicated by the `text_baseline` state to the bottom - /// of the em square in the line box, in pixels. - pub em_height_descent: f32, - /// The distance from the horizontal line indicated by the `text_baseline` state to the hanging - /// baseline of the line box, in pixels. - pub hanging_baseline: f32, - /// The distance from the horizontal line indicated by the `text_baseline` state to the - /// alphabetic baseline of the line box, in pixels. - pub alphabetic_baseline: f32, - /// The distance from the horizontal line indicated by the `text_baseline` state to the - /// ideographic baseline of the line box, in pixels. - pub ideographic_baseline: f32, -} - -#[cfg(feature = "pf-text")] -#[derive(Clone)] -pub struct CanvasFontContext(pub(crate) Rc>); - -pub(super) struct CanvasFontContextData { - pub(super) font_context: FontContext, - #[allow(dead_code)] - pub(super) font_source: Arc, - #[allow(dead_code)] - pub(super) default_font_collection: Arc, -} - -impl CanvasFontContext { - pub fn new(font_source: Arc) -> CanvasFontContext { - let mut default_font_collection = FontCollection::new(); - if let Ok(default_font) = font_source.select_best_match(&[FamilyName::SansSerif], - &Properties::new()) { - if let Ok(default_font) = default_font.load() { - default_font_collection.add_family(FontFamily::new_from_font(default_font)); - } - } - - CanvasFontContext(Rc::new(RefCell::new(CanvasFontContextData { - font_source, - default_font_collection: Arc::new(default_font_collection), - font_context: FontContext::new(), - }))) - } - - /// A convenience method to create a font context with the system source. - /// This allows usage of fonts installed on the system. - pub fn from_system_source() -> CanvasFontContext { - CanvasFontContext::new(Arc::new(SystemSource::new())) - } - - /// A convenience method to create a font context with a set of in-memory fonts. - pub fn from_fonts(fonts: I) -> CanvasFontContext where I: Iterator { - CanvasFontContext::new(Arc::new(MemSource::from_fonts(fonts).unwrap())) - } - - fn get_font_by_postscript_name(&self, postscript_name: &str) -> Font { - let this = self.0.borrow(); - if let Some(cached_font) = this.font_context.get_cached_font(postscript_name) { - return (*cached_font).clone(); - } - this.font_source - .select_by_postscript_name(postscript_name) - .expect("Couldn't find a font with that PostScript name!") - .load() - .expect("Failed to load the font!") - } -} - -// Text layout utilities - -impl TextMetrics { - fn text_origin(&self, state: &State) -> Vector2F { - let x = match state.text_align { - TextAlign::Left => 0.0, - TextAlign::Right => -self.width, - TextAlign::Center => -0.5 * self.width, - }; - - let y = match state.text_baseline { - TextBaseline::Alphabetic => 0.0, - TextBaseline::Top => self.em_height_ascent, - TextBaseline::Middle => util::lerp(self.em_height_ascent, self.em_height_descent, 0.5), - TextBaseline::Bottom => self.em_height_descent, - TextBaseline::Ideographic => self.ideographic_baseline, - TextBaseline::Hanging => self.hanging_baseline, - }; - - vec2f(x, y) - } - - fn make_origin_relative(&mut self, state: &State) { - let text_origin = self.text_origin(state); - self.actual_bounding_box_left += text_origin.x(); - self.actual_bounding_box_right += text_origin.x(); - self.font_bounding_box_ascent -= text_origin.y(); - self.font_bounding_box_descent -= text_origin.y(); - self.actual_bounding_box_ascent -= text_origin.y(); - self.actual_bounding_box_descent -= text_origin.y(); - self.em_height_ascent -= text_origin.y(); - self.em_height_descent -= text_origin.y(); - self.hanging_baseline -= text_origin.y(); - self.alphabetic_baseline -= text_origin.y(); - self.ideographic_baseline -= text_origin.y(); - } -} - -pub trait LayoutExt { - fn metrics(&self) -> TextMetrics; - fn width(&self) -> f32; - fn actual_bounding_box_left(&self) -> f32; - fn actual_bounding_box_right(&self) -> f32; - fn hanging_baseline(&self) -> f32; - fn ideographic_baseline(&self) -> f32; -} - -impl LayoutExt for Layout { - // NB: This does not return origin-relative values. To get those, call `make_origin_relative()` - // afterward. - fn metrics(&self) -> TextMetrics { - let (mut em_height_ascent, mut em_height_descent) = (0.0, 0.0); - let (mut font_bounding_box_ascent, mut font_bounding_box_descent) = (0.0, 0.0); - let (mut actual_bounding_box_ascent, mut actual_bounding_box_descent) = (0.0, 0.0); - - let mut last_font: Option> = None; - for glyph in &self.glyphs { - match last_font { - Some(ref last_font) if Arc::ptr_eq(&last_font, &glyph.font.font) => {} - _ => { - let font = glyph.font.font.clone(); - - let font_metrics = font.metrics(); - let scale_factor = self.size / font_metrics.units_per_em as f32; - em_height_ascent = (font_metrics.ascent * scale_factor).max(em_height_ascent); - em_height_descent = - (font_metrics.descent * scale_factor).min(em_height_descent); - font_bounding_box_ascent = (font_metrics.bounding_box.max_y() * - scale_factor).max(font_bounding_box_ascent); - font_bounding_box_descent = (font_metrics.bounding_box.min_y() * - scale_factor).min(font_bounding_box_descent); - - last_font = Some(font); - } - } - - let font = last_font.as_ref().unwrap(); - let glyph_rect = font.raster_bounds(glyph.glyph_id, - self.size, - Transform2F::default(), - HintingOptions::None, - RasterizationOptions::GrayscaleAa).unwrap(); - actual_bounding_box_ascent = - (glyph_rect.max_y() as f32).max(actual_bounding_box_ascent); - actual_bounding_box_descent = - (glyph_rect.min_y() as f32).min(actual_bounding_box_descent); - } - - TextMetrics { - width: self.width(), - actual_bounding_box_left: self.actual_bounding_box_left(), - actual_bounding_box_right: self.actual_bounding_box_right(), - font_bounding_box_ascent, - font_bounding_box_descent, - actual_bounding_box_ascent, - actual_bounding_box_descent, - em_height_ascent, - em_height_descent, - alphabetic_baseline: 0.0, - hanging_baseline: self.hanging_baseline(), - ideographic_baseline: self.ideographic_baseline(), - } - } - - fn width(&self) -> f32 { - let last_glyph = match self.glyphs.last() { - None => return 0.0, - Some(last_glyph) => last_glyph, - }; - - let glyph_id = last_glyph.glyph_id; - let font_metrics = last_glyph.font.font.metrics(); - let scale_factor = self.size / font_metrics.units_per_em as f32; - let glyph_rect = last_glyph.font.font.typographic_bounds(glyph_id).unwrap(); - last_glyph.offset.x() + glyph_rect.max_x() * scale_factor - } - - fn actual_bounding_box_left(&self) -> f32 { - let first_glyph = match self.glyphs.get(0) { - None => return 0.0, - Some(first_glyph) => first_glyph, - }; - - let glyph_id = first_glyph.glyph_id; - let font_metrics = first_glyph.font.font.metrics(); - let scale_factor = self.size / font_metrics.units_per_em as f32; - let glyph_rect = first_glyph.font - .font - .raster_bounds(glyph_id, - font_metrics.units_per_em as f32, - Transform2F::default(), - HintingOptions::None, - RasterizationOptions::GrayscaleAa).unwrap(); - first_glyph.offset.x() + glyph_rect.min_x() as f32 * scale_factor - } - - fn actual_bounding_box_right(&self) -> f32 { - let last_glyph = match self.glyphs.last() { - None => return 0.0, - Some(last_glyph) => last_glyph, - }; - - let glyph_id = last_glyph.glyph_id; - let font_metrics = last_glyph.font.font.metrics(); - let scale_factor = self.size / font_metrics.units_per_em as f32; - let glyph_rect = last_glyph.font - .font - .raster_bounds(glyph_id, - font_metrics.units_per_em as f32, - Transform2F::default(), - HintingOptions::None, - RasterizationOptions::GrayscaleAa).unwrap(); - last_glyph.offset.x() + glyph_rect.max_x() as f32 * scale_factor - } - - fn hanging_baseline(&self) -> f32 { - // TODO(pcwalton) - 0.0 - } - - fn ideographic_baseline(&self) -> f32 { - // TODO(pcwalton) - 0.0 - } -} - -/// Various things that can be conveniently converted into font collections for use with -/// `CanvasRenderingContext2D::set_font()`. -pub trait IntoFontCollection { - fn into_font_collection(self, font_context: &CanvasFontContext) -> Arc; -} - -impl IntoFontCollection for Arc { - #[inline] - fn into_font_collection(self, _: &CanvasFontContext) -> Arc { - self - } -} - -impl IntoFontCollection for FontFamily { - #[inline] - fn into_font_collection(self, _: &CanvasFontContext) -> Arc { - let mut font_collection = FontCollection::new(); - font_collection.add_family(self); - Arc::new(font_collection) - } -} - -impl IntoFontCollection for Vec { - #[inline] - fn into_font_collection(self, _: &CanvasFontContext) -> Arc { - let mut font_collection = FontCollection::new(); - for family in self { - font_collection.add_family(family); - } - Arc::new(font_collection) - } -} - -/* -impl IntoFontCollection for Handle { - #[inline] - fn into_font_collection(self, context: &CanvasFontContext) -> Arc { - self.load().expect("Failed to load the font!").into_font_collection(context) - } -} - -impl<'a> IntoFontCollection for &'a [Handle] { - #[inline] - fn into_font_collection(self, context: &CanvasFontContext) -> Arc { - let mut font_collection = FontCollection::new(); - for handle in self { - let postscript_name = handle.postscript_name(); - - let font = handle.load().expect("Failed to load the font!"); - font_collection.add_family(FontFamily::new_from_font(font)); - } - Arc::new(font_collection) - } -} -*/ - -impl IntoFontCollection for Font { - #[inline] - fn into_font_collection(self, context: &CanvasFontContext) -> Arc { - FontFamily::new_from_font(self).into_font_collection(context) - } -} - -impl<'a> IntoFontCollection for &'a [Font] { - #[inline] - fn into_font_collection(self, context: &CanvasFontContext) -> Arc { - let mut family = FontFamily::new(); - for font in self { - family.add_font(FontRef::new((*font).clone())) - } - family.into_font_collection(context) - } -} - -impl<'a> IntoFontCollection for &'a str { - #[inline] - fn into_font_collection(self, context: &CanvasFontContext) -> Arc { - context.get_font_by_postscript_name(self).into_font_collection(context) - } -} - -impl<'a, 'b> IntoFontCollection for &'a [&'b str] { - #[inline] - fn into_font_collection(self, context: &CanvasFontContext) -> Arc { - let mut font_collection = FontCollection::new(); - for postscript_name in self { - let font = context.get_font_by_postscript_name(postscript_name); - font_collection.add_family(FontFamily::new_from_font(font)); - } - Arc::new(font_collection) - } -} diff --git a/crates/pathfinder/color/Cargo.toml b/crates/pathfinder/color/Cargo.toml deleted file mode 100644 index bbae0b6b9c..0000000000 --- a/crates/pathfinder/color/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "pathfinder_color" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -description = "A minimal SIMD-accelerated color handling library" -license = "MIT/Apache-2.0" -repository = "https://github.com/servo/pathfinder" -homepage = "https://github.com/servo/pathfinder" - -[dependencies] - -[dependencies.pathfinder_simd] -path = "../simd" -version = "0.5" diff --git a/crates/pathfinder/color/src/lib.rs b/crates/pathfinder/color/src/lib.rs deleted file mode 100644 index 2a2486b949..0000000000 --- a/crates/pathfinder/color/src/lib.rs +++ /dev/null @@ -1,272 +0,0 @@ -// pathfinder/color/src/lib.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use pathfinder_simd::default::F32x4; -use std::f32::consts::PI; -use std::fmt::{self, Debug, Formatter}; -use std::slice; - -// TODO(pcwalton): Maybe this should be a u32? Need to be aware of endianness issues if we do that. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] -#[repr(C)] -pub struct ColorU { - pub r: u8, - pub g: u8, - pub b: u8, - pub a: u8, -} - -impl ColorU { - #[inline] - pub fn new(r: u8, g: u8, b: u8, a: u8) -> ColorU { - ColorU { r, g, b, a } - } - - #[inline] - pub fn transparent_black() -> ColorU { - ColorU::from_u32(0) - } - - #[inline] - pub fn from_u32(rgba: u32) -> ColorU { - ColorU { - r: (rgba >> 24) as u8, - g: ((rgba >> 16) & 0xff) as u8, - b: ((rgba >> 8) & 0xff) as u8, - a: (rgba & 0xff) as u8, - } - } - - #[inline] - pub fn black() -> ColorU { - ColorU { - r: 0, - g: 0, - b: 0, - a: 255, - } - } - - #[inline] - pub fn white() -> ColorU { - ColorU { - r: 255, - g: 255, - b: 255, - a: 255, - } - } - - #[inline] - pub fn to_f32(&self) -> ColorF { - let color = F32x4::new(self.r as f32, self.g as f32, self.b as f32, self.a as f32); - ColorF(color * F32x4::splat(1.0 / 255.0)) - } - - #[inline] - pub fn is_opaque(&self) -> bool { - self.a == !0 - } - - #[inline] - pub fn is_fully_transparent(&self) -> bool { - self.a == 0 - } -} - -impl Debug for ColorU { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - if self.a == 255 { - write!(formatter, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b) - } else { - write!( - formatter, - "rgba({}, {}, {}, {})", - self.r, - self.g, - self.b, - self.a as f32 / 255.0 - ) - } - } -} - -#[derive(Clone, Copy, PartialEq, Default)] -pub struct ColorF(pub F32x4); - -impl ColorF { - // Constructors - - #[inline] - pub fn new(r: f32, g: f32, b: f32, a: f32) -> ColorF { - ColorF(F32x4::new(r, g, b, a)) - } - - #[inline] - pub fn from_hsla(mut h: f32, s: f32, l: f32, a: f32) -> ColorF { - // https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB - - // Make sure hue is always positive. - h %= 2.0 * PI; - if h < 0.0 { - h += 2.0 * PI; - } - - h *= 3.0 / PI; - - // Calculate chroma. - let c = (1.0 - f32::abs(2.0 * l - 1.0)) * s; - let xc = F32x4::new(c * (1.0 - f32::abs(h % 2.0 - 1.0)), c, 0.0, a); - let rgba = match f32::ceil(h) as i32 { - 1 => xc.yxzw(), - 2 => xc.xyzw(), - 3 => xc.zyxw(), - 4 => xc.zxyw(), - 5 => xc.xzyw(), - 0 | 6 => xc.yzxw(), - _ => xc.zzzw(), - }; - let m = l - 0.5 * c; - ColorF(rgba + F32x4::new(m, m, m, 0.0)) - } - - #[inline] - pub fn from_hsl(h: f32, s: f32, l: f32) -> ColorF { - ColorF::from_hsla(h, s, l, 1.0) - } - - #[inline] - pub fn transparent_black() -> ColorF { - ColorF::default() - } - - #[inline] - pub fn black() -> ColorF { - ColorF(F32x4::new(0.0, 0.0, 0.0, 1.0)) - } - - #[inline] - pub fn white() -> ColorF { - ColorF(F32x4::splat(1.0)) - } - - #[inline] - pub fn to_u8(&self) -> ColorU { - let color = (self.0 * F32x4::splat(255.0)).to_i32x4(); - ColorU { r: color[0] as u8, g: color[1] as u8, b: color[2] as u8, a: color[3] as u8 } - } - - #[inline] - pub fn lerp(&self, other: ColorF, t: f32) -> ColorF { - ColorF(self.0 + (other.0 - self.0) * F32x4::splat(t)) - } - - #[inline] - pub fn r(&self) -> f32 { - self.0[0] - } - - #[inline] - pub fn g(&self) -> f32 { - self.0[1] - } - - #[inline] - pub fn b(&self) -> f32 { - self.0[2] - } - - #[inline] - pub fn a(&self) -> f32 { - self.0[3] - } - - #[inline] - pub fn set_r(&mut self, r: f32) { - self.0[0] = r; - } - - #[inline] - pub fn set_g(&mut self, g: f32) { - self.0[1] = g; - } - - #[inline] - pub fn set_b(&mut self, b: f32) { - self.0[2] = b; - } - - #[inline] - pub fn set_a(&mut self, a: f32) { - self.0[3] = a; - } -} - -impl Debug for ColorF { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - write!( - formatter, - "rgba({}, {}, {}, {})", - self.r() * 255.0, - self.g() * 255.0, - self.b() * 255.0, - self.a() - ) - } -} - -#[inline] -pub fn color_slice_to_u8_slice(slice: &[ColorU]) -> &[u8] { - unsafe { - slice::from_raw_parts(slice.as_ptr() as *const u8, slice.len() * 4) - } -} - -#[inline] -pub fn u8_slice_to_color_slice(slice: &[u8]) -> &[ColorU] { - unsafe { - assert_eq!(slice.len() % 4, 0); - slice::from_raw_parts(slice.as_ptr() as *const ColorU, slice.len() / 4) - } -} - -// TODO(pcwalton): Do this without a copy? -#[inline] -pub fn u8_vec_to_color_vec(buffer: Vec) -> Vec { - u8_slice_to_color_slice(&buffer).to_vec() -} - -/// A convenience method to construct a `ColorU` from an RGB triple. -/// -/// Alpha is set to 255. -#[inline] -pub fn rgbu(r: u8, g: u8, b: u8) -> ColorU { - ColorU::new(r, g, b, 255) -} - -/// A convenience method to construct a `ColorU` from an RGBA triple. -#[inline] -pub fn rgbau(r: u8, g: u8, b: u8, a: u8) -> ColorU { - ColorU::new(r, g, b, a) -} - -/// A convenience method to construct a `ColorF` from an RGB triple. -/// -/// Alpha is set to 1.0. -#[inline] -pub fn rgbf(r: f32, g: f32, b: f32) -> ColorF { - ColorF::new(r, g, b, 1.0) -} - -/// A convenience method to construct a `ColorF` from an RGBA triple. -#[inline] -pub fn rgbaf(r: f32, g: f32, b: f32, a: f32) -> ColorF { - ColorF::new(r, g, b, a) -} diff --git a/crates/pathfinder/content/Cargo.toml b/crates/pathfinder/content/Cargo.toml deleted file mode 100644 index c2b769e0d3..0000000000 --- a/crates/pathfinder/content/Cargo.toml +++ /dev/null @@ -1,40 +0,0 @@ -[package] -name = "pathfinder_content" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -description = "Vector path utilities for the Pathfinder rendering library" -license = "MIT/Apache-2.0" -repository = "https://github.com/servo/pathfinder" -homepage = "https://github.com/servo/pathfinder" - -[dependencies] -arrayvec = "0.5" -bitflags = "1.0" -log = "0.4" -smallvec = "1.2" - -[dependencies.image] -version = "0.23" -default-features = false -features = [] -optional = true - -[features] -default = ["pf-image"] -pf-image = ["image"] - -[dependencies.pathfinder_color] -path = "../color" -version = "0.5" - -[dependencies.pathfinder_geometry] -path = "../geometry" -version = "0.5" - -[dependencies.pathfinder_simd] -path = "../simd" -version = "0.5" - -[dev-dependencies] -quickcheck = "0.9" diff --git a/crates/pathfinder/content/src/clip.rs b/crates/pathfinder/content/src/clip.rs deleted file mode 100644 index c5d4aa70cf..0000000000 --- a/crates/pathfinder/content/src/clip.rs +++ /dev/null @@ -1,555 +0,0 @@ -// pathfinder/content/src/clip.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::outline::{Contour, ContourIterFlags, PointFlags, PushSegmentFlags}; -use crate::segment::{CubicSegment, Segment}; -use arrayvec::ArrayVec; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::util::lerp; -use pathfinder_geometry::vector::{Vector2F, Vector4F}; -use smallvec::SmallVec; -use std::fmt::Debug; -use std::mem; - -#[derive(Clone, Copy, Debug)] -struct Edge(LineSegment2F); - -impl TEdge for Edge { - #[inline] - fn point_is_inside(&self, point: Vector2F) -> bool { - let area = (self.0.to() - self.0.from()).det(point - self.0.from()); - debug!("point_is_inside({:?}, {:?}), area={}", self, point, area); - area >= 0.0 - } - - fn intersect_line_segment(&self, segment: LineSegment2F) -> ArrayVec<[f32; 3]> { - let mut results = ArrayVec::new(); - if let Some(t) = segment.intersection_t(self.0) { - if t >= 0.0 && t <= 1.0 { - results.push(t); - } - } - results - } -} - -#[derive(Clone, Copy, Debug)] -enum AxisAlignedEdge { - Left(f32), - Top(f32), - Right(f32), - Bottom(f32), -} - -impl TEdge for AxisAlignedEdge { - #[inline] - fn point_is_inside(&self, point: Vector2F) -> bool { - match *self { - AxisAlignedEdge::Left(x) => point.x() >= x, - AxisAlignedEdge::Top(y) => point.y() >= y, - AxisAlignedEdge::Right(x) => point.x() <= x, - AxisAlignedEdge::Bottom(y) => point.y() <= y, - } - } - - fn intersect_line_segment(&self, segment: LineSegment2F) -> ArrayVec<[f32; 3]> { - let mut results = ArrayVec::new(); - let t = match *self { - AxisAlignedEdge::Left(x) | AxisAlignedEdge::Right(x) => segment.solve_t_for_x(x), - AxisAlignedEdge::Top(y) | AxisAlignedEdge::Bottom(y) => segment.solve_t_for_y(y), - }; - if t >= 0.0 && t <= 1.0 { - results.push(t); - } - results - } -} - -trait TEdge: Debug { - fn point_is_inside(&self, point: Vector2F) -> bool; - fn intersect_line_segment(&self, segment: LineSegment2F) -> ArrayVec<[f32; 3]>; - - fn trivially_test_segment(&self, segment: &Segment) -> EdgeRelativeLocation { - let from_inside = self.point_is_inside(segment.baseline.from()); - debug!( - "point {:?} inside {:?}: {:?}", - segment.baseline.from(), - self, - from_inside - ); - if from_inside != self.point_is_inside(segment.baseline.to()) { - return EdgeRelativeLocation::Intersecting; - } - if !segment.is_line() { - if from_inside != self.point_is_inside(segment.ctrl.from()) { - return EdgeRelativeLocation::Intersecting; - } - if !segment.is_quadratic() { - if from_inside != self.point_is_inside(segment.ctrl.to()) { - return EdgeRelativeLocation::Intersecting; - } - } - } - if from_inside { - EdgeRelativeLocation::Inside - } else { - EdgeRelativeLocation::Outside - } - } - - fn intersect_segment(&self, segment: &Segment) -> ArrayVec<[f32; 3]> { - if segment.is_line() { - return self.intersect_line_segment(segment.baseline); - } - - let mut segment = *segment; - if segment.is_quadratic() { - segment = segment.to_cubic(); - } - - let mut results = ArrayVec::new(); - let mut prev_t = 0.0; - while !results.is_full() { - if prev_t >= 1.0 { - break; - } - let next_t = match self.intersect_cubic_segment(&segment, prev_t, 1.0) { - None => break, - Some(next_t) => next_t, - }; - results.push(next_t); - prev_t = next_t + EPSILON; - } - return results; - - const EPSILON: f32 = 0.0001; - } - - fn intersect_cubic_segment( - &self, - segment: &Segment, - mut t_min: f32, - mut t_max: f32, - ) -> Option { - debug!( - "... intersect_cubic_segment({:?}, {:?}, t=({}, {}))", - self, segment, t_min, t_max - ); - - let mut segment = segment.as_cubic_segment().split_after(t_min); - segment = segment - .as_cubic_segment() - .split_before(t_max / (1.0 - t_min)); - - if !self.intersects_cubic_segment_hull(segment.as_cubic_segment()) { - return None; - } - - loop { - let t_mid = lerp(t_min, t_max, 0.5); - if t_max - t_min < 0.00001 { - return Some(t_mid); - } - - let (prev_segment, next_segment) = segment.as_cubic_segment().split(0.5); - if self.intersects_cubic_segment_hull(prev_segment.as_cubic_segment()) { - t_max = t_mid; - segment = prev_segment; - } else if self.intersects_cubic_segment_hull(next_segment.as_cubic_segment()) { - t_min = t_mid; - segment = next_segment; - } else { - return None; - } - } - } - - fn intersects_cubic_segment_hull(&self, cubic_segment: CubicSegment) -> bool { - let inside = self.point_is_inside(cubic_segment.0.baseline.from()); - inside != self.point_is_inside(cubic_segment.0.ctrl.from()) - || inside != self.point_is_inside(cubic_segment.0.ctrl.to()) - || inside != self.point_is_inside(cubic_segment.0.baseline.to()) - } -} - -trait ContourClipper -where - Self::Edge: TEdge + Debug, -{ - type Edge; - - fn contour_mut(&mut self) -> &mut Contour; - - fn clip_against(&mut self, edge: Self::Edge) { - // Fast path to avoid allocation in the no-clip case. - match self.check_for_fast_clip(&edge) { - FastClipResult::SlowPath => {} - FastClipResult::AllInside => return, - FastClipResult::AllOutside => { - *self.contour_mut() = Contour::new(); - return; - } - } - - let input = self.contour_mut().take(); - for segment in input.iter(ContourIterFlags::empty()) { - self.clip_segment_against(segment, &edge); - } - if input.is_closed() { - self.contour_mut().close(); - } - } - - fn clip_segment_against(&mut self, mut segment: Segment, edge: &Self::Edge) { - // Easy cases. - match edge.trivially_test_segment(&segment) { - EdgeRelativeLocation::Outside => return, - EdgeRelativeLocation::Inside => { - debug!("trivial test inside, pushing segment"); - self.push_segment(&segment); - return; - } - EdgeRelativeLocation::Intersecting => {} - } - - // We have a potential intersection. - debug!("potential intersection: {:?} edge: {:?}", segment, edge); - let mut starts_inside = edge.point_is_inside(segment.baseline.from()); - let intersection_ts = edge.intersect_segment(&segment); - let mut last_t = 0.0; - debug!("... intersections: {:?}", intersection_ts); - for t in intersection_ts { - let (before_split, after_split) = segment.split((t - last_t) / (1.0 - last_t)); - - // Push the split segment if appropriate. - debug!( - "... ... edge={:?} before_split={:?} t={:?} starts_inside={:?}", - edge, before_split, t, starts_inside - ); - if starts_inside { - debug!("... split segment case, pushing segment"); - self.push_segment(&before_split); - } - - // We've now transitioned from inside to outside or vice versa. - starts_inside = !starts_inside; - last_t = t; - segment = after_split; - } - - // No more intersections. Push the last segment if applicable. - if starts_inside { - debug!("... last segment case, pushing segment"); - self.push_segment(&segment); - } - } - - fn push_segment(&mut self, segment: &Segment) { - let contour = self.contour_mut(); - if let Some(last_position) = contour.last_position() { - if last_position != segment.baseline.from() { - // Add a line to join up segments. - contour.push_point(segment.baseline.from(), PointFlags::empty(), true); - } - } - - contour.push_segment(segment, PushSegmentFlags::UPDATE_BOUNDS); - } - - fn check_for_fast_clip(&mut self, edge: &Self::Edge) -> FastClipResult { - let mut result = None; - for segment in self.contour_mut().iter(ContourIterFlags::empty()) { - let location = edge.trivially_test_segment(&segment); - match (result, location) { - (None, EdgeRelativeLocation::Outside) => { - result = Some(FastClipResult::AllOutside); - } - (None, EdgeRelativeLocation::Inside) => { - result = Some(FastClipResult::AllInside); - } - (Some(FastClipResult::AllInside), EdgeRelativeLocation::Inside) - | (Some(FastClipResult::AllOutside), EdgeRelativeLocation::Outside) => {} - (_, _) => return FastClipResult::SlowPath, - } - } - result.unwrap_or(FastClipResult::AllOutside) - } -} - -#[derive(Clone, Copy)] -enum FastClipResult { - SlowPath, - AllInside, - AllOutside, -} - -// General convex polygon clipping in 2D - -pub(crate) struct ContourPolygonClipper { - clip_polygon: SmallVec<[Vector2F; 4]>, - contour: Contour, -} - -impl ContourClipper for ContourPolygonClipper { - type Edge = Edge; - - #[inline] - fn contour_mut(&mut self) -> &mut Contour { - &mut self.contour - } -} - -impl ContourPolygonClipper { - #[inline] - pub(crate) fn new(clip_polygon: &[Vector2F], contour: Contour) -> ContourPolygonClipper { - ContourPolygonClipper { - clip_polygon: SmallVec::from_slice(clip_polygon), - contour, - } - } - - pub(crate) fn clip(mut self) -> Contour { - // TODO(pcwalton): Maybe have a coarse circumscribed rect and use that for clipping? - - let clip_polygon = mem::replace(&mut self.clip_polygon, SmallVec::default()); - let mut prev = match clip_polygon.last() { - None => return Contour::new(), - Some(prev) => *prev, - }; - for &next in &clip_polygon { - self.clip_against(Edge(LineSegment2F::new(prev, next))); - prev = next; - } - - self.contour - } -} - -#[derive(PartialEq)] -enum EdgeRelativeLocation { - Intersecting, - Inside, - Outside, -} - -// Fast axis-aligned box 2D clipping - -pub(crate) struct ContourRectClipper { - clip_rect: RectF, - contour: Contour, -} - -impl ContourClipper for ContourRectClipper { - type Edge = AxisAlignedEdge; - - #[inline] - fn contour_mut(&mut self) -> &mut Contour { - &mut self.contour - } -} - -impl ContourRectClipper { - #[inline] - pub(crate) fn new(clip_rect: RectF, contour: Contour) -> ContourRectClipper { - ContourRectClipper { clip_rect, contour } - } - - pub(crate) fn clip(mut self) -> Contour { - if self.clip_rect.contains_rect(self.contour.bounds()) { - return self.contour; - } - - self.clip_against(AxisAlignedEdge::Left(self.clip_rect.min_x())); - self.clip_against(AxisAlignedEdge::Top(self.clip_rect.min_y())); - self.clip_against(AxisAlignedEdge::Right(self.clip_rect.max_x())); - self.clip_against(AxisAlignedEdge::Bottom(self.clip_rect.max_y())); - - self.contour - } -} - -// 3D quad clipping - -pub struct PolygonClipper3D { - subject: Vec, -} - -impl PolygonClipper3D { - #[inline] - pub fn new(subject: Vec) -> PolygonClipper3D { - PolygonClipper3D { subject } - } - - pub fn clip(mut self) -> Vec { - // TODO(pcwalton): Fast path for completely contained polygon? - - debug!("before clipping against bottom: {:?}", self.subject); - self.clip_against(Edge3D::Bottom); - debug!("before clipping against top: {:?}", self.subject); - self.clip_against(Edge3D::Top); - debug!("before clipping against left: {:?}", self.subject); - self.clip_against(Edge3D::Left); - debug!("before clipping against right: {:?}", self.subject); - self.clip_against(Edge3D::Right); - debug!("before clipping against far: {:?}", self.subject); - self.clip_against(Edge3D::Far); - debug!("before clipping against near: {:?}", self.subject); - self.clip_against(Edge3D::Near); - debug!("after clipping: {:?}", self.subject); - - self.subject - } - - fn clip_against(&mut self, edge: Edge3D) { - let input = mem::replace(&mut self.subject, vec![]); - let mut prev = match input.last() { - None => return, - Some(point) => *point, - }; - for next in input { - if edge.point_is_inside(next) { - if !edge.point_is_inside(prev) { - self.subject.push(edge.line_intersection(prev, next)); - } - self.subject.push(next); - } else if edge.point_is_inside(prev) { - self.subject.push(edge.line_intersection(prev, next)); - } - prev = next; - } - } -} - -#[derive(Clone, Copy, Debug)] -enum Edge3D { - Left, - Right, - Bottom, - Top, - Near, - Far, -} - -impl Edge3D { - #[inline] - fn point_is_inside(self, point: Vector4F) -> bool { - let w = point.w(); - match self { - Edge3D::Left => point.x() >= -w, - Edge3D::Right => point.x() <= w, - Edge3D::Bottom => point.y() >= -w, - Edge3D::Top => point.y() <= w, - Edge3D::Near => point.z() >= -w, - Edge3D::Far => point.z() <= w, - } - } - - // Blinn & Newell, "Clipping using homogeneous coordinates", SIGGRAPH 1978. - fn line_intersection(self, prev: Vector4F, next: Vector4F) -> Vector4F { - let (x0, x1) = match self { - Edge3D::Left | Edge3D::Right => (prev.x(), next.x()), - Edge3D::Bottom | Edge3D::Top => (prev.y(), next.y()), - Edge3D::Near | Edge3D::Far => (prev.z(), next.z()), - }; - let (w0, w1) = (prev.w(), next.w()); - let sign = match self { - Edge3D::Left | Edge3D::Bottom | Edge3D::Near => -1.0, - Edge3D::Right | Edge3D::Top | Edge3D::Far => 1.0, - }; - let alpha = ((x0 - sign * w0) as f64) / ((sign * (w1 - w0) - (x1 - x0)) as f64); - prev.lerp(next, alpha as f32) - } -} - -/// Coarse collision detection - -// Separating axis theorem. Requires that the polygon be convex. -pub(crate) fn rect_is_outside_polygon(rect: RectF, polygon_points: &[Vector2F]) -> bool { - let mut outcode = Outcode::all(); - for point in polygon_points { - if point.x() > rect.min_x() { - outcode.remove(Outcode::LEFT); - } - if point.x() < rect.max_x() { - outcode.remove(Outcode::RIGHT); - } - if point.y() > rect.min_y() { - outcode.remove(Outcode::TOP); - } - if point.y() < rect.max_y() { - outcode.remove(Outcode::BOTTOM); - } - } - if !outcode.is_empty() { - return true; - } - - // FIXME(pcwalton): Check winding! - let rect_points = [ - rect.origin(), - rect.upper_right(), - rect.lower_left(), - rect.lower_right(), - ]; - for (next_point_index, &next) in polygon_points.iter().enumerate() { - let prev_point_index = if next_point_index == 0 { - polygon_points.len() - 1 - } else { - next_point_index - 1 - }; - let prev = polygon_points[prev_point_index]; - let polygon_edge_vector = next - prev; - if rect_points - .iter() - .all(|&rect_point| polygon_edge_vector.det(rect_point - prev) < 0.0) - { - return true; - } - } - - false -} - -// Edge equation method. Requires that the polygon be convex. -pub(crate) fn rect_is_inside_polygon(rect: RectF, polygon_points: &[Vector2F]) -> bool { - // FIXME(pcwalton): Check winding! - let rect_points = [ - rect.origin(), - rect.upper_right(), - rect.lower_left(), - rect.lower_right(), - ]; - for (next_point_index, &next) in polygon_points.iter().enumerate() { - let prev_point_index = if next_point_index == 0 { - polygon_points.len() - 1 - } else { - next_point_index - 1 - }; - let prev = polygon_points[prev_point_index]; - let polygon_edge_vector = next - prev; - for &rect_point in &rect_points { - if polygon_edge_vector.det(rect_point - prev) < 0.0 { - return false; - } - } - } - - true -} - -bitflags! { - struct Outcode: u8 { - const LEFT = 0x01; - const RIGHT = 0x02; - const TOP = 0x04; - const BOTTOM = 0x08; - } -} diff --git a/crates/pathfinder/content/src/dash.rs b/crates/pathfinder/content/src/dash.rs deleted file mode 100644 index 9c820a9740..0000000000 --- a/crates/pathfinder/content/src/dash.rs +++ /dev/null @@ -1,134 +0,0 @@ -// pathfinder/content/src/dash.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Line dashing support. - -use crate::outline::{Contour, ContourIterFlags, Outline, PushSegmentFlags}; -use std::mem; - -const EPSILON: f32 = 0.0001; - -pub struct OutlineDash<'a> { - input: &'a Outline, - output: Outline, - state: DashState<'a>, -} - -impl<'a> OutlineDash<'a> { - #[inline] - pub fn new(input: &'a Outline, dashes: &'a [f32], offset: f32) -> OutlineDash<'a> { - OutlineDash { input, output: Outline::new(), state: DashState::new(dashes, offset) } - } - - pub fn dash(&mut self) { - for contour in &self.input.contours { - ContourDash::new(contour, &mut self.output, &mut self.state).dash() - } - } - - pub fn into_outline(mut self) -> Outline { - if self.state.is_on() { - self.output.push_contour(self.state.output); - } - self.output - } -} - -struct ContourDash<'a, 'b, 'c> { - input: &'a Contour, - output: &'b mut Outline, - state: &'c mut DashState<'a>, -} - -impl<'a, 'b, 'c> ContourDash<'a, 'b, 'c> { - fn new(input: &'a Contour, output: &'b mut Outline, state: &'c mut DashState<'a>) - -> ContourDash<'a, 'b, 'c> { - ContourDash { input, output, state } - } - - fn dash(&mut self) { - let mut iterator = self.input.iter(ContourIterFlags::empty()); - let mut queued_segment = None; - loop { - if queued_segment.is_none() { - match iterator.next() { - None => break, - Some(segment) => queued_segment = Some(segment), - } - } - - let mut current_segment = queued_segment.take().unwrap(); - let mut distance = self.state.distance_left; - - let t = current_segment.time_for_distance(distance); - if t < 1.0 { - let (prev_segment, next_segment) = current_segment.split(t); - current_segment = prev_segment; - queued_segment = Some(next_segment); - } else { - distance = current_segment.arc_length(); - } - - if self.state.is_on() { - self.state.output.push_segment(¤t_segment, PushSegmentFlags::empty()); - } - - self.state.distance_left -= distance; - if self.state.distance_left < EPSILON { - if self.state.is_on() { - self.output.push_contour(mem::replace(&mut self.state.output, Contour::new())); - } - - self.state.current_dash_index += 1; - if self.state.current_dash_index == self.state.dashes.len() { - self.state.current_dash_index = 0; - } - - self.state.distance_left = self.state.dashes[self.state.current_dash_index]; - } - } - } -} - -struct DashState<'a> { - output: Contour, - dashes: &'a [f32], - current_dash_index: usize, - distance_left: f32, -} - -impl<'a> DashState<'a> { - fn new(dashes: &'a [f32], mut offset: f32) -> DashState<'a> { - let total: f32 = dashes.iter().cloned().sum(); - offset %= total; - - let mut current_dash_index = 0; - while current_dash_index < dashes.len() { - let dash = dashes[current_dash_index]; - if offset < dash { - break; - } - offset -= dash; - current_dash_index += 1; - } - - DashState { - output: Contour::new(), - dashes, - current_dash_index, - distance_left: offset, - } - } - - #[inline] - fn is_on(&self) -> bool { - self.current_dash_index % 2 == 0 - } -} diff --git a/crates/pathfinder/content/src/dilation.rs b/crates/pathfinder/content/src/dilation.rs deleted file mode 100644 index 9e39f699a5..0000000000 --- a/crates/pathfinder/content/src/dilation.rs +++ /dev/null @@ -1,125 +0,0 @@ -// pathfinder/content/src/dilation.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::orientation::Orientation; -use crate::outline::Contour; -use pathfinder_geometry::vector::{Vector2F, vec2f}; - -pub struct ContourDilator<'a> { - contour: &'a mut Contour, - amount: Vector2F, - orientation: Orientation, -} - -impl<'a> ContourDilator<'a> { - pub fn new( - contour: &'a mut Contour, - amount: Vector2F, - orientation: Orientation, - ) -> ContourDilator<'a> { - ContourDilator { - contour, - amount, - orientation, - } - } - - pub fn dilate(&mut self) { - // Determine orientation. - let scale = self.amount * (match self.orientation { - Orientation::Ccw => vec2f( 1.0, -1.0), - Orientation::Cw => vec2f(-1.0, 1.0), - }); - - // Find the starting and previous positions. - let first_position = self.contour.position_of(0); - let mut prev_point_index = 0; - let mut prev_position; - - loop { - prev_point_index = self.contour.prev_point_index_of(prev_point_index); - prev_position = self.contour.position_of(prev_point_index); - if prev_point_index == 0 || prev_position != first_position { - break; - } - } - - // Initialize our loop. - let first_point_index = self.contour.next_point_index_of(prev_point_index); - let mut current_point_index = first_point_index; - let mut position = first_position; - - let mut prev_vector = (position - prev_position).normalize(); - - loop { - // Find the next non-degenerate position. - let mut next_point_index = current_point_index; - let mut next_position; - loop { - next_point_index = self.contour.next_point_index_of(next_point_index); - if next_point_index == first_point_index { - next_position = first_position; - break; - } - next_position = self.contour.position_of(next_point_index); - if next_point_index == current_point_index || next_position != position { - break; - } - } - let next_vector = (next_position - position).normalize(); - - debug!( - "prev={} cur={} next={}", - prev_point_index, current_point_index, next_point_index - ); - - // Calculate new position by moving the point by the bisector. - let bisector = prev_vector.yx() + next_vector.yx(); - let bisector_length = bisector.length(); - let scaled_bisector = if bisector_length == 0.0 { - Vector2F::zero() - } else { - bisector * scale * (1.0 / bisector_length) - }; - let new_position = position - scaled_bisector; - - debug!( - "dilate(): prev={}({:?}) cur={}({:?}) next={}({:?}) bisector={:?}({:?}, {:?})", - prev_point_index, - prev_position, - current_point_index, - position, - next_point_index, - next_position, - bisector, - bisector_length, - scaled_bisector - ); - - // Update all points. - let mut point_index = current_point_index; - while point_index != next_point_index { - self.contour.points[point_index as usize] = new_position; - debug!("... updating {:?}", point_index); - point_index = self.contour.next_point_index_of(point_index); - } - - // Check to see if we're done. - if next_point_index == first_point_index { - break; - } - - // Continue. - prev_vector = next_vector; - position = next_position; - current_point_index = next_point_index; - } - } -} diff --git a/crates/pathfinder/content/src/effects.rs b/crates/pathfinder/content/src/effects.rs deleted file mode 100644 index e5db8f43a8..0000000000 --- a/crates/pathfinder/content/src/effects.rs +++ /dev/null @@ -1,205 +0,0 @@ -// pathfinder/content/src/effects.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Special effects that can be applied to layers. - -use pathfinder_color::ColorF; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::vector::Vector2F; -use pathfinder_simd::default::F32x2; - -/// This intentionally does not precisely match what Core Graphics does (a -/// Lanczos function), because we don't want any ringing artefacts. -pub static DEFRINGING_KERNEL_CORE_GRAPHICS: DefringingKernel = - DefringingKernel([0.033165660, 0.102074051, 0.221434336, 0.286651906]); -pub static DEFRINGING_KERNEL_FREETYPE: DefringingKernel = - DefringingKernel([0.0, 0.031372549, 0.301960784, 0.337254902]); - -/// Should match macOS 10.13 High Sierra. -pub static STEM_DARKENING_FACTORS: [f32; 2] = [0.0121, 0.0121 * 1.25]; - -/// Should match macOS 10.13 High Sierra. -pub const MAX_STEM_DARKENING_AMOUNT: [f32; 2] = [0.3, 0.3]; - -/// This value is a subjective cutoff. Above this ppem value, no stem darkening is performed. -pub const MAX_STEM_DARKENING_PIXELS_PER_EM: f32 = 72.0; - -/// The shader that should be used when compositing this layer onto its destination. -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum Filter { - /// No special filter. - None, - - /// Converts a linear gradient to a radial one. - RadialGradient { - /// The line that the circles lie along. - line: LineSegment2F, - /// The radii of the circles at the two endpoints. - radii: F32x2, - /// The origin of the linearized gradient in the texture. - uv_origin: Vector2F, - }, - - PatternFilter(PatternFilter), -} - -/// Shaders applicable to patterns. -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum PatternFilter { - /// Performs postprocessing operations useful for monochrome text. - Text { - /// The foreground color of the text. - fg_color: ColorF, - /// The background color of the text. - bg_color: ColorF, - /// The kernel used for defringing, if subpixel AA is enabled. - defringing_kernel: Option, - /// Whether gamma correction is used when compositing. - /// - /// If this is enabled, stem darkening is advised. - gamma_correction: bool, - }, - - /// A blur operation in one direction, either horizontal or vertical. - /// - /// To produce a full Gaussian blur, perform two successive blur operations, one in each - /// direction. - Blur { - direction: BlurDirection, - sigma: f32, - }, -} - -/// Blend modes that can be applied to individual paths. -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum BlendMode { - // Porter-Duff, supported by GPU blender - Clear, - Copy, - SrcIn, - SrcOut, - SrcOver, - SrcAtop, - DestIn, - DestOut, - DestOver, - DestAtop, - Xor, - Lighter, - - // Others, unsupported by GPU blender - Darken, - Lighten, - Multiply, - Screen, - HardLight, - Overlay, - ColorDodge, - ColorBurn, - SoftLight, - Difference, - Exclusion, - Hue, - Saturation, - Color, - Luminosity, -} - -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct DefringingKernel(pub [f32; 4]); - -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum BlurDirection { - X, - Y, -} - -impl Default for BlendMode { - #[inline] - fn default() -> BlendMode { - BlendMode::SrcOver - } -} - -impl Default for Filter { - #[inline] - fn default() -> Filter { - Filter::None - } -} - -impl BlendMode { - /// Whether the backdrop is irrelevant when applying this blend mode (i.e. destination blend - /// factor is zero when source alpha is one). - #[inline] - pub fn occludes_backdrop(self) -> bool { - match self { - BlendMode::SrcOver | BlendMode::Clear => true, - BlendMode::DestOver | - BlendMode::DestOut | - BlendMode::SrcAtop | - BlendMode::Xor | - BlendMode::Lighter | - BlendMode::Lighten | - BlendMode::Darken | - BlendMode::Copy | - BlendMode::SrcIn | - BlendMode::DestIn | - BlendMode::SrcOut | - BlendMode::DestAtop | - BlendMode::Multiply | - BlendMode::Screen | - BlendMode::HardLight | - BlendMode::Overlay | - BlendMode::ColorDodge | - BlendMode::ColorBurn | - BlendMode::SoftLight | - BlendMode::Difference | - BlendMode::Exclusion | - BlendMode::Hue | - BlendMode::Saturation | - BlendMode::Color | - BlendMode::Luminosity => false, - } - } - - /// True if this blend mode does not preserve destination areas outside the source. - pub fn is_destructive(self) -> bool { - match self { - BlendMode::Clear | - BlendMode::Copy | - BlendMode::SrcIn | - BlendMode::DestIn | - BlendMode::SrcOut | - BlendMode::DestAtop => true, - BlendMode::SrcOver | - BlendMode::DestOver | - BlendMode::DestOut | - BlendMode::SrcAtop | - BlendMode::Xor | - BlendMode::Lighter | - BlendMode::Lighten | - BlendMode::Darken | - BlendMode::Multiply | - BlendMode::Screen | - BlendMode::HardLight | - BlendMode::Overlay | - BlendMode::ColorDodge | - BlendMode::ColorBurn | - BlendMode::SoftLight | - BlendMode::Difference | - BlendMode::Exclusion | - BlendMode::Hue | - BlendMode::Saturation | - BlendMode::Color | - BlendMode::Luminosity => false, - } - } -} diff --git a/crates/pathfinder/content/src/fill.rs b/crates/pathfinder/content/src/fill.rs deleted file mode 100644 index e2941f17d9..0000000000 --- a/crates/pathfinder/content/src/fill.rs +++ /dev/null @@ -1,17 +0,0 @@ -// pathfinder/content/src/fill.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Fill rules. - -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum FillRule { - Winding, - EvenOdd, -} diff --git a/crates/pathfinder/content/src/gradient.rs b/crates/pathfinder/content/src/gradient.rs deleted file mode 100644 index 111559703f..0000000000 --- a/crates/pathfinder/content/src/gradient.rs +++ /dev/null @@ -1,205 +0,0 @@ -// pathfinder/content/src/gradient.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::sorted_vector::SortedVector; -use crate::util; -use pathfinder_color::ColorU; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::vector::Vector2F; -use pathfinder_geometry::util as geometry_util; -use pathfinder_simd::default::F32x2; -use std::cmp::{Ordering, PartialOrd}; -use std::convert; -use std::hash::{Hash, Hasher}; -use std::mem; - -#[derive(Clone, PartialEq, Debug)] -pub struct Gradient { - pub geometry: GradientGeometry, - stops: SortedVector, -} - -#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] -pub struct ColorStop { - pub offset: f32, - pub color: ColorU, -} - -#[derive(Clone, PartialEq, Debug)] -pub enum GradientGeometry { - Linear(LineSegment2F), - Radial { - /// The line that connects the two circles. It may have zero length for simple radial - /// gradients. - line: LineSegment2F, - /// The radii of the two circles. The first value may be zero. - radii: F32x2, - /// Transform from radial gradient space into screen space. - /// - /// Like `gradientTransform` in SVG. Note that this is the inverse of Cairo's gradient - /// transform. - transform: Transform2F, - } -} - -impl Eq for Gradient {} - -impl Hash for Gradient { - fn hash(&self, state: &mut H) where H: Hasher { - match self.geometry { - GradientGeometry::Linear(line) => { - (0).hash(state); - util::hash_line_segment(line, state); - } - GradientGeometry::Radial { line, radii, transform } => { - (1).hash(state); - util::hash_line_segment(line, state); - util::hash_f32(radii.x(), state); - util::hash_f32(radii.y(), state); - util::hash_f32(transform.m11(), state); - util::hash_f32(transform.m12(), state); - util::hash_f32(transform.m13(), state); - util::hash_f32(transform.m21(), state); - util::hash_f32(transform.m22(), state); - util::hash_f32(transform.m23(), state); - } - } - self.stops.hash(state); - } -} - -impl Eq for ColorStop {} - -impl Hash for ColorStop { - fn hash(&self, state: &mut H) where H: Hasher { - unsafe { - self.color.hash(state); - let offset = mem::transmute::(self.offset); - offset.hash(state); - } - } -} - -impl Gradient { - #[inline] - pub fn linear(line: LineSegment2F) -> Gradient { - Gradient { geometry: GradientGeometry::Linear(line), stops: SortedVector::new() } - } - - #[inline] - pub fn linear_from_points(from: Vector2F, to: Vector2F) -> Gradient { - Gradient::linear(LineSegment2F::new(from, to)) - } - - #[inline] - pub fn radial(line: L, radii: F32x2) -> Gradient where L: RadialGradientLine { - let transform = Transform2F::default(); - Gradient { - geometry: GradientGeometry::Radial { line: line.to_line(), radii, transform }, - stops: SortedVector::new(), - } - } - - #[inline] - pub fn add(&mut self, stop: ColorStop) { - self.stops.push(stop); - } - - /// A convenience method to add a color stop. - #[inline] - pub fn add_color_stop(&mut self, color: ColorU, offset: f32) { - self.add(ColorStop::new(color, offset)) - } - - #[inline] - pub fn stops(&self) -> &[ColorStop] { - &self.stops.array - } - - #[inline] - pub fn stops_mut(&mut self) -> &mut [ColorStop] { - &mut self.stops.array - } - - pub fn sample(&self, mut t: f32) -> ColorU { - if self.stops.is_empty() { - return ColorU::transparent_black(); - } - - t = geometry_util::clamp(t, 0.0, 1.0); - let last_index = self.stops.len() - 1; - let upper_index = self.stops.binary_search_by(|stop| { - stop.offset.partial_cmp(&t).unwrap_or(Ordering::Less) - }).unwrap_or_else(convert::identity).min(last_index); - let lower_index = if upper_index > 0 { upper_index - 1 } else { upper_index }; - - let lower_stop = &self.stops.array[lower_index]; - let upper_stop = &self.stops.array[upper_index]; - - let denom = upper_stop.offset - lower_stop.offset; - if denom == 0.0 { - return lower_stop.color; - } - - lower_stop.color - .to_f32() - .lerp(upper_stop.color.to_f32(), (t - lower_stop.offset) / denom) - .to_u8() - } - - #[inline] - pub fn is_opaque(&self) -> bool { - self.stops.array.iter().all(|stop| stop.color.is_opaque()) - } - - #[inline] - pub fn is_fully_transparent(&self) -> bool { - self.stops.array.iter().all(|stop| stop.color.is_fully_transparent()) - } - - pub fn apply_transform(&mut self, new_transform: Transform2F) { - if new_transform.is_identity() { - return; - } - - match self.geometry { - GradientGeometry::Linear(ref mut line) => *line = new_transform * *line, - GradientGeometry::Radial { ref mut transform, .. } => { - *transform = new_transform * *transform - } - } - } -} - -impl ColorStop { - #[inline] - pub fn new(color: ColorU, offset: f32) -> ColorStop { - ColorStop { color, offset } - } -} - -pub trait RadialGradientLine { - fn to_line(self) -> LineSegment2F; -} - -impl RadialGradientLine for LineSegment2F { - #[inline] - fn to_line(self) -> LineSegment2F { - self - } -} - -impl RadialGradientLine for Vector2F { - #[inline] - fn to_line(self) -> LineSegment2F { - LineSegment2F::new(self, self) - } -} diff --git a/crates/pathfinder/content/src/lib.rs b/crates/pathfinder/content/src/lib.rs deleted file mode 100644 index 8674760237..0000000000 --- a/crates/pathfinder/content/src/lib.rs +++ /dev/null @@ -1,35 +0,0 @@ -// pathfinder/content/src/lib.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Pathfinder's representation of a vector scene. -//! -//! This module also contains various path utilities. - -#[macro_use] -extern crate bitflags; -#[macro_use] -extern crate log; - -pub mod clip; -pub mod dash; -pub mod effects; -pub mod fill; -pub mod gradient; -pub mod orientation; -pub mod outline; -pub mod pattern; -pub mod render_target; -pub mod segment; -pub mod sorted_vector; -pub mod stroke; -pub mod transform; - -mod dilation; -mod util; diff --git a/crates/pathfinder/content/src/orientation.rs b/crates/pathfinder/content/src/orientation.rs deleted file mode 100644 index 9e815ebb0d..0000000000 --- a/crates/pathfinder/content/src/orientation.rs +++ /dev/null @@ -1,43 +0,0 @@ -// pathfinder/geometry/src/orientation.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::outline::Outline; - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum Orientation { - Ccw = -1, - Cw = 1, -} - -impl Orientation { - /// This follows the FreeType algorithm. - pub fn from_outline(outline: &Outline) -> Orientation { - let mut area = 0.0; - for contour in &outline.contours { - let mut prev_position = match contour.last_position() { - None => continue, - Some(position) => position, - }; - for &next_position in &contour.points { - area += prev_position.det(next_position); - prev_position = next_position; - } - } - Orientation::from_area(area) - } - - fn from_area(area: f32) -> Orientation { - if area <= 0.0 { - Orientation::Ccw - } else { - Orientation::Cw - } - } -} diff --git a/crates/pathfinder/content/src/outline.rs b/crates/pathfinder/content/src/outline.rs deleted file mode 100644 index 7a062ea061..0000000000 --- a/crates/pathfinder/content/src/outline.rs +++ /dev/null @@ -1,927 +0,0 @@ -// pathfinder/content/src/outline.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A compressed in-memory representation of paths. - -use crate::clip::{self, ContourPolygonClipper, ContourRectClipper}; -use crate::dilation::ContourDilator; -use crate::orientation::Orientation; -use crate::segment::{Segment, SegmentFlags, SegmentKind}; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::transform3d::Perspective; -use pathfinder_geometry::unit_vector::UnitVector; -use pathfinder_geometry::vector::{Vector2F, vec2f}; -use std::f32::consts::PI; -use std::fmt::{self, Debug, Formatter}; -use std::mem; - -#[derive(Clone)] -pub struct Outline { - pub(crate) contours: Vec, - pub(crate) bounds: RectF, -} - -#[derive(Clone)] -pub struct Contour { - pub(crate) points: Vec, - pub(crate) flags: Vec, - pub(crate) bounds: RectF, - pub(crate) closed: bool, -} - -bitflags! { - pub struct PointFlags: u8 { - const CONTROL_POINT_0 = 0x01; - const CONTROL_POINT_1 = 0x02; - } -} - -bitflags! { - pub struct PushSegmentFlags: u8 { - const UPDATE_BOUNDS = 0x01; - const INCLUDE_FROM_POINT = 0x02; - } -} - -impl Outline { - #[inline] - pub fn new() -> Outline { - Outline { - contours: vec![], - bounds: RectF::default(), - } - } - - #[inline] - pub fn from_segments(segments: I) -> Outline - where - I: Iterator, - { - let mut outline = Outline::new(); - let mut current_contour = Contour::new(); - - for segment in segments { - if segment.flags.contains(SegmentFlags::FIRST_IN_SUBPATH) { - if !current_contour.is_empty() { - outline - .contours - .push(mem::replace(&mut current_contour, Contour::new())); - } - current_contour.push_point(segment.baseline.from(), PointFlags::empty(), true); - } - - if segment.flags.contains(SegmentFlags::CLOSES_SUBPATH) { - if !current_contour.is_empty() { - current_contour.close(); - let contour = mem::replace(&mut current_contour, Contour::new()); - outline.push_contour(contour); - } - continue; - } - - if segment.is_none() { - continue; - } - - if !segment.is_line() { - current_contour.push_point(segment.ctrl.from(), PointFlags::CONTROL_POINT_0, true); - if !segment.is_quadratic() { - current_contour.push_point( - segment.ctrl.to(), - PointFlags::CONTROL_POINT_1, - true, - ); - } - } - - current_contour.push_point(segment.baseline.to(), PointFlags::empty(), true); - } - - outline.push_contour(current_contour); - outline - } - - #[inline] - pub fn from_rect(rect: RectF) -> Outline { - let mut outline = Outline::new(); - outline.push_contour(Contour::from_rect(rect)); - outline - } - - #[inline] - pub fn bounds(&self) -> RectF { - self.bounds - } - - #[inline] - pub fn contours(&self) -> &[Contour] { - &self.contours - } - - #[inline] - pub fn into_contours(self) -> Vec { - self.contours - } - - /// Removes all contours from this outline. - #[inline] - pub fn clear(&mut self) { - self.contours.clear(); - self.bounds = RectF::default(); - } - - pub fn push_contour(&mut self, contour: Contour) { - if contour.is_empty() { - return; - } - - if self.contours.is_empty() { - self.bounds = contour.bounds; - } else { - self.bounds = self.bounds.union_rect(contour.bounds); - } - - self.contours.push(contour); - } - - pub fn pop_contour(&mut self) -> Option { - let last_contour = self.contours.pop(); - - let mut new_bounds = None; - for contour in &mut self.contours { - contour.update_bounds(&mut new_bounds); - } - self.bounds = new_bounds.unwrap_or_else(|| RectF::default()); - - last_contour - } - - pub fn transform(&mut self, transform: &Transform2F) { - if transform.is_identity() { - return; - } - - let mut new_bounds = None; - for contour in &mut self.contours { - contour.transform(transform); - contour.update_bounds(&mut new_bounds); - } - self.bounds = new_bounds.unwrap_or_else(|| RectF::default()); - } - - pub fn apply_perspective(&mut self, perspective: &Perspective) { - let mut new_bounds = None; - for contour in &mut self.contours { - contour.apply_perspective(perspective); - contour.update_bounds(&mut new_bounds); - } - self.bounds = new_bounds.unwrap_or_else(|| RectF::default()); - } - - pub fn dilate(&mut self, amount: Vector2F) { - let orientation = Orientation::from_outline(self); - self.contours - .iter_mut() - .for_each(|contour| contour.dilate(amount, orientation)); - self.bounds = self.bounds.dilate(amount); - } - - pub fn prepare_for_tiling(&mut self, view_box: RectF) { - self.contours - .iter_mut() - .for_each(|contour| contour.prepare_for_tiling(view_box)); - self.bounds = self - .bounds - .intersection(view_box) - .unwrap_or_else(|| RectF::default()); - } - - pub fn is_outside_polygon(&self, clip_polygon: &[Vector2F]) -> bool { - clip::rect_is_outside_polygon(self.bounds, clip_polygon) - } - - fn is_inside_polygon(&self, clip_polygon: &[Vector2F]) -> bool { - clip::rect_is_inside_polygon(self.bounds, clip_polygon) - } - - pub fn clip_against_polygon(&mut self, clip_polygon: &[Vector2F]) { - // Quick check. - if self.is_inside_polygon(clip_polygon) { - return; - } - - for contour in mem::replace(&mut self.contours, vec![]) { - self.push_contour(ContourPolygonClipper::new(clip_polygon, contour).clip()); - } - } - - pub fn clip_against_rect(&mut self, clip_rect: RectF) { - if clip_rect.contains_rect(self.bounds) { - return; - } - - for contour in mem::replace(&mut self.contours, vec![]) { - self.push_contour(ContourRectClipper::new(clip_rect, contour).clip()); - } - } - - #[inline] - pub fn close_all_contours(&mut self) { - self.contours.iter_mut().for_each(|contour| contour.close()); - } -} - -impl Debug for Outline { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - for (contour_index, contour) in self.contours.iter().enumerate() { - if contour_index > 0 { - write!(formatter, " ")?; - } - contour.fmt(formatter)?; - } - Ok(()) - } -} - -impl Contour { - #[inline] - pub fn new() -> Contour { - Contour { - points: vec![], - flags: vec![], - bounds: RectF::default(), - closed: false, - } - } - - #[inline] - pub fn with_capacity(length: usize) -> Contour { - Contour { - points: Vec::with_capacity(length), - flags: Vec::with_capacity(length), - bounds: RectF::default(), - closed: false, - } - } - - #[inline] - pub fn from_rect(rect: RectF) -> Contour { - let mut contour = Contour::new(); - contour.push_point(rect.origin(), PointFlags::empty(), false); - contour.push_point(rect.upper_right(), PointFlags::empty(), false); - contour.push_point(rect.lower_right(), PointFlags::empty(), false); - contour.push_point(rect.lower_left(), PointFlags::empty(), false); - contour.close(); - contour.bounds = rect; - contour - } - - // Replaces this contour with a new one, with arrays preallocated to match `self`. - #[inline] - pub(crate) fn take(&mut self) -> Contour { - let length = self.len() as usize; - mem::replace( - self, - Contour { - points: Vec::with_capacity(length), - flags: Vec::with_capacity(length), - bounds: RectF::default(), - closed: false, - }, - ) - } - - /// restore self to the state of Contour::new(), but keep the points buffer allocated - #[inline] - pub fn clear(&mut self) { - self.points.clear(); - self.flags.clear(); - self.bounds = RectF::default(); - self.closed = false; - } - - #[inline] - pub fn iter(&self, flags: ContourIterFlags) -> ContourIter { - ContourIter { - contour: self, - index: 1, - flags, - } - } - - #[inline] - pub fn is_empty(&self) -> bool { - self.points.is_empty() - } - - #[inline] - pub fn len(&self) -> u32 { - self.points.len() as u32 - } - - #[inline] - pub fn bounds(&self) -> RectF { - self.bounds - } - - #[inline] - pub fn is_closed(&self) -> bool { - self.closed - } - - #[inline] - pub fn position_of(&self, index: u32) -> Vector2F { - self.points[index as usize] - } - - #[inline] - pub fn last_position(&self) -> Option { - self.points.last().cloned() - } - - #[inline] - pub(crate) fn position_of_last(&self, index: u32) -> Vector2F { - self.points[self.points.len() - index as usize] - } - - #[inline] - pub fn push_endpoint(&mut self, point: Vector2F) { - self.push_point(point, PointFlags::empty(), true); - } - - #[inline] - pub fn push_quadratic(&mut self, ctrl: Vector2F, point: Vector2F) { - self.push_point(ctrl, PointFlags::CONTROL_POINT_0, true); - self.push_point(point, PointFlags::empty(), true); - } - - #[inline] - pub fn push_cubic(&mut self, ctrl0: Vector2F, ctrl1: Vector2F, point: Vector2F) { - self.push_point(ctrl0, PointFlags::CONTROL_POINT_0, true); - self.push_point(ctrl1, PointFlags::CONTROL_POINT_1, true); - self.push_point(point, PointFlags::empty(), true); - } - - #[inline] - pub fn close(&mut self) { - self.closed = true; - } - - #[inline] - pub(crate) fn push_point(&mut self, - point: Vector2F, - flags: PointFlags, - update_bounds: bool) { - debug_assert!(!point.x().is_nan() && !point.y().is_nan()); - - if update_bounds { - let first = self.is_empty(); - union_rect(&mut self.bounds, point, first); - } - - self.points.push(point); - self.flags.push(flags); - } - - #[inline] - pub(crate) fn push_segment(&mut self, segment: &Segment, flags: PushSegmentFlags) { - if segment.is_none() { - return; - } - - let update_bounds = flags.contains(PushSegmentFlags::UPDATE_BOUNDS); - self.push_point(segment.baseline.from(), PointFlags::empty(), update_bounds); - - if !segment.is_line() { - self.push_point( - segment.ctrl.from(), - PointFlags::CONTROL_POINT_0, - update_bounds, - ); - if !segment.is_quadratic() { - self.push_point( - segment.ctrl.to(), - PointFlags::CONTROL_POINT_1, - update_bounds, - ); - } - } - - self.push_point(segment.baseline.to(), PointFlags::empty(), update_bounds); - } - - pub fn push_arc(&mut self, - transform: &Transform2F, - start_angle: f32, - end_angle: f32, - direction: ArcDirection) { - if end_angle - start_angle >= PI * 2.0 { - self.push_ellipse(transform); - } else { - let start = vec2f(start_angle.cos(), start_angle.sin()); - let end = vec2f(end_angle.cos(), end_angle.sin()); - self.push_arc_from_unit_chord(transform, LineSegment2F::new(start, end), direction); - } - } - - pub fn push_arc_from_unit_chord(&mut self, - transform: &Transform2F, - mut chord: LineSegment2F, - direction: ArcDirection) { - let mut direction_transform = Transform2F::default(); - if direction == ArcDirection::CCW { - chord *= vec2f(1.0, -1.0); - direction_transform = Transform2F::from_scale(vec2f(1.0, -1.0)); - } - - let (mut vector, end_vector) = (UnitVector(chord.from()), UnitVector(chord.to())); - for segment_index in 0..4 { - debug!("push_arc_from_unit_chord(): loop segment index {}", segment_index); - - let mut sweep_vector = end_vector.rev_rotate_by(vector); - let last = sweep_vector.0.x() >= -EPSILON && sweep_vector.0.y() >= -EPSILON; - debug!("... end_vector={:?} vector={:?} sweep_vector={:?} last={:?}", - end_vector, - vector, - sweep_vector, - last); - - let mut segment; - if !last { - sweep_vector = UnitVector(vec2f(0.0, 1.0)); - segment = Segment::quarter_circle_arc(); - } else { - segment = Segment::arc_from_cos(sweep_vector.0.x()); - } - - let half_sweep_vector = sweep_vector.halve_angle(); - let rotation = Transform2F::from_rotation_vector(half_sweep_vector.rotate_by(vector)); - segment = segment.transform(&(*transform * direction_transform * rotation)); - - let mut push_segment_flags = PushSegmentFlags::UPDATE_BOUNDS; - if segment_index == 0 { - push_segment_flags.insert(PushSegmentFlags::INCLUDE_FROM_POINT); - } - self.push_segment(&segment, push_segment_flags); - - if last { - break; - } - - vector = vector.rotate_by(sweep_vector); - } - - const EPSILON: f32 = 0.001; - } - - pub fn push_ellipse(&mut self, transform: &Transform2F) { - let segment = Segment::quarter_circle_arc(); - let mut rotation; - self.push_segment(&segment.transform(transform), - PushSegmentFlags::UPDATE_BOUNDS | PushSegmentFlags::INCLUDE_FROM_POINT); - rotation = Transform2F::from_rotation_vector(UnitVector(vec2f( 0.0, 1.0))); - self.push_segment(&segment.transform(&(*transform * rotation)), - PushSegmentFlags::UPDATE_BOUNDS); - rotation = Transform2F::from_rotation_vector(UnitVector(vec2f(-1.0, 0.0))); - self.push_segment(&segment.transform(&(*transform * rotation)), - PushSegmentFlags::UPDATE_BOUNDS); - rotation = Transform2F::from_rotation_vector(UnitVector(vec2f( 0.0, -1.0))); - self.push_segment(&segment.transform(&(*transform * rotation)), - PushSegmentFlags::UPDATE_BOUNDS); - } - - #[inline] - pub fn segment_after(&self, point_index: u32) -> Segment { - debug_assert!(self.point_is_endpoint(point_index)); - - let mut segment = Segment::none(); - segment.baseline.set_from(self.position_of(point_index)); - - let point1_index = self.add_to_point_index(point_index, 1); - if self.point_is_endpoint(point1_index) { - segment.baseline.set_to(self.position_of(point1_index)); - segment.kind = SegmentKind::Line; - } else { - segment.ctrl.set_from(self.position_of(point1_index)); - - let point2_index = self.add_to_point_index(point_index, 2); - if self.point_is_endpoint(point2_index) { - segment.baseline.set_to(self.position_of(point2_index)); - segment.kind = SegmentKind::Quadratic; - } else { - segment.ctrl.set_to(self.position_of(point2_index)); - segment.kind = SegmentKind::Cubic; - - let point3_index = self.add_to_point_index(point_index, 3); - segment.baseline.set_to(self.position_of(point3_index)); - } - } - - segment - } - - #[inline] - pub fn hull_segment_after(&self, prev_point_index: u32) -> LineSegment2F { - let next_point_index = self.next_point_index_of(prev_point_index); - LineSegment2F::new( - self.points[prev_point_index as usize], - self.points[next_point_index as usize], - ) - } - - #[inline] - pub fn point_is_endpoint(&self, point_index: u32) -> bool { - !self.flags[point_index as usize] - .intersects(PointFlags::CONTROL_POINT_0 | PointFlags::CONTROL_POINT_1) - } - - #[inline] - pub fn add_to_point_index(&self, point_index: u32, addend: u32) -> u32 { - let (index, limit) = (point_index + addend, self.len()); - if index >= limit { - index - limit - } else { - index - } - } - - #[inline] - pub fn point_is_logically_above(&self, a: u32, b: u32) -> bool { - let (a_y, b_y) = (self.points[a as usize].y(), self.points[b as usize].y()); - a_y < b_y || (a_y == b_y && a < b) - } - - #[inline] - pub fn prev_endpoint_index_of(&self, mut point_index: u32) -> u32 { - loop { - point_index = self.prev_point_index_of(point_index); - if self.point_is_endpoint(point_index) { - return point_index; - } - } - } - - #[inline] - pub fn next_endpoint_index_of(&self, mut point_index: u32) -> u32 { - loop { - point_index = self.next_point_index_of(point_index); - if self.point_is_endpoint(point_index) { - return point_index; - } - } - } - - #[inline] - pub fn prev_point_index_of(&self, point_index: u32) -> u32 { - if point_index == 0 { - self.len() - 1 - } else { - point_index - 1 - } - } - - #[inline] - pub fn next_point_index_of(&self, point_index: u32) -> u32 { - if point_index == self.len() - 1 { - 0 - } else { - point_index + 1 - } - } - - pub fn transform(&mut self, transform: &Transform2F) { - if transform.is_identity() { - return; - } - - for (point_index, point) in self.points.iter_mut().enumerate() { - *point = *transform * *point; - union_rect(&mut self.bounds, *point, point_index == 0); - } - } - - pub fn apply_perspective(&mut self, perspective: &Perspective) { - for (point_index, point) in self.points.iter_mut().enumerate() { - *point = *perspective * *point; - union_rect(&mut self.bounds, *point, point_index == 0); - } - } - - pub fn dilate(&mut self, amount: Vector2F, orientation: Orientation) { - ContourDilator::new(self, amount, orientation).dilate(); - self.bounds = self.bounds.dilate(amount); - } - - fn prepare_for_tiling(&mut self, view_box: RectF) { - // Snap points to the view box bounds. This mops up floating point error from the clipping - // process. - let (mut last_endpoint_index, mut contour_is_monotonic) = (None, true); - for point_index in 0..(self.points.len() as u32) { - if contour_is_monotonic { - if self.point_is_endpoint(point_index) { - if let Some(last_endpoint_index) = last_endpoint_index { - if !self.curve_with_endpoints_is_monotonic(last_endpoint_index, - point_index) { - contour_is_monotonic = false; - } - } - last_endpoint_index = Some(point_index); - } - } - } - - // Convert to monotonic, if necessary. - if !contour_is_monotonic { - self.make_monotonic(); - } - - // Update bounds. - self.bounds = self - .bounds - .intersection(view_box) - .unwrap_or_else(|| RectF::default()); - } - - fn make_monotonic(&mut self) { - debug!("--- make_monotonic() ---"); - - let contour = self.take(); - self.bounds = contour.bounds; - - let mut last_endpoint_index = None; - let input_point_count = contour.points.len() as u32; - for point_index in 0..(input_point_count + 1) { - if point_index < input_point_count && !contour.point_is_endpoint(point_index) { - continue; - } - - if let Some(last_endpoint_index) = last_endpoint_index { - let position_index = if point_index == input_point_count { - 0 - } else { - point_index - }; - let baseline = LineSegment2F::new( - contour.points[last_endpoint_index as usize], - contour.points[position_index as usize], - ); - let point_count = point_index - last_endpoint_index + 1; - if point_count == 3 { - let ctrl_point_index = last_endpoint_index as usize + 1; - let ctrl_position = &contour.points[ctrl_point_index]; - handle_cubic( - self, - &Segment::quadratic(baseline, *ctrl_position).to_cubic(), - ); - } else if point_count == 4 { - let first_ctrl_point_index = last_endpoint_index as usize + 1; - let ctrl_position_0 = &contour.points[first_ctrl_point_index + 0]; - let ctrl_position_1 = &contour.points[first_ctrl_point_index + 1]; - let ctrl = LineSegment2F::new(*ctrl_position_0, *ctrl_position_1); - handle_cubic(self, &Segment::cubic(baseline, ctrl)); - } - - self.push_point( - contour.points[position_index as usize], - PointFlags::empty(), - false, - ); - } - - last_endpoint_index = Some(point_index); - } - - fn handle_cubic(contour: &mut Contour, segment: &Segment) { - debug!("handle_cubic({:?})", segment); - - match segment.as_cubic_segment().y_extrema() { - (Some(t0), Some(t1)) => { - let (segments_01, segment_2) = segment.as_cubic_segment().split(t1); - let (segment_0, segment_1) = segments_01.as_cubic_segment().split(t0 / t1); - contour.push_segment(&segment_0, PushSegmentFlags::empty()); - contour.push_segment(&segment_1, PushSegmentFlags::empty()); - contour.push_segment(&segment_2, PushSegmentFlags::empty()); - } - (Some(t0), None) | (None, Some(t0)) => { - let (segment_0, segment_1) = segment.as_cubic_segment().split(t0); - contour.push_segment(&segment_0, PushSegmentFlags::empty()); - contour.push_segment(&segment_1, PushSegmentFlags::empty()); - } - (None, None) => contour.push_segment(segment, PushSegmentFlags::empty()), - } - } - } - - fn curve_with_endpoints_is_monotonic( - &self, - start_endpoint_index: u32, - end_endpoint_index: u32, - ) -> bool { - let start_position = self.points[start_endpoint_index as usize]; - let end_position = self.points[end_endpoint_index as usize]; - - if start_position.x() <= end_position.x() { - for point_index in start_endpoint_index..end_endpoint_index { - if self.points[point_index as usize].x() > self.points[point_index as usize + 1].x() - { - return false; - } - } - } else { - for point_index in start_endpoint_index..end_endpoint_index { - if self.points[point_index as usize].x() < self.points[point_index as usize + 1].x() - { - return false; - } - } - } - - if start_position.y() <= end_position.y() { - for point_index in start_endpoint_index..end_endpoint_index { - if self.points[point_index as usize].y() > self.points[point_index as usize + 1].y() - { - return false; - } - } - } else { - for point_index in start_endpoint_index..end_endpoint_index { - if self.points[point_index as usize].y() < self.points[point_index as usize + 1].y() - { - return false; - } - } - } - - true - } - - // Use this function to keep bounds up to date when mutating paths. See `Outline::transform()` - // for an example of use. - pub(crate) fn update_bounds(&self, bounds: &mut Option) { - *bounds = Some(match *bounds { - None => self.bounds, - Some(bounds) => bounds.union_rect(self.bounds), - }) - } -} - -impl Debug for Contour { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - for (segment_index, segment) in self.iter(ContourIterFlags::IGNORE_CLOSE_SEGMENT) - .enumerate() { - if segment_index == 0 { - write!( - formatter, - "M {} {}", - segment.baseline.from_x(), - segment.baseline.from_y() - )?; - } - - match segment.kind { - SegmentKind::None => {} - SegmentKind::Line => { - write!( - formatter, - " L {} {}", - segment.baseline.to_x(), - segment.baseline.to_y() - )?; - } - SegmentKind::Quadratic => { - write!( - formatter, - " Q {} {} {} {}", - segment.ctrl.from_x(), - segment.ctrl.from_y(), - segment.baseline.to_x(), - segment.baseline.to_y() - )?; - } - SegmentKind::Cubic => { - write!( - formatter, - " C {} {} {} {} {} {}", - segment.ctrl.from_x(), - segment.ctrl.from_y(), - segment.ctrl.to_x(), - segment.ctrl.to_y(), - segment.baseline.to_x(), - segment.baseline.to_y() - )?; - } - } - } - - if self.closed { - write!(formatter, " z")?; - } - - Ok(()) - } -} - -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] -pub struct PointIndex(u32); - -impl PointIndex { - #[inline] - pub fn new(contour: u32, point: u32) -> PointIndex { - debug_assert!(contour <= 0xfff); - debug_assert!(point <= 0x000f_ffff); - PointIndex((contour << 20) | point) - } - - #[inline] - pub fn contour(self) -> u32 { - self.0 >> 20 - } - - #[inline] - pub fn point(self) -> u32 { - self.0 & 0x000f_ffff - } -} - -pub struct ContourIter<'a> { - contour: &'a Contour, - index: u32, - flags: ContourIterFlags, -} - -impl<'a> Iterator for ContourIter<'a> { - type Item = Segment; - - #[inline] - fn next(&mut self) -> Option { - let contour = self.contour; - - let include_close_segment = self.contour.closed && - !self.flags.contains(ContourIterFlags::IGNORE_CLOSE_SEGMENT); - if (self.index == contour.len() && !include_close_segment) || - self.index == contour.len() + 1 { - return None; - } - - let point0_index = self.index - 1; - let point0 = contour.position_of(point0_index); - if self.index == contour.len() { - let point1 = contour.position_of(0); - self.index += 1; - return Some(Segment::line(LineSegment2F::new(point0, point1))); - } - - let point1_index = self.index; - self.index += 1; - let point1 = contour.position_of(point1_index); - if contour.point_is_endpoint(point1_index) { - return Some(Segment::line(LineSegment2F::new(point0, point1))); - } - - let point2_index = self.index; - let point2 = contour.position_of(point2_index); - self.index += 1; - if contour.point_is_endpoint(point2_index) { - return Some(Segment::quadratic(LineSegment2F::new(point0, point2), point1)); - } - - let point3_index = self.index; - let point3 = contour.position_of(point3_index); - self.index += 1; - debug_assert!(contour.point_is_endpoint(point3_index)); - return Some(Segment::cubic( - LineSegment2F::new(point0, point3), - LineSegment2F::new(point1, point2), - )); - } -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum ArcDirection { - CW, - CCW, -} - -bitflags! { - pub struct ContourIterFlags: u8 { - const IGNORE_CLOSE_SEGMENT = 1; - } -} - -#[inline] -pub(crate) fn union_rect(bounds: &mut RectF, new_point: Vector2F, first: bool) { - if first { - *bounds = RectF::from_points(new_point, new_point); - } else { - *bounds = bounds.union_point(new_point) - } -} diff --git a/crates/pathfinder/content/src/pattern.rs b/crates/pathfinder/content/src/pattern.rs deleted file mode 100644 index cdd34205cf..0000000000 --- a/crates/pathfinder/content/src/pattern.rs +++ /dev/null @@ -1,226 +0,0 @@ -// pathfinder/content/src/pattern.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Raster image patterns. - -use crate::effects::PatternFilter; -use crate::render_target::RenderTargetId; -use crate::util; -use pathfinder_color::{self as color, ColorU}; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::vector::{Vector2I, vec2i}; -use std::collections::hash_map::DefaultHasher; -use std::fmt::{self, Debug, Formatter}; -use std::hash::{Hash, Hasher}; -use std::sync::Arc; - -#[cfg(feature = "pf-image")] -use image::RgbaImage; - -/// A raster image pattern. -#[derive(Clone, PartialEq, Debug)] -pub struct Pattern { - source: PatternSource, - transform: Transform2F, - filter: Option, - flags: PatternFlags, -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub enum PatternSource { - Image(Image), - RenderTarget { - id: RenderTargetId, - size: Vector2I, - } -} - -/// RGBA, non-premultiplied. -// FIXME(pcwalton): Hash the pixel contents so that we don't have to compare every pixel! -// TODO(pcwalton): Should the pixels be premultiplied? -#[derive(Clone, PartialEq, Eq)] -pub struct Image { - size: Vector2I, - pixels: Arc>, - pixels_hash: u64, - is_opaque: bool, -} - -bitflags! { - pub struct PatternFlags: u8 { - const REPEAT_X = 0x01; - const REPEAT_Y = 0x02; - const NO_SMOOTHING = 0x04; - } -} - -impl Pattern { - #[inline] - fn from_source(source: PatternSource) -> Pattern { - Pattern { - source, - transform: Transform2F::default(), - filter: None, - flags: PatternFlags::empty(), - } - } - - #[inline] - pub fn from_image(image: Image) -> Pattern { - Pattern::from_source(PatternSource::Image(image)) - } - - #[inline] - pub fn from_render_target(id: RenderTargetId, size: Vector2I) -> Pattern { - Pattern::from_source(PatternSource::RenderTarget { id, size }) - } - - #[inline] - pub fn transform(&self) -> Transform2F { - self.transform - } - - #[inline] - pub fn apply_transform(&mut self, transform: Transform2F) { - self.transform = transform * self.transform; - } - - #[inline] - pub fn size(&self) -> Vector2I { - match self.source { - PatternSource::Image(ref image) => image.size(), - PatternSource::RenderTarget { size, .. } => size, - } - } - - #[inline] - pub fn filter(&self) -> Option { - self.filter - } - - #[inline] - pub fn set_filter(&mut self, filter: Option) { - self.filter = filter; - } - - #[inline] - pub fn repeat_x(&self) -> bool { - self.flags.contains(PatternFlags::REPEAT_X) - } - - #[inline] - pub fn set_repeat_x(&mut self, repeat_x: bool) { - self.flags.set(PatternFlags::REPEAT_X, repeat_x); - } - - #[inline] - pub fn repeat_y(&self) -> bool { - self.flags.contains(PatternFlags::REPEAT_Y) - } - - #[inline] - pub fn set_repeat_y(&mut self, repeat_y: bool) { - self.flags.set(PatternFlags::REPEAT_Y, repeat_y); - } - - #[inline] - pub fn smoothing_enabled(&self) -> bool { - !self.flags.contains(PatternFlags::NO_SMOOTHING) - } - - #[inline] - pub fn set_smoothing_enabled(&mut self, enable: bool) { - self.flags.set(PatternFlags::NO_SMOOTHING, !enable); - } - - #[inline] - pub fn is_opaque(&self) -> bool { - self.source.is_opaque() - } - - #[inline] - pub fn source(&self) -> &PatternSource { - &self.source - } -} - -impl Image { - #[inline] - pub fn new(size: Vector2I, pixels: Arc>) -> Image { - assert_eq!(size.x() as usize * size.y() as usize, pixels.len()); - let is_opaque = pixels.iter().all(|pixel| pixel.is_opaque()); - - let mut pixels_hasher = DefaultHasher::new(); - pixels.hash(&mut pixels_hasher); - let pixels_hash = pixels_hasher.finish(); - - Image { size, pixels, pixels_hash, is_opaque } - } - - #[cfg(feature = "pf-image")] - pub fn from_image_buffer(image_buffer: RgbaImage) -> Image { - let (width, height) = image_buffer.dimensions(); - let pixels = color::u8_vec_to_color_vec(image_buffer.into_raw()); - Image::new(vec2i(width as i32, height as i32), Arc::new(pixels)) - } - - #[inline] - pub fn size(&self) -> Vector2I { - self.size - } - - #[inline] - pub fn pixels(&self) -> &Arc> { - &self.pixels - } - - #[inline] - pub fn is_opaque(&self) -> bool { - self.is_opaque - } -} - -impl PatternSource { - #[inline] - pub fn is_opaque(&self) -> bool { - match *self { - PatternSource::Image(ref image) => image.is_opaque(), - PatternSource::RenderTarget { .. } => { - // TODO(pcwalton): Maybe do something smarter here? - false - } - } - } -} - -impl Debug for Image { - #[inline] - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - write!(formatter, "(image {}×{} px)", self.size.x(), self.size.y()) - } -} - -impl Hash for Image { - fn hash(&self, hasher: &mut H) where H: Hasher { - self.size.hash(hasher); - self.pixels_hash.hash(hasher); - self.is_opaque.hash(hasher); - } -} - -impl Eq for Pattern {} - -impl Hash for Pattern { - fn hash(&self, state: &mut H) where H: Hasher { - self.source.hash(state); - util::hash_transform2f(self.transform, state); - self.flags.hash(state); - } -} diff --git a/crates/pathfinder/content/src/render_target.rs b/crates/pathfinder/content/src/render_target.rs deleted file mode 100644 index ffd1b88f65..0000000000 --- a/crates/pathfinder/content/src/render_target.rs +++ /dev/null @@ -1,17 +0,0 @@ -// pathfinder/content/src/render_target.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Render targets. - -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -pub struct RenderTargetId { - pub scene: u32, - pub render_target: u32, -} diff --git a/crates/pathfinder/content/src/segment.rs b/crates/pathfinder/content/src/segment.rs deleted file mode 100644 index 3c607f7990..0000000000 --- a/crates/pathfinder/content/src/segment.rs +++ /dev/null @@ -1,426 +0,0 @@ -// pathfinder/content/src/segment.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Line or curve segments, optimized with SIMD. - -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::util::{self, EPSILON}; -use pathfinder_geometry::vector::{Vector2F, vec2f}; -use pathfinder_simd::default::F32x4; -use std::f32::consts::SQRT_2; - -const MAX_NEWTON_ITERATIONS: u32 = 32; - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct Segment { - pub baseline: LineSegment2F, - pub ctrl: LineSegment2F, - pub kind: SegmentKind, - pub flags: SegmentFlags, -} - -impl Segment { - #[inline] - pub fn none() -> Segment { - Segment { - baseline: LineSegment2F::default(), - ctrl: LineSegment2F::default(), - kind: SegmentKind::None, - flags: SegmentFlags::empty(), - } - } - - #[inline] - pub fn line(line: LineSegment2F) -> Segment { - Segment { - baseline: line, - ctrl: LineSegment2F::default(), - kind: SegmentKind::Line, - flags: SegmentFlags::empty(), - } - } - - #[inline] - pub fn quadratic(baseline: LineSegment2F, ctrl: Vector2F) -> Segment { - Segment { - baseline, - ctrl: LineSegment2F::new(ctrl, Vector2F::zero()), - kind: SegmentKind::Quadratic, - flags: SegmentFlags::empty(), - } - } - - #[inline] - pub fn cubic(baseline: LineSegment2F, ctrl: LineSegment2F) -> Segment { - Segment { - baseline, - ctrl, - kind: SegmentKind::Cubic, - flags: SegmentFlags::empty(), - } - } - - /// Approximates an unit-length arc with a cubic Bézier curve. - /// - /// The maximum supported sweep angle is π/2 (i.e. 90°). - pub fn arc(sweep_angle: f32) -> Segment { - Segment::arc_from_cos(f32::cos(sweep_angle)) - } - - /// Approximates an unit-length arc with a cubic Bézier curve, given the cosine of the sweep - /// angle. - /// - /// The maximum supported sweep angle is π/2 (i.e. 90°). - pub fn arc_from_cos(cos_sweep_angle: f32) -> Segment { - // Richard A. DeVeneza, "How to determine the control points of a Bézier curve that - // approximates a small arc", 2004. - // - // https://www.tinaja.com/glib/bezcirc2.pdf - if cos_sweep_angle >= 1.0 - EPSILON { - return Segment::line(LineSegment2F::new(vec2f(1.0, 0.0), vec2f(1.0, 0.0))); - } - - let term = F32x4::new(cos_sweep_angle, -cos_sweep_angle, - cos_sweep_angle, -cos_sweep_angle); - let signs = F32x4::new(1.0, -1.0, 1.0, 1.0); - let p3p0 = ((F32x4::splat(1.0) + term) * F32x4::splat(0.5)).sqrt() * signs; - let (p0x, p0y) = (p3p0.z(), p3p0.w()); - let (p1x, p1y) = (4.0 - p0x, (1.0 - p0x) * (3.0 - p0x) / p0y); - let p2p1 = F32x4::new(p1x, -p1y, p1x, p1y) * F32x4::splat(1.0 / 3.0); - return Segment::cubic(LineSegment2F(p3p0), LineSegment2F(p2p1)); - } - - #[inline] - pub fn quarter_circle_arc() -> Segment { - let p0 = Vector2F::splat(SQRT_2 * 0.5); - let p1 = vec2f(-SQRT_2 / 6.0 + 4.0 / 3.0, 7.0 * SQRT_2 / 6.0 - 4.0 / 3.0); - let flip = vec2f(1.0, -1.0); - let (p2, p3) = (p1 * flip, p0 * flip); - Segment::cubic(LineSegment2F::new(p3, p0), LineSegment2F::new(p2, p1)) - } - - #[inline] - pub fn as_line_segment(&self) -> LineSegment2F { - debug_assert!(self.is_line()); - self.baseline - } - - #[inline] - pub fn is_none(&self) -> bool { - self.kind == SegmentKind::None - } - - #[inline] - pub fn is_line(&self) -> bool { - self.kind == SegmentKind::Line - } - - #[inline] - pub fn is_quadratic(&self) -> bool { - self.kind == SegmentKind::Quadratic - } - - #[inline] - pub fn is_cubic(&self) -> bool { - self.kind == SegmentKind::Cubic - } - - #[inline] - pub fn as_cubic_segment(&self) -> CubicSegment { - debug_assert!(self.is_cubic()); - CubicSegment(self) - } - - // FIXME(pcwalton): We should basically never use this function. - // FIXME(pcwalton): Handle lines! - #[inline] - pub fn to_cubic(&self) -> Segment { - if self.is_cubic() { - return *self; - } - - let mut new_segment = *self; - let p1_2 = self.ctrl.from() + self.ctrl.from(); - new_segment.ctrl = LineSegment2F::new(self.baseline.from() + p1_2, - p1_2 + self.baseline.to()) * (1.0 / 3.0); - new_segment.kind = SegmentKind::Cubic; - new_segment - } - - #[inline] - pub fn is_monotonic(&self) -> bool { - // FIXME(pcwalton): Don't degree elevate! - match self.kind { - SegmentKind::None | SegmentKind::Line => true, - SegmentKind::Quadratic => self.to_cubic().as_cubic_segment().is_monotonic(), - SegmentKind::Cubic => self.as_cubic_segment().is_monotonic(), - } - } - - #[inline] - pub fn reversed(&self) -> Segment { - Segment { - baseline: self.baseline.reversed(), - ctrl: if self.is_quadratic() { - self.ctrl - } else { - self.ctrl.reversed() - }, - kind: self.kind, - flags: self.flags, - } - } - - // Reverses if necessary so that the from point is above the to point. Calling this method - // again will undo the transformation. - #[inline] - pub fn orient(&self, y_winding: i32) -> Segment { - if y_winding >= 0 { - *self - } else { - self.reversed() - } - } - - #[inline] - pub fn is_tiny(&self) -> bool { - const EPSILON: f32 = 0.0001; - self.baseline.square_length() < EPSILON - } - - #[inline] - pub fn split(&self, t: f32) -> (Segment, Segment) { - // FIXME(pcwalton): Don't degree elevate! - if self.is_line() { - let (before, after) = self.as_line_segment().split(t); - (Segment::line(before), Segment::line(after)) - } else { - self.to_cubic().as_cubic_segment().split(t) - } - } - - #[inline] - pub fn sample(self, t: f32) -> Vector2F { - // FIXME(pcwalton): Don't degree elevate! - if self.is_line() { - self.as_line_segment().sample(t) - } else { - self.to_cubic().as_cubic_segment().sample(t) - } - } - - #[inline] - pub fn transform(self, transform: &Transform2F) -> Segment { - Segment { - baseline: *transform * self.baseline, - ctrl: *transform * self.ctrl, - kind: self.kind, - flags: self.flags, - } - } - - pub fn arc_length(&self) -> f32 { - // FIXME(pcwalton) - self.baseline.vector().length() - } - - pub fn time_for_distance(&self, distance: f32) -> f32 { - // FIXME(pcwalton) - distance / self.arc_length() - } -} - -#[derive(Clone, Copy, Debug, PartialEq)] -#[repr(u8)] -pub enum SegmentKind { - None, - Line, - Quadratic, - Cubic, -} - -bitflags! { - pub struct SegmentFlags: u8 { - const FIRST_IN_SUBPATH = 0x01; - const CLOSES_SUBPATH = 0x02; - } -} - -#[derive(Clone, Copy, Debug)] -pub struct CubicSegment<'s>(pub &'s Segment); - -impl<'s> CubicSegment<'s> { - // See Kaspar Fischer, "Piecewise Linear Approximation of Bézier Curves", 2000. - #[inline] - pub fn is_flat(self, tolerance: f32) -> bool { - let mut uv = F32x4::splat(3.0) * self.0.ctrl.0 - - self.0.baseline.0 - - self.0.baseline.0 - - self.0.baseline.reversed().0; - uv = uv * uv; - uv = uv.max(uv.zwxy()); - uv[0] + uv[1] <= 16.0 * tolerance * tolerance - } - - #[inline] - pub fn split(self, t: f32) -> (Segment, Segment) { - let (baseline0, ctrl0, baseline1, ctrl1); - if t <= 0.0 { - let from = &self.0.baseline.from(); - baseline0 = LineSegment2F::new(*from, *from); - ctrl0 = LineSegment2F::new(*from, *from); - baseline1 = self.0.baseline; - ctrl1 = self.0.ctrl; - } else if t >= 1.0 { - let to = &self.0.baseline.to(); - baseline0 = self.0.baseline; - ctrl0 = self.0.ctrl; - baseline1 = LineSegment2F::new(*to, *to); - ctrl1 = LineSegment2F::new(*to, *to); - } else { - let tttt = F32x4::splat(t); - - let (p0p3, p1p2) = (self.0.baseline.0, self.0.ctrl.0); - let p0p1 = p0p3.concat_xy_xy(p1p2); - - // p01 = lerp(p0, p1, t), p12 = lerp(p1, p2, t), p23 = lerp(p2, p3, t) - let p01p12 = p0p1 + tttt * (p1p2 - p0p1); - let pxxp23 = p1p2 + tttt * (p0p3 - p1p2); - let p12p23 = p01p12.concat_zw_zw(pxxp23); - - // p012 = lerp(p01, p12, t), p123 = lerp(p12, p23, t) - let p012p123 = p01p12 + tttt * (p12p23 - p01p12); - let p123 = p012p123.zwzw(); - - // p0123 = lerp(p012, p123, t) - let p0123 = p012p123 + tttt * (p123 - p012p123); - - baseline0 = LineSegment2F(p0p3.concat_xy_xy(p0123)); - ctrl0 = LineSegment2F(p01p12.concat_xy_xy(p012p123)); - baseline1 = LineSegment2F(p0123.concat_xy_zw(p0p3)); - ctrl1 = LineSegment2F(p012p123.concat_zw_zw(p12p23)); - } - - ( - Segment { - baseline: baseline0, - ctrl: ctrl0, - kind: SegmentKind::Cubic, - flags: self.0.flags & SegmentFlags::FIRST_IN_SUBPATH, - }, - Segment { - baseline: baseline1, - ctrl: ctrl1, - kind: SegmentKind::Cubic, - flags: self.0.flags & SegmentFlags::CLOSES_SUBPATH, - }, - ) - } - - #[inline] - pub fn split_before(self, t: f32) -> Segment { - self.split(t).0 - } - - #[inline] - pub fn split_after(self, t: f32) -> Segment { - self.split(t).1 - } - - // FIXME(pcwalton): Use Horner's method! - #[inline] - pub fn sample(self, t: f32) -> Vector2F { - self.split(t).0.baseline.to() - } - - #[inline] - pub fn is_monotonic(self) -> bool { - // TODO(pcwalton): Optimize this. - let (p0, p3) = (self.0.baseline.from_y(), self.0.baseline.to_y()); - let (p1, p2) = (self.0.ctrl.from_y(), self.0.ctrl.to_y()); - (p0 <= p1 && p1 <= p2 && p2 <= p3) || (p0 >= p1 && p1 >= p2 && p2 >= p3) - } - - #[inline] - pub fn y_extrema(self) -> (Option, Option) { - if self.is_monotonic() { - return (None, None); - } - - let p0p1p2p3 = F32x4::new( - self.0.baseline.from_y(), - self.0.ctrl.from_y(), - self.0.ctrl.to_y(), - self.0.baseline.to_y(), - ); - - let pxp0p1p2 = p0p1p2p3.wxyz(); - let pxv0v1v2 = p0p1p2p3 - pxp0p1p2; - let (v0, v1, v2) = (pxv0v1v2[1], pxv0v1v2[2], pxv0v1v2[3]); - - let (t0, t1); - let (v0_to_v1, v2_to_v1) = (v0 - v1, v2 - v1); - let denom = v0_to_v1 + v2_to_v1; - - if util::approx_eq(denom, 0.0) { - // Let's not divide by zero (issue #146). Fall back to Newton's method. - // FIXME(pcwalton): Can we have two roots here? - let mut t = 0.5; - for _ in 0..MAX_NEWTON_ITERATIONS { - let dydt = 3.0 * ((denom * t - v0_to_v1 - v0_to_v1) * t + v0); - if f32::abs(dydt) <= EPSILON { - break - } - let d2ydt2 = 6.0 * (denom * t - v0_to_v1); - t -= dydt / d2ydt2; - } - t0 = t; - t1 = 0.0; - debug!("... t=(newton) {}", t); - } else { - // Algebraically compute the values for t. - let discrim = f32::sqrt(v1 * v1 - v0 * v2); - let denom_recip = 1.0 / denom; - - t0 = (v0_to_v1 + discrim) * denom_recip; - t1 = (v0_to_v1 - discrim) * denom_recip; - - debug!("... t=({} +/- {})/{} t0={} t1={}", v0_to_v1, discrim, denom, t0, t1); - } - - return match ( - t0 > EPSILON && t0 < 1.0 - EPSILON, - t1 > EPSILON && t1 < 1.0 - EPSILON, - ) { - (false, false) => (None, None), - (true, false) => (Some(t0), None), - (false, true) => (Some(t1), None), - (true, true) => (Some(f32::min(t0, t1)), Some(f32::max(t0, t1))), - }; - } - - #[inline] - pub fn min_x(&self) -> f32 { - f32::min(self.0.baseline.min_x(), self.0.ctrl.min_x()) - } - #[inline] - pub fn min_y(&self) -> f32 { - f32::min(self.0.baseline.min_y(), self.0.ctrl.min_y()) - } - #[inline] - pub fn max_x(&self) -> f32 { - f32::max(self.0.baseline.max_x(), self.0.ctrl.max_x()) - } - #[inline] - pub fn max_y(&self) -> f32 { - f32::max(self.0.baseline.max_y(), self.0.ctrl.max_y()) - } -} diff --git a/crates/pathfinder/content/src/sorted_vector.rs b/crates/pathfinder/content/src/sorted_vector.rs deleted file mode 100644 index 21c584f515..0000000000 --- a/crates/pathfinder/content/src/sorted_vector.rs +++ /dev/null @@ -1,100 +0,0 @@ -// pathfinder/content/src/sorted_vector.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A vector that maintains sorted order with insertion sort. - -use std::cmp::Ordering; -use std::convert; - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct SortedVector -where - T: PartialOrd, -{ - pub array: Vec, -} - -impl SortedVector -where - T: PartialOrd, -{ - #[inline] - pub fn new() -> SortedVector { - SortedVector { array: vec![] } - } - - #[inline] - pub fn push(&mut self, value: T) { - let index = self.binary_search_by(|other| { - other.partial_cmp(&value).unwrap_or(Ordering::Less) - }).unwrap_or_else(convert::identity); - self.array.insert(index, value); - } - - #[inline] - pub fn peek(&self) -> Option<&T> { - self.array.last() - } - - #[inline] - pub fn pop(&mut self) -> Option { - self.array.pop() - } - - #[inline] - pub fn clear(&mut self) { - self.array.clear() - } - - #[allow(dead_code)] - #[inline] - pub fn is_empty(&self) -> bool { - self.array.is_empty() - } - - #[inline] - pub fn len(&self) -> usize { - self.array.len() - } - - #[inline] - pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result - where F: FnMut(&'a T) -> Ordering { - self.array.binary_search_by(f) - } -} - -#[cfg(test)] -mod test { - use crate::sorted_vector::SortedVector; - use quickcheck; - - #[test] - fn test_sorted_vec() { - quickcheck::quickcheck(prop_sorted_vec as fn(Vec) -> bool); - - fn prop_sorted_vec(mut values: Vec) -> bool { - let mut sorted_vec = SortedVector::new(); - for &value in &values { - sorted_vec.push(value) - } - - values.sort(); - let mut results = Vec::with_capacity(values.len()); - while !sorted_vec.is_empty() { - results.push(sorted_vec.pop().unwrap()); - } - results.reverse(); - assert_eq!(&values, &results); - - true - } - } -} diff --git a/crates/pathfinder/content/src/stroke.rs b/crates/pathfinder/content/src/stroke.rs deleted file mode 100644 index 385fbecf3d..0000000000 --- a/crates/pathfinder/content/src/stroke.rs +++ /dev/null @@ -1,428 +0,0 @@ -// pathfinder/content/src/stroke.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Utilities for converting path strokes to fills. - -use crate::outline::{ArcDirection, Contour, ContourIterFlags, Outline, PushSegmentFlags}; -use crate::segment::Segment; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::util::EPSILON; -use pathfinder_geometry::vector::{Vector2F, vec2f}; -use std::f32; - -const TOLERANCE: f32 = 0.01; - -pub struct OutlineStrokeToFill<'a> { - input: &'a Outline, - output: Outline, - style: StrokeStyle, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct StrokeStyle { - pub line_width: f32, - pub line_cap: LineCap, - pub line_join: LineJoin, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum LineCap { - Butt, - Square, - Round, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum LineJoin { - Miter(f32), - Bevel, - Round, -} - -impl<'a> OutlineStrokeToFill<'a> { - #[inline] - pub fn new(input: &Outline, style: StrokeStyle) -> OutlineStrokeToFill { - OutlineStrokeToFill { input, output: Outline::new(), style } - } - - pub fn offset(&mut self) { - let mut new_contours = vec![]; - for input in &self.input.contours { - let closed = input.closed; - let mut stroker = ContourStrokeToFill::new(input, - Contour::new(), - self.style.line_width * 0.5, - self.style.line_join); - - stroker.offset_forward(); - if closed { - self.push_stroked_contour(&mut new_contours, stroker, true); - stroker = ContourStrokeToFill::new(input, - Contour::new(), - self.style.line_width * 0.5, - self.style.line_join); - } else { - self.add_cap(&mut stroker.output); - } - - stroker.offset_backward(); - if !closed { - self.add_cap(&mut stroker.output); - } - - self.push_stroked_contour(&mut new_contours, stroker, closed); - } - - let mut new_bounds = None; - new_contours.iter().for_each(|contour| contour.update_bounds(&mut new_bounds)); - - self.output.contours = new_contours; - self.output.bounds = new_bounds.unwrap_or_else(|| RectF::default()); - } - - #[inline] - pub fn into_outline(self) -> Outline { - self.output - } - - fn push_stroked_contour(&mut self, - new_contours: &mut Vec, - mut stroker: ContourStrokeToFill, - closed: bool) { - // Add join if necessary. - if closed && stroker.output.might_need_join(self.style.line_join) { - let (p1, p0) = (stroker.output.position_of(1), stroker.output.position_of(0)); - let final_segment = LineSegment2F::new(p1, p0); - stroker.output.add_join(self.style.line_width * 0.5, - self.style.line_join, - stroker.input.position_of(0), - final_segment); - } - - stroker.output.closed = true; - new_contours.push(stroker.output); - } - - fn add_cap(&mut self, contour: &mut Contour) { - if self.style.line_cap == LineCap::Butt || contour.len() < 2 { - return - } - - let width = self.style.line_width; - let p1 = contour.position_of_last(1); - - // Determine the ending gradient. - let mut p0; - let mut p0_index = contour.len() - 2; - loop { - p0 = contour.position_of(p0_index); - if (p1 - p0).square_length() > EPSILON { - break; - } - if p0_index == 0 { - return; - } - p0_index -= 1; - } - let gradient = (p1 - p0).normalize(); - - match self.style.line_cap { - LineCap::Butt => unreachable!(), - - LineCap::Square => { - let offset = gradient * (width * 0.5); - - let p2 = p1 + offset; - let p3 = p2 + gradient.yx() * vec2f(-width, width); - let p4 = p3 - offset; - - contour.push_endpoint(p2); - contour.push_endpoint(p3); - contour.push_endpoint(p4); - } - - LineCap::Round => { - let scale = width * 0.5; - let offset = gradient.yx() * vec2f(-1.0, 1.0); - let translation = p1 + offset * (width * 0.5); - let transform = Transform2F::from_scale(scale).translate(translation); - let chord = LineSegment2F::new(-offset, offset); - contour.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW); - } - } - } -} - -struct ContourStrokeToFill<'a> { - input: &'a Contour, - output: Contour, - radius: f32, - join: LineJoin, -} - -impl<'a> ContourStrokeToFill<'a> { - #[inline] - fn new(input: &Contour, output: Contour, radius: f32, join: LineJoin) -> ContourStrokeToFill { - ContourStrokeToFill { input, output, radius, join } - } - - fn offset_forward(&mut self) { - for (segment_index, segment) in self.input.iter(ContourIterFlags::empty()).enumerate() { - // FIXME(pcwalton): We negate the radius here so that round end caps can be drawn - // clockwise. Of course, we should just implement anticlockwise arcs to begin with... - let join = if segment_index == 0 { LineJoin::Bevel } else { self.join }; - segment.offset(-self.radius, join, &mut self.output); - } - } - - fn offset_backward(&mut self) { - let mut segments: Vec<_> = self - .input - .iter(ContourIterFlags::empty()) - .map(|segment| segment.reversed()) - .collect(); - segments.reverse(); - for (segment_index, segment) in segments.iter().enumerate() { - // FIXME(pcwalton): We negate the radius here so that round end caps can be drawn - // clockwise. Of course, we should just implement anticlockwise arcs to begin with... - let join = if segment_index == 0 { LineJoin::Bevel } else { self.join }; - segment.offset(-self.radius, join, &mut self.output); - } - } -} - -trait Offset { - fn offset(&self, distance: f32, join: LineJoin, contour: &mut Contour); - fn add_to_contour(&self, - distance: f32, - join: LineJoin, - join_point: Vector2F, - contour: &mut Contour); - fn offset_once(&self, distance: f32) -> Self; - fn error_is_within_tolerance(&self, other: &Segment, distance: f32) -> bool; -} - -impl Offset for Segment { - fn offset(&self, distance: f32, join: LineJoin, contour: &mut Contour) { - let join_point = self.baseline.from(); - if self.baseline.square_length() < TOLERANCE * TOLERANCE { - self.add_to_contour(distance, join, join_point, contour); - return; - } - - let candidate = self.offset_once(distance); - if self.error_is_within_tolerance(&candidate, distance) { - candidate.add_to_contour(distance, join, join_point, contour); - return; - } - - debug!("--- SPLITTING ---"); - debug!("... PRE-SPLIT: {:?}", self); - let (before, after) = self.split(0.5); - debug!("... AFTER-SPLIT: {:?} {:?}", before, after); - before.offset(distance, join, contour); - after.offset(distance, join, contour); - } - - fn add_to_contour(&self, - distance: f32, - join: LineJoin, - join_point: Vector2F, - contour: &mut Contour) { - // Add join if necessary. - if contour.might_need_join(join) { - let p3 = self.baseline.from(); - let p4 = if self.is_line() { - self.baseline.to() - } else { - // NB: If you change the representation of quadratic curves, you will need to - // change this. - self.ctrl.from() - }; - - contour.add_join(distance, join, join_point, LineSegment2F::new(p4, p3)); - } - - // Push segment. - let flags = PushSegmentFlags::UPDATE_BOUNDS | PushSegmentFlags::INCLUDE_FROM_POINT; - contour.push_segment(self, flags); - } - - fn offset_once(&self, distance: f32) -> Segment { - if self.is_line() { - return Segment::line(self.baseline.offset(distance)); - } - - if self.is_quadratic() { - let mut segment_0 = LineSegment2F::new(self.baseline.from(), self.ctrl.from()); - let mut segment_1 = LineSegment2F::new(self.ctrl.from(), self.baseline.to()); - segment_0 = segment_0.offset(distance); - segment_1 = segment_1.offset(distance); - let ctrl = match segment_0.intersection_t(segment_1) { - Some(t) => segment_0.sample(t), - None => segment_0.to().lerp(segment_1.from(), 0.5), - }; - let baseline = LineSegment2F::new(segment_0.from(), segment_1.to()); - return Segment::quadratic(baseline, ctrl); - } - - debug_assert!(self.is_cubic()); - - if self.baseline.from() == self.ctrl.from() { - let mut segment_0 = LineSegment2F::new(self.baseline.from(), self.ctrl.to()); - let mut segment_1 = LineSegment2F::new(self.ctrl.to(), self.baseline.to()); - segment_0 = segment_0.offset(distance); - segment_1 = segment_1.offset(distance); - let ctrl = match segment_0.intersection_t(segment_1) { - Some(t) => segment_0.sample(t), - None => segment_0.to().lerp(segment_1.from(), 0.5), - }; - let baseline = LineSegment2F::new(segment_0.from(), segment_1.to()); - let ctrl = LineSegment2F::new(segment_0.from(), ctrl); - return Segment::cubic(baseline, ctrl); - } - - if self.ctrl.to() == self.baseline.to() { - let mut segment_0 = LineSegment2F::new(self.baseline.from(), self.ctrl.from()); - let mut segment_1 = LineSegment2F::new(self.ctrl.from(), self.baseline.to()); - segment_0 = segment_0.offset(distance); - segment_1 = segment_1.offset(distance); - let ctrl = match segment_0.intersection_t(segment_1) { - Some(t) => segment_0.sample(t), - None => segment_0.to().lerp(segment_1.from(), 0.5), - }; - let baseline = LineSegment2F::new(segment_0.from(), segment_1.to()); - let ctrl = LineSegment2F::new(ctrl, segment_1.to()); - return Segment::cubic(baseline, ctrl); - } - - let mut segment_0 = LineSegment2F::new(self.baseline.from(), self.ctrl.from()); - let mut segment_1 = LineSegment2F::new(self.ctrl.from(), self.ctrl.to()); - let mut segment_2 = LineSegment2F::new(self.ctrl.to(), self.baseline.to()); - segment_0 = segment_0.offset(distance); - segment_1 = segment_1.offset(distance); - segment_2 = segment_2.offset(distance); - let (ctrl_0, ctrl_1) = match ( - segment_0.intersection_t(segment_1), - segment_1.intersection_t(segment_2), - ) { - (Some(t0), Some(t1)) => (segment_0.sample(t0), segment_1.sample(t1)), - _ => ( - segment_0.to().lerp(segment_1.from(), 0.5), - segment_1.to().lerp(segment_2.from(), 0.5), - ), - }; - let baseline = LineSegment2F::new(segment_0.from(), segment_2.to()); - let ctrl = LineSegment2F::new(ctrl_0, ctrl_1); - Segment::cubic(baseline, ctrl) - } - - fn error_is_within_tolerance(&self, other: &Segment, distance: f32) -> bool { - let (mut min, mut max) = ( - f32::abs(distance) - TOLERANCE, - f32::abs(distance) + TOLERANCE, - ); - min = if min <= 0.0 { 0.0 } else { min * min }; - max = if max <= 0.0 { 0.0 } else { max * max }; - - for t_num in 0..(SAMPLE_COUNT + 1) { - let t = t_num as f32 / SAMPLE_COUNT as f32; - // FIXME(pcwalton): Use signed distance! - let (this_p, other_p) = (self.sample(t), other.sample(t)); - let vector = this_p - other_p; - let square_distance = vector.square_length(); - debug!( - "this_p={:?} other_p={:?} vector={:?} sqdist={:?} min={:?} max={:?}", - this_p, other_p, vector, square_distance, min, max - ); - if square_distance < min || square_distance > max { - return false; - } - } - - return true; - - const SAMPLE_COUNT: u32 = 16; - } -} - -impl Contour { - fn might_need_join(&self, join: LineJoin) -> bool { - if self.len() < 2 { - false - } else { - match join { - LineJoin::Miter(_) | LineJoin::Round => true, - LineJoin::Bevel => false, - } - } - } - - fn add_join(&mut self, - distance: f32, - join: LineJoin, - join_point: Vector2F, - next_tangent: LineSegment2F) { - let (p0, p1) = (self.position_of_last(2), self.position_of_last(1)); - let prev_tangent = LineSegment2F::new(p0, p1); - - if prev_tangent.square_length() < EPSILON || next_tangent.square_length() < EPSILON { - return; - } - - match join { - LineJoin::Bevel => {} - LineJoin::Miter(miter_limit) => { - if let Some(prev_tangent_t) = prev_tangent.intersection_t(next_tangent) { - if prev_tangent_t < -EPSILON { - return; - } - let miter_endpoint = prev_tangent.sample(prev_tangent_t); - let threshold = miter_limit * distance; - if (miter_endpoint - join_point).square_length() > threshold * threshold { - return; - } - self.push_endpoint(miter_endpoint); - } - } - LineJoin::Round => { - let scale = distance.abs(); - let transform = Transform2F::from_scale(scale).translate(join_point); - let chord_from = (prev_tangent.to() - join_point).normalize(); - let chord_to = (next_tangent.to() - join_point).normalize(); - let chord = LineSegment2F::new(chord_from, chord_to); - self.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW); - } - } - } -} - -impl Default for StrokeStyle { - #[inline] - fn default() -> StrokeStyle { - StrokeStyle { - line_width: 1.0, - line_cap: LineCap::default(), - line_join: LineJoin::default(), - } - } -} - -impl Default for LineCap { - #[inline] - fn default() -> LineCap { LineCap::Butt } -} - -impl Default for LineJoin { - #[inline] - fn default() -> LineJoin { LineJoin::Miter(10.0) } -} diff --git a/crates/pathfinder/content/src/transform.rs b/crates/pathfinder/content/src/transform.rs deleted file mode 100644 index 4f2cde2b2b..0000000000 --- a/crates/pathfinder/content/src/transform.rs +++ /dev/null @@ -1,106 +0,0 @@ -// pathfinder/content/src/transform.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Utilities for transforming paths. - -use crate::segment::Segment; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::transform3d::Perspective; - -/// Transforms a path with a SIMD 2D transform. -pub struct Transform2FPathIter -where - I: Iterator, -{ - iter: I, - transform: Transform2F, -} - -impl Iterator for Transform2FPathIter -where - I: Iterator, -{ - type Item = Segment; - - #[inline] - fn next(&mut self) -> Option { - // TODO(pcwalton): Can we go faster by transforming an entire line segment with SIMD? - let mut segment = self.iter.next()?; - if !segment.is_none() { - segment.baseline.set_from(self.transform * segment.baseline.from()); - segment.baseline.set_to(self.transform * segment.baseline.to()); - if !segment.is_line() { - segment.ctrl.set_from(self.transform * segment.ctrl.from()); - if !segment.is_quadratic() { - segment.ctrl.set_to(self.transform * segment.ctrl.to()); - } - } - } - Some(segment) - } -} - -impl Transform2FPathIter -where - I: Iterator, -{ - #[inline] - pub fn new(iter: I, transform: &Transform2F) -> Transform2FPathIter { - Transform2FPathIter { - iter, - transform: *transform, - } - } -} - -/// Transforms a path with a perspective projection. -pub struct PerspectivePathIter -where - I: Iterator, -{ - iter: I, - perspective: Perspective, -} - -impl Iterator for PerspectivePathIter -where - I: Iterator, -{ - type Item = Segment; - - #[inline] - fn next(&mut self) -> Option { - let mut segment = self.iter.next()?; - if !segment.is_none() { - segment.baseline.set_from(self.perspective * segment.baseline.from()); - segment.baseline.set_to(self.perspective * segment.baseline.to()); - if !segment.is_line() { - segment.ctrl.set_from(self.perspective * segment.ctrl.from()); - if !segment.is_quadratic() { - segment.ctrl.set_to(self.perspective * segment.ctrl.to()); - } - } - } - Some(segment) - } -} - -impl PerspectivePathIter -where - I: Iterator, -{ - #[inline] - pub fn new(iter: I, perspective: &Perspective) -> PerspectivePathIter { - PerspectivePathIter { - iter, - perspective: *perspective, - } - } -} diff --git a/crates/pathfinder/content/src/util.rs b/crates/pathfinder/content/src/util.rs deleted file mode 100644 index 8c0c186b4d..0000000000 --- a/crates/pathfinder/content/src/util.rs +++ /dev/null @@ -1,47 +0,0 @@ -// pathfinder/content/src/util.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Miscellaneous utilities. - -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_simd::default::{F32x2, F32x4}; -use std::hash::{Hash, Hasher}; -use std::mem; - -pub(crate) fn hash_line_segment(line_segment: LineSegment2F, state: &mut H) where H: Hasher { - hash_f32x4(line_segment.0, state); -} - -pub(crate) fn hash_transform2f(transform: Transform2F, state: &mut H) where H: Hasher { - hash_f32x4(transform.matrix.0, state); - hash_f32x2(transform.vector.0, state); -} - -pub(crate) fn hash_f32(value: f32, state: &mut H) where H: Hasher { - unsafe { - let data: u32 = mem::transmute::(value); - data.hash(state); - } -} - -pub(crate) fn hash_f32x2(vector: F32x2, state: &mut H) where H: Hasher { - unsafe { - let data: [u32; 2] = mem::transmute::(vector); - data.hash(state); - } -} - -pub(crate) fn hash_f32x4(vector: F32x4, state: &mut H) where H: Hasher { - unsafe { - let data: [u32; 4] = mem::transmute::(vector); - data.hash(state); - } -} diff --git a/crates/pathfinder/export/Cargo.toml b/crates/pathfinder/export/Cargo.toml deleted file mode 100644 index 49db4a001d..0000000000 --- a/crates/pathfinder/export/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "pathfinder_export" -version = "0.1.0" -authors = ["Sebastian Köln "] -edition = "2018" - -[dependencies] -pathfinder_color = { path = "../color" } -pathfinder_content = { path = "../content" } -pathfinder_geometry = { path = "../geometry" } -pathfinder_renderer = { path = "../renderer" } -deflate = "*" diff --git a/crates/pathfinder/export/src/lib.rs b/crates/pathfinder/export/src/lib.rs deleted file mode 100644 index 4a4ab5b54b..0000000000 --- a/crates/pathfinder/export/src/lib.rs +++ /dev/null @@ -1,194 +0,0 @@ -// pathfinder/export/src/lib.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use pathfinder_content::outline::ContourIterFlags; -use pathfinder_content::segment::SegmentKind; -use pathfinder_renderer::scene::Scene; -use pathfinder_geometry::vector::{Vector2F, vec2f}; -use std::fmt; -use std::io::{self, Write}; - -mod pdf; -use pdf::Pdf; - -pub enum FileFormat { - /// Scalable Vector Graphics - SVG, - - /// Portable Document Format - PDF, - - /// PostScript - PS, -} - -pub trait Export { - fn export(&self, writer: &mut W, format: FileFormat) -> io::Result<()>; -} - -impl Export for Scene { - fn export(&self, writer: &mut W, format: FileFormat) -> io::Result<()> { - match format { - FileFormat::SVG => export_svg(self, writer), - FileFormat::PDF => export_pdf(self, writer), - FileFormat::PS => export_ps(self, writer) - } - } -} - -fn export_svg(scene: &Scene, writer: &mut W) -> io::Result<()> { - let view_box = scene.view_box(); - writeln!( - writer, - "", - view_box.origin().x(), - view_box.origin().y(), - view_box.size().x(), - view_box.size().y() - )?; - for (paint, outline, name) in scene.paths() { - write!(writer, " ", paint, outline)?; - } - writeln!(writer, "")?; - Ok(()) -} - -fn export_pdf(scene: &Scene, writer: &mut W) -> io::Result<()> { - let mut pdf = Pdf::new(); - let view_box = scene.view_box(); - pdf.add_page(view_box.size()); - - let height = view_box.size().y(); - let tr = |v: Vector2F| -> Vector2F { - let r = v - view_box.origin(); - vec2f(r.x(), height - r.y()) - }; - - for (paint, outline, _) in scene.paths() { - // TODO(pcwalton): Gradients and patterns. - if paint.is_color() { - pdf.set_fill_color(paint.base_color()); - } - - for contour in outline.contours() { - for (segment_index, segment) in contour.iter(ContourIterFlags::empty()).enumerate() { - if segment_index == 0 { - pdf.move_to(tr(segment.baseline.from())); - } - - match segment.kind { - SegmentKind::None => {} - SegmentKind::Line => pdf.line_to(tr(segment.baseline.to())), - SegmentKind::Quadratic => { - let current = segment.baseline.from(); - let c = segment.ctrl.from(); - let p = segment.baseline.to(); - let c1 = c * (2.0 / 3.0) + current * (1.0 / 3.0); - let c2 = c * (2.0 / 3.0) + p * (1.0 / 3.0); - pdf.cubic_to(c1, c2, p); - } - SegmentKind::Cubic => { - pdf.cubic_to(tr(segment.ctrl.from()), - tr(segment.ctrl.to()), - tr(segment.baseline.to())) - } - } - } - - if contour.is_closed() { - pdf.close(); - } - } - - // closes implicitly - pdf.fill(); - } - pdf.write_to(writer) -} - -fn export_ps(scene: &Scene, writer: &mut W) -> io::Result<()> { - struct P(Vector2F); - impl fmt::Display for P { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} {}", self.0.x(), self.0.y()) - } - } - - let view_box = scene.view_box(); - writeln!(writer, "%!PS-Adobe-3.0 EPSF-3.0")?; - writeln!(writer, "%%BoundingBox: {:.0} {:.0}", - P(view_box.origin()), - P(view_box.size()), - )?; - writeln!(writer, "%%HiResBoundingBox: {} {}", - P(view_box.origin()), - P(view_box.size()), - )?; - writeln!(writer, "0 {} translate", view_box.size().y())?; - writeln!(writer, "1 -1 scale")?; - - for (paint, outline, name) in scene.paths() { - if !name.is_empty() { - writeln!(writer, "newpath % {}", name)?; - } else { - writeln!(writer, "newpath")?; - } - - for contour in outline.contours() { - for (segment_index, segment) in contour.iter(ContourIterFlags::empty()).enumerate() { - if segment_index == 0 { - writeln!(writer, "{} moveto", P(segment.baseline.from()))?; - } - - match segment.kind { - SegmentKind::None => {} - SegmentKind::Line => { - writeln!(writer, "{} lineto", P(segment.baseline.to()))?; - } - SegmentKind::Quadratic => { - let current = segment.baseline.from(); - let c = segment.ctrl.from(); - let p = segment.baseline.to(); - let c1 = c * (2.0 / 3.0) + current * (1.0 / 3.0); - let c2 = c * (2.0 / 3.0) + p * (1.0 / 3.0); - writeln!(writer, "{} {} {} curveto", P(c1), P(c2), P(p))?; - } - SegmentKind::Cubic => { - writeln!(writer, "{} {} {} curveto", - P(segment.ctrl.from()), - P(segment.ctrl.to()), - P(segment.baseline.to()) - )?; - } - } - } - - if contour.is_closed() { - writeln!(writer, "closepath")?; - } - } - - // TODO(pcwalton): Gradients and patterns. - if paint.is_color() { - let color = paint.base_color(); - writeln!(writer, "{} {} {} setrgbcolor", color.r, color.g, color.b)?; - } - - writeln!(writer, "fill")?; - } - writeln!(writer, "showpage")?; - Ok(()) -} - - diff --git a/crates/pathfinder/export/src/pdf.rs b/crates/pathfinder/export/src/pdf.rs deleted file mode 100644 index bb85344b50..0000000000 --- a/crates/pathfinder/export/src/pdf.rs +++ /dev/null @@ -1,260 +0,0 @@ -// pathfinder/export/src/pdf.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! This is a heavily modified version of the pdfpdf crate by Benjamin Kimock -//! (aka. saethlin) - -use deflate::Compression; -use pathfinder_color::ColorU; -use pathfinder_geometry::vector::Vector2F; -use std::io::{self, Write}; - -struct Counter { - inner: T, - count: u64 -} -impl Counter { - pub fn new(inner: T) -> Counter { - Counter { - inner, - count: 0 - } - } - pub fn pos(&self) -> u64 { - self.count - } -} -impl Write for Counter { - fn write(&mut self, buf: &[u8]) -> io::Result { - match self.inner.write(buf) { - Ok(n) => { - self.count += n as u64; - Ok(n) - }, - Err(e) => Err(e) - } - } - fn flush(&mut self) -> io::Result<()> { - self.inner.flush() - } - - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - self.inner.write_all(buf)?; - self.count += buf.len() as u64; - Ok(()) - } -} - -/// Represents a PDF internal object -struct PdfObject { - contents: Vec, - is_page: bool, - is_xobject: bool, - offset: Option, -} - -/// The top-level struct that represents a (partially) in-memory PDF file -pub struct Pdf { - page_buffer: Vec, - objects: Vec, - page_size: Option, - compression: Option, -} - -impl Default for Pdf { - fn default() -> Self { - Self::new() - } -} - -impl Pdf { - /// Create a new blank PDF document - #[inline] - pub fn new() -> Self { - Self { - page_buffer: Vec::new(), - objects: vec![ - PdfObject { - contents: Vec::new(), - is_page: false, - is_xobject: false, - offset: None, - }, - PdfObject { - contents: Vec::new(), - is_page: false, - is_xobject: false, - offset: None, - }, - ], - page_size: None, - compression: Some(Compression::Fast) - } - } - - fn add_object(&mut self, data: Vec, is_page: bool, is_xobject: bool) -> usize { - self.objects.push(PdfObject { - contents: data, - is_page, - is_xobject, - offset: None, - }); - self.objects.len() - } - - /// Set the color for all subsequent drawing operations - #[inline] - pub fn set_fill_color(&mut self, color: ColorU) { - let norm = |color| f32::from(color) / 255.0; - writeln!(self.page_buffer, "{} {} {} rg", - norm(color.r), - norm(color.g), - norm(color.b) - ).unwrap(); - } - - /// Move to a new page in the PDF document - #[inline] - pub fn add_page(&mut self, size: Vector2F) { - // Compress and write out the previous page if it exists - if !self.page_buffer.is_empty() { - self.end_page(); - self.page_buffer.clear(); - } - - self.page_buffer - .extend("/DeviceRGB cs /DeviceRGB CS\n1 j 1 J\n".bytes()); - self.page_size = Some(size); - } - - pub fn move_to(&mut self, p: Vector2F) { - writeln!(self.page_buffer, "{} {} m", p.x(), p.y()).unwrap(); - } - - pub fn line_to(&mut self, p: Vector2F) { - writeln!(self.page_buffer, "{} {} l", p.x(), p.y()).unwrap(); - } - - pub fn cubic_to(&mut self, c1: Vector2F, c2: Vector2F, p: Vector2F) { - writeln!(self.page_buffer, "{} {} {} {} {} {} c", c1.x(), c1.y(), c2.x(), c2.y(), p.x(), p.y()).unwrap(); - } - pub fn fill(&mut self) { - writeln!(self.page_buffer, "f").unwrap(); - } - - pub fn close(&mut self) { - writeln!(self.page_buffer, "h").unwrap(); - } - /// Dump a page out to disk - fn end_page(&mut self) { - let size = match self.page_size.take() { - Some(size) => size, - None => return // no page started - }; - let page_stream = if let Some(level) = self.compression { - let compressed = deflate::deflate_bytes_zlib_conf(&self.page_buffer, level); - let mut page = format!( - "<< /Length {} /Filter [/FlateDecode] >>\nstream\n", - compressed.len() - ) - .into_bytes(); - page.extend_from_slice(&compressed); - page.extend(b"endstream\n"); - page - } else { - let mut page = Vec::new(); - page.extend(format!("<< /Length {} >>\nstream\n", self.page_buffer.len()).bytes()); - page.extend(&self.page_buffer); - page.extend(b"endstream\n"); - page - }; - - // Create the stream object for this page - let stream_object_id = self.add_object(page_stream, false, false); - - // Create the page object, which describes settings for the whole page - let mut page_object = b"<< /Type /Page\n \ - /Parent 2 0 R\n \ - /Resources <<\n" - .to_vec(); - - for (idx, _obj) in self.objects.iter().enumerate().filter(|&(_, o)| o.is_xobject) { - write!(page_object, "/XObject {} 0 R ", idx+1).unwrap(); - } - - write!(page_object, - " >>\n \ - /MediaBox [0 0 {} {}]\n \ - /Contents {} 0 R\n\ - >>\n", - size.x(), size.y(), stream_object_id - ).unwrap(); - self.add_object(page_object, true, false); - } - - /// Write the in-memory PDF representation to disk - pub fn write_to(&mut self, writer: W) -> io::Result<()> where W: Write { - let mut out = Counter::new(writer); - out.write_all(b"%PDF-1.7\n%\xB5\xED\xAE\xFB\n")?; - - if !self.page_buffer.is_empty() { - self.end_page(); - } - - // Write out each object - for (idx, obj) in self.objects.iter_mut().enumerate().skip(2) { - obj.offset = Some(out.pos()); - write!(out, "{} 0 obj\n", idx+1)?; - out.write_all(&obj.contents)?; - out.write_all(b"endobj\n")?; - } - - // Write out the page tree object - self.objects[1].offset = Some(out.pos()); - out.write_all(b"2 0 obj\n")?; - out.write_all(b"<< /Type /Pages\n")?; - write!(out, - "/Count {}\n", - self.objects.iter().filter(|o| o.is_page).count() - )?; - out.write_all(b"/Kids [")?; - for (idx, _obj) in self.objects.iter().enumerate().filter(|&(_, obj)| obj.is_page) { - write!(out, "{} 0 R ", idx + 1)?; - } - out.write_all(b"] >>\nendobj\n")?; - - // Write out the catalog dictionary object - self.objects[0].offset = Some(out.pos()); - out.write_all(b"1 0 obj\n<< /Type /Catalog\n/Pages 2 0 R >>\nendobj\n")?; - - // Write the cross-reference table - let startxref = out.pos() + 1; // NOTE: apparently there's some 1-based indexing?? - out.write_all(b"xref\n")?; - write!(out, "0 {}\n", self.objects.len() + 1)?; - out.write_all(b"0000000000 65535 f \n")?; - - for obj in &self.objects { - write!(out, "{:010} 00000 f \n", obj.offset.unwrap())?; - } - - // Write the document trailer - out.write_all(b"trailer\n")?; - write!(out, "<< /Size {}\n", self.objects.len())?; - out.write_all(b"/Root 1 0 R >>\n")?; - - // Write the offset to the xref table - write!(out, "startxref\n{}\n", startxref)?; - - // Write the PDF EOF - out.write_all(b"%%EOF")?; - - Ok(()) - } -} diff --git a/crates/pathfinder/geometry/Cargo.toml b/crates/pathfinder/geometry/Cargo.toml deleted file mode 100644 index b05e929977..0000000000 --- a/crates/pathfinder/geometry/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "pathfinder_geometry" -version = "0.5.1" -edition = "2018" -authors = ["Patrick Walton "] -description = "Basic SIMD-accelerated geometry/linear algebra" -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] -version = "0.4" - -[dependencies.pathfinder_simd] -path = "../simd" -version = "0.5" diff --git a/crates/pathfinder/geometry/src/alignment.rs b/crates/pathfinder/geometry/src/alignment.rs deleted file mode 100644 index 44db8652ba..0000000000 --- a/crates/pathfinder/geometry/src/alignment.rs +++ /dev/null @@ -1,19 +0,0 @@ -#[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/crates/pathfinder/geometry/src/angle.rs b/crates/pathfinder/geometry/src/angle.rs deleted file mode 100644 index 1fa9e09eea..0000000000 --- a/crates/pathfinder/geometry/src/angle.rs +++ /dev/null @@ -1,19 +0,0 @@ -// pathfinder/geometry/src/angle.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Angle utilities. - -use std::f32::consts::PI; - -#[inline] -pub fn angle_from_degrees(degrees: f32) -> f32 { - const SCALE: f32 = 2.0 * PI / 360.0; - degrees * SCALE -} diff --git a/crates/pathfinder/geometry/src/lib.rs b/crates/pathfinder/geometry/src/lib.rs deleted file mode 100644 index 44d88cc2a0..0000000000 --- a/crates/pathfinder/geometry/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// pathfinder/geometry/src/lib.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Basic geometry and linear algebra primitives, optimized with SIMD. - -pub mod angle; -pub mod line_segment; -pub mod rect; -pub mod transform2d; -pub mod transform3d; -pub mod unit_vector; -pub mod util; -pub mod vector; -pub mod alignment; diff --git a/crates/pathfinder/geometry/src/line_segment.rs b/crates/pathfinder/geometry/src/line_segment.rs deleted file mode 100644 index 1fb0a7cd65..0000000000 --- a/crates/pathfinder/geometry/src/line_segment.rs +++ /dev/null @@ -1,309 +0,0 @@ -// pathfinder/geometry/src/basic/line_segment.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Line segment types, optimized with SIMD. - -use crate::transform2d::Matrix2x2F; -use crate::alignment::AlignedU8; -use crate::util; -use crate::vector::{vec2f, Vector2F}; -use pathfinder_simd::default::F32x4; -use std::ops::{Add, Mul, MulAssign, Sub}; - -#[derive(Clone, Copy, Debug, PartialEq, Default)] -pub struct LineSegment2F(pub F32x4); - -impl LineSegment2F { - #[inline] - pub fn new(from: Vector2F, to: Vector2F) -> LineSegment2F { - LineSegment2F(from.0.concat_xy_xy(to.0)) - } - - #[inline] - pub fn from(self) -> Vector2F { - Vector2F(self.0.xy()) - } - - #[inline] - pub fn to(self) -> Vector2F { - Vector2F(self.0.zw()) - } - - #[inline] - pub fn set_from(&mut self, point: Vector2F) { - self.0 = point.0.to_f32x4().concat_xy_zw(self.0) - } - - #[inline] - pub fn set_to(&mut self, point: Vector2F) { - self.0 = self.0.concat_xy_xy(point.0.to_f32x4()) - } - - #[allow(clippy::wrong_self_convention)] - #[inline] - pub fn from_x(self) -> f32 { - self.0[0] - } - - #[allow(clippy::wrong_self_convention)] - #[inline] - pub fn from_y(self) -> f32 { - self.0[1] - } - - #[inline] - pub fn to_x(self) -> f32 { - self.0[2] - } - - #[inline] - pub fn to_y(self) -> f32 { - self.0[3] - } - - #[inline] - pub fn set_from_x(&mut self, x: f32) { - self.0[0] = x - } - - #[inline] - pub fn set_from_y(&mut self, y: f32) { - self.0[1] = y - } - - #[inline] - pub fn set_to_x(&mut self, x: f32) { - self.0[2] = x - } - - #[inline] - pub fn set_to_y(&mut self, y: f32) { - self.0[3] = y - } - - #[inline] - pub fn split(self, t: f32) -> (LineSegment2F, LineSegment2F) { - debug_assert!(t >= 0.0 && t <= 1.0); - let (from_from, to_to) = (self.0.xyxy(), self.0.zwzw()); - let d_d = to_to - from_from; - let mid_mid = from_from + d_d * F32x4::splat(t); - ( - LineSegment2F(from_from.concat_xy_xy(mid_mid)), - LineSegment2F(mid_mid.concat_xy_xy(to_to)), - ) - } - - // Returns the left segment first, followed by the right segment. - #[inline] - pub fn split_at_x(self, x: f32) -> (LineSegment2F, LineSegment2F) { - let (min_part, max_part) = self.split(self.solve_t_for_x(x)); - if min_part.from_x() < max_part.from_x() { - (min_part, max_part) - } else { - (max_part, min_part) - } - } - - // Returns the upper segment first, followed by the lower segment. - #[inline] - pub fn split_at_y(self, y: f32) -> (LineSegment2F, LineSegment2F) { - let (min_part, max_part) = self.split(self.solve_t_for_y(y)); - - // Make sure we compare `from_y` and `to_y` to properly handle the case in which one of the - // two segments is zero-length. - if min_part.from_y() < max_part.to_y() { - (min_part, max_part) - } else { - (max_part, min_part) - } - } - - #[inline] - pub fn solve_t_for_x(self, x: f32) -> f32 { - (x - self.from_x()) / (self.to_x() - self.from_x()) - } - - #[inline] - pub fn solve_t_for_y(self, y: f32) -> f32 { - (y - self.from_y()) / (self.to_y() - self.from_y()) - } - - #[inline] - pub fn solve_x_for_y(self, y: f32) -> f32 { - util::lerp(self.from_x(), self.to_x(), self.solve_t_for_y(y)) - } - - #[inline] - pub fn solve_y_for_x(self, x: f32) -> f32 { - util::lerp(self.from_y(), self.to_y(), self.solve_t_for_x(x)) - } - - #[inline] - pub fn reversed(self) -> LineSegment2F { - LineSegment2F(self.0.zwxy()) - } - - #[inline] - pub fn upper_point(self) -> Vector2F { - if self.from_y() < self.to_y() { - self.from() - } else { - self.to() - } - } - - #[inline] - pub fn min_x(self) -> f32 { - f32::min(self.from_x(), self.to_x()) - } - - #[inline] - pub fn max_x(self) -> f32 { - f32::max(self.from_x(), self.to_x()) - } - - #[inline] - pub fn min_y(self) -> f32 { - f32::min(self.from_y(), self.to_y()) - } - - #[inline] - pub fn max_y(self) -> f32 { - f32::max(self.from_y(), self.to_y()) - } - - #[inline] - pub fn y_winding(self) -> i32 { - if self.from_y() < self.to_y() { - 1 - } else { - -1 - } - } - - // Reverses if necessary so that the from point is above the to point. Calling this method - // again will undo the transformation. - #[inline] - pub fn orient(self, y_winding: i32) -> LineSegment2F { - if y_winding >= 0 { - self - } else { - self.reversed() - } - } - - // TODO(pcwalton): Optimize with SIMD. - #[inline] - pub fn square_length(self) -> f32 { - let (dx, dy) = (self.to_x() - self.from_x(), self.to_y() - self.from_y()); - dx * dx + dy * dy - } - - #[inline] - pub fn length(self) -> f32 { - self.square_length().sqrt() - } - - #[inline] - pub fn vector(self) -> Vector2F { - self.to() - self.from() - } - - // http://www.cs.swan.ac.uk/~cssimon/line_intersection.html - pub fn intersection_t(self, other: LineSegment2F) -> Option { - let p0p1 = self.vector(); - let matrix = Matrix2x2F(other.vector().0.concat_xy_xy((-p0p1).0)); - if f32::abs(matrix.det()) < EPSILON { - return None; - } - return Some((matrix.inverse() * (self.from() - other.from())).y()); - - const EPSILON: f32 = 0.0001; - } - - #[inline] - pub fn sample(self, t: f32) -> Vector2F { - self.from() + self.vector() * t - } - - #[inline] - pub fn midpoint(self) -> Vector2F { - self.sample(0.5) - } - - #[inline] - pub fn offset(self, distance: f32) -> LineSegment2F { - if self.is_zero_length() { - self - } else { - self + self.vector().yx().normalize() * vec2f(-distance, distance) - } - } - - #[inline] - pub fn is_zero_length(self) -> bool { - self.vector().is_zero() - } -} - -impl Add for LineSegment2F { - type Output = LineSegment2F; - #[inline] - fn add(self, point: Vector2F) -> LineSegment2F { - LineSegment2F(self.0 + point.0.to_f32x4().xyxy()) - } -} - -impl Sub for LineSegment2F { - type Output = LineSegment2F; - #[inline] - fn sub(self, point: Vector2F) -> LineSegment2F { - LineSegment2F(self.0 - point.0.to_f32x4().xyxy()) - } -} - -impl Mul for LineSegment2F { - type Output = LineSegment2F; - #[inline] - fn mul(self, factors: Vector2F) -> LineSegment2F { - LineSegment2F(self.0 * factors.0.to_f32x4().xyxy()) - } -} - -impl Mul for LineSegment2F { - type Output = LineSegment2F; - #[inline] - fn mul(self, factor: f32) -> LineSegment2F { - LineSegment2F(self.0 * F32x4::splat(factor)) - } -} - -impl MulAssign for LineSegment2F { - #[inline] - fn mul_assign(&mut self, factors: Vector2F) { - *self = *self * factors - } -} - -#[derive(Clone, Copy, Debug, Default)] -#[repr(C)] -pub struct LineSegmentU4 { - pub from: AlignedU8, - pub to: AlignedU8, -} - -#[derive(Clone, Copy, Debug, Default)] -#[repr(C)] -pub struct LineSegmentU8 { - pub from_x: u8, - pub from_y: u8, - pub to_x: u8, - pub to_y: u8, -} diff --git a/crates/pathfinder/geometry/src/rect.rs b/crates/pathfinder/geometry/src/rect.rs deleted file mode 100644 index 858c27123f..0000000000 --- a/crates/pathfinder/geometry/src/rect.rs +++ /dev/null @@ -1,371 +0,0 @@ -// pathfinder/geometry/src/basic/rect.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! 2D axis-aligned rectangles, optimized with SIMD. - -use crate::vector::{IntoVector2F, Vector2F, Vector2I}; -use pathfinder_simd::default::{F32x4, I32x4}; -use std::ops::{Add, Mul, Sub}; - -#[derive(Clone, Copy, Debug, PartialEq, Default)] -pub struct RectF(pub F32x4); - -impl RectF { - #[inline] - pub fn new(origin: Vector2F, size: Vector2F) -> RectF { - RectF(origin.0.concat_xy_xy(origin.0 + size.0)) - } - - #[inline] - pub fn from_points(origin: Vector2F, lower_right: Vector2F) -> RectF { - RectF(origin.0.concat_xy_xy(lower_right.0)) - } - - // Accessors - - #[inline] - pub fn origin(self) -> Vector2F { - Vector2F(self.0.xy()) - } - - #[inline] - pub fn size(self) -> Vector2F { - Vector2F(self.0.zw() - self.0.xy()) - } - - #[inline] - pub fn origin_x(self) -> f32 { - self.0.x() - } - - #[inline] - pub fn origin_y(self) -> f32 { - self.0.y() - } - - #[inline] - pub fn width(self) -> f32 { - self.0.z() - self.0.x() - } - - #[inline] - pub fn height(self) -> f32 { - self.0.w() - self.0.y() - } - - #[inline] - pub fn upper_right(self) -> Vector2F { - Vector2F(self.0.zy()) - } - - #[inline] - pub fn lower_left(self) -> Vector2F { - Vector2F(self.0.xw()) - } - - #[inline] - pub fn lower_right(self) -> Vector2F { - Vector2F(self.0.zw()) - } - - // Mutators - - #[inline] - pub fn set_origin_x(&mut self, x: f32) { - self.0.set_x(x) - } - - #[inline] - pub fn set_origin_y(&mut self, y: f32) { - self.0.set_y(y) - } - - #[inline] - pub fn contains_point(self, point: Vector2F) -> bool { - // self.origin <= point && point <= self.lower_right - let point = point.0.to_f32x4(); - self.0.concat_xy_xy(point).packed_le(point.concat_xy_zw(self.0)).all_true() - } - - #[inline] - pub fn contains_rect(self, other: RectF) -> bool { - // self.origin <= other.origin && other.lower_right <= self.lower_right - self.0.concat_xy_zw(other.0).packed_le(other.0.concat_xy_zw(self.0)).all_true() - } - - #[inline] - pub fn is_empty(self) -> bool { - self.origin() == self.lower_right() - } - - #[inline] - pub fn union_point(self, point: Vector2F) -> RectF { - RectF::from_points(self.origin().min(point), self.lower_right().max(point)) - } - - #[inline] - pub fn union_rect(self, other: RectF) -> RectF { - RectF::from_points( - self.origin().min(other.origin()), - self.lower_right().max(other.lower_right()), - ) - } - - #[inline] - pub fn intersects(self, other: RectF) -> bool { - // self.origin < other.lower_right && other.origin < self.lower_right - self.0.concat_xy_xy(other.0).packed_lt(other.0.concat_zw_zw(self.0)).all_true() - } - - #[inline] - pub fn intersection(self, other: RectF) -> Option { - if !self.intersects(other) { - None - } else { - Some(RectF::from_points( - self.origin().max(other.origin()), - self.lower_right().min(other.lower_right()), - )) - } - } - - #[inline] - pub fn min_x(self) -> f32 { - self.0[0] - } - - #[inline] - pub fn min_y(self) -> f32 { - self.0[1] - } - - #[inline] - pub fn max_x(self) -> f32 { - self.0[2] - } - - #[inline] - pub fn max_y(self) -> f32 { - self.0[3] - } - - #[inline] - pub fn center(self) -> Vector2F { - self.origin() + self.size() * 0.5 - } - - /// Rounds all points to the nearest integer. - #[inline] - pub fn round(self) -> RectF { - RectF(self.0.to_i32x4().to_f32x4()) - } - - #[inline] - pub fn round_out(self) -> RectF { - RectF::from_points(self.origin().floor(), self.lower_right().ceil()) - } - - #[inline] - pub fn dilate(self, amount: A) -> RectF where A: IntoVector2F { - let amount = amount.into_vector_2f(); - RectF::from_points(self.origin() - amount, self.lower_right() + amount) - } - - #[inline] - pub fn contract(self, amount: A) -> RectF where A: IntoVector2F { - let amount = amount.into_vector_2f(); - RectF::from_points(self.origin() + amount, self.lower_right() - amount) - } - - #[inline] - pub fn to_i32(&self) -> RectI { - RectI(self.0.to_i32x4()) - } -} - -impl Add for RectF { - type Output = RectF; - #[inline] - fn add(self, other: Vector2F) -> RectF { - RectF::new(self.origin() + other, self.size()) - } -} - -impl Add for RectF { - type Output = RectF; - #[inline] - fn add(self, other: f32) -> RectF { - RectF::new(self.origin() + other, self.size()) - } -} - -impl Mul for RectF { - type Output = RectF; - #[inline] - fn mul(self, factors: Vector2F) -> RectF { - RectF(self.0 * factors.0.concat_xy_xy(factors.0)) - } -} - -impl Mul for RectF { - type Output = RectF; - #[inline] - fn mul(self, factor: f32) -> RectF { - RectF(self.0 * F32x4::splat(factor)) - } -} - -impl Sub for RectF { - type Output = RectF; - #[inline] - fn sub(self, other: Vector2F) -> RectF { - RectF::new(self.origin() - other, self.size()) - } -} - -impl Sub for RectF { - type Output = RectF; - #[inline] - fn sub(self, other: f32) -> RectF { - RectF::new(self.origin() - other, self.size()) - } -} - -/// NB: The origin is inclusive, while the lower right point is exclusive. -#[derive(Clone, Copy, Debug, PartialEq, Default)] -pub struct RectI(pub I32x4); - -impl RectI { - #[inline] - pub fn new(origin: Vector2I, size: Vector2I) -> RectI { - RectI(origin.0.concat_xy_xy(origin.0 + size.0)) - } - - #[inline] - pub fn from_points(origin: Vector2I, lower_right: Vector2I) -> RectI { - RectI(origin.0.concat_xy_xy(lower_right.0)) - } - - // Accessors - - #[inline] - pub fn origin(&self) -> Vector2I { - Vector2I(self.0.xy()) - } - - #[inline] - pub fn size(&self) -> Vector2I { - Vector2I(self.0.zw() - self.0.xy()) - } - - #[inline] - pub fn origin_x(self) -> i32 { - self.0.x() - } - - #[inline] - pub fn origin_y(self) -> i32 { - self.0.y() - } - - #[inline] - pub fn width(self) -> i32 { - self.0.z() - self.0.x() - } - - #[inline] - pub fn height(self) -> i32 { - self.0.w() - self.0.y() - } - - #[inline] - pub fn upper_right(&self) -> Vector2I { - Vector2I(self.0.zy()) - } - - #[inline] - pub fn lower_left(&self) -> Vector2I { - Vector2I(self.0.xw()) - } - - #[inline] - pub fn lower_right(&self) -> Vector2I { - Vector2I(self.0.zw()) - } - - #[inline] - pub fn scale(self, factor: i32) -> RectI { - RectI(self.0 * I32x4::splat(factor)) - } - - #[inline] - pub fn scale_xy(self, factors: Vector2I) -> RectI { - RectI(self.0 * factors.0.concat_xy_xy(factors.0)) - } - - #[inline] - pub fn min_x(self) -> i32 { - self.0[0] - } - - #[inline] - pub fn min_y(self) -> i32 { - self.0[1] - } - - #[inline] - pub fn max_x(self) -> i32 { - self.0[2] - } - - #[inline] - pub fn max_y(self) -> i32 { - self.0[3] - } - - #[inline] - pub fn intersects(self, other: RectI) -> bool { - // self.origin < other.lower_right && other.origin < self.lower_right - self.0.concat_xy_xy(other.0).packed_lt(other.0.concat_zw_zw(self.0)).all_true() - } - - #[inline] - pub fn intersection(self, other: RectI) -> Option { - if !self.intersects(other) { - None - } else { - Some(RectI::from_points( - self.origin().max(other.origin()), - self.lower_right().min(other.lower_right()), - )) - } - } - - #[inline] - pub fn contains_point(&self, point: Vector2I) -> bool { - // self.origin <= point && point <= self.lower_right - 1 - let lower_right = self.lower_right() - 1; - self.origin() - .0 - .concat_xy_xy(point.0) - .packed_le(point.0.concat_xy_xy(lower_right.0)) - .all_true() - } - - #[inline] - pub fn contract(self, amount: Vector2I) -> RectI { - RectI::from_points(self.origin() + amount, self.lower_right() - amount) - } - - #[inline] - pub fn to_f32(&self) -> RectF { - RectF(self.0.to_f32x4()) - } -} diff --git a/crates/pathfinder/geometry/src/transform2d.rs b/crates/pathfinder/geometry/src/transform2d.rs deleted file mode 100644 index c29ae7b9c3..0000000000 --- a/crates/pathfinder/geometry/src/transform2d.rs +++ /dev/null @@ -1,345 +0,0 @@ -// pathfinder/geometry/src/basic/transform2d.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! 2D affine transforms. - -use crate::line_segment::LineSegment2F; -use crate::rect::RectF; -use crate::transform3d::Transform4F; -use crate::unit_vector::UnitVector; -use crate::vector::{IntoVector2F, Vector2F, vec2f}; -use pathfinder_simd::default::F32x4; -use std::ops::{Mul, MulAssign, Sub}; - -/// A 2x2 matrix, optimized with SIMD, in column-major order. -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct Matrix2x2F(pub F32x4); - -impl Default for Matrix2x2F { - #[inline] - fn default() -> Matrix2x2F { - Self::from_scale(1.0) - } -} - -impl Matrix2x2F { - #[inline] - pub fn from_scale(scale: S) -> Matrix2x2F where S: IntoVector2F { - let scale = scale.into_vector_2f(); - Matrix2x2F(F32x4::new(scale.x(), 0.0, 0.0, scale.y())) - } - - #[inline] - pub fn from_rotation(theta: f32) -> Matrix2x2F { - Matrix2x2F::from_rotation_vector(UnitVector::from_angle(theta)) - } - - #[inline] - pub fn from_rotation_vector(vector: UnitVector) -> Matrix2x2F { - Matrix2x2F((vector.0).0.to_f32x4().xyyx() * F32x4::new(1.0, 1.0, -1.0, 1.0)) - } - - #[inline] - pub fn row_major(m00: f32, m01: f32, m10: f32, m11: f32) -> Matrix2x2F { - Matrix2x2F(F32x4::new(m00, m10, m01, m11)) - } - - #[inline] - pub fn entrywise_mul(&self, other: &Matrix2x2F) -> Matrix2x2F { - Matrix2x2F(self.0 * other.0) - } - - #[inline] - pub fn adjugate(&self) -> Matrix2x2F { - Matrix2x2F(self.0.wyzx() * F32x4::new(1.0, -1.0, -1.0, 1.0)) - } - - #[inline] - pub fn det(&self) -> f32 { - self.0[0] * self.0[3] - self.0[2] * self.0[1] - } - - #[inline] - pub fn inverse(&self) -> Matrix2x2F { - Matrix2x2F(F32x4::splat(1.0 / self.det()) * self.adjugate().0) - } - - #[inline] - pub fn scale(&self, factor: f32) -> Matrix2x2F { - Matrix2x2F(self.0 * F32x4::splat(factor)) - } - - /// Extracts the scale from this matrix. - #[inline] - pub fn extract_scale(&self) -> Vector2F { - let squared = self.0 * self.0; - Vector2F((squared.xy() + squared.zw()).sqrt()) - } - - #[inline] - pub fn m11(&self) -> f32 { - self.0[0] - } - - #[inline] - pub fn m21(&self) -> f32 { - self.0[1] - } - - #[inline] - pub fn m12(&self) -> f32 { - self.0[2] - } - - #[inline] - pub fn m22(&self) -> f32 { - self.0[3] - } -} - -impl Sub for Matrix2x2F { - type Output = Matrix2x2F; - #[inline] - fn sub(self, other: Matrix2x2F) -> Matrix2x2F { - Matrix2x2F(self.0 - other.0) - } -} - -impl Mul for Matrix2x2F { - type Output = Matrix2x2F; - #[inline] - fn mul(self, other: Matrix2x2F) -> Matrix2x2F { - Matrix2x2F(self.0.xyxy() * other.0.xxzz() + self.0.zwzw() * other.0.yyww()) - } -} - -impl Mul for Matrix2x2F { - type Output = Vector2F; - #[inline] - fn mul(self, vector: Vector2F) -> Vector2F { - let halves = self.0 * vector.0.to_f32x4().xxyy(); - Vector2F(halves.xy() + halves.zw()) - } -} - -/// An affine transform, optimized with SIMD. -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct Transform2F { - pub matrix: Matrix2x2F, - pub vector: Vector2F, -} - -impl Default for Transform2F { - #[inline] - fn default() -> Transform2F { - Self::from_scale(vec2f(1.0, 1.0)) - } -} - -impl Transform2F { - #[inline] - pub fn from_scale(scale: S) -> Transform2F where S: IntoVector2F { - let scale = scale.into_vector_2f(); - Transform2F { - matrix: Matrix2x2F::from_scale(scale), - vector: Vector2F::zero(), - } - } - - #[inline] - pub fn from_rotation(theta: f32) -> Transform2F { - Transform2F { - matrix: Matrix2x2F::from_rotation(theta), - vector: Vector2F::zero(), - } - } - - #[inline] - pub fn from_rotation_vector(vector: UnitVector) -> Transform2F { - Transform2F { - matrix: Matrix2x2F::from_rotation_vector(vector), - vector: Vector2F::zero(), - } - } - - #[inline] - pub fn from_translation(vector: Vector2F) -> Transform2F { - Transform2F { matrix: Matrix2x2F::default(), vector } - } - - #[inline] - pub fn from_scale_rotation_translation(scale: S, theta: f32, translation: Vector2F) - -> Transform2F where S: IntoVector2F { - let scale = scale.into_vector_2f(); - let rotation = Transform2F::from_rotation(theta); - let translation = Transform2F::from_translation(translation); - Transform2F::from_scale(scale) * rotation * translation - } - - #[inline] - pub fn row_major(m11: f32, m12: f32, m13: f32, m21: f32, m22: f32, m23: f32) -> Transform2F { - Transform2F { - matrix: Matrix2x2F::row_major(m11, m12, m21, m22), - vector: Vector2F::new(m13, m23), - } - } - - // TODO(pcwalton): Optimize better with SIMD. - #[inline] - pub fn to_3d(&self) -> Transform4F { - Transform4F::row_major( - self.matrix.0[0], - self.matrix.0[1], - 0.0, - self.vector.x(), - self.matrix.0[2], - self.matrix.0[3], - 0.0, - self.vector.y(), - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - ) - } - - #[inline] - pub fn is_identity(&self) -> bool { - *self == Transform2F::default() - } - - /// Extracts the scale from this matrix. - #[inline] - pub fn extract_scale(&self) -> Vector2F { - self.matrix.extract_scale() - } - - #[inline] - pub fn m11(&self) -> f32 { - self.matrix.m11() - } - #[inline] - pub fn m21(&self) -> f32 { - self.matrix.m21() - } - #[inline] - pub fn m12(&self) -> f32 { - self.matrix.m12() - } - #[inline] - pub fn m22(&self) -> f32 { - self.matrix.m22() - } - #[inline] - pub fn m13(&self) -> f32 { - self.vector.x() - } - #[inline] - pub fn m23(&self) -> f32 { - self.vector.y() - } - - #[inline] - pub fn translate(&self, vector: Vector2F) -> Transform2F { - Transform2F::from_translation(vector) * *self - } - - #[inline] - pub fn rotate(&self, theta: f32) -> Transform2F { - Transform2F::from_rotation(theta) * *self - } - - #[inline] - pub fn scale(&self, scale: S) -> Transform2F where S: IntoVector2F { - let scale = scale.into_vector_2f(); - Transform2F::from_scale(scale) * *self - } - - /// Returns the translation part of this matrix. - /// - /// This decomposition assumes that scale, rotation, and translation are applied in that order. - #[inline] - pub fn translation(&self) -> Vector2F { - self.vector - } - - /// Returns the rotation angle of this matrix. - /// - /// This decomposition assumes that scale, rotation, and translation are applied in that order. - #[inline] - pub fn rotation(&self) -> f32 { - f32::atan2(self.m21(), self.m11()) - } - - /// Returns the scale factor of this matrix. - /// - /// This decomposition assumes that scale, rotation, and translation are applied in that order. - #[inline] - pub fn scale_factor(&self) -> f32 { - Vector2F(self.matrix.0.zw()).length() - } - - #[inline] - pub fn inverse(&self) -> Transform2F { - let matrix_inv = self.matrix.inverse(); - let vector_inv = -(matrix_inv * self.vector); - Transform2F { matrix: matrix_inv, vector: vector_inv } - } -} - -impl Mul for Transform2F { - type Output = Transform2F; - #[inline] - fn mul(self, other: Transform2F) -> Transform2F { - Transform2F { - matrix: self.matrix * other.matrix, - vector: self * other.vector, - } - } -} - -impl Mul for Transform2F { - type Output = Vector2F; - #[inline] - fn mul(self, vector: Vector2F) -> Vector2F { - self.matrix * vector + self.vector - } -} - -impl Mul for Transform2F { - type Output = LineSegment2F; - #[inline] - fn mul(self, line_segment: LineSegment2F) -> LineSegment2F { - LineSegment2F::new(self * line_segment.from(), self * line_segment.to()) - } -} - -impl Mul for Transform2F { - type Output = RectF; - #[inline] - fn mul(self, rect: RectF) -> RectF { - let (upper_left, upper_right) = (self * rect.origin(), self * rect.upper_right()); - let (lower_left, lower_right) = (self * rect.lower_left(), self * rect.lower_right()); - let min_point = upper_left.min(upper_right).min(lower_left).min(lower_right); - let max_point = upper_left.max(upper_right).max(lower_left).max(lower_right); - RectF::from_points(min_point, max_point) - } -} - -impl MulAssign for Transform2F { - #[inline] - fn mul_assign(&mut self, other: Transform2F) { - *self = *self * other - } -} diff --git a/crates/pathfinder/geometry/src/transform3d.rs b/crates/pathfinder/geometry/src/transform3d.rs deleted file mode 100644 index 94d3648578..0000000000 --- a/crates/pathfinder/geometry/src/transform3d.rs +++ /dev/null @@ -1,504 +0,0 @@ -// pathfinder/geometry/src/basic/transform3d.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! 3D transforms that can be applied to paths. - -use crate::rect::RectF; -use crate::transform2d::Matrix2x2F; -use crate::vector::{Vector2F, Vector2I, Vector3F, Vector4F}; -use pathfinder_simd::default::F32x4; -use std::ops::{Add, Mul, MulAssign, Neg}; - -/// An transform, optimized with SIMD. -/// -/// In column-major order. -#[derive(Clone, Copy, Debug, PartialEq)] -#[repr(C)] -pub struct Transform4F { - pub c0: F32x4, - pub c1: F32x4, - pub c2: F32x4, - pub c3: F32x4, -} - -impl Default for Transform4F { - #[inline] - fn default() -> Transform4F { - Transform4F { - c0: F32x4::new(1.0, 0.0, 0.0, 0.0), - c1: F32x4::new(0.0, 1.0, 0.0, 0.0), - c2: F32x4::new(0.0, 0.0, 1.0, 0.0), - c3: F32x4::new(0.0, 0.0, 0.0, 1.0), - } - } -} - -impl Transform4F { - #[inline] - pub fn row_major( - m00: f32, - m01: f32, - m02: f32, - m03: f32, - m10: f32, - m11: f32, - m12: f32, - m13: f32, - m20: f32, - m21: f32, - m22: f32, - m23: f32, - m30: f32, - m31: f32, - m32: f32, - m33: f32, - ) -> Transform4F { - Transform4F { - c0: F32x4::new(m00, m10, m20, m30), - c1: F32x4::new(m01, m11, m21, m31), - c2: F32x4::new(m02, m12, m22, m32), - c3: F32x4::new(m03, m13, m23, m33), - } - } - - #[inline] - pub fn from_scale(scale: Vector4F) -> Transform4F { - Transform4F { - c0: F32x4::new(scale.x(), 0.0, 0.0, 0.0), - c1: F32x4::new(0.0, scale.y(), 0.0, 0.0), - c2: F32x4::new(0.0, 0.0, scale.z(), 0.0), - c3: F32x4::new(0.0, 0.0, 0.0, 1.0), - } - } - - #[inline] - pub fn from_uniform_scale(factor: f32) -> Transform4F { - Transform4F::from_scale(Vector4F::splat(factor)) - } - - #[inline] - pub fn from_translation(mut translation: Vector4F) -> Transform4F { - translation.set_w(1.0); - Transform4F { c3: translation.0, ..Transform4F::default() } - } - - // TODO(pcwalton): Optimize. - pub fn from_rotation(yaw: f32, pitch: f32, roll: f32) -> Transform4F { - let (cos_b, sin_b) = (yaw.cos(), yaw.sin()); - let (cos_c, sin_c) = (pitch.cos(), pitch.sin()); - let (cos_a, sin_a) = (roll.cos(), roll.sin()); - let m00 = cos_a * cos_b; - let m01 = cos_a * sin_b * sin_c - sin_a * cos_c; - let m02 = cos_a * sin_b * cos_c + sin_a * sin_c; - let m10 = sin_a * cos_b; - let m11 = sin_a * sin_b * sin_c + cos_a * cos_c; - let m12 = sin_a * sin_b * cos_c - cos_a * sin_c; - let m20 = -sin_b; - let m21 = cos_b * sin_c; - let m22 = cos_b * cos_c; - Transform4F::row_major( - m00, m01, m02, 0.0, m10, m11, m12, 0.0, m20, m21, m22, 0.0, 0.0, 0.0, 0.0, 1.0, - ) - } - - /// Creates a rotation matrix from the given quaternion. - /// - /// The quaternion is expected to be packed into a SIMD type (x, y, z, w) corresponding to - /// x + yi + zj + wk. - pub fn from_rotation_quaternion(q: F32x4) -> Transform4F { - // TODO(pcwalton): Optimize better with more shuffles. - let (mut sq, mut w, mut xy_xz_yz) = (q * q, q.wwww() * q, q.xxyy() * q.yzzy()); - sq += sq; - w += w; - xy_xz_yz += xy_xz_yz; - let diag = F32x4::splat(1.0) - (sq.yxxy() + sq.zzyy()); - let (wx2, wy2, wz2) = (w.x(), w.y(), w.z()); - let (xy2, xz2, yz2) = (xy_xz_yz.x(), xy_xz_yz.y(), xy_xz_yz.z()); - Transform4F::row_major( - diag.x(), - xy2 - wz2, - xz2 + wy2, - 0.0, - xy2 + wz2, - diag.y(), - yz2 - wx2, - 0.0, - xz2 - wy2, - yz2 + wx2, - diag.z(), - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - ) - } - - /// Just like `glOrtho()`. - #[inline] - pub fn from_ortho( - left: f32, - right: f32, - bottom: f32, - top: f32, - near_val: f32, - far_val: f32, - ) -> Transform4F { - let x_inv = 1.0 / (right - left); - let y_inv = 1.0 / (top - bottom); - let z_inv = 1.0 / (far_val - near_val); - let tx = -(right + left) * x_inv; - let ty = -(top + bottom) * y_inv; - let tz = -(far_val + near_val) * z_inv; - Transform4F::row_major( - 2.0 * x_inv, - 0.0, - 0.0, - tx, - 0.0, - 2.0 * y_inv, - 0.0, - ty, - 0.0, - 0.0, - -2.0 * z_inv, - tz, - 0.0, - 0.0, - 0.0, - 1.0, - ) - } - - /// Linearly interpolate between transforms - pub fn lerp(&self, weight: f32, other: &Transform4F) -> Transform4F { - let c0 = self.c0 * F32x4::splat(weight) + other.c0 * F32x4::splat(1.0 - weight); - let c1 = self.c1 * F32x4::splat(weight) + other.c1 * F32x4::splat(1.0 - weight); - let c2 = self.c2 * F32x4::splat(weight) + other.c2 * F32x4::splat(1.0 - weight); - let c3 = self.c3 * F32x4::splat(weight) + other.c3 * F32x4::splat(1.0 - weight); - Transform4F { c0, c1, c2, c3 } - } - - /// Just like `gluPerspective()`. - #[inline] - pub fn from_perspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) -> Transform4F { - let f = 1.0 / (fov_y * 0.5).tan(); - let z_denom = 1.0 / (z_near - z_far); - let m00 = f / aspect; - let m11 = f; - let m22 = (z_far + z_near) * z_denom; - let m23 = 2.0 * z_far * z_near * z_denom; - let m32 = -1.0; - Transform4F::row_major( - m00, 0.0, 0.0, 0.0, 0.0, m11, 0.0, 0.0, 0.0, 0.0, m22, m23, 0.0, 0.0, m32, 0.0, - ) - } - - /// Just like `gluLookAt()`. - #[inline] - pub fn looking_at(eye: Vector3F, center: Vector3F, mut up: Vector3F) -> Transform4F { - let f = (center - eye).normalize(); - up = up.normalize(); - let s = f.cross(up); - let u = s.normalize().cross(f); - let minus_f = -f; - - // TODO(pcwalton): Use SIMD. This needs a matrix transpose: - // https://fgiesen.wordpress.com/2013/07/09/simd-transposes-1/ - let transform = Transform4F::row_major(s.x(), s.y(), s.z(), 0.0, - u.x(), u.y(), u.z(), 0.0, - minus_f.x(), minus_f.y(), minus_f.z(), 0.0, - 0.0, 0.0, 0.0, 1.0) * - Transform4F::from_translation((-eye).to_4d()); - transform - } - - // +- -+ - // | A B | - // | C D | - // +- -+ - #[inline] - pub fn from_submatrices( - a: Matrix2x2F, - b: Matrix2x2F, - c: Matrix2x2F, - d: Matrix2x2F, - ) -> Transform4F { - Transform4F { - c0: a.0.concat_xy_xy(c.0), - c1: a.0.concat_zw_zw(c.0), - c2: b.0.concat_xy_xy(d.0), - c3: b.0.concat_zw_zw(d.0), - } - } - - #[inline] - pub fn rotate(&self, yaw: f32, pitch: f32, roll: f32) -> Transform4F { - Transform4F::from_rotation(yaw, pitch, roll) * *self - } - - #[inline] - pub fn scale(&self, scale: Vector4F) -> Transform4F { - Transform4F::from_scale(scale) * *self - } - - #[inline] - pub fn uniform_scale(&self, scale: f32) -> Transform4F { - Transform4F::from_uniform_scale(scale) * *self - } - - #[inline] - pub fn translate(&self, translation: Vector4F) -> Transform4F { - Transform4F::from_translation(translation) * *self - } - - #[inline] - pub fn upper_left(&self) -> Matrix2x2F { - Matrix2x2F(self.c0.concat_xy_xy(self.c1)) - } - - #[inline] - pub fn upper_right(&self) -> Matrix2x2F { - Matrix2x2F(self.c2.concat_xy_xy(self.c3)) - } - - #[inline] - pub fn lower_left(&self) -> Matrix2x2F { - Matrix2x2F(self.c0.concat_zw_zw(self.c1)) - } - - #[inline] - pub fn lower_right(&self) -> Matrix2x2F { - Matrix2x2F(self.c2.concat_zw_zw(self.c3)) - } - - // https://en.wikipedia.org/wiki/Invertible_matrix#Blockwise_inversion - // - // If A is the upper left submatrix of this matrix, this method assumes that A and the Schur - // complement of A are invertible. - pub fn inverse(&self) -> Transform4F { - // Extract submatrices. - let (a, b) = (self.upper_left(), self.upper_right()); - let (c, d) = (self.lower_left(), self.lower_right()); - - // Compute temporary matrices. - let a_inv = a.inverse(); - let x = c * a_inv; - let y = (d - x * b).inverse(); - let z = a_inv * b; - - // Compute new submatrices. - let (a_new, b_new) = (a_inv + z * y * x, -z * y); - let (c_new, d_new) = (-y * x, y); - - // Construct inverse. - Transform4F::from_submatrices(a_new, b_new, c_new, d_new) - } - - pub fn approx_eq(&self, other: &Transform4F, epsilon: f32) -> bool { - self.c0.approx_eq(other.c0, epsilon) - && self.c1.approx_eq(other.c1, epsilon) - && self.c2.approx_eq(other.c2, epsilon) - && self.c3.approx_eq(other.c3, epsilon) - } - - #[inline] - pub fn as_ptr(&self) -> *const f32 { - (&self.c0) as *const F32x4 as *const f32 - } - - #[inline] - pub fn to_columns(&self) -> [F32x4; 4] { - [self.c0, self.c1, self.c2, self.c3] - } -} - -impl Mul for Transform4F { - type Output = Transform4F; - - // https://stackoverflow.com/a/18508113 - #[inline] - fn mul(self, other: Transform4F) -> Transform4F { - return Transform4F { - c0: mul_col(&self, other.c0), - c1: mul_col(&self, other.c1), - c2: mul_col(&self, other.c2), - c3: mul_col(&self, other.c3), - }; - - #[inline] - fn mul_col(a: &Transform4F, b_col: F32x4) -> F32x4 { - a.c0 * b_col.xxxx() + a.c1 * b_col.yyyy() + a.c2 * b_col.zzzz() + a.c3 * b_col.wwww() - } - } -} - -impl Mul for Transform4F { - type Output = Vector4F; - - #[inline] - fn mul(self, vector: Vector4F) -> Vector4F { - let term0 = self.c0 * F32x4::splat(vector.x()); - let term1 = self.c1 * F32x4::splat(vector.y()); - let term2 = self.c2 * F32x4::splat(vector.z()); - let term3 = self.c3 * F32x4::splat(vector.w()); - Vector4F(term0 + term1 + term2 + term3) - } -} - -impl MulAssign for Transform4F { - fn mul_assign(&mut self, other: Transform4F) { - *self = *self * other - } -} - -impl Add for Matrix2x2F { - type Output = Matrix2x2F; - #[inline] - fn add(self, other: Matrix2x2F) -> Matrix2x2F { - Matrix2x2F(self.0 + other.0) - } -} - -impl Neg for Matrix2x2F { - type Output = Matrix2x2F; - #[inline] - fn neg(self) -> Matrix2x2F { - Matrix2x2F(-self.0) - } -} - -#[derive(Clone, Copy, Debug)] -pub struct Perspective { - pub transform: Transform4F, - pub window_size: Vector2I, -} - -impl Perspective { - #[inline] - pub fn new(transform: &Transform4F, window_size: Vector2I) -> Perspective { - Perspective { - transform: *transform, - window_size, - } - } -} - -impl Mul for Perspective { - type Output = Perspective; - #[inline] - fn mul(self, other: Transform4F) -> Perspective { - Perspective { - transform: self.transform * other, - window_size: self.window_size, - } - } -} - -impl Mul for Perspective { - type Output = Vector2F; - #[inline] - fn mul(self, vector: Vector2F) -> Vector2F { - let point = (self.transform * vector.to_4d()).to_2d() * Vector2F::new(1.0, -1.0); - (point + 1.0) * self.window_size.to_f32() * 0.5 - } -} - -impl Mul for Perspective { - type Output = RectF; - #[inline] - fn mul(self, rect: RectF) -> RectF { - let (upper_left, upper_right) = (self * rect.origin(), self * rect.upper_right()); - let (lower_left, lower_right) = (self * rect.lower_left(), self * rect.lower_right()); - let min_point = upper_left.min(upper_right).min(lower_left).min(lower_right); - let max_point = upper_left.max(upper_right).max(lower_left).max(lower_right); - RectF::from_points(min_point, max_point) - } -} - -#[cfg(test)] -mod test { - use crate::vector::Vector4F; - use crate::transform3d::Transform4F; - - #[test] - fn test_post_mul() { - let a = Transform4F::row_major( - 3.0, 1.0, 4.0, 5.0, 9.0, 2.0, 6.0, 5.0, 3.0, 5.0, 8.0, 9.0, 7.0, 9.0, 3.0, 2.0, - ); - let b = Transform4F::row_major( - 3.0, 8.0, 4.0, 6.0, 2.0, 6.0, 4.0, 3.0, 3.0, 8.0, 3.0, 2.0, 7.0, 9.0, 5.0, 0.0, - ); - let c = Transform4F::row_major( - 58.0, 107.0, 53.0, 29.0, 84.0, 177.0, 87.0, 72.0, 106.0, 199.0, 101.0, 49.0, 62.0, - 152.0, 83.0, 75.0, - ); - assert_eq!(a * b, c); - } - - #[test] - fn test_pre_mul() { - let a = Transform4F::row_major( - 3.0, 1.0, 4.0, 5.0, 9.0, 2.0, 6.0, 5.0, 3.0, 5.0, 8.0, 9.0, 7.0, 9.0, 3.0, 2.0, - ); - let b = Transform4F::row_major( - 3.0, 8.0, 4.0, 6.0, 2.0, 6.0, 4.0, 3.0, 3.0, 8.0, 3.0, 2.0, 7.0, 9.0, 5.0, 0.0, - ); - let c = Transform4F::row_major( - 135.0, 93.0, 110.0, 103.0, 93.0, 61.0, 85.0, 82.0, 104.0, 52.0, 90.0, 86.0, 117.0, - 50.0, 122.0, 125.0, - ); - assert_eq!(b * a, c); - } - - #[test] - fn test_transform_point() { - let a = Transform4F::row_major( - 3.0, 1.0, 4.0, 5.0, 9.0, 2.0, 6.0, 5.0, 3.0, 5.0, 8.0, 9.0, 7.0, 9.0, 3.0, 2.0, - ); - let p = Vector4F::new(3.0, 8.0, 4.0, 6.0); - let q = Vector4F::new(63.0, 97.0, 135.0, 117.0); - assert_eq!(a * p, q); - } - - #[test] - fn test_inverse() { - // Random matrix. - let m = Transform4F::row_major( - 0.86277982, 0.15986552, 0.90739898, 0.60066808, 0.17386167, 0.016353, 0.8535783, - 0.12969608, 0.0946466, 0.43248631, 0.63480505, 0.08154603, 0.50305436, 0.48359687, - 0.51057162, 0.24812012, - ); - let p0 = Vector4F::new(0.95536648, 0.80633691, 0.16357357, 0.5477598); - let p1 = m * p0; - let m_inv = m.inverse(); - let m_inv_exp = Transform4F::row_major( - -2.47290136, - 3.48865688, - -6.12298336, - 6.17536696, - 0.00124033357, - -1.72561993, - 2.16876606, - 0.186227748, - -0.375021729, - 1.53883017, - -0.0558194403, - 0.121857058, - 5.78300323, - -6.87635769, - 8.30196620, - -9.10374060, - ); - assert!(m_inv.approx_eq(&m_inv_exp, 0.0001)); - let p2 = m_inv * p1; - assert!(p0.approx_eq(p2, 0.0001)); - } -} diff --git a/crates/pathfinder/geometry/src/unit_vector.rs b/crates/pathfinder/geometry/src/unit_vector.rs deleted file mode 100644 index 5a36d1d1f3..0000000000 --- a/crates/pathfinder/geometry/src/unit_vector.rs +++ /dev/null @@ -1,47 +0,0 @@ -// pathfinder/geometry/src/unit_vector.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A utility module that allows unit vectors to be treated like angles. - -use crate::vector::Vector2F; -use pathfinder_simd::default::F32x2; - -#[derive(Clone, Copy, Debug)] -pub struct UnitVector(pub Vector2F); - -impl UnitVector { - #[inline] - pub fn from_angle(theta: f32) -> UnitVector { - UnitVector(Vector2F::new(theta.cos(), theta.sin())) - } - - /// Angle addition formula. - #[inline] - pub fn rotate_by(&self, other: UnitVector) -> UnitVector { - let products = (self.0).0.to_f32x4().xyyx() * (other.0).0.to_f32x4().xyxy(); - UnitVector(Vector2F::new(products[0] - products[1], products[2] + products[3])) - } - - /// Angle subtraction formula. - #[inline] - pub fn rev_rotate_by(&self, other: UnitVector) -> UnitVector { - let products = (self.0).0.to_f32x4().xyyx() * (other.0).0.to_f32x4().xyxy(); - UnitVector(Vector2F::new(products[0] + products[1], products[2] - products[3])) - } - - /// Half angle formula. - #[inline] - pub fn halve_angle(&self) -> UnitVector { - let x = self.0.x(); - let term = F32x2::new(x, -x); - UnitVector(Vector2F((F32x2::splat(0.5) * (F32x2::splat(1.0) + term)).max(F32x2::default()) - .sqrt())) - } -} diff --git a/crates/pathfinder/geometry/src/util.rs b/crates/pathfinder/geometry/src/util.rs deleted file mode 100644 index 1add973be9..0000000000 --- a/crates/pathfinder/geometry/src/util.rs +++ /dev/null @@ -1,39 +0,0 @@ -// pathfinder/geometry/src/util.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Various utilities. - -use std::f32; - -pub const EPSILON: f32 = 0.001; - -/// Approximate equality. -#[inline] -pub fn approx_eq(a: f32, b: f32) -> bool { - f32::abs(a - b) <= EPSILON -} - -/// Linear interpolation. -#[inline] -pub fn lerp(a: f32, b: f32, t: f32) -> f32 { - a + (b - a) * t -} - -/// Clamping. -#[inline] -pub fn clamp(x: f32, min_val: f32, max_val: f32) -> f32 { - f32::min(max_val, f32::max(min_val, x)) -} - -/// Divides `a` by `b`, rounding up. -#[inline] -pub fn alignup_i32(a: i32, b: i32) -> i32 { - (a + b - 1) / b -} diff --git a/crates/pathfinder/geometry/src/vector.rs b/crates/pathfinder/geometry/src/vector.rs deleted file mode 100644 index cd2c28cf08..0000000000 --- a/crates/pathfinder/geometry/src/vector.rs +++ /dev/null @@ -1,687 +0,0 @@ -// pathfinder/geometry/src/basic/point.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A SIMD-optimized point type. - -use pathfinder_simd::default::{F32x2, F32x4, I32x2}; -use std::hash::{Hash, Hasher}; -use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign}; - -/// 2D points with 32-bit floating point coordinates. -#[derive(Clone, Copy, Debug, Default)] -pub struct Vector2F(pub F32x2); - -impl Vector2F { - #[inline] - pub fn new(x: f32, y: f32) -> Vector2F { - Vector2F(F32x2::new(x, y)) - } - - #[inline] - pub fn splat(value: f32) -> Vector2F { - Vector2F(F32x2::splat(value)) - } - - #[inline] - pub fn zero() -> Vector2F { - Vector2F::default() - } - - #[inline] - pub fn to_3d(self) -> Vector3F { - Vector3F(self.0.to_f32x4().concat_xy_zw(F32x4::new(0.0, 0.0, 0.0, 0.0))) - } - - #[inline] - pub fn to_4d(self) -> Vector4F { - Vector4F(self.0.to_f32x4().concat_xy_zw(F32x4::new(0.0, 0.0, 0.0, 1.0))) - } - - #[inline] - pub fn x(self) -> f32 { - self.0[0] - } - - #[inline] - pub fn y(self) -> f32 { - self.0[1] - } - - #[inline] - pub fn set_x(&mut self, x: f32) { - self.0[0] = x; - } - - #[inline] - pub fn set_y(&mut self, y: f32) { - self.0[1] = y; - } - - #[inline] - pub fn min(self, other: Vector2F) -> Vector2F { - Vector2F(self.0.min(other.0)) - } - - #[inline] - pub fn max(self, other: Vector2F) -> Vector2F { - Vector2F(self.0.max(other.0)) - } - - #[inline] - pub fn clamp(self, min_val: Vector2F, max_val: Vector2F) -> Vector2F { - self.max(min_val).min(max_val) - } - - #[inline] - pub fn det(self, other: Vector2F) -> f32 { - self.x() * other.y() - self.y() * other.x() - } - - #[inline] - pub fn dot(self, other: Vector2F) -> f32 { - let xy = self.0 * other.0; - xy.x() + xy.y() - } - - #[inline] - pub fn floor(self) -> Vector2F { - Vector2F(self.0.floor()) - } - - #[inline] - pub fn ceil(self) -> Vector2F { - Vector2F(self.0.ceil()) - } - - /// Rounds both coordinates to the nearest integer. - #[inline] - pub fn round(self) -> Vector2F { - Vector2F(self.0.to_i32x2().to_f32x2()) - } - - /// Treats this point as a vector and calculates its squared length. - #[inline] - pub fn square_length(self) -> f32 { - let squared = self.0 * self.0; - squared[0] + squared[1] - } - - /// Treats this point as a vector and calculates its length. - #[inline] - pub fn length(self) -> f32 { - f32::sqrt(self.square_length()) - } - - /// Treats this point as a vector and normalizes it. - #[inline] - pub fn normalize(self) -> Vector2F { - self * (1.0 / self.length()) - } - - /// Swaps y and x. - #[inline] - pub fn yx(self) -> Vector2F { - Vector2F(self.0.yx()) - } - - /// Returns the coefficient when the given vector `a` is projected onto this one. - /// - /// That is, if this vector is `v` and this function returns `c`, then `proj_v a = cv`. In - /// other words, this function computes `(a⋅v) / (v⋅v)`. - #[inline] - pub fn projection_coefficient(self, a: Vector2F) -> f32 { - a.dot(self) / self.square_length() - } - - #[inline] - pub fn is_zero(self) -> bool { - self == Vector2F::zero() - } - - #[inline] - pub fn lerp(self, other: Vector2F, t: f32) -> Vector2F { - self + (other - self) * t - } - - #[inline] - pub fn to_i32(self) -> Vector2I { - Vector2I(self.0.to_i32x2()) - } -} - -/// A convenience alias for `Vector2F::new()`. -#[inline] -pub fn vec2f(x: f32, y: f32) -> Vector2F { - Vector2F::new(x, y) -} - -impl PartialEq for Vector2F { - #[inline] - fn eq(&self, other: &Vector2F) -> bool { - self.0.packed_eq(other.0).all_true() - } -} - -impl Add for Vector2F { - type Output = Vector2F; - #[inline] - fn add(self, other: Vector2F) -> Vector2F { - Vector2F(self.0 + other.0) - } -} - -impl Add for Vector2F { - type Output = Vector2F; - #[inline] - fn add(self, other: f32) -> Vector2F { - self + Vector2F::splat(other) - } -} - -impl AddAssign for Vector2F { - #[inline] - fn add_assign(&mut self, other: Vector2F) { - *self = *self + other - } -} - -impl Sub for Vector2F { - type Output = Vector2F; - #[inline] - fn sub(self, other: Vector2F) -> Vector2F { - Vector2F(self.0 - other.0) - } -} - -impl Sub for Vector2F { - type Output = Vector2F; - #[inline] - fn sub(self, other: f32) -> Vector2F { - self - Vector2F::splat(other) - } -} - -impl SubAssign for Vector2F { - #[inline] - fn sub_assign(&mut self, other: Vector2F) { - *self = *self - other - } -} - -impl Mul for Vector2F { - type Output = Vector2F; - #[inline] - fn mul(self, other: Vector2F) -> Vector2F { - Vector2F(self.0 * other.0) - } -} - -impl Mul for Vector2F { - type Output = Vector2F; - #[inline] - fn mul(self, other: f32) -> Vector2F { - self * Vector2F::splat(other) - } -} - -impl MulAssign for Vector2F { - #[inline] - fn mul_assign(&mut self, other: Vector2F) { - *self = *self * other - } -} - -impl MulAssign for Vector2F { - #[inline] - fn mul_assign(&mut self, other: f32) { - *self = *self * other - } -} - -impl Div for Vector2F { - type Output = Vector2F; - #[inline] - fn div(self, other: Vector2F) -> Vector2F { - Vector2F(self.0 / other.0) - } -} - -impl Div for Vector2F { - type Output = Vector2F; - #[inline] - fn div(self, other: f32) -> Vector2F { - self / Vector2F::splat(other) - } -} - -impl Neg for Vector2F { - type Output = Vector2F; - #[inline] - fn neg(self) -> Vector2F { - Vector2F(-self.0) - } -} - -/// Either a scalar or a `Vector2F`. -/// -/// Scalars will be automatically splatted (i.e. `x` becomes `vec2f(x, x)`). -/// -/// Be judicious with the use of this trait. Only use it if it will aid readability without the -/// potential to introduce bugs. -pub trait IntoVector2F { - fn into_vector_2f(self) -> Vector2F; -} - -impl IntoVector2F for Vector2F { - #[inline] - fn into_vector_2f(self) -> Vector2F { - self - } -} - -impl IntoVector2F for f32 { - #[inline] - fn into_vector_2f(self) -> Vector2F { - Vector2F::splat(self) - } -} - -/// 2D points with 32-bit signed integer coordinates. -#[derive(Clone, Copy, Debug, Default)] -pub struct Vector2I(pub I32x2); - -impl Vector2I { - #[inline] - pub fn new(x: i32, y: i32) -> Vector2I { - Vector2I(I32x2::new(x, y)) - } - - #[inline] - pub fn splat(value: i32) -> Vector2I { - Vector2I(I32x2::splat(value)) - } - - #[inline] - pub fn zero() -> Vector2I { - Vector2I::default() - } - - #[inline] - pub fn x(self) -> i32 { - self.0[0] - } - - #[inline] - pub fn y(self) -> i32 { - self.0[1] - } - - #[inline] - pub fn set_x(&mut self, x: i32) { - self.0[0] = x; - } - - #[inline] - pub fn set_y(&mut self, y: i32) { - self.0[1] = y; - } - - #[inline] - pub fn min(self, other: Vector2I) -> Vector2I { - Vector2I(self.0.min(other.0)) - } - - #[inline] - pub fn max(self, other: Vector2I) -> Vector2I { - Vector2I(self.0.max(other.0)) - } - - #[inline] - pub fn to_f32(self) -> Vector2F { - Vector2F(self.0.to_f32x2()) - } -} - -/// A convenience alias for `Vector2I::new()`. -#[inline] -pub fn vec2i(x: i32, y: i32) -> Vector2I { - Vector2I::new(x, y) -} - -impl Add for Vector2I { - type Output = Vector2I; - #[inline] - fn add(self, other: Vector2I) -> Vector2I { - Vector2I(self.0 + other.0) - } -} - -impl Add for Vector2I { - type Output = Vector2I; - #[inline] - fn add(self, other: i32) -> Vector2I { - self + Vector2I::splat(other) - } -} - -impl AddAssign for Vector2I { - #[inline] - fn add_assign(&mut self, other: Vector2I) { - self.0 += other.0 - } -} - -impl Neg for Vector2I { - type Output = Vector2I; - #[inline] - fn neg(self) -> Vector2I { - Vector2I(-self.0) - } -} - -impl Sub for Vector2I { - type Output = Vector2I; - #[inline] - fn sub(self, other: Vector2I) -> Vector2I { - Vector2I(self.0 - other.0) - } -} - -impl Sub for Vector2I { - type Output = Vector2I; - #[inline] - fn sub(self, other: i32) -> Vector2I { - self - Vector2I::splat(other) - } -} - -impl Mul for Vector2I { - type Output = Vector2I; - #[inline] - fn mul(self, other: Vector2I) -> Vector2I { - Vector2I(self.0 * other.0) - } -} - -impl Mul for Vector2I { - type Output = Vector2I; - #[inline] - fn mul(self, other: i32) -> Vector2I { - self * Vector2I::splat(other) - } -} - -impl PartialEq for Vector2I { - #[inline] - fn eq(&self, other: &Vector2I) -> bool { - self.0.packed_eq(other.0).all_true() - } -} - -impl Eq for Vector2I {} - -impl Hash for Vector2I { - #[inline] - fn hash(&self, state: &mut H) where H: Hasher { - self.x().hash(state); - self.y().hash(state); - } -} - -/// 3D points. -/// -/// The w value in the SIMD vector is always 0.0. -#[derive(Clone, Copy, Debug, Default, PartialEq)] -pub struct Vector3F(pub F32x4); - -impl Vector3F { - #[inline] - pub fn new(x: f32, y: f32, z: f32) -> Vector3F { - Vector3F(F32x4::new(x, y, z, 0.0)) - } - - #[inline] - pub fn splat(x: f32) -> Vector3F { - let mut vector = F32x4::splat(x); - vector.set_w(0.0); - Vector3F(vector) - } - - /// Truncates this vector to 2D. - #[inline] - pub fn to_2d(self) -> Vector2F { - Vector2F(self.0.xy()) - } - - /// Converts this vector to an equivalent 3D homogeneous one with a w component of 1.0. - #[inline] - pub fn to_4d(self) -> Vector4F { - let mut vector = self.0; - vector.set_w(1.0); - Vector4F(vector) - } - - #[inline] - pub fn cross(self, other: Vector3F) -> Vector3F { - Vector3F(self.0.yzxw() * other.0.zxyw() - self.0.zxyw() * other.0.yzxw()) - } - - #[inline] - pub fn square_length(self) -> f32 { - let squared = self.0 * self.0; - squared[0] + squared[1] + squared[2] - } - - #[inline] - pub fn length(self) -> f32 { - f32::sqrt(self.square_length()) - } - - #[inline] - pub fn normalize(self) -> Vector3F { - Vector3F(self.0 * F32x4::splat(1.0 / self.length())) - } - - #[inline] - pub fn x(self) -> f32 { - self.0[0] - } - - #[inline] - pub fn y(self) -> f32 { - self.0[1] - } - - #[inline] - pub fn z(self) -> f32 { - self.0[2] - } - - #[inline] - pub fn scale(self, factor: f32) -> Vector3F { - Vector3F(self.0 * F32x4::splat(factor)) - } -} - -impl Add for Vector3F { - type Output = Vector3F; - #[inline] - fn add(self, other: Vector3F) -> Vector3F { - Vector3F(self.0 + other.0) - } -} - -impl AddAssign for Vector3F { - #[inline] - fn add_assign(&mut self, other: Vector3F) { - self.0 += other.0 - } -} - -impl Neg for Vector3F { - type Output = Vector3F; - #[inline] - fn neg(self) -> Vector3F { - Vector3F(self.0 * F32x4::new(-1.0, -1.0, -1.0, 0.0)) - } -} - -impl Sub for Vector3F { - type Output = Vector3F; - #[inline] - fn sub(self, other: Vector3F) -> Vector3F { - Vector3F(self.0 - other.0) - } -} - -/// 3D homogeneous points. -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct Vector4F(pub F32x4); - -impl Vector4F { - #[inline] - pub fn new(x: f32, y: f32, z: f32, w: f32) -> Vector4F { - Vector4F(F32x4::new(x, y, z, w)) - } - - #[inline] - pub fn splat(value: f32) -> Vector4F { - Vector4F(F32x4::splat(value)) - } - - #[inline] - pub fn to_2d(self) -> Vector2F { - self.to_3d().to_2d() - } - - /// Performs perspective division to convert this vector to 3D. - #[inline] - pub fn to_3d(self) -> Vector3F { - let mut vector = self.0 * F32x4::splat(1.0 / self.w()); - vector.set_w(0.0); - Vector3F(vector) - } - - #[inline] - pub fn x(self) -> f32 { - self.0[0] - } - - #[inline] - pub fn y(self) -> f32 { - self.0[1] - } - - #[inline] - pub fn z(self) -> f32 { - self.0[2] - } - - #[inline] - pub fn w(self) -> f32 { - self.0[3] - } - - #[inline] - pub fn scale(self, x: f32) -> Vector4F { - let mut factors = F32x4::splat(x); - factors[3] = 1.0; - Vector4F(self.0 * factors) - } - - #[inline] - pub fn set_x(&mut self, x: f32) { - self.0[0] = x - } - - #[inline] - pub fn set_y(&mut self, y: f32) { - self.0[1] = y - } - - #[inline] - pub fn set_z(&mut self, z: f32) { - self.0[2] = z - } - - #[inline] - pub fn set_w(&mut self, w: f32) { - self.0[3] = w - } - - #[inline] - pub fn approx_eq(self, other: Vector4F, epsilon: f32) -> bool { - self.0.approx_eq(other.0, epsilon) - } - - /// Checks to see whether this *homogeneous* coordinate equals zero. - /// - /// Note that since this treats the coordinate as a homogeneous coordinate, the `w` is ignored. - // TODO(pcwalton): Optimize with SIMD. - #[inline] - pub fn is_zero(self) -> bool { - self.x() == 0.0 && self.y() == 0.0 && self.z() == 0.0 - } - - #[inline] - pub fn lerp(self, other: Vector4F, t: f32) -> Vector4F { - Vector4F(self.0 + (other.0 - self.0) * F32x4::splat(t)) - } -} - -impl Add for Vector4F { - type Output = Vector4F; - #[inline] - fn add(self, other: Vector4F) -> Vector4F { - Vector4F(self.0 + other.0) - } -} - -impl AddAssign for Vector4F { - #[inline] - fn add_assign(&mut self, other: Vector4F) { - self.0 += other.0 - } -} - -impl Mul for Vector4F { - type Output = Vector4F; - #[inline] - fn mul(self, other: Vector4F) -> Vector4F { - Vector4F(self.0 * other.0) - } -} - -impl Neg for Vector4F { - type Output = Vector4F; - /// NB: This does not negate w, because that is rarely what you what for homogeneous - /// coordinates. - #[inline] - fn neg(self) -> Vector4F { - Vector4F(self.0 * F32x4::new(-1.0, -1.0, -1.0, 1.0)) - } -} - -impl Sub for Vector4F { - type Output = Vector4F; - #[inline] - fn sub(self, other: Vector4F) -> Vector4F { - Vector4F(self.0 - other.0) - } -} - -impl Default for Vector4F { - #[inline] - fn default() -> Vector4F { - let mut point = F32x4::default(); - point.set_w(1.0); - Vector4F(point) - } -} diff --git a/crates/pathfinder/gpu/Cargo.toml b/crates/pathfinder/gpu/Cargo.toml deleted file mode 100644 index 80a178692b..0000000000 --- a/crates/pathfinder/gpu/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "pathfinder_gpu" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -description = "A simple cross-platform GPU abstraction library" -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" - -[dependencies.image] -version = "0.23" -default-features = false -features = ["png"] - -[dependencies.pathfinder_color] -path = "../color" -version = "0.5" - -[dependencies.pathfinder_geometry] -path = "../geometry" -version = "0.5" - -[dependencies.pathfinder_resources] -path = "../resources" -version = "0.5" - -[dependencies.pathfinder_simd] -path = "../simd" -version = "0.5" diff --git a/crates/pathfinder/gpu/src/lib.rs b/crates/pathfinder/gpu/src/lib.rs deleted file mode 100644 index 77a1b5f55a..0000000000 --- a/crates/pathfinder/gpu/src/lib.rs +++ /dev/null @@ -1,605 +0,0 @@ -// pathfinder/gpu/src/lib.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Minimal abstractions over GPU device capabilities. - -#[macro_use] -extern crate bitflags; - -use half::f16; -use image::ImageFormat; -use pathfinder_color::ColorF; -use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::transform3d::Transform4F; -use pathfinder_geometry::vector::{Vector2I, vec2i}; -use pathfinder_resources::ResourceLoader; -use pathfinder_simd::default::{F32x2, F32x4, I32x2}; -use std::os::raw::c_void; -use std::time::Duration; - -pub trait Device: Sized { - type Buffer; - type Fence; - type Framebuffer; - type Program; - type Shader; - type StorageBuffer; - type Texture; - type TextureDataReceiver; - type TimerQuery; - type Uniform; - type VertexArray; - type VertexAttr; - - fn feature_level(&self) -> FeatureLevel; - fn create_texture(&self, format: TextureFormat, size: Vector2I) -> Self::Texture; - fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef) - -> Self::Texture; - fn create_shader(&self, resources: &dyn ResourceLoader, name: &str, kind: ShaderKind) - -> Self::Shader; - fn create_shader_from_source(&self, name: &str, source: &[u8], kind: ShaderKind) - -> Self::Shader; - fn create_vertex_array(&self) -> Self::VertexArray; - fn create_program_from_shaders(&self, - resources: &dyn ResourceLoader, - name: &str, - shaders: ProgramKind) - -> Self::Program; - fn set_compute_program_local_size(&self, - program: &mut Self::Program, - local_size: ComputeDimensions); - fn get_vertex_attr(&self, program: &Self::Program, name: &str) -> Option; - fn get_uniform(&self, program: &Self::Program, name: &str) -> Self::Uniform; - fn get_storage_buffer(&self, program: &Self::Program, name: &str, binding: u32) - -> Self::StorageBuffer; - fn bind_buffer(&self, - vertex_array: &Self::VertexArray, - buffer: &Self::Buffer, - target: BufferTarget); - fn configure_vertex_attr(&self, - vertex_array: &Self::VertexArray, - attr: &Self::VertexAttr, - descriptor: &VertexAttrDescriptor); - fn create_framebuffer(&self, texture: Self::Texture) -> Self::Framebuffer; - fn create_buffer(&self, mode: BufferUploadMode) -> Self::Buffer; - fn allocate_buffer(&self, - buffer: &Self::Buffer, - data: BufferData, - target: BufferTarget); - fn upload_to_buffer(&self, - buffer: &Self::Buffer, - position: usize, - data: &[T], - target: BufferTarget); - fn framebuffer_texture<'f>(&self, framebuffer: &'f Self::Framebuffer) -> &'f Self::Texture; - fn destroy_framebuffer(&self, framebuffer: Self::Framebuffer) -> Self::Texture; - fn texture_format(&self, texture: &Self::Texture) -> TextureFormat; - fn texture_size(&self, texture: &Self::Texture) -> Vector2I; - fn set_texture_sampling_mode(&self, texture: &Self::Texture, flags: TextureSamplingFlags); - fn upload_to_texture(&self, texture: &Self::Texture, rect: RectI, data: TextureDataRef); - fn read_pixels(&self, target: &RenderTarget, viewport: RectI) - -> Self::TextureDataReceiver; - fn begin_commands(&self); - fn end_commands(&self); - fn draw_arrays(&self, index_count: u32, render_state: &RenderState); - fn draw_elements(&self, index_count: u32, render_state: &RenderState); - fn draw_elements_instanced(&self, - index_count: u32, - instance_count: u32, - render_state: &RenderState); - fn dispatch_compute(&self, dimensions: ComputeDimensions, state: &ComputeState); - fn add_fence(&self) -> Self::Fence; - fn wait_for_fence(&self, fence: &Self::Fence); - fn create_timer_query(&self) -> Self::TimerQuery; - fn begin_timer_query(&self, query: &Self::TimerQuery); - fn end_timer_query(&self, query: &Self::TimerQuery); - fn try_recv_timer_query(&self, query: &Self::TimerQuery) -> Option; - fn recv_timer_query(&self, query: &Self::TimerQuery) -> Duration; - fn try_recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> Option; - fn recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> TextureData; - - fn create_texture_from_png(&self, - resources: &dyn ResourceLoader, - name: &str, - format: TextureFormat) - -> Self::Texture { - let data = resources.slurp(&format!("textures/{}.png", name)).unwrap(); - let image = image::load_from_memory_with_format(&data, ImageFormat::Png).unwrap(); - match format { - TextureFormat::R8 => { - let image = image.to_luma(); - let size = vec2i(image.width() as i32, image.height() as i32); - self.create_texture_from_data(format, size, TextureDataRef::U8(&image)) - } - TextureFormat::RGBA8 => { - let image = image.to_rgba(); - let size = vec2i(image.width() as i32, image.height() as i32); - self.create_texture_from_data(format, size, TextureDataRef::U8(&image)) - } - _ => unimplemented!(), - } - } - - fn create_program_from_shader_names( - &self, - resources: &dyn ResourceLoader, - program_name: &str, - shader_names: ProgramKind<&str>, - ) -> Self::Program { - let shaders = match shader_names { - ProgramKind::Raster { vertex, fragment } => { - ProgramKind::Raster { - vertex: self.create_shader(resources, vertex, ShaderKind::Vertex), - fragment: self.create_shader(resources, fragment, ShaderKind::Fragment), - } - } - ProgramKind::Compute(compute) => { - ProgramKind::Compute(self.create_shader(resources, compute, ShaderKind::Compute)) - } - }; - self.create_program_from_shaders(resources, program_name, shaders) - } - - fn create_raster_program(&self, resources: &dyn ResourceLoader, name: &str) -> Self::Program { - let shaders = ProgramKind::Raster { vertex: name, fragment: name }; - self.create_program_from_shader_names(resources, name, shaders) - } - - fn create_compute_program(&self, resources: &dyn ResourceLoader, name: &str) -> Self::Program { - let shaders = ProgramKind::Compute(name); - self.create_program_from_shader_names(resources, name, shaders) - } -} - -/// These are rough analogues to D3D versions; don't expect them to represent exactly the feature -/// set of the versions. -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum FeatureLevel { - D3D10, - D3D11, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum TextureFormat { - R8, - R16F, - RGBA8, - RGBA16F, - RGBA32F, -} - -#[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), - Memory(&'a [T]), -} - -#[derive(Clone, Copy, Debug)] -pub enum BufferTarget { - Vertex, - Index, - Storage, -} - -#[derive(Clone, Copy, Debug)] -pub enum BufferUploadMode { - Static, - Dynamic, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum ShaderKind { - Vertex, - Fragment, - Compute, -} - -#[derive(Clone, Copy, Debug)] -pub enum ProgramKind { - Raster { - vertex: T, - fragment: T, - }, - Compute(T), -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct ComputeDimensions { - pub x: u32, - pub y: u32, - pub z: u32, -} - -#[derive(Clone, Copy)] -pub enum UniformData { - Float(f32), - IVec2(I32x2), - IVec3([i32; 3]), - Int(i32), - Mat2(F32x4), - Mat4([F32x4; 4]), - Vec2(F32x2), - Vec3([f32; 3]), - Vec4(F32x4), - TextureUnit(u32), - ImageUnit(u32), -} - -#[derive(Clone, Copy)] -pub enum Primitive { - Triangles, - Lines, -} - -#[derive(Clone)] -pub struct RenderState<'a, D> where D: Device { - pub target: &'a RenderTarget<'a, D>, - pub program: &'a D::Program, - pub vertex_array: &'a D::VertexArray, - pub primitive: Primitive, - pub uniforms: &'a [(&'a D::Uniform, UniformData)], - pub textures: &'a [&'a D::Texture], - pub images: &'a [ImageBinding<'a, D>], - pub viewport: RectI, - pub options: RenderOptions, -} - -#[derive(Clone)] -pub struct ComputeState<'a, D> where D: Device { - pub program: &'a D::Program, - pub uniforms: &'a [(&'a D::Uniform, UniformData)], - pub textures: &'a [&'a D::Texture], - pub images: &'a [ImageBinding<'a, D>], - pub storage_buffers: &'a [(&'a D::StorageBuffer, &'a D::Buffer)], -} - -#[derive(Clone, Debug)] -pub struct ImageBinding<'a, D> where D: Device { - pub texture: &'a D::Texture, - pub access: ImageAccess, -} - -#[derive(Clone, Debug)] -pub struct RenderOptions { - pub blend: Option, - pub depth: Option, - pub stencil: Option, - pub clear_ops: ClearOps, - pub color_mask: bool, -} - -#[derive(Clone, Copy, Debug, Default)] -pub struct ClearOps { - pub color: Option, - pub depth: Option, - pub stencil: Option, -} - -#[derive(Clone, Copy, Debug)] -pub enum RenderTarget<'a, D> where D: Device { - Default, - Framebuffer(&'a D::Framebuffer), -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct BlendState { - pub dest_rgb_factor: BlendFactor, - pub dest_alpha_factor: BlendFactor, - pub src_rgb_factor: BlendFactor, - pub src_alpha_factor: BlendFactor, - pub op: BlendOp, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum BlendFactor { - Zero, - One, - SrcAlpha, - OneMinusSrcAlpha, - DestAlpha, - OneMinusDestAlpha, - DestColor, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum BlendOp { - Add, - Subtract, - ReverseSubtract, - Min, - Max, -} - -#[derive(Clone, Copy, Default, Debug)] -pub struct DepthState { - pub func: DepthFunc, - pub write: bool, -} - -#[derive(Clone, Copy, Debug)] -pub enum DepthFunc { - Less, - Always, -} - -#[derive(Clone, Copy, Debug)] -pub struct StencilState { - pub func: StencilFunc, - pub reference: u32, - pub mask: u32, - pub write: bool, -} - -#[derive(Clone, Copy, Debug)] -pub enum StencilFunc { - Always, - Equal, -} - -impl Default for RenderOptions { - #[inline] - fn default() -> RenderOptions { - RenderOptions { - blend: None, - depth: None, - stencil: None, - clear_ops: ClearOps::default(), - color_mask: true, - } - } -} - -impl Default for BlendOp { - #[inline] - fn default() -> BlendOp { - BlendOp::Add - } -} - -impl Default for StencilState { - #[inline] - fn default() -> StencilState { - StencilState { - func: StencilFunc::default(), - reference: 0, - mask: !0, - write: false, - } - } -} - -impl Default for DepthFunc { - #[inline] - fn default() -> DepthFunc { - DepthFunc::Less - } -} - -impl Default for StencilFunc { - #[inline] - fn default() -> StencilFunc { - StencilFunc::Always - } -} - -#[derive(Clone, Debug)] -pub enum TextureData { - U8(Vec), - U16(Vec), - F16(Vec), - F32(Vec), -} - -#[derive(Clone, Copy, Debug)] -pub enum TextureDataRef<'a> { - U8(&'a [u8]), - F16(&'a [f16]), - F32(&'a [f32]), -} - -impl UniformData { - #[inline] - pub fn from_transform_3d(transform: &Transform4F) -> UniformData { - UniformData::Mat4([transform.c0, transform.c1, transform.c2, transform.c3]) - } -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct VertexAttrDescriptor { - pub size: usize, - pub class: VertexAttrClass, - pub attr_type: VertexAttrType, - pub stride: usize, - pub offset: usize, - pub divisor: u32, - pub buffer_index: u32, -} - -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, - Int, -} - -impl TextureFormat { - #[inline] - pub fn channels(self) -> usize { - match self { - TextureFormat::R8 | TextureFormat::R16F => 1, - TextureFormat::RGBA8 | TextureFormat::RGBA16F | TextureFormat::RGBA32F => 4, - } - } - - #[inline] - pub fn bytes_per_pixel(self) -> usize { - match self { - TextureFormat::R8 => 1, - TextureFormat::R16F => 2, - TextureFormat::RGBA8 => 4, - TextureFormat::RGBA16F => 8, - TextureFormat::RGBA32F => 16, - } - } -} - -impl ClearOps { - #[inline] - pub fn has_ops(&self) -> bool { - self.color.is_some() || self.depth.is_some() || self.stencil.is_some() - } -} - -impl Default for BlendState { - #[inline] - fn default() -> BlendState { - BlendState { - src_rgb_factor: BlendFactor::One, - dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, - src_alpha_factor: BlendFactor::One, - dest_alpha_factor: BlendFactor::One, - op: BlendOp::Add, - } - } -} - -bitflags! { - pub struct TextureSamplingFlags: u8 { - const REPEAT_U = 0x01; - const REPEAT_V = 0x02; - const NEAREST_MIN = 0x04; - const NEAREST_MAG = 0x08; - } -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum ImageAccess { - Read, - Write, - ReadWrite, -} - -impl<'a> TextureDataRef<'a> { - #[doc(hidden)] - pub fn check_and_extract_data_ptr(self, minimum_size: Vector2I, format: TextureFormat) - -> *const c_void { - let channels = match (format, self) { - (TextureFormat::R8, TextureDataRef::U8(_)) => 1, - (TextureFormat::RGBA8, TextureDataRef::U8(_)) => 4, - (TextureFormat::RGBA16F, TextureDataRef::F16(_)) => 4, - (TextureFormat::RGBA32F, TextureDataRef::F32(_)) => 4, - _ => panic!("Unimplemented texture format!"), - }; - - let area = minimum_size.x() as usize * minimum_size.y() as usize; - - match self { - TextureDataRef::U8(data) => { - assert!(data.len() >= area * channels); - data.as_ptr() as *const c_void - } - TextureDataRef::F16(data) => { - assert!(data.len() >= area * channels); - data.as_ptr() as *const c_void - } - TextureDataRef::F32(data) => { - assert!(data.len() >= area * channels); - data.as_ptr() as *const c_void - } - } - } -} diff --git a/crates/pathfinder/lottie/Cargo.toml b/crates/pathfinder/lottie/Cargo.toml deleted file mode 100644 index a7b6b26271..0000000000 --- a/crates/pathfinder/lottie/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "pathfinder_lottie" -version = "0.1.0" -authors = ["Patrick Walton "] -edition = "2018" - -[dependencies] -serde_json = "1.0" - -[dependencies.serde] -version = "1.0" -features = ["derive"] diff --git a/crates/pathfinder/lottie/src/lib.rs b/crates/pathfinder/lottie/src/lib.rs deleted file mode 100644 index 4b062cdb23..0000000000 --- a/crates/pathfinder/lottie/src/lib.rs +++ /dev/null @@ -1,313 +0,0 @@ -// pathfinder/lottie/src/lib.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Experimental support for Lottie. This is very incomplete. - -use serde::{Deserialize, Serialize}; -use serde_json::Error as JSONError; -use std::io::Read; - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Lottie { - #[serde(rename = "v")] - pub version: String, - #[serde(rename = "fr")] - pub frame_rate: i64, - #[serde(rename = "ip")] - pub in_point: i64, - #[serde(rename = "op")] - pub out_point: i64, - #[serde(rename = "w")] - pub width: f64, - #[serde(rename = "h")] - pub height: f64, - #[serde(rename = "ddd")] - pub three_d: i64, - pub assets: Vec, - pub layers: Vec, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Asset {} - -// FIXME(pcwalton): Using an untagged enum is a botch here. There actually is a tag: it's just an -// integer, which `serde_json` doesn't support natively. -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(untagged)] -pub enum Layer { - Shape { - #[serde(rename = "ddd")] - three_d: i64, - #[serde(rename = "ind")] - index: i64, - #[serde(rename = "nm")] - name: String, - #[serde(rename = "ks")] - transform: Transform, - #[serde(rename = "ao")] - auto_orient: i64, - #[serde(rename = "ip")] - in_point: i64, - #[serde(rename = "op")] - out_point: i64, - #[serde(rename = "st")] - start_time: i64, - #[serde(rename = "bm")] - blend_mode: i64, - #[serde(rename = "sr")] - stretch: i64, - #[serde(rename = "ln")] - #[serde(default)] - layer_id: Option, - shapes: Vec, - }, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Transform { - #[serde(rename = "p")] - pub position: MultidimensionalPropertyValue, - #[serde(rename = "a")] - pub anchor_point: MultidimensionalPropertyValue, - #[serde(rename = "s")] - pub scale: MultidimensionalPropertyValue, - #[serde(rename = "r")] - pub rotation: PropertyValue, - #[serde(rename = "o")] - #[serde(default)] - pub opacity: Option, - #[serde(rename = "px")] - #[serde(default)] - pub position_x: Option, - #[serde(rename = "py")] - #[serde(default)] - pub position_y: Option, - #[serde(rename = "pz")] - #[serde(default)] - pub position_z: Option, - #[serde(rename = "sk")] - #[serde(default)] - pub skew: Option, - #[serde(rename = "sa")] - #[serde(default)] - pub skew_axis: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(untagged)] -pub enum PropertyValue { - Value { - #[serde(rename = "k")] - value: f32, - #[serde(rename = "x")] - #[serde(default)] - expression: Option, - #[serde(rename = "ix")] - #[serde(default)] - index: Option, - }, - KeyframedValue { - #[serde(rename = "k")] - keyframes: Vec, - #[serde(rename = "x")] - #[serde(default)] - expression: Option, - #[serde(rename = "ix")] - #[serde(default)] - index: Option, - }, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct KeyframeValue { - #[serde(rename = "s")] - #[serde(default)] - pub start: Option>, - #[serde(rename = "t")] - pub time: i64, - #[serde(rename = "i")] - #[serde(default)] - pub interpolation: Option, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize)] -pub struct Interpolation { - pub x: f32, - pub y: f32, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct OffsetInterpolation { - pub x: Vec, - pub y: Vec, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct OffsetKeyframe { - #[serde(rename = "s")] - #[serde(default)] - pub start: Option>, - #[serde(rename = "t")] - pub time: i64, - #[serde(rename = "i")] - #[serde(default)] - pub in_value: Option, - #[serde(rename = "o")] - #[serde(default)] - pub out_value: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(untagged)] -pub enum MultidimensionalPropertyValue { - Value { - #[serde(rename = "k")] - value: Vec, - #[serde(rename = "x")] - #[serde(default)] - expression: Option, - #[serde(rename = "ix")] - #[serde(default)] - index: Option, - }, - KeyframedValue { - #[serde(rename = "k")] - keyframes: Vec, - #[serde(rename = "x")] - #[serde(default)] - expression: Option, - #[serde(rename = "ix")] - #[serde(default)] - index: Option, - #[serde(rename = "ti")] - #[serde(default)] - in_tangent: Option, - #[serde(rename = "to")] - #[serde(default)] - out_tangent: Option, - }, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(tag = "ty")] -pub enum Shape { - #[serde(rename = "gr")] - Group { - #[serde(rename = "it")] - items: Vec, - #[serde(rename = "nm")] - name: String, - }, - #[serde(rename = "sh")] - Shape { - #[serde(rename = "ks")] - vertices: ShapeVertices, - #[serde(rename = "d")] - #[serde(default)] - direction: Option, - }, - #[serde(rename = "fl")] - Fill { - #[serde(rename = "nm")] - #[serde(default)] - name: Option, - #[serde(rename = "o")] - #[serde(default)] - opacity: Option, - #[serde(rename = "c")] - color: MultidimensionalPropertyValue, - }, - #[serde(rename = "tr")] - Transform { - #[serde(rename = "r")] - rotation: PropertyValue, - #[serde(rename = "sk")] - skew: PropertyValue, - #[serde(rename = "sa")] - skew_axis: PropertyValue, - #[serde(rename = "p")] - position: MultidimensionalPropertyValue, - #[serde(rename = "a")] - anchor_point: MultidimensionalPropertyValue, - #[serde(rename = "s")] - scale: MultidimensionalPropertyValue, - }, - #[serde(other)] - Unimplemented, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(untagged)] -pub enum ShapeVertices { - Shape { - #[serde(rename = "k")] - value: ShapeProperty, - #[serde(rename = "x")] - #[serde(default)] - expression: Option, - #[serde(rename = "ix")] - #[serde(default)] - index: Option, - #[serde(rename = "a")] - animated: i64, - }, - ShapeKeyframed { - #[serde(rename = "k")] - value: Vec, - #[serde(rename = "x")] - #[serde(default)] - expression: Option, - #[serde(rename = "ix")] - #[serde(default)] - index: Option, - #[serde(rename = "a")] - animated: i64, - #[serde(rename = "ti")] - #[serde(default)] - in_tangent: Vec, - #[serde(rename = "to")] - #[serde(default)] - out_tangent: Vec, - }, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct ShapeProperty { - #[serde(rename = "c")] - pub closed: bool, - #[serde(rename = "i")] - pub in_points: Vec<[f32; 2]>, - #[serde(rename = "o")] - pub out_points: Vec<[f32; 2]>, - #[serde(rename = "v")] - pub vertices: Vec<[f32; 2]>, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct ShapeKeyframeProperty { - #[serde(rename = "s")] - #[serde(default)] - pub start: Vec>, - #[serde(rename = "t")] - pub time: i64, - #[serde(rename = "i")] - #[serde(default)] - pub in_value: Option, - #[serde(rename = "o")] - #[serde(default)] - pub out_value: Option, -} - -impl Lottie { - #[inline] - pub fn from_reader(reader: R) -> Result where R: Read { - serde_json::from_reader(reader) - } -} diff --git a/crates/pathfinder/renderer/Cargo.toml b/crates/pathfinder/renderer/Cargo.toml deleted file mode 100644 index 282794e57e..0000000000 --- a/crates/pathfinder/renderer/Cargo.toml +++ /dev/null @@ -1,58 +0,0 @@ -[package] -name = "pathfinder_renderer" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -description = "A GPU-accelerated vector graphics and font renderer" -license = "MIT/Apache-2.0" -repository = "https://github.com/servo/pathfinder" -homepage = "https://github.com/servo/pathfinder" - -[dependencies] -bitflags = "1.0" -byteorder = "1.2" -crossbeam-channel = "0.4" -once_cell = "1.3.1" -fxhash = "0.2" -half = "1.5" -hashbrown = "0.7" -rayon = "1.0" -serde = "1.0" -serde_json = "1.0" -smallvec = "1.2" -vec_map = "0.8" -instant = { version = "0.1.2", features = ["wasm-bindgen"] } - -[dependencies.log] -version = "0.4" - -[dependencies.pathfinder_color] -path = "../color" -version = "0.5" - -[dependencies.pathfinder_content] -path = "../content" -version = "0.5" - -[dependencies.pathfinder_geometry] -path = "../geometry" -version = "0.5" - -[dependencies.pathfinder_gpu] -path = "../gpu" -version = "0.5" - -[dependencies.pathfinder_resources] -path = "../resources" -version = "0.5" - -[dependencies.pathfinder_simd] -path = "../simd" -version = "0.5" - -[dependencies.pathfinder_ui] -path = "../ui" -version = "0.5" - -[dev-dependencies] -quickcheck = "0.9" diff --git a/crates/pathfinder/renderer/src/allocator.rs b/crates/pathfinder/renderer/src/allocator.rs deleted file mode 100644 index 929ef25dde..0000000000 --- a/crates/pathfinder/renderer/src/allocator.rs +++ /dev/null @@ -1,327 +0,0 @@ -// pathfinder/renderer/src/allocator.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A simple quadtree-based texture allocator. - -use crate::gpu_data::{TextureLocation, TexturePageId}; -use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2f, vec2i}; - -const ATLAS_TEXTURE_LENGTH: u32 = 1024; - -#[derive(Clone, Debug)] -pub struct TextureAllocator { - pages: Vec, -} - -#[derive(Clone, Debug)] -pub struct TexturePage { - allocator: TexturePageAllocator, - is_new: bool, -} - -#[derive(Clone, Debug)] -pub enum TexturePageAllocator { - // An atlas allocated with our quadtree allocator. - Atlas(TextureAtlasAllocator), - // A single image. - Image { size: Vector2I }, -} - -#[derive(Clone, Debug)] -pub struct TextureAtlasAllocator { - root: TreeNode, - size: u32, -} - -#[derive(Clone, Debug)] -enum TreeNode { - EmptyLeaf, - FullLeaf, - // Top left, top right, bottom left, and bottom right, in that order. - Parent([Box; 4]), -} - -#[derive(Clone, Copy, PartialEq, Debug)] -#[allow(dead_code)] -pub enum AllocationMode { - Atlas, - OwnPage, -} - -impl TextureAllocator { - #[inline] - pub fn new() -> TextureAllocator { - TextureAllocator { pages: vec![] } - } - - pub fn allocate(&mut self, requested_size: Vector2I, mode: AllocationMode) -> TextureLocation { - // If requested, or if the image is too big, use a separate page. - if mode == AllocationMode::OwnPage || - requested_size.x() > ATLAS_TEXTURE_LENGTH as i32 || - requested_size.y() > ATLAS_TEXTURE_LENGTH as i32 { - return self.allocate_image(requested_size); - } - - // Try to add to each atlas. - for (page_index, page) in self.pages.iter_mut().enumerate() { - match page.allocator { - TexturePageAllocator::Image { .. } => {} - TexturePageAllocator::Atlas(ref mut allocator) => { - if let Some(rect) = allocator.allocate(requested_size) { - return TextureLocation { page: TexturePageId(page_index as u32), rect }; - } - } - } - } - - // Add a new atlas. - let page = TexturePageId(self.pages.len() as u32); - let mut allocator = TextureAtlasAllocator::new(); - let rect = allocator.allocate(requested_size).expect("Allocation failed!"); - self.pages.push(TexturePage { - is_new: true, - allocator: TexturePageAllocator::Atlas(allocator), - }); - TextureLocation { page, rect } - } - - pub fn allocate_image(&mut self, requested_size: Vector2I) -> TextureLocation { - let page = TexturePageId(self.pages.len() as u32); - let rect = RectI::new(Vector2I::default(), requested_size); - self.pages.push(TexturePage { - is_new: true, - allocator: TexturePageAllocator::Image { size: rect.size() }, - }); - TextureLocation { page, rect } - } - - pub fn page_size(&self, page_id: TexturePageId) -> Vector2I { - match self.pages[page_id.0 as usize].allocator { - TexturePageAllocator::Atlas(ref atlas) => Vector2I::splat(atlas.size as i32), - TexturePageAllocator::Image { size, .. } => size, - } - } - - pub fn page_scale(&self, page_id: TexturePageId) -> Vector2F { - vec2f(1.0, 1.0) / self.page_size(page_id).to_f32() - } - - pub fn page_is_new(&self, page_id: TexturePageId) -> bool { - self.pages[page_id.0 as usize].is_new - } - - pub fn mark_page_as_allocated(&mut self, page_id: TexturePageId) { - self.pages[page_id.0 as usize].is_new = false; - } - - #[inline] - pub fn page_count(&self) -> u32 { - self.pages.len() as u32 - } -} - -impl TextureAtlasAllocator { - #[inline] - fn new() -> TextureAtlasAllocator { - TextureAtlasAllocator::with_length(ATLAS_TEXTURE_LENGTH) - } - - #[inline] - fn with_length(length: u32) -> TextureAtlasAllocator { - TextureAtlasAllocator { root: TreeNode::EmptyLeaf, size: length } - } - - #[inline] - fn allocate(&mut self, requested_size: Vector2I) -> Option { - let requested_length = - (requested_size.x().max(requested_size.y()) as u32).next_power_of_two(); - self.root.allocate(Vector2I::default(), self.size, requested_length) - } - - #[inline] - #[allow(dead_code)] - fn free(&mut self, rect: RectI) { - let requested_length = rect.width() as u32; - self.root.free(Vector2I::default(), self.size, rect.origin(), requested_length) - } - - #[inline] - #[allow(dead_code)] - fn is_empty(&self) -> bool { - match self.root { - TreeNode::EmptyLeaf => true, - _ => false, - } - } -} - -impl TreeNode { - // Invariant: `requested_size` must be a power of two. - fn allocate(&mut self, this_origin: Vector2I, this_size: u32, requested_size: u32) - -> Option { - if let TreeNode::FullLeaf = *self { - // No room here. - return None; - } - if this_size < requested_size { - // Doesn't fit. - return None; - } - - // Allocate here or split, as necessary. - if let TreeNode::EmptyLeaf = *self { - // Do we have a perfect fit? - if this_size == requested_size { - *self = TreeNode::FullLeaf; - return Some(RectI::new(this_origin, Vector2I::splat(this_size as i32))); - } - - // Split. - *self = TreeNode::Parent([ - Box::new(TreeNode::EmptyLeaf), - Box::new(TreeNode::EmptyLeaf), - Box::new(TreeNode::EmptyLeaf), - Box::new(TreeNode::EmptyLeaf), - ]); - } - - // Recurse into children. - match *self { - TreeNode::Parent(ref mut kids) => { - let kid_size = this_size / 2; - if let Some(origin) = kids[0].allocate(this_origin, kid_size, requested_size) { - return Some(origin); - } - if let Some(origin) = kids[1].allocate(this_origin + vec2i(kid_size as i32, 0), - kid_size, - requested_size) { - return Some(origin); - } - if let Some(origin) = kids[2].allocate(this_origin + vec2i(0, kid_size as i32), - kid_size, - requested_size) { - return Some(origin); - } - if let Some(origin) = kids[3].allocate(this_origin + kid_size as i32, - kid_size, - requested_size) { - return Some(origin); - } - - self.merge_if_necessary(); - return None; - } - TreeNode::EmptyLeaf | TreeNode::FullLeaf => unreachable!(), - } - } - - #[allow(dead_code)] - fn free(&mut self, - this_origin: Vector2I, - this_size: u32, - requested_origin: Vector2I, - requested_size: u32) { - if this_size <= requested_size { - if this_size == requested_size && this_origin == requested_origin { - *self = TreeNode::EmptyLeaf; - } - return; - } - - let child_size = this_size / 2; - let this_center = this_origin + child_size as i32; - - let child_index; - let mut child_origin = this_origin; - - if requested_origin.y() < this_center.y() { - if requested_origin.x() < this_center.x() { - child_index = 0; - } else { - child_index = 1; - child_origin += vec2i(child_size as i32, 0); - } - } else { - if requested_origin.x() < this_center.x() { - child_index = 2; - child_origin += vec2i(0, child_size as i32); - } else { - child_index = 3; - child_origin = this_center; - } - } - - match *self { - TreeNode::Parent(ref mut kids) => { - kids[child_index].free(child_origin, child_size, requested_origin, requested_size); - self.merge_if_necessary(); - } - TreeNode::EmptyLeaf | TreeNode::FullLeaf => unreachable!(), - } - } - - fn merge_if_necessary(&mut self) { - match *self { - TreeNode::Parent(ref mut kids) => { - if kids.iter().all(|kid| { - match **kid { - TreeNode::EmptyLeaf => true, - _ => false, - } - }) { - *self = TreeNode::EmptyLeaf; - } - } - _ => {} - } - } -} - -#[cfg(test)] -mod test { - use pathfinder_geometry::vector::vec2i; - use quickcheck; - use std::u32; - - use super::TextureAtlasAllocator; - - #[test] - fn test_allocation_and_freeing() { - quickcheck::quickcheck(prop_allocation_and_freeing_work as - fn(u32, Vec<(u32, u32)>) -> bool); - - fn prop_allocation_and_freeing_work(mut length: u32, mut sizes: Vec<(u32, u32)>) -> bool { - length = u32::next_power_of_two(length).max(1); - - for &mut (ref mut width, ref mut height) in &mut sizes { - *width = (*width).min(length).max(1); - *height = (*height).min(length).max(1); - } - - let mut allocator = TextureAtlasAllocator::with_length(length); - let mut locations = vec![]; - for &(width, height) in &sizes { - let size = vec2i(width as i32, height as i32); - if let Some(location) = allocator.allocate(size) { - locations.push(location); - } - } - - for location in locations { - allocator.free(location); - } - - assert!(allocator.is_empty()); - - true - } - } -} diff --git a/crates/pathfinder/renderer/src/builder.rs b/crates/pathfinder/renderer/src/builder.rs deleted file mode 100644 index 61e98d6454..0000000000 --- a/crates/pathfinder/renderer/src/builder.rs +++ /dev/null @@ -1,884 +0,0 @@ -// pathfinder/renderer/src/builder.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Packs data onto the GPU. - -use crate::concurrent::executor::Executor; -use crate::gpu::renderer::{BlendModeExt, MASK_TILES_ACROSS, MASK_TILES_DOWN}; -use crate::gpu_data::{AlphaTileId, Clip, ClipBatch, ClipBatchKey, ClipBatchKind, Fill}; -use crate::gpu_data::{FillBatchEntry, RenderCommand, TILE_CTRL_MASK_0_SHIFT}; -use crate::gpu_data::{TILE_CTRL_MASK_EVEN_ODD, TILE_CTRL_MASK_WINDING, Tile, TileBatch}; -use crate::gpu_data::{TileBatchTexture, TileObjectPrimitive}; -use crate::options::{PreparedBuildOptions, PreparedRenderTransform, RenderCommandListener}; -use crate::paint::{PaintInfo, PaintMetadata}; -use crate::scene::{DisplayItem, Scene}; -use crate::tile_map::DenseTileMap; -use crate::tiles::{self, DrawTilingPathInfo, PackedTile, TILE_HEIGHT, TILE_WIDTH}; -use crate::tiles::{Tiler, TilingPathInfo}; -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; -use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2f, vec2i}; -use pathfinder_gpu::TextureSamplingFlags; -use pathfinder_simd::default::{F32x4, I32x4}; -use std::sync::atomic::AtomicUsize; -use instant::Instant; -use std::u32; - -pub(crate) const ALPHA_TILE_LEVEL_COUNT: usize = 2; -pub(crate) const ALPHA_TILES_PER_LEVEL: usize = 1 << (32 - ALPHA_TILE_LEVEL_COUNT + 1); - -pub(crate) struct SceneBuilder<'a, 'b> { - scene: &'a mut Scene, - built_options: &'b PreparedBuildOptions, - next_alpha_tile_indices: [AtomicUsize; ALPHA_TILE_LEVEL_COUNT], - pub(crate) listener: Box, -} - -#[derive(Debug)] -pub(crate) struct ObjectBuilder { - pub built_path: BuiltPath, - pub fills: Vec, - pub bounds: RectF, -} - -#[derive(Debug)] -struct BuiltDrawPath { - path: BuiltPath, - blend_mode: BlendMode, - filter: Filter, - color_texture: Option, - sampling_flags_1: TextureSamplingFlags, - mask_0_fill_rule: FillRule, -} - -#[derive(Debug)] -pub(crate) struct BuiltPath { - pub solid_tiles: SolidTiles, - pub empty_tiles: Vec, - pub single_mask_tiles: Vec, - pub clip_tiles: Vec, - pub tiles: DenseTileMap, - pub fill_rule: FillRule, -} - -#[derive(Clone, Debug)] -pub struct BuiltTile { - pub page: u16, - pub tile: Tile, -} - -#[derive(Clone, Copy, Debug)] -pub struct BuiltClip { - pub clip: Clip, - pub key: ClipBatchKey, -} - -#[derive(Clone, Debug)] -pub(crate) enum SolidTiles { - Occluders(Vec), - Regular(Vec), -} - -#[derive(Clone, Copy, Debug)] -pub(crate) struct Occluder { - pub(crate) coords: Vector2I, -} - -impl<'a, 'b> SceneBuilder<'a, 'b> { - pub(crate) fn new( - scene: &'a mut Scene, - built_options: &'b PreparedBuildOptions, - listener: Box, - ) -> SceneBuilder<'a, 'b> { - SceneBuilder { - scene, - built_options, - next_alpha_tile_indices: [AtomicUsize::new(0), AtomicUsize::new(0)], - listener, - } - } - - pub fn build(&mut self, executor: &E) where E: Executor { - let start_time = Instant::now(); - - // Send the start rendering command. - let bounding_quad = self.built_options.bounding_quad(); - - let clip_path_count = self.scene.clip_paths.len(); - let draw_path_count = self.scene.paths.len(); - let total_path_count = clip_path_count + draw_path_count; - - let needs_readable_framebuffer = self.needs_readable_framebuffer(); - - self.listener.send(RenderCommand::Start { - bounding_quad, - path_count: total_path_count, - needs_readable_framebuffer, - }); - - let render_transform = match self.built_options.transform { - PreparedRenderTransform::Transform2D(transform) => transform.inverse(), - _ => Transform2F::default() - }; - - // Build paint data. - let PaintInfo { - render_commands, - paint_metadata, - render_target_metadata: _, - } = self.scene.build_paint_info(render_transform); - for render_command in render_commands { - self.listener.send(render_command); - } - - let effective_view_box = self.scene.effective_view_box(self.built_options); - - let built_clip_paths = executor.build_vector(clip_path_count, |path_index| { - self.build_clip_path(PathBuildParams { - path_index, - view_box: effective_view_box, - built_options: &self.built_options, - scene: &self.scene, - }) - }); - - let built_draw_paths = executor.build_vector(draw_path_count, |path_index| { - self.build_draw_path(DrawPathBuildParams { - path_build_params: PathBuildParams { - path_index, - view_box: effective_view_box, - built_options: &self.built_options, - scene: &self.scene, - }, - paint_metadata: &paint_metadata, - built_clip_paths: &built_clip_paths, - }) - }); - - self.finish_building(&paint_metadata, built_draw_paths); - - let cpu_build_time = Instant::now() - start_time; - self.listener.send(RenderCommand::Finish { cpu_build_time }); - } - - fn build_clip_path(&self, params: PathBuildParams) -> BuiltPath { - let PathBuildParams { path_index, view_box, built_options, scene } = params; - let path_object = &scene.clip_paths[path_index]; - let outline = scene.apply_render_options(path_object.outline(), built_options); - - let mut tiler = Tiler::new(self, - &outline, - path_object.fill_rule(), - view_box, - TilingPathInfo::Clip); - - tiler.generate_tiles(); - self.send_fills(tiler.object_builder.fills); - tiler.object_builder.built_path - } - - fn build_draw_path(&self, params: DrawPathBuildParams) -> BuiltDrawPath { - let DrawPathBuildParams { - path_build_params: PathBuildParams { path_index, view_box, built_options, scene }, - paint_metadata, - built_clip_paths, - } = params; - - let path_object = &scene.paths[path_index]; - let outline = scene.apply_render_options(path_object.outline(), built_options); - - let paint_id = path_object.paint(); - let paint_metadata = &paint_metadata[paint_id.0 as usize]; - let built_clip_path = path_object.clip_path().map(|clip_path_id| { - &built_clip_paths[clip_path_id.0 as usize] - }); - - let mut tiler = Tiler::new(self, - &outline, - path_object.fill_rule(), - view_box, - TilingPathInfo::Draw(DrawTilingPathInfo { - paint_id, - paint_metadata, - blend_mode: path_object.blend_mode(), - built_clip_path, - fill_rule: path_object.fill_rule(), - })); - - tiler.generate_tiles(); - self.send_fills(tiler.object_builder.fills); - BuiltDrawPath { - path: tiler.object_builder.built_path, - blend_mode: path_object.blend_mode(), - filter: paint_metadata.filter(), - color_texture: paint_metadata.tile_batch_texture(), - sampling_flags_1: TextureSamplingFlags::empty(), - mask_0_fill_rule: path_object.fill_rule(), - } - } - - fn send_fills(&self, fills: Vec) { - if !fills.is_empty() { - self.listener.send(RenderCommand::AddFills(fills)); - } - } - - fn build_clips(&self, built_draw_paths: &[BuiltDrawPath]) { - let mut built_clip_tiles = vec![]; - for built_draw_path in built_draw_paths { - for built_clip_tile in &built_draw_path.path.clip_tiles { - built_clip_tiles.push(*built_clip_tile); - } - } - - built_clip_tiles.sort_by_key(|built_clip_tile| built_clip_tile.key); - - let mut batches: Vec = vec![]; - for built_clip_tile in built_clip_tiles { - if batches.is_empty() || batches.last_mut().unwrap().key != built_clip_tile.key { - batches.push(ClipBatch { key: built_clip_tile.key, clips: vec![] }); - } - batches.last_mut().unwrap().clips.push(built_clip_tile.clip); - } - - if !batches.is_empty() { - self.listener.send(RenderCommand::ClipTiles(batches)); - } - } - - fn cull_tiles(&self, paint_metadata: &[PaintMetadata], built_draw_paths: Vec) - -> CulledTiles { - let mut culled_tiles = CulledTiles { display_list: vec![] }; - - let mut remaining_layer_z_buffers = self.build_solid_tiles(&built_draw_paths); - remaining_layer_z_buffers.reverse(); - - // Process first Z-buffer. - let first_z_buffer = remaining_layer_z_buffers.pop().unwrap(); - let first_solid_tiles = first_z_buffer.build_solid_tiles(paint_metadata); - for batch in first_solid_tiles.batches { - culled_tiles.display_list.push(CulledDisplayItem::DrawTiles(batch)); - } - - let mut layer_z_buffers_stack = vec![first_z_buffer]; - let mut current_depth = 1; - - for display_item in &self.scene.display_list { - match *display_item { - DisplayItem::PushRenderTarget(render_target_id) => { - culled_tiles.display_list - .push(CulledDisplayItem::PushRenderTarget(render_target_id)); - - let z_buffer = remaining_layer_z_buffers.pop().unwrap(); - let solid_tiles = z_buffer.build_solid_tiles(paint_metadata); - for batch in solid_tiles.batches { - culled_tiles.display_list.push(CulledDisplayItem::DrawTiles(batch)); - } - layer_z_buffers_stack.push(z_buffer); - } - - DisplayItem::PopRenderTarget => { - culled_tiles.display_list.push(CulledDisplayItem::PopRenderTarget); - layer_z_buffers_stack.pop(); - } - - DisplayItem::DrawPaths { - start_index: start_draw_path_index, - end_index: end_draw_path_index, - } => { - for draw_path_index in start_draw_path_index..end_draw_path_index { - let built_draw_path = &built_draw_paths[draw_path_index as usize]; - let layer_z_buffer = layer_z_buffers_stack.last().unwrap(); - let color_texture = built_draw_path.color_texture; - - debug_assert!(built_draw_path.path.empty_tiles.is_empty() || - built_draw_path.blend_mode.is_destructive()); - self.add_alpha_tiles(&mut culled_tiles, - layer_z_buffer, - &built_draw_path.path.empty_tiles, - current_depth, - None, - built_draw_path.blend_mode, - built_draw_path.filter); - - self.add_alpha_tiles(&mut culled_tiles, - layer_z_buffer, - &built_draw_path.path.single_mask_tiles, - current_depth, - color_texture, - built_draw_path.blend_mode, - built_draw_path.filter); - - match built_draw_path.path.solid_tiles { - SolidTiles::Regular(ref tiles) => { - self.add_alpha_tiles(&mut culled_tiles, - layer_z_buffer, - tiles, - current_depth, - color_texture, - built_draw_path.blend_mode, - built_draw_path.filter); - } - SolidTiles::Occluders(_) => {} - } - - current_depth += 1; - } - } - } - } - - culled_tiles - } - - fn build_solid_tiles(&self, built_draw_paths: &[BuiltDrawPath]) -> Vec { - let effective_view_box = self.scene.effective_view_box(self.built_options); - let mut z_buffers = vec![ZBuffer::new(effective_view_box)]; - let mut z_buffer_index_stack = vec![0]; - let mut current_depth = 1; - - // Create Z-buffers. - for display_item in &self.scene.display_list { - match *display_item { - DisplayItem::PushRenderTarget { .. } => { - z_buffer_index_stack.push(z_buffers.len()); - z_buffers.push(ZBuffer::new(effective_view_box)); - } - DisplayItem::PopRenderTarget => { - z_buffer_index_stack.pop(); - } - DisplayItem::DrawPaths { start_index, end_index } => { - let (start_index, end_index) = (start_index as usize, end_index as usize); - let z_buffer = &mut z_buffers[*z_buffer_index_stack.last().unwrap()]; - for (path_subindex, built_draw_path) in - built_draw_paths[start_index..end_index].iter().enumerate() { - let path_index = (path_subindex + start_index) as u32; - let path = &self.scene.paths[path_index as usize]; - let metadata = DepthMetadata { paint_id: path.paint() }; - match built_draw_path.path.solid_tiles { - SolidTiles::Regular(_) => { - z_buffer.update(&[], current_depth, metadata); - } - SolidTiles::Occluders(ref occluders) => { - z_buffer.update(occluders, current_depth, metadata); - } - } - current_depth += 1; - } - } - } - } - debug_assert_eq!(z_buffer_index_stack.len(), 1); - - z_buffers - } - - fn add_alpha_tiles(&self, - culled_tiles: &mut CulledTiles, - layer_z_buffer: &ZBuffer, - built_alpha_tiles: &[BuiltTile], - current_depth: u32, - color_texture: Option, - blend_mode: BlendMode, - filter: Filter) { - let mut batch_indices: Vec = vec![]; - for built_alpha_tile in built_alpha_tiles { - // Early cull if possible. - let alpha_tile_coords = built_alpha_tile.tile.tile_position(); - if !layer_z_buffer.test(alpha_tile_coords, current_depth) { - continue; - } - - // Find an appropriate batch if we can. - let mut dest_batch_index = batch_indices.iter().filter(|&batch_index| { - batch_index.tile_page == built_alpha_tile.page - }).next().cloned(); - - // If no batch was found, try to reuse the last batch in the display list. - // - // TODO(pcwalton): We could try harder to find a batch by taking tile positions into - // account... - if dest_batch_index.is_none() { - match culled_tiles.display_list.last() { - Some(&CulledDisplayItem::DrawTiles(TileBatch { - tiles: _, - color_texture: ref batch_color_texture, - blend_mode: batch_blend_mode, - filter: batch_filter, - tile_page: batch_tile_page - })) if *batch_color_texture == color_texture && - batch_blend_mode == blend_mode && - batch_filter == filter && - !batch_blend_mode.needs_readable_framebuffer() && - batch_tile_page == built_alpha_tile.page => { - dest_batch_index = Some(BatchIndex { - display_item_index: culled_tiles.display_list.len() - 1, - tile_page: batch_tile_page, - }); - batch_indices.push(dest_batch_index.unwrap()); - } - _ => {} - } - } - - // If it's still the case that no suitable batch was found, then make a new one. - if dest_batch_index.is_none() { - dest_batch_index = Some(BatchIndex { - display_item_index: culled_tiles.display_list.len(), - tile_page: built_alpha_tile.page, - }); - batch_indices.push(dest_batch_index.unwrap()); - culled_tiles.display_list.push(CulledDisplayItem::DrawTiles(TileBatch { - tiles: vec![], - color_texture, - blend_mode, - filter, - tile_page: built_alpha_tile.page, - })); - } - - // Add to the appropriate batch. - match culled_tiles.display_list[dest_batch_index.unwrap().display_item_index] { - CulledDisplayItem::DrawTiles(ref mut tiles) => { - tiles.tiles.push(built_alpha_tile.tile); - } - _ => unreachable!(), - } - } - - #[derive(Clone, Copy)] - struct BatchIndex { - display_item_index: usize, - tile_page: u16, - } - } - - fn pack_tiles(&mut self, culled_tiles: CulledTiles) { - self.listener.send(RenderCommand::BeginTileDrawing); - for display_item in culled_tiles.display_list { - match display_item { - CulledDisplayItem::DrawTiles(batch) => { - self.listener.send(RenderCommand::DrawTiles(batch)) - } - CulledDisplayItem::PushRenderTarget(render_target_id) => { - self.listener.send(RenderCommand::PushRenderTarget(render_target_id)) - } - CulledDisplayItem::PopRenderTarget => { - self.listener.send(RenderCommand::PopRenderTarget) - } - } - } - } - - fn finish_building(&mut self, - paint_metadata: &[PaintMetadata], - built_draw_paths: Vec) { - self.listener.send(RenderCommand::FlushFills); - self.build_clips(&built_draw_paths); - let culled_tiles = self.cull_tiles(paint_metadata, built_draw_paths); - self.pack_tiles(culled_tiles); - } - - fn needs_readable_framebuffer(&self) -> bool { - let mut framebuffer_nesting = 0; - for display_item in &self.scene.display_list { - match *display_item { - DisplayItem::PushRenderTarget(_) => framebuffer_nesting += 1, - DisplayItem::PopRenderTarget => framebuffer_nesting -= 1, - DisplayItem::DrawPaths { start_index, end_index } => { - if framebuffer_nesting > 0 { - continue; - } - for path_index in start_index..end_index { - let blend_mode = self.scene.paths[path_index as usize].blend_mode(); - if blend_mode.needs_readable_framebuffer() { - return true; - } - } - } - } - } - false - } -} - -struct PathBuildParams<'a> { - path_index: usize, - view_box: RectF, - built_options: &'a PreparedBuildOptions, - scene: &'a Scene, -} - -struct DrawPathBuildParams<'a> { - path_build_params: PathBuildParams<'a>, - paint_metadata: &'a [PaintMetadata], - built_clip_paths: &'a [BuiltPath], -} - -impl BuiltPath { - fn new(path_bounds: RectF, - view_box_bounds: RectF, - fill_rule: FillRule, - tiling_path_info: &TilingPathInfo) - -> BuiltPath { - let occludes = match *tiling_path_info { - TilingPathInfo::Draw(ref draw_tiling_path_info) => { - draw_tiling_path_info.paint_metadata.is_opaque && - draw_tiling_path_info.blend_mode.occludes_backdrop() - } - TilingPathInfo::Clip => true, - }; - - let tile_map_bounds = if tiling_path_info.has_destructive_blend_mode() { - view_box_bounds - } else { - path_bounds - }; - - BuiltPath { - empty_tiles: vec![], - single_mask_tiles: vec![], - clip_tiles: vec![], - solid_tiles: if occludes { - SolidTiles::Occluders(vec![]) - } else { - SolidTiles::Regular(vec![]) - }, - tiles: DenseTileMap::new(tiles::round_rect_out_to_tile_bounds(tile_map_bounds)), - fill_rule, - } - } -} - -impl Occluder { - #[inline] - pub(crate) fn new(coords: Vector2I) -> Occluder { - Occluder { coords } - } -} - -struct CulledTiles { - display_list: Vec, -} - -enum CulledDisplayItem { - DrawTiles(TileBatch), - PushRenderTarget(RenderTargetId), - PopRenderTarget, -} - -#[derive(Clone, Copy, Debug, Default)] -pub struct TileStats { - pub solid_tile_count: u32, - pub alpha_tile_count: u32, -} - -// Utilities for built objects - -impl ObjectBuilder { - pub(crate) fn new(path_bounds: RectF, - view_box_bounds: RectF, - fill_rule: FillRule, - tiling_path_info: &TilingPathInfo) - -> ObjectBuilder { - ObjectBuilder { - built_path: BuiltPath::new(path_bounds, view_box_bounds, fill_rule, tiling_path_info), - bounds: path_bounds, - fills: vec![], - } - } - - #[inline] - pub(crate) fn tile_rect(&self) -> RectI { - self.built_path.tiles.rect - } - - fn add_fill( - &mut self, - scene_builder: &SceneBuilder, - segment: LineSegment2F, - tile_coords: Vector2I, - ) { - debug!("add_fill({:?} ({:?}))", segment, tile_coords); - - // Ensure this fill is in bounds. If not, cull it. - if self.tile_coords_to_local_index(tile_coords).is_none() { - return; - } - - debug_assert_eq!(TILE_WIDTH, TILE_HEIGHT); - - // Compute the upper left corner of the tile. - let tile_size = F32x4::splat(TILE_WIDTH as f32); - let tile_upper_left = tile_coords.to_f32().0.to_f32x4().xyxy() * tile_size; - - // Convert to 4.8 fixed point. - let segment = (segment.0 - tile_upper_left) * F32x4::splat(256.0); - let (min, max) = (F32x4::default(), F32x4::splat((TILE_WIDTH * 256 - 1) as f32)); - let segment = segment.clamp(min, max).to_i32x4(); - let (from_x, from_y, to_x, to_y) = (segment[0], segment[1], segment[2], segment[3]); - - // Cull degenerate fills. - if from_x == to_x { - debug!("... culling!"); - return; - } - - // Allocate a global tile if necessary. - let alpha_tile_id = self.get_or_allocate_alpha_tile_index(scene_builder, tile_coords); - - // Pack whole pixels. - let px = (segment & I32x4::splat(0xf00)).to_u32x4(); - let px = (px >> 8).to_i32x4() | (px >> 4).to_i32x4().yxwz(); - - // Pack instance data. - debug!("... OK, pushing"); - self.fills.push(FillBatchEntry { - page: alpha_tile_id.page(), - fill: Fill { - 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() as AlignedU16, - }, - }); - } - - fn get_or_allocate_alpha_tile_index( - &mut self, - scene_builder: &SceneBuilder, - tile_coords: Vector2I, - ) -> AlphaTileId { - let local_tile_index = self.built_path.tiles.coords_to_index_unchecked(tile_coords); - let alpha_tile_id = self.built_path.tiles.data[local_tile_index].alpha_tile_id; - if alpha_tile_id.is_valid() { - return alpha_tile_id; - } - - let alpha_tile_id = AlphaTileId::new(&scene_builder.next_alpha_tile_indices, 0); - self.built_path.tiles.data[local_tile_index].alpha_tile_id = alpha_tile_id; - alpha_tile_id - } - - pub(crate) fn add_active_fill( - &mut self, - scene_builder: &SceneBuilder, - left: f32, - right: f32, - mut winding: i32, - tile_coords: Vector2I, - ) { - let tile_origin_y = (tile_coords.y() * TILE_HEIGHT as i32) as f32; - let left = vec2f(left, tile_origin_y); - let right = vec2f(right, tile_origin_y); - - let segment = if winding < 0 { - LineSegment2F::new(left, right) - } else { - LineSegment2F::new(right, left) - }; - - debug!( - "... emitting active fill {} -> {} winding {} @ tile {:?}", - left.x(), - right.x(), - winding, - tile_coords - ); - - while winding != 0 { - self.add_fill(scene_builder, segment, tile_coords); - if winding < 0 { - winding += 1 - } else { - winding -= 1 - } - } - } - - pub(crate) fn generate_fill_primitives_for_line( - &mut self, - scene_builder: &SceneBuilder, - mut segment: LineSegment2F, - tile_y: i32, - ) { - debug!( - "... generate_fill_primitives_for_line(): segment={:?} tile_y={} ({}-{})", - segment, - tile_y, - tile_y as f32 * TILE_HEIGHT as f32, - (tile_y + 1) as f32 * TILE_HEIGHT as f32 - ); - - let winding = segment.from_x() > segment.to_x(); - let (segment_left, segment_right) = if !winding { - (segment.from_x(), segment.to_x()) - } else { - (segment.to_x(), segment.from_x()) - }; - - let mut subsegment_x = (segment_left as i32 & !(TILE_WIDTH as i32 - 1)) as f32; - while subsegment_x < segment_right { - let (mut fill_from, mut fill_to) = (segment.from(), segment.to()); - let subsegment_x_next = subsegment_x + TILE_WIDTH as f32; - if subsegment_x_next < segment_right { - let x = subsegment_x_next; - let point = Vector2F::new(x, segment.solve_y_for_x(x)); - if !winding { - fill_to = point; - segment = LineSegment2F::new(point, segment.to()); - } else { - fill_from = point; - segment = LineSegment2F::new(segment.from(), point); - } - } - - let fill_segment = LineSegment2F::new(fill_from, fill_to); - let fill_tile_coords = vec2i(subsegment_x as i32 / TILE_WIDTH as i32, tile_y); - self.add_fill(scene_builder, fill_segment, fill_tile_coords); - - subsegment_x = subsegment_x_next; - } - } - - #[inline] - pub(crate) fn tile_coords_to_local_index(&self, coords: Vector2I) -> Option { - self.built_path.tiles.coords_to_index(coords).map(|index| index as u32) - } - - #[inline] - pub(crate) fn local_tile_index_to_coords(&self, tile_index: u32) -> Vector2I { - self.built_path.tiles.index_to_coords(tile_index as usize) - } -} - -impl<'a> PackedTile<'a> { - pub(crate) fn add_to(&self, - tiles: &mut Vec, - clips: &mut Vec, - draw_tiling_path_info: &DrawTilingPathInfo, - scene_builder: &SceneBuilder) { - let draw_tile_page = self.draw_tile.alpha_tile_id.page() as u16; - let draw_tile_index = self.draw_tile.alpha_tile_id.tile() as u16; - let draw_tile_backdrop = self.draw_tile.backdrop as i8; - - match self.clip_tile { - None => { - tiles.push(BuiltTile { - page: draw_tile_page, - tile: Tile::new_alpha(self.tile_coords, - draw_tile_index, - draw_tile_backdrop, - draw_tiling_path_info), - }); - } - Some(clip_tile) => { - let clip_tile_page = clip_tile.alpha_tile_id.page() as u16; - let clip_tile_index = clip_tile.alpha_tile_id.tile() as u16; - let clip_tile_backdrop = clip_tile.backdrop; - - let dest_tile_id = AlphaTileId::new(&scene_builder.next_alpha_tile_indices, 1); - let dest_tile_page = dest_tile_id.page() as u16; - let dest_tile_index = dest_tile_id.tile() as u16; - - clips.push(BuiltClip { - clip: Clip::new(dest_tile_index, draw_tile_index, draw_tile_backdrop), - key: ClipBatchKey { - src_page: draw_tile_page, - dest_page: dest_tile_page, - kind: ClipBatchKind::Draw, - }, - }); - clips.push(BuiltClip { - clip: Clip::new(dest_tile_index, clip_tile_index, clip_tile_backdrop), - key: ClipBatchKey { - src_page: clip_tile_page, - dest_page: dest_tile_page, - kind: ClipBatchKind::Clip, - }, - }); - tiles.push(BuiltTile { - page: dest_tile_page, - tile: Tile::new_alpha(self.tile_coords, - dest_tile_index, - 0, - draw_tiling_path_info), - }); - } - } - } -} - -impl Tile { - #[inline] - fn new_alpha(tile_origin: Vector2I, - draw_tile_index: u16, - draw_tile_backdrop: i8, - draw_tiling_path_info: &DrawTilingPathInfo) - -> Tile { - let mask_0_uv = calculate_mask_uv(draw_tile_index); - - let mut ctrl = 0; - match draw_tiling_path_info.fill_rule { - FillRule::EvenOdd => ctrl |= TILE_CTRL_MASK_EVEN_ODD << TILE_CTRL_MASK_0_SHIFT, - FillRule::Winding => ctrl |= TILE_CTRL_MASK_WINDING << TILE_CTRL_MASK_0_SHIFT, - } - - Tile { - 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 as AlignedU16, - } - } - - #[inline] - pub fn tile_position(&self) -> Vector2I { - vec2i(self.tile_x as i32, self.tile_y as i32) - } -} - -impl Clip { - #[inline] - fn new(dest_tile_index: u16, src_tile_index: u16, src_backdrop: i8) -> 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 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, - } - } -} - -fn calculate_mask_uv(tile_index: u16) -> Vector2I { - debug_assert_eq!(MASK_TILES_ACROSS, MASK_TILES_DOWN); - let mask_u = tile_index as i32 % MASK_TILES_ACROSS as i32; - let mask_v = tile_index as i32 / MASK_TILES_ACROSS as i32; - vec2i(mask_u, mask_v) -} diff --git a/crates/pathfinder/renderer/src/concurrent/executor.rs b/crates/pathfinder/renderer/src/concurrent/executor.rs deleted file mode 100644 index 150f4d32d2..0000000000 --- a/crates/pathfinder/renderer/src/concurrent/executor.rs +++ /dev/null @@ -1,31 +0,0 @@ -// pathfinder/renderer/src/concurrent/executor.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! An abstraction over threading and parallelism systems such as Rayon. - -/// An abstraction over threading and parallelism systems such as Rayon. -pub trait Executor { - /// Like the Rayon snippet: - /// - /// ```norun - /// (0..length).into_par_iter().map(builder).collect() - /// ``` - fn build_vector(&self, length: usize, builder: F) -> Vec - where T: Send, F: Fn(usize) -> T + Send + Sync; -} - -pub struct SequentialExecutor; - -impl Executor for SequentialExecutor { - fn build_vector(&self, length: usize, builder: F) -> Vec - where T: Send, F: Fn(usize) -> T + Send + Sync { - (0..length).into_iter().map(builder).collect() - } -} diff --git a/crates/pathfinder/renderer/src/concurrent/mod.rs b/crates/pathfinder/renderer/src/concurrent/mod.rs deleted file mode 100644 index 01ceffe393..0000000000 --- a/crates/pathfinder/renderer/src/concurrent/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -// pathfinder/renderer/src/concurrent/mod.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Threading and concurrency support. - -pub mod executor; -pub mod rayon; -pub mod scene_proxy; diff --git a/crates/pathfinder/renderer/src/concurrent/rayon.rs b/crates/pathfinder/renderer/src/concurrent/rayon.rs deleted file mode 100644 index e11d28b1d2..0000000000 --- a/crates/pathfinder/renderer/src/concurrent/rayon.rs +++ /dev/null @@ -1,23 +0,0 @@ -// pathfinder/renderer/src/concurrent/rayon.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! An implementation of the executor using the Rayon library. - -use crate::concurrent::executor::Executor; -use rayon::iter::{IntoParallelIterator, ParallelIterator}; - -pub struct RayonExecutor; - -impl Executor for RayonExecutor { - fn build_vector(&self, length: usize, builder: F) -> Vec - where T: Send, F: Fn(usize) -> T + Send + Sync { - (0..length).into_par_iter().map(builder).collect() - } -} diff --git a/crates/pathfinder/renderer/src/concurrent/scene_proxy.rs b/crates/pathfinder/renderer/src/concurrent/scene_proxy.rs deleted file mode 100644 index 69cdf131a8..0000000000 --- a/crates/pathfinder/renderer/src/concurrent/scene_proxy.rs +++ /dev/null @@ -1,151 +0,0 @@ -// pathfinder/renderer/src/concurrent/scene_proxy.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A version of `Scene` that proxies all method calls out to a separate -//! thread. -//! -//! This is useful for: -//! -//! * Avoiding GPU driver stalls on synchronous APIs such as OpenGL. -//! -//! * Avoiding UI latency by building scenes off the main thread. -//! -//! You don't need to use this API to use Pathfinder; it's only a convenience. - -use crate::concurrent::executor::Executor; -use crate::gpu::renderer::Renderer; -use crate::gpu_data::RenderCommand; -use crate::options::{BuildOptions, RenderCommandListener}; -use crate::scene::Scene; -use crossbeam_channel::{self, Receiver, Sender}; -use pathfinder_geometry::rect::RectF; -use pathfinder_gpu::Device; -use std::thread; - -const MAX_MESSAGES_IN_FLIGHT: usize = 1024; - -pub struct SceneProxy { - sender: Sender, -} - -impl SceneProxy { - pub fn new(executor: E) -> SceneProxy where E: Executor + Send + 'static { - SceneProxy::from_scene(Scene::new(), executor) - } - - pub fn from_scene(scene: Scene, executor: E) -> SceneProxy - where E: Executor + Send + 'static { - let (main_to_worker_sender, main_to_worker_receiver) = - crossbeam_channel::bounded(MAX_MESSAGES_IN_FLIGHT); - thread::spawn(move || scene_thread(scene, executor, main_to_worker_receiver)); - SceneProxy { sender: main_to_worker_sender } - } - - #[inline] - pub fn replace_scene(&self, new_scene: Scene) { - self.sender.send(MainToWorkerMsg::ReplaceScene(new_scene)).unwrap(); - } - - #[inline] - pub fn set_view_box(&self, new_view_box: RectF) { - self.sender.send(MainToWorkerMsg::SetViewBox(new_view_box)).unwrap(); - } - - #[inline] - pub fn build_with_listener(&self, - options: BuildOptions, - listener: Box) { - self.sender.send(MainToWorkerMsg::Build(options, listener)).unwrap(); - } - - #[inline] - pub fn build_with_stream(&self, options: BuildOptions) -> RenderCommandStream { - let (sender, receiver) = crossbeam_channel::bounded(MAX_MESSAGES_IN_FLIGHT); - let listener = Box::new(move |command| drop(sender.send(command))); - self.build_with_listener(options, listener); - RenderCommandStream::new(receiver) - } - - /// A convenience method to build a scene and send the resulting commands - /// to the given renderer. - /// - /// Exactly equivalent to: - /// - /// ```norun - /// for command in scene_proxy.build_with_stream(options) { - /// renderer.render_command(&command) - /// } - /// ``` - #[inline] - pub fn build_and_render(&self, renderer: &mut Renderer, build_options: BuildOptions) - where D: Device { - renderer.begin_scene(); - for command in self.build_with_stream(build_options) { - renderer.render_command(&command); - } - renderer.end_scene(); - } - - #[inline] - pub fn copy_scene(&self) -> Scene { - let (sender, receiver) = crossbeam_channel::bounded(MAX_MESSAGES_IN_FLIGHT); - self.sender.send(MainToWorkerMsg::CopyScene(sender)).unwrap(); - receiver.recv().unwrap() - } -} - -fn scene_thread(mut scene: Scene, - executor: E, - main_to_worker_receiver: Receiver) - where E: Executor { - while let Ok(msg) = main_to_worker_receiver.recv() { - match msg { - MainToWorkerMsg::ReplaceScene(new_scene) => scene = new_scene, - MainToWorkerMsg::CopyScene(sender) => sender.send(scene.clone()).unwrap(), - MainToWorkerMsg::SetViewBox(new_view_box) => scene.set_view_box(new_view_box), - MainToWorkerMsg::Build(options, listener) => scene.build(options, listener, &executor) - } - } -} - -enum MainToWorkerMsg { - ReplaceScene(Scene), - CopyScene(Sender), - SetViewBox(RectF), - Build(BuildOptions, Box), -} - -pub struct RenderCommandStream { - receiver: Receiver, - done: bool, -} - -impl RenderCommandStream { - fn new(receiver: Receiver) -> RenderCommandStream { - RenderCommandStream { receiver, done: false } - } -} - -impl Iterator for RenderCommandStream { - type Item = RenderCommand; - - #[inline] - fn next(&mut self) -> Option { - if self.done { - None - } else { - let command = self.receiver.recv().unwrap(); - if let RenderCommand::Finish { .. } = command { - self.done = true; - } - Some(command) - } - } -} diff --git a/crates/pathfinder/renderer/src/gpu/debug.rs b/crates/pathfinder/renderer/src/gpu/debug.rs deleted file mode 100644 index 1f85035a61..0000000000 --- a/crates/pathfinder/renderer/src/gpu/debug.rs +++ /dev/null @@ -1,217 +0,0 @@ -// pathfinder/renderer/src/gpu/debug.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A debug overlay. -//! -//! We don't render the demo UI text using Pathfinder itself so that we can use the debug UI to -//! debug Pathfinder if it's totally busted. -//! -//! The debug font atlas was generated using: https://evanw.github.io/font-texture-generator/ - -use crate::gpu::renderer::{RenderStats, RenderTime}; -use pathfinder_geometry::vector::{Vector2I, vec2i}; -use pathfinder_geometry::rect::RectI; -use pathfinder_gpu::Device; -use pathfinder_resources::ResourceLoader; -use pathfinder_ui::{FONT_ASCENT, LINE_HEIGHT, PADDING, UIPresenter, WINDOW_COLOR}; -use std::collections::VecDeque; -use std::ops::{Add, Div}; -use std::time::Duration; - -const SAMPLE_BUFFER_SIZE: usize = 60; - -const STATS_WINDOW_WIDTH: i32 = 325; -const STATS_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 4 + PADDING + 2; - -const PERFORMANCE_WINDOW_WIDTH: i32 = 400; -const PERFORMANCE_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 4 + PADDING + 2; - -pub struct DebugUIPresenter -where - D: Device, -{ - pub ui_presenter: UIPresenter, - cpu_samples: SampleBuffer, - gpu_samples: SampleBuffer, -} - -impl DebugUIPresenter -where - D: Device, -{ - pub fn new( - device: &D, - resources: &dyn ResourceLoader, - framebuffer_size: Vector2I, - ) -> DebugUIPresenter { - let ui_presenter = UIPresenter::new(device, resources, framebuffer_size); - DebugUIPresenter { - ui_presenter, - cpu_samples: SampleBuffer::new(), - gpu_samples: SampleBuffer::new(), - } - } - - pub fn add_sample(&mut self, stats: RenderStats, rendering_time: RenderTime) { - self.cpu_samples.push(stats); - self.gpu_samples.push(rendering_time); - } - - pub fn draw(&self, device: &D) { - self.draw_stats_window(device); - self.draw_performance_window(device); - } - - fn draw_stats_window(&self, device: &D) { - let framebuffer_size = self.ui_presenter.framebuffer_size(); - let bottom = framebuffer_size.y() - PADDING; - let window_rect = RectI::new( - vec2i(framebuffer_size.x() - PADDING - STATS_WINDOW_WIDTH, - bottom - PERFORMANCE_WINDOW_HEIGHT - PADDING - STATS_WINDOW_HEIGHT), - vec2i(STATS_WINDOW_WIDTH, STATS_WINDOW_HEIGHT), - ); - - self.ui_presenter.draw_solid_rounded_rect(device, window_rect, WINDOW_COLOR); - - let mean_cpu_sample = self.cpu_samples.mean(); - let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT); - self.ui_presenter.draw_text( - device, - &format!("Paths: {}", mean_cpu_sample.path_count), - origin, - false, - ); - self.ui_presenter.draw_text( - device, - &format!("Solid Tiles: {}", mean_cpu_sample.solid_tile_count), - origin + vec2i(0, LINE_HEIGHT * 1), - false, - ); - self.ui_presenter.draw_text( - device, - &format!("Alpha Tiles: {}", mean_cpu_sample.alpha_tile_count), - origin + vec2i(0, LINE_HEIGHT * 2), - false, - ); - self.ui_presenter.draw_text( - device, - &format!("Fills: {}", mean_cpu_sample.fill_count), - origin + vec2i(0, LINE_HEIGHT * 3), - false, - ); - } - - fn draw_performance_window(&self, device: &D) { - let framebuffer_size = self.ui_presenter.framebuffer_size(); - let bottom = framebuffer_size.y() - PADDING; - let window_rect = RectI::new( - vec2i(framebuffer_size.x() - PADDING - PERFORMANCE_WINDOW_WIDTH, - bottom - PERFORMANCE_WINDOW_HEIGHT), - vec2i(PERFORMANCE_WINDOW_WIDTH, PERFORMANCE_WINDOW_HEIGHT), - ); - - self.ui_presenter.draw_solid_rounded_rect(device, window_rect, WINDOW_COLOR); - - let mean_cpu_sample = self.cpu_samples.mean(); - let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT); - self.ui_presenter.draw_text( - device, - &format!("CPU: {:.3} ms", duration_to_ms(mean_cpu_sample.cpu_build_time)), - origin, - false, - ); - - let mean_gpu_sample = self.gpu_samples.mean(); - self.ui_presenter.draw_text( - device, - &format!("GPU: {:.3} ms", duration_to_ms(mean_gpu_sample.gpu_time)), - origin + vec2i(0, LINE_HEIGHT * 1), - false, - ); - - let wallclock_time = f64::max(duration_to_ms(mean_gpu_sample.gpu_time), - duration_to_ms(mean_cpu_sample.cpu_build_time)); - self.ui_presenter.draw_text( - device, - &format!("Wallclock: {:.3} ms", wallclock_time), - origin + vec2i(0, LINE_HEIGHT * 3), - false, - ); - } - -} - -struct SampleBuffer -where - S: Add + Div + Clone + Default, -{ - samples: VecDeque, -} - -impl SampleBuffer -where - S: Add + Div + Clone + Default, -{ - fn new() -> SampleBuffer { - SampleBuffer { - samples: VecDeque::with_capacity(SAMPLE_BUFFER_SIZE), - } - } - - fn push(&mut self, time: S) { - self.samples.push_back(time); - while self.samples.len() > SAMPLE_BUFFER_SIZE { - self.samples.pop_front(); - } - } - - fn mean(&self) -> S { - let mut mean = Default::default(); - if self.samples.is_empty() { - return mean; - } - - for time in &self.samples { - mean = mean + (*time).clone(); - } - - mean / self.samples.len() - } -} - -#[derive(Clone, Default)] -struct CPUSample { - elapsed: Duration, - stats: RenderStats, -} - -impl Add for CPUSample { - type Output = CPUSample; - fn add(self, other: CPUSample) -> CPUSample { - CPUSample { - elapsed: self.elapsed + other.elapsed, - stats: self.stats + other.stats, - } - } -} - -impl Div for CPUSample { - type Output = CPUSample; - fn div(self, divisor: usize) -> CPUSample { - CPUSample { - elapsed: self.elapsed / (divisor as u32), - stats: self.stats / divisor, - } - } -} - -fn duration_to_ms(time: Duration) -> f64 { - time.as_secs() as f64 * 1000.0 + time.subsec_nanos() as f64 / 1000000.0 -} diff --git a/crates/pathfinder/renderer/src/gpu/mod.rs b/crates/pathfinder/renderer/src/gpu/mod.rs deleted file mode 100644 index 9d005dec1f..0000000000 --- a/crates/pathfinder/renderer/src/gpu/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -// pathfinder/renderer/src/gpu/mod.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! The GPU renderer for Pathfinder 3. - -pub mod debug; -pub mod options; -pub mod renderer; - -pub(crate) mod shaders; diff --git a/crates/pathfinder/renderer/src/gpu/options.rs b/crates/pathfinder/renderer/src/gpu/options.rs deleted file mode 100644 index 435a631774..0000000000 --- a/crates/pathfinder/renderer/src/gpu/options.rs +++ /dev/null @@ -1,58 +0,0 @@ -// pathfinder/renderer/src/gpu/options.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use pathfinder_color::ColorF; -use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::Vector2I; -use pathfinder_gpu::Device; - -/// Options that influence rendering. -#[derive(Default)] -pub struct RendererOptions { - pub background_color: Option, - pub no_compute: bool, -} - -#[derive(Clone)] -pub enum DestFramebuffer where D: Device { - Default { - viewport: RectI, - window_size: Vector2I, - }, - Other(D::Framebuffer), -} - -impl Default for DestFramebuffer where D: Device { - #[inline] - fn default() -> DestFramebuffer { - DestFramebuffer::Default { viewport: RectI::default(), window_size: Vector2I::default() } - } -} - -impl DestFramebuffer -where - D: Device, -{ - #[inline] - pub fn full_window(window_size: Vector2I) -> DestFramebuffer { - let viewport = RectI::new(Vector2I::default(), window_size); - DestFramebuffer::Default { viewport, window_size } - } - - #[inline] - pub fn window_size(&self, device: &D) -> Vector2I { - match *self { - DestFramebuffer::Default { window_size, .. } => window_size, - DestFramebuffer::Other(ref framebuffer) => { - device.texture_size(device.framebuffer_texture(framebuffer)) - } - } - } -} diff --git a/crates/pathfinder/renderer/src/gpu/renderer.rs b/crates/pathfinder/renderer/src/gpu/renderer.rs deleted file mode 100644 index 8fd5b27f3b..0000000000 --- a/crates/pathfinder/renderer/src/gpu/renderer.rs +++ /dev/null @@ -1,2040 +0,0 @@ -// pathfinder/renderer/src/gpu/renderer.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::gpu::debug::DebugUIPresenter; -use crate::gpu::options::{DestFramebuffer, RendererOptions}; -use crate::gpu::shaders::{BlitProgram, BlitVertexArray, ClearProgram, ClearVertexArray, ClipTileProgram, ClipTileVertexArray}; -use crate::gpu::shaders::{CopyTileProgram, CopyTileVertexArray, FillProgram, FillVertexArray}; -use crate::gpu::shaders::{MAX_FILLS_PER_BATCH, MAX_TILES_PER_BATCH, ReprojectionProgram}; -use crate::gpu::shaders::{ReprojectionVertexArray, StencilProgram, StencilVertexArray}; -use crate::gpu::shaders::{TileProgram, TileVertexArray}; -use crate::gpu_data::{ClipBatch, ClipBatchKey, ClipBatchKind, Fill, FillBatchEntry, RenderCommand}; -use crate::gpu_data::{TextureLocation, TextureMetadataEntry, TexturePageDescriptor, TexturePageId}; -use crate::gpu_data::{Tile, TileBatchTexture}; -use crate::options::BoundingQuad; -use crate::paint::PaintCompositeOp; -use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; -use fxhash::FxHashMap; -use half::f16; -use pathfinder_color::{self as color, ColorF, ColorU}; -use pathfinder_content::effects::{BlendMode, BlurDirection, DefringingKernel}; -use pathfinder_content::effects::{Filter, PatternFilter}; -use pathfinder_content::render_target::RenderTargetId; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::transform3d::Transform4F; -use pathfinder_geometry::util; -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}; -use pathfinder_gpu::{RenderTarget, StencilFunc, StencilState, TextureDataRef}; -use pathfinder_gpu::{TextureFormat, UniformData}; -use pathfinder_resources::ResourceLoader; -use pathfinder_simd::default::{F32x2, F32x4, I32x2}; -use std::collections::VecDeque; -use std::f32; -use std::marker::PhantomData; -use std::mem; -use std::ops::{Add, Div}; -use std::time::Duration; -use std::u32; - -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; -pub(crate) const MASK_TILES_DOWN: u32 = 256; - -// 1.0 / sqrt(2*pi) -const SQRT_2_PI_INV: f32 = 0.3989422804014327; - -const TEXTURE_CACHE_SIZE: usize = 8; - -const MIN_FILL_STORAGE_CLASS: usize = 14; // 0x4000 entries, 128kB -const MIN_TILE_STORAGE_CLASS: usize = 10; // 1024 entries, 12kB - -const TEXTURE_METADATA_ENTRIES_PER_ROW: i32 = 128; -const TEXTURE_METADATA_TEXTURE_WIDTH: i32 = TEXTURE_METADATA_ENTRIES_PER_ROW * 4; -const TEXTURE_METADATA_TEXTURE_HEIGHT: i32 = 65536 / TEXTURE_METADATA_ENTRIES_PER_ROW; - -// FIXME(pcwalton): Shrink this again! -const MASK_FRAMEBUFFER_WIDTH: i32 = TILE_WIDTH as i32 * MASK_TILES_ACROSS as i32; -const MASK_FRAMEBUFFER_HEIGHT: i32 = TILE_HEIGHT as i32 / 4 * MASK_TILES_DOWN as i32; - -const COMBINER_CTRL_COLOR_COMBINE_SRC_IN: i32 = 0x1; -const COMBINER_CTRL_COLOR_COMBINE_DEST_IN: i32 = 0x2; - -const COMBINER_CTRL_FILTER_RADIAL_GRADIENT: i32 = 0x1; -const COMBINER_CTRL_FILTER_TEXT: i32 = 0x2; -const COMBINER_CTRL_FILTER_BLUR: i32 = 0x3; - -const COMBINER_CTRL_COMPOSITE_NORMAL: i32 = 0x0; -const COMBINER_CTRL_COMPOSITE_MULTIPLY: i32 = 0x1; -const COMBINER_CTRL_COMPOSITE_SCREEN: i32 = 0x2; -const COMBINER_CTRL_COMPOSITE_OVERLAY: i32 = 0x3; -const COMBINER_CTRL_COMPOSITE_DARKEN: i32 = 0x4; -const COMBINER_CTRL_COMPOSITE_LIGHTEN: i32 = 0x5; -const COMBINER_CTRL_COMPOSITE_COLOR_DODGE: i32 = 0x6; -const COMBINER_CTRL_COMPOSITE_COLOR_BURN: i32 = 0x7; -const COMBINER_CTRL_COMPOSITE_HARD_LIGHT: i32 = 0x8; -const COMBINER_CTRL_COMPOSITE_SOFT_LIGHT: i32 = 0x9; -const COMBINER_CTRL_COMPOSITE_DIFFERENCE: i32 = 0xa; -const COMBINER_CTRL_COMPOSITE_EXCLUSION: i32 = 0xb; -const COMBINER_CTRL_COMPOSITE_HUE: i32 = 0xc; -const COMBINER_CTRL_COMPOSITE_SATURATION: i32 = 0xd; -const COMBINER_CTRL_COMPOSITE_COLOR: i32 = 0xe; -const COMBINER_CTRL_COMPOSITE_LUMINOSITY: i32 = 0xf; - -const COMBINER_CTRL_COLOR_FILTER_SHIFT: i32 = 4; -const COMBINER_CTRL_COLOR_COMBINE_SHIFT: i32 = 6; -const COMBINER_CTRL_COMPOSITE_SHIFT: i32 = 8; - -pub struct Renderer where D: Device { - // Device - pub device: D, - - // Core data - dest_framebuffer: DestFramebuffer, - options: RendererOptions, - blit_program: BlitProgram, - clear_program: ClearProgram, - fill_program: FillProgram, - tile_program: TileProgram, - tile_copy_program: CopyTileProgram, - tile_clip_program: ClipTileProgram, - stencil_program: StencilProgram, - reprojection_program: ReprojectionProgram, - quad_vertex_positions_buffer: D::Buffer, - quad_vertex_indices_buffer: D::Buffer, - next_fills: Vec, - fill_tile_map: Vec, - texture_pages: Vec>>, - render_targets: Vec, - render_target_stack: Vec, - area_lut_texture: D::Texture, - gamma_lut_texture: D::Texture, - - // Frames - front_frame: Frame, - back_frame: Frame, - front_frame_fence: Option, - - // Rendering state - texture_cache: TextureCache, - - // Debug - pub stats: RenderStats, - current_cpu_build_time: Option, - current_timer: Option>, - pending_timers: VecDeque>, - timer_query_cache: TimerQueryCache, - pub debug_ui_presenter: DebugUIPresenter, - - // Extra info - flags: RendererFlags, -} - -struct Frame where D: Device { - framebuffer_flags: FramebufferFlags, - blit_vertex_array: BlitVertexArray, - clear_vertex_array: ClearVertexArray, - fill_vertex_storage_allocator: StorageAllocator>, - tile_vertex_storage_allocator: StorageAllocator>, - quads_vertex_indices_buffer: D::Buffer, - quads_vertex_indices_length: usize, - alpha_tile_pages: FxHashMap>, - tile_clip_vertex_array: ClipTileVertexArray, - stencil_vertex_array: StencilVertexArray, - reprojection_vertex_array: ReprojectionVertexArray, - dest_blend_framebuffer: D::Framebuffer, - intermediate_dest_framebuffer: D::Framebuffer, - texture_metadata_texture: D::Texture, -} - -impl Renderer where D: Device { - pub fn new(device: D, - resources: &dyn ResourceLoader, - dest_framebuffer: DestFramebuffer, - options: RendererOptions) - -> Renderer { - let blit_program = BlitProgram::new(&device, resources); - let clear_program = ClearProgram::new(&device, resources); - let fill_program = FillProgram::new(&device, resources, &options); - let tile_program = TileProgram::new(&device, resources); - let tile_copy_program = CopyTileProgram::new(&device, resources); - let tile_clip_program = ClipTileProgram::new(&device, resources); - let stencil_program = StencilProgram::new(&device, resources); - let reprojection_program = ReprojectionProgram::new(&device, resources); - - let area_lut_texture = - device.create_texture_from_png(resources, "area-lut", TextureFormat::RGBA8); - let gamma_lut_texture = - device.create_texture_from_png(resources, "gamma-lut", TextureFormat::R8); - - let quad_vertex_positions_buffer = device.create_buffer(BufferUploadMode::Static); - device.allocate_buffer(&quad_vertex_positions_buffer, - BufferData::Memory(&QUAD_VERTEX_POSITIONS), - BufferTarget::Vertex); - let quad_vertex_indices_buffer = device.create_buffer(BufferUploadMode::Static); - device.allocate_buffer(&quad_vertex_indices_buffer, - BufferData::Memory(&QUAD_VERTEX_INDICES), - BufferTarget::Index); - - let window_size = dest_framebuffer.window_size(&device); - - let timer_query_cache = TimerQueryCache::new(&device); - let debug_ui_presenter = DebugUIPresenter::new(&device, resources, window_size); - - let front_frame = Frame::new(&device, - &blit_program, - &clear_program, - &tile_clip_program, - &reprojection_program, - &stencil_program, - &quad_vertex_positions_buffer, - &quad_vertex_indices_buffer, - window_size); - let back_frame = Frame::new(&device, - &blit_program, - &clear_program, - &tile_clip_program, - &reprojection_program, - &stencil_program, - &quad_vertex_positions_buffer, - &quad_vertex_indices_buffer, - window_size); - - Renderer { - device, - - dest_framebuffer, - options, - blit_program, - clear_program, - fill_program, - tile_program, - tile_copy_program, - tile_clip_program, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer, - next_fills: vec![], - fill_tile_map: vec![-1; 256 * 256], - texture_pages: vec![], - render_targets: vec![], - render_target_stack: vec![], - - front_frame, - back_frame, - front_frame_fence: None, - - area_lut_texture, - gamma_lut_texture, - - stencil_program, - - reprojection_program, - - stats: RenderStats::default(), - current_cpu_build_time: None, - current_timer: None, - pending_timers: VecDeque::new(), - timer_query_cache, - debug_ui_presenter, - - texture_cache: TextureCache::new(), - - flags: RendererFlags::empty(), - } - } - - pub fn begin_scene(&mut self) { - self.back_frame.framebuffer_flags = FramebufferFlags::empty(); - for alpha_tile_page in self.back_frame.alpha_tile_pages.values_mut() { - alpha_tile_page.framebuffer_is_dirty = false; - } - - self.device.begin_commands(); - self.current_timer = Some(PendingTimer::new()); - self.stats = RenderStats::default(); - } - - pub fn render_command(&mut self, command: &RenderCommand) { - debug!("render command: {:?}", command); - match *command { - RenderCommand::Start { bounding_quad, path_count, needs_readable_framebuffer } => { - self.start_rendering(bounding_quad, path_count, needs_readable_framebuffer); - } - RenderCommand::AllocateTexturePage { page_id, ref descriptor } => { - self.allocate_texture_page(page_id, descriptor) - } - RenderCommand::UploadTexelData { ref texels, location } => { - self.upload_texel_data(texels, location) - } - RenderCommand::DeclareRenderTarget { id, location } => { - self.declare_render_target(id, location) - } - RenderCommand::UploadTextureMetadata(ref metadata) => { - self.upload_texture_metadata(metadata) - } - RenderCommand::AddFills(ref fills) => self.add_fills(fills), - RenderCommand::FlushFills => { - let page_indices: Vec<_> = - self.back_frame.alpha_tile_pages.keys().cloned().collect(); - for page_index in page_indices { - self.draw_buffered_fills(page_index) - } - } - RenderCommand::ClipTiles(ref batches) => { - batches.iter().for_each(|batch| self.draw_clip_batch(batch)) - } - RenderCommand::BeginTileDrawing => {} - RenderCommand::PushRenderTarget(render_target_id) => { - self.push_render_target(render_target_id) - } - RenderCommand::PopRenderTarget => self.pop_render_target(), - RenderCommand::DrawTiles(ref batch) => { - let count = batch.tiles.len(); - self.stats.alpha_tile_count += count; - let storage_id = self.upload_tiles(&batch.tiles); - self.draw_tiles(batch.tile_page, - count as u32, - storage_id, - batch.color_texture, - batch.blend_mode, - batch.filter) - } - RenderCommand::Finish { cpu_build_time } => { - self.stats.cpu_build_time = cpu_build_time; - } - } - } - - pub fn end_scene(&mut self) { - self.clear_dest_framebuffer_if_necessary(); - self.blit_intermediate_dest_framebuffer_if_necessary(); - - let old_front_frame_fence = self.front_frame_fence.take(); - self.front_frame_fence = Some(self.device.add_fence()); - self.device.end_commands(); - - self.back_frame.fill_vertex_storage_allocator.end_frame(); - self.back_frame.tile_vertex_storage_allocator.end_frame(); - - if let Some(timer) = self.current_timer.take() { - self.pending_timers.push_back(timer); - } - self.current_cpu_build_time = None; - - if let Some(old_front_frame_fence) = old_front_frame_fence { - self.device.wait_for_fence(&old_front_frame_fence); - } - - mem::swap(&mut self.front_frame, &mut self.back_frame); - } - - fn start_rendering(&mut self, - bounding_quad: BoundingQuad, - path_count: usize, - mut needs_readable_framebuffer: bool) { - if let DestFramebuffer::Other(_) = self.dest_framebuffer { - needs_readable_framebuffer = false; - } - - if self.flags.contains(RendererFlags::USE_DEPTH) { - self.draw_stencil(&bounding_quad); - } - self.stats.path_count = path_count; - - self.flags.set(RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED, - needs_readable_framebuffer); - - self.render_targets.clear(); - } - - pub fn draw_debug_ui(&self) { - self.debug_ui_presenter.draw(&self.device); - } - - pub fn shift_rendering_time(&mut self) -> Option { - if let Some(mut pending_timer) = self.pending_timers.pop_front() { - for old_query in pending_timer.poll(&self.device) { - self.timer_query_cache.free(old_query); - } - if let Some(gpu_time) = pending_timer.total_time() { - return Some(RenderTime { gpu_time }) - } - self.pending_timers.push_front(pending_timer); - } - None - } - - #[inline] - pub fn dest_framebuffer(&self) -> &DestFramebuffer { - &self.dest_framebuffer - } - - #[inline] - pub fn replace_dest_framebuffer( - &mut self, - new_dest_framebuffer: DestFramebuffer, - ) -> DestFramebuffer { - mem::replace(&mut self.dest_framebuffer, new_dest_framebuffer) - } - - #[inline] - pub fn set_options(&mut self, new_options: RendererOptions) { - self.options = new_options - } - - #[inline] - pub fn set_main_framebuffer_size(&mut self, new_framebuffer_size: Vector2I) { - self.debug_ui_presenter.ui_presenter.set_framebuffer_size(new_framebuffer_size); - } - - #[inline] - pub fn disable_depth(&mut self) { - self.flags.remove(RendererFlags::USE_DEPTH); - } - - #[inline] - pub fn enable_depth(&mut self) { - self.flags.insert(RendererFlags::USE_DEPTH); - } - - #[inline] - pub fn quad_vertex_positions_buffer(&self) -> &D::Buffer { - &self.quad_vertex_positions_buffer - } - - #[inline] - pub fn quad_vertex_indices_buffer(&self) -> &D::Buffer { - &self.quad_vertex_indices_buffer - } - - fn allocate_texture_page(&mut self, - page_id: TexturePageId, - descriptor: &TexturePageDescriptor) { - // Fill in IDs up to the requested page ID. - let page_index = page_id.0 as usize; - while self.texture_pages.len() < page_index + 1 { - self.texture_pages.push(None); - } - - // Clear out any existing texture. - if let Some(old_texture_page) = self.texture_pages[page_index].take() { - let old_texture = self.device.destroy_framebuffer(old_texture_page.framebuffer); - self.texture_cache.release_texture(old_texture); - } - - // Allocate texture. - let texture_size = descriptor.size; - let texture = self.texture_cache.create_texture(&mut self.device, - TextureFormat::RGBA8, - texture_size); - let framebuffer = self.device.create_framebuffer(texture); - self.texture_pages[page_index] = Some(TexturePage { - framebuffer, - must_preserve_contents: false, - }); - } - - fn upload_texel_data(&mut self, texels: &[ColorU], location: TextureLocation) { - let texture_page = self.texture_pages[location.page.0 as usize] - .as_mut() - .expect("Texture page not allocated yet!"); - let texture = self.device.framebuffer_texture(&texture_page.framebuffer); - let texels = color::color_slice_to_u8_slice(texels); - self.device.upload_to_texture(texture, location.rect, TextureDataRef::U8(texels)); - texture_page.must_preserve_contents = true; - } - - fn declare_render_target(&mut self, - render_target_id: RenderTargetId, - location: TextureLocation) { - while self.render_targets.len() < render_target_id.render_target as usize + 1 { - self.render_targets.push(RenderTargetInfo { - location: TextureLocation { page: TexturePageId(!0), rect: RectI::default() }, - }); - } - let mut render_target = &mut self.render_targets[render_target_id.render_target as usize]; - debug_assert_eq!(render_target.location.page, TexturePageId(!0)); - render_target.location = location; - } - - fn upload_texture_metadata(&mut self, metadata: &[TextureMetadataEntry]) { - let padded_texel_size = - (util::alignup_i32(metadata.len() as i32, TEXTURE_METADATA_ENTRIES_PER_ROW) * - TEXTURE_METADATA_TEXTURE_WIDTH * 4) as usize; - let mut texels = Vec::with_capacity(padded_texel_size); - for entry in metadata { - let base_color = entry.base_color.to_f32(); - texels.extend_from_slice(&[ - f16::from_f32(entry.color_0_transform.m11()), - f16::from_f32(entry.color_0_transform.m21()), - f16::from_f32(entry.color_0_transform.m12()), - f16::from_f32(entry.color_0_transform.m22()), - f16::from_f32(entry.color_0_transform.m13()), - f16::from_f32(entry.color_0_transform.m23()), - f16::default(), - f16::default(), - f16::from_f32(base_color.r()), - f16::from_f32(base_color.g()), - f16::from_f32(base_color.b()), - f16::from_f32(base_color.a()), - f16::default(), - f16::default(), - f16::default(), - f16::default(), - ]); - } - while texels.len() < padded_texel_size { - texels.push(f16::default()) - } - - let texture = &mut self.back_frame.texture_metadata_texture; - let width = TEXTURE_METADATA_TEXTURE_WIDTH; - let height = texels.len() as i32 / (4 * TEXTURE_METADATA_TEXTURE_WIDTH); - let rect = RectI::new(Vector2I::zero(), Vector2I::new(width, height)); - self.device.upload_to_texture(texture, rect, TextureDataRef::F16(&texels)); - } - - fn upload_tiles(&mut self, tiles: &[Tile]) -> StorageID { - debug_assert!(tiles.len() <= MAX_TILES_PER_BATCH); - - let tile_program = &self.tile_program; - let tile_copy_program = &self.tile_copy_program; - let quad_vertex_positions_buffer = &self.quad_vertex_positions_buffer; - let quad_vertex_indices_buffer = &self.quad_vertex_indices_buffer; - let storage_id = self.back_frame.tile_vertex_storage_allocator.allocate(&self.device, - tiles.len() as u64, - |device, size| { - TileVertexStorage::new(size, - device, - tile_program, - tile_copy_program, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer) - }); - - let vertex_buffer = &self.back_frame - .tile_vertex_storage_allocator - .get(storage_id) - .vertex_buffer; - self.device.upload_to_buffer(vertex_buffer, 0, tiles, BufferTarget::Vertex); - - self.ensure_index_buffer(tiles.len()); - - storage_id - } - - fn ensure_index_buffer(&mut self, mut length: usize) { - length = length.next_power_of_two(); - if self.back_frame.quads_vertex_indices_length >= length { - return; - } - - // TODO(pcwalton): Generate these with SIMD. - let mut indices: Vec = Vec::with_capacity(length * 6); - for index in 0..(length as u32) { - indices.extend_from_slice(&[ - index * 4 + 0, index * 4 + 1, index * 4 + 2, - index * 4 + 1, index * 4 + 3, index * 4 + 2, - ]); - } - - self.device.allocate_buffer(&self.back_frame.quads_vertex_indices_buffer, - BufferData::Memory(&indices), - BufferTarget::Index); - - self.back_frame.quads_vertex_indices_length = length; - } - - fn add_fills(&mut self, fill_batch: &[FillBatchEntry]) { - if fill_batch.is_empty() { - return; - } - - self.stats.fill_count += fill_batch.len(); - - // We have to make sure we don't split batches across draw calls, or else the compute - // shader path, which expects to see all the fills belonging to one tile in the same - // batch, will break. - - let mut pages_touched = vec![]; - for fill_batch_entry in fill_batch { - let page_index = fill_batch_entry.page; - if !self.back_frame.alpha_tile_pages.contains_key(&page_index) { - let alpha_tile_page = AlphaTilePage::new(&mut self.device); - self.back_frame.alpha_tile_pages.insert(page_index, alpha_tile_page); - } - - let page = self.back_frame.alpha_tile_pages.get_mut(&page_index).unwrap(); - if page.pending_fills.is_empty() { - pages_touched.push(page_index); - } - page.pending_fills.push(fill_batch_entry.fill); - } - - for page_index in pages_touched { - if self.back_frame.alpha_tile_pages[&page_index].buffered_fills.len() + - self.back_frame.alpha_tile_pages[&page_index].pending_fills.len() > - MAX_FILLS_PER_BATCH { - self.draw_buffered_fills(page_index); - } - - let page = self.back_frame.alpha_tile_pages.get_mut(&page_index).unwrap(); - for fill in &page.pending_fills { - page.buffered_fills.push(*fill); - } - page.pending_fills.clear(); - } - } - - fn draw_buffered_fills(&mut self, page: u16) { - match self.fill_program { - FillProgram::Raster(_) => self.draw_buffered_fills_via_raster(page), - FillProgram::Compute(_) => self.draw_buffered_fills_via_compute(page), - } - } - - fn draw_buffered_fills_via_raster(&mut self, page: u16) { - let fill_raster_program = match self.fill_program { - FillProgram::Raster(ref fill_raster_program) => fill_raster_program, - _ => unreachable!(), - }; - - let mask_viewport = self.mask_viewport(); - - let alpha_tile_page = self.back_frame - .alpha_tile_pages - .get_mut(&page) - .expect("Where's the alpha tile page?"); - let buffered_fills = &mut alpha_tile_page.buffered_fills; - if buffered_fills.is_empty() { - return; - } - - let storage_id = { - let fill_program = &self.fill_program; - let quad_vertex_positions_buffer = &self.quad_vertex_positions_buffer; - let quad_vertex_indices_buffer = &self.quad_vertex_indices_buffer; - self.back_frame - .fill_vertex_storage_allocator - .allocate(&self.device, MAX_FILLS_PER_BATCH as u64, |device, size| { - FillVertexStorage::new(size, - device, - fill_program, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer) - }) - }; - let fill_vertex_storage = self.back_frame.fill_vertex_storage_allocator.get(storage_id); - - let fill_vertex_array = match fill_vertex_storage.auxiliary { - FillVertexStorageAuxiliary::Raster { ref vertex_array } => vertex_array, - _ => unreachable!(), - }; - - self.device.upload_to_buffer(&fill_vertex_storage.vertex_buffer, - 0, - &buffered_fills, - BufferTarget::Vertex); - - let mut clear_color = None; - if !alpha_tile_page.framebuffer_is_dirty { - clear_color = Some(ColorF::default()); - }; - - let timer_query = self.timer_query_cache.alloc(&self.device); - self.device.begin_timer_query(&timer_query); - - debug_assert!(buffered_fills.len() <= u32::MAX as usize); - self.device.draw_elements_instanced(6, buffered_fills.len() as u32, &RenderState { - target: &RenderTarget::Framebuffer(&alpha_tile_page.framebuffer), - program: &fill_raster_program.program, - vertex_array: &fill_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[&self.area_lut_texture], - uniforms: &[ - (&fill_raster_program.framebuffer_size_uniform, - UniformData::Vec2(F32x2::new(MASK_FRAMEBUFFER_WIDTH as f32, - MASK_FRAMEBUFFER_HEIGHT as f32))), - (&fill_raster_program.tile_size_uniform, - UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))), - (&fill_raster_program.area_lut_uniform, UniformData::TextureUnit(0)), - ], - images: &[], - viewport: mask_viewport, - options: RenderOptions { - blend: Some(BlendState { - src_rgb_factor: BlendFactor::One, - src_alpha_factor: BlendFactor::One, - dest_rgb_factor: BlendFactor::One, - dest_alpha_factor: BlendFactor::One, - ..BlendState::default() - }), - clear_ops: ClearOps { color: clear_color, ..ClearOps::default() }, - ..RenderOptions::default() - }, - }); - - self.device.end_timer_query(&timer_query); - self.current_timer.as_mut().unwrap().fill_times.push(TimerFuture::new(timer_query)); - - alpha_tile_page.framebuffer_is_dirty = true; - buffered_fills.clear(); - } - - fn draw_buffered_fills_via_compute(&mut self, page: u16) { - let fill_compute_program = match self.fill_program { - FillProgram::Compute(ref fill_compute_program) => fill_compute_program, - _ => unreachable!(), - }; - - let alpha_tile_page = self.back_frame - .alpha_tile_pages - .get_mut(&page) - .expect("Where's the alpha tile page?"); - let buffered_fills = &mut alpha_tile_page.buffered_fills; - if buffered_fills.is_empty() { - return; - } - - let storage_id = { - let fill_program = &self.fill_program; - let quad_vertex_positions_buffer = &self.quad_vertex_positions_buffer; - let quad_vertex_indices_buffer = &self.quad_vertex_indices_buffer; - self.back_frame.fill_vertex_storage_allocator.allocate(&self.device, - MAX_FILLS_PER_BATCH as u64, - |device, size| { - FillVertexStorage::new(size, - device, - fill_program, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer) - }) - }; - let fill_vertex_storage = self.back_frame.fill_vertex_storage_allocator.get(storage_id); - - let (tile_map_buffer, next_fills_buffer) = match fill_vertex_storage.auxiliary { - FillVertexStorageAuxiliary::Compute { ref tile_map_buffer, ref next_fills_buffer } => { - (tile_map_buffer, next_fills_buffer) - } - _ => unreachable!(), - }; - - // Initialize the tile map and fill linked list buffers. - self.fill_tile_map.iter_mut().for_each(|entry| *entry = -1); - while self.next_fills.len() < buffered_fills.len() { - self.next_fills.push(-1); - } - - // Create a linked list running through all our fills. - let (mut first_fill_tile, mut last_fill_tile) = (256 * 256, 0); - for (fill_index, fill) in buffered_fills.iter().enumerate() { - let fill_tile_index = fill.alpha_tile_index as usize; - self.next_fills[fill_index as usize] = self.fill_tile_map[fill_tile_index]; - self.fill_tile_map[fill_tile_index] = fill_index as i32; - first_fill_tile = first_fill_tile.min(fill_tile_index as u32); - last_fill_tile = last_fill_tile.max(fill_tile_index as u32); - } - let fill_tile_count = last_fill_tile - first_fill_tile + 1; - - self.device.upload_to_buffer(&fill_vertex_storage.vertex_buffer, - 0, - &buffered_fills, - BufferTarget::Storage); - self.device.upload_to_buffer(next_fills_buffer, - 0, - &self.next_fills, - BufferTarget::Storage); - self.device.upload_to_buffer(tile_map_buffer, - 0, - &self.fill_tile_map, - BufferTarget::Storage); - - let image_binding = ImageBinding { - texture: self.device.framebuffer_texture(&alpha_tile_page.framebuffer), - access: ImageAccess::Write, - }; - - let timer_query = self.timer_query_cache.alloc(&self.device); - self.device.begin_timer_query(&timer_query); - - debug_assert!(buffered_fills.len() <= u32::MAX as usize); - let dimensions = ComputeDimensions { x: 1, y: 1, z: fill_tile_count as u32 }; - self.device.dispatch_compute(dimensions, &ComputeState { - program: &fill_compute_program.program, - textures: &[&self.area_lut_texture], - images: &[image_binding], - uniforms: &[ - (&fill_compute_program.area_lut_uniform, UniformData::TextureUnit(0)), - (&fill_compute_program.dest_uniform, UniformData::ImageUnit(0)), - (&fill_compute_program.first_tile_index_uniform, - UniformData::Int(first_fill_tile as i32)), - ], - storage_buffers: &[ - (&fill_compute_program.fills_storage_buffer, &fill_vertex_storage.vertex_buffer), - (&fill_compute_program.next_fills_storage_buffer, next_fills_buffer), - (&fill_compute_program.fill_tile_map_storage_buffer, tile_map_buffer), - ], - }); - - self.device.end_timer_query(&timer_query); - self.current_timer.as_mut().unwrap().fill_times.push(TimerFuture::new(timer_query)); - - alpha_tile_page.framebuffer_is_dirty = true; - buffered_fills.clear(); - } - - fn draw_clip_batch(&mut self, batch: &ClipBatch) { - if batch.clips.is_empty() { - return; - } - - let ClipBatchKey { dest_page, src_page, kind } = batch.key; - - self.device.allocate_buffer(&self.back_frame.tile_clip_vertex_array.vertex_buffer, - BufferData::Memory(&batch.clips), - BufferTarget::Vertex); - - if !self.back_frame.alpha_tile_pages.contains_key(&dest_page) { - let alpha_tile_page = AlphaTilePage::new(&mut self.device); - self.back_frame.alpha_tile_pages.insert(dest_page, alpha_tile_page); - } - - let mut clear_color = None; - if !self.back_frame.alpha_tile_pages[&dest_page].framebuffer_is_dirty { - clear_color = Some(ColorF::default()); - }; - - let blend = match kind { - ClipBatchKind::Draw => None, - ClipBatchKind::Clip => { - Some(BlendState { - src_rgb_factor: BlendFactor::One, - src_alpha_factor: BlendFactor::One, - dest_rgb_factor: BlendFactor::One, - dest_alpha_factor: BlendFactor::One, - op: BlendOp::Min, - }) - } - }; - - let mask_viewport = self.mask_viewport(); - - let timer_query = self.timer_query_cache.alloc(&self.device); - self.device.begin_timer_query(&timer_query); - - { - let dest_framebuffer = &self.back_frame.alpha_tile_pages[&dest_page].framebuffer; - let src_framebuffer = &self.back_frame.alpha_tile_pages[&src_page].framebuffer; - let src_texture = self.device.framebuffer_texture(&src_framebuffer); - - debug_assert!(batch.clips.len() <= u32::MAX as usize); - self.device.draw_elements_instanced(6, batch.clips.len() as u32, &RenderState { - target: &RenderTarget::Framebuffer(dest_framebuffer), - program: &self.tile_clip_program.program, - vertex_array: &self.back_frame.tile_clip_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[src_texture], - images: &[], - uniforms: &[(&self.tile_clip_program.src_uniform, UniformData::TextureUnit(0))], - viewport: mask_viewport, - options: RenderOptions { - blend, - clear_ops: ClearOps { color: clear_color, ..ClearOps::default() }, - ..RenderOptions::default() - }, - }); - - self.device.end_timer_query(&timer_query); - self.current_timer.as_mut().unwrap().fill_times.push(TimerFuture::new(timer_query)); - } - - self.back_frame - .alpha_tile_pages - .get_mut(&dest_page) - .unwrap() - .framebuffer_is_dirty = true; - } - - fn tile_transform(&self) -> Transform4F { - let draw_viewport = self.draw_viewport().size().to_f32(); - let scale = Vector4F::new(2.0 / draw_viewport.x(), -2.0 / draw_viewport.y(), 1.0, 1.0); - Transform4F::from_scale(scale).translate(Vector4F::new(-1.0, 1.0, 0.0, 1.0)) - } - - fn draw_tiles(&mut self, - tile_page: u16, - tile_count: u32, - storage_id: StorageID, - color_texture_0: Option, - blend_mode: BlendMode, - filter: Filter) { - // TODO(pcwalton): Disable blend for solid tiles. - - let needs_readable_framebuffer = blend_mode.needs_readable_framebuffer(); - if needs_readable_framebuffer { - self.copy_alpha_tiles_to_dest_blend_texture(tile_count, storage_id); - } - - let clear_color = self.clear_color_for_draw_operation(); - let draw_viewport = self.draw_viewport(); - - let timer_query = self.timer_query_cache.alloc(&self.device); - self.device.begin_timer_query(&timer_query); - - let mut textures = vec![&self.back_frame.texture_metadata_texture]; - let mut uniforms = vec![ - (&self.tile_program.transform_uniform, - UniformData::Mat4(self.tile_transform().to_columns())), - (&self.tile_program.tile_size_uniform, - UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))), - (&self.tile_program.framebuffer_size_uniform, - UniformData::Vec2(draw_viewport.size().to_f32().0)), - (&self.tile_program.texture_metadata_uniform, UniformData::TextureUnit(0)), - (&self.tile_program.texture_metadata_size_uniform, - UniformData::IVec2(I32x2::new(TEXTURE_METADATA_TEXTURE_WIDTH, - TEXTURE_METADATA_TEXTURE_HEIGHT))), - ]; - - if needs_readable_framebuffer { - uniforms.push((&self.tile_program.dest_texture_uniform, - UniformData::TextureUnit(textures.len() as u32))); - textures.push(self.device - .framebuffer_texture(&self.back_frame.dest_blend_framebuffer)); - } - - if let Some(alpha_tile_page) = self.back_frame.alpha_tile_pages.get(&tile_page) { - uniforms.push((&self.tile_program.mask_texture_0_uniform, - UniformData::TextureUnit(textures.len() as u32))); - uniforms.push((&self.tile_program.mask_texture_size_0_uniform, - UniformData::Vec2(F32x2::new(MASK_FRAMEBUFFER_WIDTH as f32, - MASK_FRAMEBUFFER_HEIGHT as f32)))); - textures.push(self.device.framebuffer_texture(&alpha_tile_page.framebuffer)); - } - - // TODO(pcwalton): Refactor. - let mut ctrl = 0; - match color_texture_0 { - Some(color_texture) => { - let color_texture_page = self.texture_page(color_texture.page); - let color_texture_size = self.device.texture_size(color_texture_page).to_f32(); - self.device.set_texture_sampling_mode(color_texture_page, - color_texture.sampling_flags); - uniforms.push((&self.tile_program.color_texture_0_uniform, - UniformData::TextureUnit(textures.len() as u32))); - uniforms.push((&self.tile_program.color_texture_size_0_uniform, - UniformData::Vec2(color_texture_size.0))); - textures.push(color_texture_page); - - ctrl |= color_texture.composite_op.to_combine_mode() << - COMBINER_CTRL_COLOR_COMBINE_SHIFT; - } - None => { - uniforms.push((&self.tile_program.color_texture_size_0_uniform, - UniformData::Vec2(F32x2::default()))); - } - } - - ctrl |= blend_mode.to_composite_ctrl() << COMBINER_CTRL_COMPOSITE_SHIFT; - - match filter { - Filter::None => self.set_uniforms_for_no_filter(&mut uniforms), - Filter::RadialGradient { line, radii, uv_origin } => { - ctrl |= COMBINER_CTRL_FILTER_RADIAL_GRADIENT << COMBINER_CTRL_COLOR_FILTER_SHIFT; - self.set_uniforms_for_radial_gradient_filter(&mut uniforms, line, radii, uv_origin) - } - Filter::PatternFilter(PatternFilter::Text { - fg_color, - bg_color, - defringing_kernel, - gamma_correction, - }) => { - ctrl |= COMBINER_CTRL_FILTER_TEXT << COMBINER_CTRL_COLOR_FILTER_SHIFT; - self.set_uniforms_for_text_filter(&mut textures, - &mut uniforms, - fg_color, - bg_color, - defringing_kernel, - gamma_correction); - } - Filter::PatternFilter(PatternFilter::Blur { direction, sigma }) => { - ctrl |= COMBINER_CTRL_FILTER_BLUR << COMBINER_CTRL_COLOR_FILTER_SHIFT; - self.set_uniforms_for_blur_filter(&mut uniforms, direction, sigma); - } - } - - uniforms.push((&self.tile_program.ctrl_uniform, UniformData::Int(ctrl))); - - let vertex_array = &self.back_frame - .tile_vertex_storage_allocator - .get(storage_id) - .tile_vertex_array - .vertex_array; - - self.device.draw_elements_instanced(6, tile_count, &RenderState { - target: &self.draw_render_target(), - program: &self.tile_program.program, - vertex_array, - primitive: Primitive::Triangles, - textures: &textures, - images: &[], - uniforms: &uniforms, - viewport: draw_viewport, - options: RenderOptions { - blend: blend_mode.to_blend_state(), - stencil: self.stencil_state(), - clear_ops: ClearOps { color: clear_color, ..ClearOps::default() }, - ..RenderOptions::default() - }, - }); - - self.device.end_timer_query(&timer_query); - self.current_timer.as_mut().unwrap().tile_times.push(TimerFuture::new(timer_query)); - - self.preserve_draw_framebuffer(); - } - - fn copy_alpha_tiles_to_dest_blend_texture(&mut self, tile_count: u32, storage_id: StorageID) { - let draw_viewport = self.draw_viewport(); - - let mut textures = vec![]; - let mut uniforms = vec![ - (&self.tile_copy_program.transform_uniform, - UniformData::Mat4(self.tile_transform().to_columns())), - (&self.tile_copy_program.tile_size_uniform, - UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))), - ]; - - let draw_framebuffer = match self.draw_render_target() { - RenderTarget::Framebuffer(framebuffer) => framebuffer, - RenderTarget::Default => panic!("Can't copy alpha tiles from default framebuffer!"), - }; - let draw_texture = self.device.framebuffer_texture(&draw_framebuffer); - - uniforms.push((&self.tile_copy_program.src_uniform, - UniformData::TextureUnit(textures.len() as u32))); - textures.push(draw_texture); - uniforms.push((&self.tile_copy_program.framebuffer_size_uniform, - UniformData::Vec2(draw_viewport.size().to_f32().0))); - - let vertex_array = &self.back_frame - .tile_vertex_storage_allocator - .get(storage_id) - .tile_copy_vertex_array - .vertex_array; - - self.device.draw_elements(tile_count * 6, &RenderState { - target: &RenderTarget::Framebuffer(&self.back_frame.dest_blend_framebuffer), - program: &self.tile_copy_program.program, - vertex_array, - primitive: Primitive::Triangles, - textures: &textures, - images: &[], - uniforms: &uniforms, - viewport: draw_viewport, - options: RenderOptions { - clear_ops: ClearOps { - color: Some(ColorF::new(1.0, 0.0, 0.0, 1.0)), - ..ClearOps::default() - }, - ..RenderOptions::default() - }, - }); - } - - fn draw_stencil(&mut self, quad_positions: &[Vector4F]) { - self.device.allocate_buffer(&self.back_frame.stencil_vertex_array.vertex_buffer, - BufferData::Memory(quad_positions), - BufferTarget::Vertex); - - // Create indices for a triangle fan. (This is OK because the clipped quad should always be - // convex.) - let mut indices: Vec = vec![]; - for index in 1..(quad_positions.len() as u32 - 1) { - indices.extend_from_slice(&[0, index as u32, index + 1]); - } - self.device.allocate_buffer(&self.back_frame.stencil_vertex_array.index_buffer, - BufferData::Memory(&indices), - BufferTarget::Index); - - self.device.draw_elements(indices.len() as u32, &RenderState { - target: &self.draw_render_target(), - program: &self.stencil_program.program, - vertex_array: &self.back_frame.stencil_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[], - images: &[], - uniforms: &[], - viewport: self.draw_viewport(), - options: RenderOptions { - // FIXME(pcwalton): Should we really write to the depth buffer? - depth: Some(DepthState { func: DepthFunc::Less, write: true }), - stencil: Some(StencilState { - func: StencilFunc::Always, - reference: 1, - mask: 1, - write: true, - }), - color_mask: false, - clear_ops: ClearOps { stencil: Some(0), ..ClearOps::default() }, - ..RenderOptions::default() - }, - }); - } - - pub fn reproject_texture( - &mut self, - texture: &D::Texture, - old_transform: &Transform4F, - new_transform: &Transform4F, - ) { - let clear_color = self.clear_color_for_draw_operation(); - - self.device.draw_elements(6, &RenderState { - target: &self.draw_render_target(), - program: &self.reprojection_program.program, - vertex_array: &self.back_frame.reprojection_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[texture], - images: &[], - uniforms: &[ - (&self.reprojection_program.old_transform_uniform, - UniformData::from_transform_3d(old_transform)), - (&self.reprojection_program.new_transform_uniform, - UniformData::from_transform_3d(new_transform)), - (&self.reprojection_program.texture_uniform, UniformData::TextureUnit(0)), - ], - viewport: self.draw_viewport(), - options: RenderOptions { - blend: BlendMode::SrcOver.to_blend_state(), - depth: Some(DepthState { func: DepthFunc::Less, write: false, }), - clear_ops: ClearOps { color: clear_color, ..ClearOps::default() }, - ..RenderOptions::default() - }, - }); - - self.preserve_draw_framebuffer(); - } - - pub fn draw_render_target(&self) -> RenderTarget { - match self.render_target_stack.last() { - Some(&render_target_id) => { - let texture_page_id = self.render_target_location(render_target_id).page; - let framebuffer = self.texture_page_framebuffer(texture_page_id); - RenderTarget::Framebuffer(framebuffer) - } - None => { - if self.flags.contains(RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED) { - RenderTarget::Framebuffer(&self.back_frame.intermediate_dest_framebuffer) - } else { - match self.dest_framebuffer { - DestFramebuffer::Default { .. } => RenderTarget::Default, - DestFramebuffer::Other(ref framebuffer) => { - RenderTarget::Framebuffer(framebuffer) - } - } - } - } - } - } - - fn push_render_target(&mut self, render_target_id: RenderTargetId) { - self.render_target_stack.push(render_target_id); - } - - fn pop_render_target(&mut self) { - self.render_target_stack.pop().expect("Render target stack underflow!"); - } - - fn set_uniforms_for_no_filter<'a>(&'a self, - uniforms: &mut Vec<(&'a D::Uniform, UniformData)>) { - uniforms.extend_from_slice(&[ - (&self.tile_program.filter_params_0_uniform, UniformData::Vec4(F32x4::default())), - (&self.tile_program.filter_params_1_uniform, UniformData::Vec4(F32x4::default())), - (&self.tile_program.filter_params_2_uniform, UniformData::Vec4(F32x4::default())), - ]); - } - - fn set_uniforms_for_radial_gradient_filter<'a>( - &'a self, - uniforms: &mut Vec<(&'a D::Uniform, UniformData)>, - line: LineSegment2F, - radii: F32x2, - uv_origin: Vector2F) { - uniforms.extend_from_slice(&[ - (&self.tile_program.filter_params_0_uniform, - UniformData::Vec4(line.from().0.concat_xy_xy(line.vector().0))), - (&self.tile_program.filter_params_1_uniform, - UniformData::Vec4(radii.concat_xy_xy(uv_origin.0))), - (&self.tile_program.filter_params_2_uniform, UniformData::Vec4(F32x4::default())), - ]); - } - - fn set_uniforms_for_text_filter<'a>(&'a self, - textures: &mut Vec<&'a D::Texture>, - uniforms: &mut Vec<(&'a D::Uniform, UniformData)>, - fg_color: ColorF, - bg_color: ColorF, - defringing_kernel: Option, - gamma_correction: bool) { - let gamma_lut_texture_unit = textures.len() as u32; - textures.push(&self.gamma_lut_texture); - - match defringing_kernel { - Some(ref kernel) => { - uniforms.push((&self.tile_program.filter_params_0_uniform, - UniformData::Vec4(F32x4::from_slice(&kernel.0)))); - } - None => { - uniforms.push((&self.tile_program.filter_params_0_uniform, - UniformData::Vec4(F32x4::default()))); - } - } - - let mut params_2 = fg_color.0; - params_2.set_w(gamma_correction as i32 as f32); - - uniforms.extend_from_slice(&[ - (&self.tile_program.gamma_lut_uniform, - UniformData::TextureUnit(gamma_lut_texture_unit)), - (&self.tile_program.filter_params_1_uniform, UniformData::Vec4(bg_color.0)), - (&self.tile_program.filter_params_2_uniform, UniformData::Vec4(params_2)), - ]); - - } - - fn set_uniforms_for_blur_filter<'a>(&'a self, - uniforms: &mut Vec<(&'a D::Uniform, UniformData)>, - direction: BlurDirection, - sigma: f32) { - let sigma_inv = 1.0 / sigma; - let gauss_coeff_x = SQRT_2_PI_INV * sigma_inv; - let gauss_coeff_y = f32::exp(-0.5 * sigma_inv * sigma_inv); - let gauss_coeff_z = gauss_coeff_y * gauss_coeff_y; - - let src_offset = match direction { - BlurDirection::X => vec2f(1.0, 0.0), - BlurDirection::Y => vec2f(0.0, 1.0), - }; - - let support = f32::ceil(1.5 * sigma) * 2.0; - - uniforms.extend_from_slice(&[ - (&self.tile_program.filter_params_0_uniform, - UniformData::Vec4(src_offset.0.concat_xy_xy(F32x2::new(support, 0.0)))), - (&self.tile_program.filter_params_1_uniform, - UniformData::Vec4(F32x4::new(gauss_coeff_x, gauss_coeff_y, gauss_coeff_z, 0.0))), - (&self.tile_program.filter_params_2_uniform, UniformData::Vec4(F32x4::default())), - ]); - } - - fn clear_dest_framebuffer_if_necessary(&mut self) { - let background_color = match self.options.background_color { - None => return, - Some(background_color) => background_color, - }; - - if self.back_frame - .framebuffer_flags - .contains(FramebufferFlags::DEST_FRAMEBUFFER_IS_DIRTY) { - return; - } - - let main_viewport = self.main_viewport(); - let uniforms = [ - (&self.clear_program.rect_uniform, UniformData::Vec4(main_viewport.to_f32().0)), - (&self.clear_program.framebuffer_size_uniform, - UniformData::Vec2(main_viewport.size().to_f32().0)), - (&self.clear_program.color_uniform, UniformData::Vec4(background_color.0)), - ]; - - self.device.draw_elements(6, &RenderState { - target: &RenderTarget::Default, - program: &self.clear_program.program, - vertex_array: &self.back_frame.clear_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[], - images: &[], - uniforms: &uniforms[..], - viewport: main_viewport, - options: RenderOptions::default(), - }); - } - - fn blit_intermediate_dest_framebuffer_if_necessary(&mut self) { - if !self.flags.contains(RendererFlags::INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED) { - return; - } - - let main_viewport = self.main_viewport(); - - let uniforms = [(&self.blit_program.src_uniform, UniformData::TextureUnit(0))]; - let textures = [ - (self.device.framebuffer_texture(&self.back_frame.intermediate_dest_framebuffer)) - ]; - - self.device.draw_elements(6, &RenderState { - target: &RenderTarget::Default, - program: &self.blit_program.program, - vertex_array: &self.back_frame.blit_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &textures[..], - images: &[], - uniforms: &uniforms[..], - viewport: main_viewport, - options: RenderOptions { - clear_ops: ClearOps { - color: Some(ColorF::new(0.0, 0.0, 0.0, 1.0)), - ..ClearOps::default() - }, - ..RenderOptions::default() - }, - }); - } - - fn stencil_state(&self) -> Option { - if !self.flags.contains(RendererFlags::USE_DEPTH) { - return None; - } - - Some(StencilState { - func: StencilFunc::Equal, - reference: 1, - mask: 1, - write: false, - }) - } - - fn clear_color_for_draw_operation(&self) -> Option { - let must_preserve_contents = match self.render_target_stack.last() { - Some(&render_target_id) => { - let texture_page = self.render_target_location(render_target_id).page; - self.texture_pages[texture_page.0 as usize] - .as_ref() - .expect("Draw target texture page not allocated!") - .must_preserve_contents - } - None => { - self.back_frame - .framebuffer_flags - .contains(FramebufferFlags::DEST_FRAMEBUFFER_IS_DIRTY) - } - }; - - if must_preserve_contents { - None - } else if self.render_target_stack.is_empty() { - self.options.background_color - } else { - Some(ColorF::default()) - } - } - - fn preserve_draw_framebuffer(&mut self) { - match self.render_target_stack.last() { - Some(&render_target_id) => { - let texture_page = self.render_target_location(render_target_id).page; - self.texture_pages[texture_page.0 as usize] - .as_mut() - .expect("Draw target texture page not allocated!") - .must_preserve_contents = true; - } - None => { - self.back_frame - .framebuffer_flags - .insert(FramebufferFlags::DEST_FRAMEBUFFER_IS_DIRTY); - } - } - } - - pub fn draw_viewport(&self) -> RectI { - match self.render_target_stack.last() { - Some(&render_target_id) => self.render_target_location(render_target_id).rect, - None => self.main_viewport(), - } - } - - fn main_viewport(&self) -> RectI { - match self.dest_framebuffer { - DestFramebuffer::Default { viewport, .. } => viewport, - DestFramebuffer::Other(ref framebuffer) => { - let size = self - .device - .texture_size(self.device.framebuffer_texture(framebuffer)); - RectI::new(Vector2I::default(), size) - } - } - } - - fn mask_viewport(&self) -> RectI { - RectI::new(Vector2I::zero(), vec2i(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT)) - } - - fn render_target_location(&self, render_target_id: RenderTargetId) -> TextureLocation { - self.render_targets[render_target_id.render_target as usize].location - } - - fn texture_page_framebuffer(&self, id: TexturePageId) -> &D::Framebuffer { - &self.texture_pages[id.0 as usize] - .as_ref() - .expect("Texture page not allocated!") - .framebuffer - } - - fn texture_page(&self, id: TexturePageId) -> &D::Texture { - self.device.framebuffer_texture(&self.texture_page_framebuffer(id)) - } -} - -impl Frame where D: Device { - // FIXME(pcwalton): This signature shouldn't be so big. Make a struct. - fn new(device: &D, - blit_program: &BlitProgram, - clear_program: &ClearProgram, - tile_clip_program: &ClipTileProgram, - reprojection_program: &ReprojectionProgram, - stencil_program: &StencilProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer, - window_size: Vector2I) - -> Frame { - let quads_vertex_indices_buffer = device.create_buffer(BufferUploadMode::Dynamic); - - let blit_vertex_array = BlitVertexArray::new(device, - &blit_program, - &quad_vertex_positions_buffer, - &quad_vertex_indices_buffer); - let clear_vertex_array = ClearVertexArray::new(device, - &clear_program, - &quad_vertex_positions_buffer, - &quad_vertex_indices_buffer); - let tile_clip_vertex_array = ClipTileVertexArray::new(device, - &tile_clip_program, - &quad_vertex_positions_buffer, - &quad_vertex_indices_buffer); - let reprojection_vertex_array = ReprojectionVertexArray::new(device, - &reprojection_program, - &quad_vertex_positions_buffer, - &quad_vertex_indices_buffer); - let stencil_vertex_array = StencilVertexArray::new(device, &stencil_program); - - let fill_vertex_storage_allocator = StorageAllocator::new(MIN_FILL_STORAGE_CLASS); - let tile_vertex_storage_allocator = StorageAllocator::new(MIN_TILE_STORAGE_CLASS); - - let texture_metadata_texture_size = vec2i(TEXTURE_METADATA_TEXTURE_WIDTH, - TEXTURE_METADATA_TEXTURE_HEIGHT); - let texture_metadata_texture = device.create_texture(TextureFormat::RGBA16F, - texture_metadata_texture_size); - - let intermediate_dest_texture = device.create_texture(TextureFormat::RGBA8, window_size); - let intermediate_dest_framebuffer = device.create_framebuffer(intermediate_dest_texture); - - let dest_blend_texture = device.create_texture(TextureFormat::RGBA8, window_size); - let dest_blend_framebuffer = device.create_framebuffer(dest_blend_texture); - - Frame { - blit_vertex_array, - clear_vertex_array, - tile_vertex_storage_allocator, - fill_vertex_storage_allocator, - tile_clip_vertex_array, - reprojection_vertex_array, - stencil_vertex_array, - quads_vertex_indices_buffer, - quads_vertex_indices_length: 0, - alpha_tile_pages: FxHashMap::default(), - texture_metadata_texture, - intermediate_dest_framebuffer, - dest_blend_framebuffer, - framebuffer_flags: FramebufferFlags::empty(), - } - } -} - -// Buffer management - -struct StorageAllocator where D: Device { - buckets: Vec>, - min_size_class: usize, - phantom: PhantomData, -} - -struct StorageAllocatorBucket { - free: Vec, - in_use: Vec, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -struct StorageID { - bucket: usize, - index: usize, -} - -impl StorageAllocator where D: Device { - fn new(min_size_class: usize) -> StorageAllocator { - StorageAllocator { buckets: vec![], min_size_class, phantom: PhantomData } - } - - fn allocate(&mut self, device: &D, size: u64, allocator: F) -> StorageID - where D: Device, F: FnOnce(&D, u64) -> S { - let size_class = (64 - (size.leading_zeros() as usize)).max(self.min_size_class); - let bucket_index = size_class - self.min_size_class; - while self.buckets.len() < bucket_index + 1 { - self.buckets.push(StorageAllocatorBucket { free: vec![], in_use: vec![] }); - } - - let bucket = &mut self.buckets[bucket_index]; - match bucket.free.pop() { - Some(storage) => bucket.in_use.push(storage), - None => bucket.in_use.push(allocator(device, 1 << size_class as u64)), - } - StorageID { bucket: bucket_index, index: bucket.in_use.len() - 1 } - } - - fn get(&self, storage_id: StorageID) -> &S { - &self.buckets[storage_id.bucket].in_use[storage_id.index] - } - - fn end_frame(&mut self) { - for bucket in &mut self.buckets { - bucket.free.extend(mem::replace(&mut bucket.in_use, vec![]).into_iter()) - } - } -} - -struct FillVertexStorage where D: Device { - vertex_buffer: D::Buffer, - auxiliary: FillVertexStorageAuxiliary, -} - -enum FillVertexStorageAuxiliary where D: Device { - Raster { vertex_array: FillVertexArray }, - Compute { - next_fills_buffer: D::Buffer, - tile_map_buffer: D::Buffer, - }, -} - -struct TileVertexStorage where D: Device { - tile_vertex_array: TileVertexArray, - tile_copy_vertex_array: CopyTileVertexArray, - vertex_buffer: D::Buffer, -} - -impl FillVertexStorage where D: Device { - fn new(size: u64, - device: &D, - fill_program: &FillProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> FillVertexStorage { - let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic); - let vertex_buffer_data: BufferData = BufferData::Uninitialized(size as usize); - device.allocate_buffer(&vertex_buffer, vertex_buffer_data, BufferTarget::Vertex); - - let auxiliary = match *fill_program { - FillProgram::Raster(ref fill_raster_program) => { - FillVertexStorageAuxiliary::Raster { - vertex_array: FillVertexArray::new(device, - fill_raster_program, - &vertex_buffer, - quad_vertex_positions_buffer, - quad_vertex_indices_buffer), - } - } - FillProgram::Compute(_) => { - let next_fills_buffer = device.create_buffer(BufferUploadMode::Dynamic); - let tile_map_buffer = device.create_buffer(BufferUploadMode::Dynamic); - let next_fills_buffer_data: BufferData = - BufferData::Uninitialized(size as usize); - let tile_map_buffer_data: BufferData = - BufferData::Uninitialized(256 * 256); - device.allocate_buffer(&next_fills_buffer, - next_fills_buffer_data, - BufferTarget::Storage); - device.allocate_buffer(&tile_map_buffer, - tile_map_buffer_data, - BufferTarget::Storage); - FillVertexStorageAuxiliary::Compute { next_fills_buffer, tile_map_buffer } - } - }; - - FillVertexStorage { vertex_buffer, auxiliary } - } -} - -impl TileVertexStorage where D: Device { - fn new(size: u64, - device: &D, - tile_program: &TileProgram, - tile_copy_program: &CopyTileProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> TileVertexStorage { - let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic); - device.allocate_buffer::(&vertex_buffer, - BufferData::Uninitialized(size as usize), - BufferTarget::Vertex); - let tile_vertex_array = TileVertexArray::new(device, - &tile_program, - &vertex_buffer, - &quad_vertex_positions_buffer, - &quad_vertex_indices_buffer); - let tile_copy_vertex_array = CopyTileVertexArray::new(device, - &tile_copy_program, - &vertex_buffer, - &quad_vertex_indices_buffer); - TileVertexStorage { vertex_buffer, tile_vertex_array, tile_copy_vertex_array } - } -} - -// Render stats - -#[derive(Clone, Copy, Debug, Default)] -pub struct RenderStats { - pub path_count: usize, - pub fill_count: usize, - pub alpha_tile_count: usize, - pub solid_tile_count: usize, - pub cpu_build_time: Duration, -} - -impl Add for RenderStats { - type Output = RenderStats; - fn add(self, other: RenderStats) -> RenderStats { - RenderStats { - path_count: self.path_count + other.path_count, - solid_tile_count: self.solid_tile_count + other.solid_tile_count, - alpha_tile_count: self.alpha_tile_count + other.alpha_tile_count, - fill_count: self.fill_count + other.fill_count, - cpu_build_time: self.cpu_build_time + other.cpu_build_time, - } - } -} - -impl Div for RenderStats { - type Output = RenderStats; - fn div(self, divisor: usize) -> RenderStats { - RenderStats { - path_count: self.path_count / divisor, - solid_tile_count: self.solid_tile_count / divisor, - alpha_tile_count: self.alpha_tile_count / divisor, - fill_count: self.fill_count / divisor, - cpu_build_time: self.cpu_build_time / divisor as u32, - } - } -} - -struct TimerQueryCache where D: Device { - free_queries: Vec, -} - -struct PendingTimer where D: Device { - fill_times: Vec>, - tile_times: Vec>, -} - -enum TimerFuture where D: Device { - Pending(D::TimerQuery), - Resolved(Duration), -} - -impl TimerQueryCache where D: Device { - fn new(_: &D) -> TimerQueryCache { - TimerQueryCache { free_queries: vec![] } - } - - fn alloc(&mut self, device: &D) -> D::TimerQuery { - self.free_queries.pop().unwrap_or_else(|| device.create_timer_query()) - } - - fn free(&mut self, old_query: D::TimerQuery) { - self.free_queries.push(old_query); - } -} - -impl PendingTimer where D: Device { - fn new() -> PendingTimer { - PendingTimer { fill_times: vec![], tile_times: vec![] } - } - - fn poll(&mut self, device: &D) -> Vec { - let mut old_queries = vec![]; - for future in self.fill_times.iter_mut().chain(self.tile_times.iter_mut()) { - if let Some(old_query) = future.poll(device) { - old_queries.push(old_query) - } - } - old_queries - } - - fn total_time(&self) -> Option { - let mut total = Duration::default(); - for future in self.fill_times.iter().chain(self.tile_times.iter()) { - match *future { - TimerFuture::Pending(_) => return None, - TimerFuture::Resolved(time) => total += time, - } - } - Some(total) - } -} - -impl TimerFuture where D: Device { - fn new(query: D::TimerQuery) -> TimerFuture { - TimerFuture::Pending(query) - } - - fn poll(&mut self, device: &D) -> Option { - let duration = match *self { - TimerFuture::Pending(ref query) => device.try_recv_timer_query(query), - TimerFuture::Resolved(_) => None, - }; - match duration { - None => None, - Some(duration) => { - match mem::replace(self, TimerFuture::Resolved(duration)) { - TimerFuture::Resolved(_) => unreachable!(), - TimerFuture::Pending(old_query) => Some(old_query), - } - } - } - } -} - -#[derive(Clone, Copy, Debug)] -pub struct RenderTime { - pub gpu_time: Duration, -} - -impl Default for RenderTime { - #[inline] - fn default() -> RenderTime { - RenderTime { gpu_time: Duration::new(0, 0) } - } -} - -impl Add for RenderTime { - type Output = RenderTime; - - #[inline] - fn add(self, other: RenderTime) -> RenderTime { - RenderTime { gpu_time: self.gpu_time + other.gpu_time } - } -} - -impl Div for RenderTime { - type Output = RenderTime; - - #[inline] - fn div(self, divisor: usize) -> RenderTime { - RenderTime { gpu_time: self.gpu_time / divisor as u32 } - } -} - -bitflags! { - struct FramebufferFlags: u8 { - const MASK_FRAMEBUFFER_IS_DIRTY = 0x01; - const DEST_FRAMEBUFFER_IS_DIRTY = 0x02; - } -} - -struct TextureCache where D: Device { - textures: Vec, -} - -impl TextureCache where D: Device { - fn new() -> TextureCache { - TextureCache { textures: vec![] } - } - - fn create_texture(&mut self, device: &mut D, format: TextureFormat, size: Vector2I) - -> D::Texture { - for index in 0..self.textures.len() { - if device.texture_size(&self.textures[index]) == size && - device.texture_format(&self.textures[index]) == format { - return self.textures.remove(index); - } - } - - device.create_texture(format, size) - } - - fn release_texture(&mut self, texture: D::Texture) { - if self.textures.len() == TEXTURE_CACHE_SIZE { - self.textures.pop(); - } - self.textures.insert(0, texture); - } -} - -struct TexturePage where D: Device { - framebuffer: D::Framebuffer, - must_preserve_contents: bool, -} - -struct RenderTargetInfo { - location: TextureLocation, -} - -trait ToBlendState { - fn to_blend_state(self) -> Option; -} - -impl ToBlendState for BlendMode { - fn to_blend_state(self) -> Option { - match self { - BlendMode::Clear => { - Some(BlendState { - src_rgb_factor: BlendFactor::Zero, - dest_rgb_factor: BlendFactor::Zero, - src_alpha_factor: BlendFactor::Zero, - dest_alpha_factor: BlendFactor::Zero, - ..BlendState::default() - }) - } - BlendMode::SrcOver => { - Some(BlendState { - src_rgb_factor: BlendFactor::One, - dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, - src_alpha_factor: BlendFactor::One, - dest_alpha_factor: BlendFactor::OneMinusSrcAlpha, - ..BlendState::default() - }) - } - BlendMode::DestOver => { - Some(BlendState { - src_rgb_factor: BlendFactor::OneMinusDestAlpha, - dest_rgb_factor: BlendFactor::One, - src_alpha_factor: BlendFactor::OneMinusDestAlpha, - dest_alpha_factor: BlendFactor::One, - ..BlendState::default() - }) - } - BlendMode::SrcIn => { - Some(BlendState { - src_rgb_factor: BlendFactor::DestAlpha, - dest_rgb_factor: BlendFactor::Zero, - src_alpha_factor: BlendFactor::DestAlpha, - dest_alpha_factor: BlendFactor::Zero, - ..BlendState::default() - }) - } - BlendMode::DestIn => { - Some(BlendState { - src_rgb_factor: BlendFactor::Zero, - dest_rgb_factor: BlendFactor::SrcAlpha, - src_alpha_factor: BlendFactor::Zero, - dest_alpha_factor: BlendFactor::SrcAlpha, - ..BlendState::default() - }) - } - BlendMode::SrcOut => { - Some(BlendState { - src_rgb_factor: BlendFactor::OneMinusDestAlpha, - dest_rgb_factor: BlendFactor::Zero, - src_alpha_factor: BlendFactor::OneMinusDestAlpha, - dest_alpha_factor: BlendFactor::Zero, - ..BlendState::default() - }) - } - BlendMode::DestOut => { - Some(BlendState { - src_rgb_factor: BlendFactor::Zero, - dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, - src_alpha_factor: BlendFactor::Zero, - dest_alpha_factor: BlendFactor::OneMinusSrcAlpha, - ..BlendState::default() - }) - } - BlendMode::SrcAtop => { - Some(BlendState { - src_rgb_factor: BlendFactor::DestAlpha, - dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, - src_alpha_factor: BlendFactor::DestAlpha, - dest_alpha_factor: BlendFactor::OneMinusSrcAlpha, - ..BlendState::default() - }) - } - BlendMode::DestAtop => { - Some(BlendState { - src_rgb_factor: BlendFactor::OneMinusDestAlpha, - dest_rgb_factor: BlendFactor::SrcAlpha, - src_alpha_factor: BlendFactor::OneMinusDestAlpha, - dest_alpha_factor: BlendFactor::SrcAlpha, - ..BlendState::default() - }) - } - BlendMode::Xor => { - Some(BlendState { - src_rgb_factor: BlendFactor::OneMinusDestAlpha, - dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, - src_alpha_factor: BlendFactor::OneMinusDestAlpha, - dest_alpha_factor: BlendFactor::OneMinusSrcAlpha, - ..BlendState::default() - }) - } - BlendMode::Lighter => { - Some(BlendState { - src_rgb_factor: BlendFactor::One, - dest_rgb_factor: BlendFactor::One, - src_alpha_factor: BlendFactor::One, - dest_alpha_factor: BlendFactor::One, - ..BlendState::default() - }) - } - BlendMode::Copy | - BlendMode::Darken | - BlendMode::Lighten | - BlendMode::Multiply | - BlendMode::Screen | - BlendMode::HardLight | - BlendMode::Overlay | - BlendMode::ColorDodge | - BlendMode::ColorBurn | - BlendMode::SoftLight | - BlendMode::Difference | - BlendMode::Exclusion | - BlendMode::Hue | - BlendMode::Saturation | - BlendMode::Color | - BlendMode::Luminosity => { - // Blending is done manually in the shader. - None - } - } - } -} - -pub trait BlendModeExt { - fn needs_readable_framebuffer(self) -> bool; -} - -impl BlendModeExt for BlendMode { - fn needs_readable_framebuffer(self) -> bool { - match self { - BlendMode::Clear | - BlendMode::SrcOver | - BlendMode::DestOver | - BlendMode::SrcIn | - BlendMode::DestIn | - BlendMode::SrcOut | - BlendMode::DestOut | - BlendMode::SrcAtop | - BlendMode::DestAtop | - BlendMode::Xor | - BlendMode::Lighter | - BlendMode::Copy => false, - BlendMode::Lighten | - BlendMode::Darken | - BlendMode::Multiply | - BlendMode::Screen | - BlendMode::HardLight | - BlendMode::Overlay | - BlendMode::ColorDodge | - BlendMode::ColorBurn | - BlendMode::SoftLight | - BlendMode::Difference | - BlendMode::Exclusion | - BlendMode::Hue | - BlendMode::Saturation | - BlendMode::Color | - BlendMode::Luminosity => true, - } - } -} - -struct AlphaTilePage where D: Device { - buffered_fills: Vec, - pending_fills: Vec, - framebuffer: D::Framebuffer, - framebuffer_is_dirty: bool, -} - -impl AlphaTilePage where D: Device { - fn new(device: &mut D) -> AlphaTilePage { - let framebuffer_size = vec2i(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT); - let framebuffer_texture = device.create_texture(TextureFormat::RGBA16F, framebuffer_size); - let framebuffer = device.create_framebuffer(framebuffer_texture); - AlphaTilePage { - buffered_fills: vec![], - pending_fills: vec![], - framebuffer, - framebuffer_is_dirty: false, - } - } -} - -bitflags! { - struct RendererFlags: u8 { - // Whether we need a depth buffer. - const USE_DEPTH = 0x01; - // Whether an intermediate destination framebuffer is needed. - // - // This will be true if any exotic blend modes are used at the top level (not inside a - // render target), *and* the output framebuffer is the default framebuffer. - const INTERMEDIATE_DEST_FRAMEBUFFER_NEEDED = 0x02; - } -} - -trait ToCompositeCtrl { - fn to_composite_ctrl(&self) -> i32; -} - -impl ToCompositeCtrl for BlendMode { - fn to_composite_ctrl(&self) -> i32 { - match *self { - BlendMode::SrcOver | - BlendMode::SrcAtop | - BlendMode::DestOver | - BlendMode::DestOut | - BlendMode::Xor | - BlendMode::Lighter | - BlendMode::Clear | - BlendMode::Copy | - BlendMode::SrcIn | - BlendMode::SrcOut | - BlendMode::DestIn | - BlendMode::DestAtop => COMBINER_CTRL_COMPOSITE_NORMAL, - BlendMode::Multiply => COMBINER_CTRL_COMPOSITE_MULTIPLY, - BlendMode::Darken => COMBINER_CTRL_COMPOSITE_DARKEN, - BlendMode::Lighten => COMBINER_CTRL_COMPOSITE_LIGHTEN, - BlendMode::Screen => COMBINER_CTRL_COMPOSITE_SCREEN, - BlendMode::Overlay => COMBINER_CTRL_COMPOSITE_OVERLAY, - BlendMode::ColorDodge => COMBINER_CTRL_COMPOSITE_COLOR_DODGE, - BlendMode::ColorBurn => COMBINER_CTRL_COMPOSITE_COLOR_BURN, - BlendMode::HardLight => COMBINER_CTRL_COMPOSITE_HARD_LIGHT, - BlendMode::SoftLight => COMBINER_CTRL_COMPOSITE_SOFT_LIGHT, - BlendMode::Difference => COMBINER_CTRL_COMPOSITE_DIFFERENCE, - BlendMode::Exclusion => COMBINER_CTRL_COMPOSITE_EXCLUSION, - BlendMode::Hue => COMBINER_CTRL_COMPOSITE_HUE, - BlendMode::Saturation => COMBINER_CTRL_COMPOSITE_SATURATION, - BlendMode::Color => COMBINER_CTRL_COMPOSITE_COLOR, - BlendMode::Luminosity => COMBINER_CTRL_COMPOSITE_LUMINOSITY, - } - } -} - -trait ToCombineMode { - fn to_combine_mode(self) -> i32; -} - -impl ToCombineMode for PaintCompositeOp { - fn to_combine_mode(self) -> i32 { - match self { - PaintCompositeOp::DestIn => COMBINER_CTRL_COLOR_COMBINE_DEST_IN, - PaintCompositeOp::SrcIn => COMBINER_CTRL_COLOR_COMBINE_SRC_IN, - } - } -} diff --git a/crates/pathfinder/renderer/src/gpu/shaders.rs b/crates/pathfinder/renderer/src/gpu/shaders.rs deleted file mode 100644 index 827276af51..0000000000 --- a/crates/pathfinder/renderer/src/gpu/shaders.rs +++ /dev/null @@ -1,648 +0,0 @@ -// pathfinder/renderer/src/gpu/shaders.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -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, 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; -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; - -pub struct BlitVertexArray where D: Device { - pub vertex_array: D::VertexArray, -} - -impl BlitVertexArray where D: Device { - pub fn new(device: &D, - blit_program: &BlitProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> BlitVertexArray { - let vertex_array = device.create_vertex_array(); - 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); - POSITION_BUFFER.configure_vertex_attrs(device, &vertex_array, position_attrs); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); - - BlitVertexArray { vertex_array } - } -} - -pub struct ClearVertexArray where D: Device { - pub vertex_array: D::VertexArray, -} - -impl ClearVertexArray where D: Device { - pub fn new(device: &D, - clear_program: &ClearProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> ClearVertexArray { - let vertex_array = device.create_vertex_array(); - 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); - POSITION_BUFFER.configure_vertex_attrs(device, &vertex_array, position_attrs); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); - - ClearVertexArray { vertex_array } - } -} - -pub struct FillVertexArray where D: Device { - pub vertex_array: D::VertexArray, -} - -impl FillVertexArray -where - D: Device, -{ - pub fn new( - device: &D, - fill_program: &FillRasterProgram, - vertex_buffer: &D::Buffer, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer, - ) -> FillVertexArray { - let vertex_array = device.create_vertex_array(); - - 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 - }); - - 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); - FILL_BUFFER.configure_vertex_attrs(device, &vertex_array, fill_attrs); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); - - FillVertexArray { vertex_array } - } -} - -pub struct TileVertexArray where D: Device { - pub vertex_array: D::VertexArray, -} - -impl TileVertexArray where D: Device { - pub fn new(device: &D, - tile_program: &TileProgram, - tile_vertex_buffer: &D::Buffer, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> TileVertexArray { - let vertex_array = device.create_vertex_array(); - - 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); - TILE_OFFSET_BUFFER.configure_vertex_attrs(device, &vertex_array, tile_offset_attrs); - device.bind_buffer(&vertex_array, tile_vertex_buffer, BufferTarget::Vertex); - 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 } - } -} - -pub struct CopyTileVertexArray where D: Device { - pub vertex_array: D::VertexArray, -} - -impl CopyTileVertexArray where D: Device { - pub fn new( - device: &D, - copy_tile_program: &CopyTileProgram, - copy_tile_vertex_buffer: &D::Buffer, - quads_vertex_indices_buffer: &D::Buffer, - ) -> CopyTileVertexArray { - let vertex_array = device.create_vertex_array(); - - 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); - 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 } - } -} - -pub struct ClipTileVertexArray where D: Device { - pub vertex_array: D::VertexArray, - pub vertex_buffer: D::Buffer, -} - -impl ClipTileVertexArray where D: Device { - pub fn new(device: &D, - clip_tile_program: &ClipTileProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> 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 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); - TILE_OFFSET_BUFFER.configure_vertex_attrs(device, &vertex_array, tile_offset_attrs); - device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - 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 } - } -} - - -pub struct BlitProgram where D: Device { - pub program: D::Program, - pub src_uniform: D::Uniform, -} - -impl BlitProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> BlitProgram { - let program = device.create_raster_program(resources, "blit"); - let src_uniform = device.get_uniform(&program, "Src"); - BlitProgram { program, src_uniform } - } -} - -pub struct ClearProgram where D: Device { - pub program: D::Program, - pub rect_uniform: D::Uniform, - pub framebuffer_size_uniform: D::Uniform, - pub color_uniform: D::Uniform, -} - -impl ClearProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> ClearProgram { - let program = device.create_raster_program(resources, "clear"); - let rect_uniform = device.get_uniform(&program, "Rect"); - let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - let color_uniform = device.get_uniform(&program, "Color"); - ClearProgram { program, rect_uniform, framebuffer_size_uniform, color_uniform } - } -} - -pub enum FillProgram where D: Device { - Raster(FillRasterProgram), - Compute(FillComputeProgram), -} - -impl FillProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader, options: &RendererOptions) - -> FillProgram { - match (options.no_compute, device.feature_level()) { - (false, FeatureLevel::D3D11) => { - FillProgram::Compute(FillComputeProgram::new(device, resources)) - } - (_, FeatureLevel::D3D10) | (true, _) => { - FillProgram::Raster(FillRasterProgram::new(device, resources)) - } - } - } -} - -pub struct FillRasterProgram where D: Device { - pub program: D::Program, - pub framebuffer_size_uniform: D::Uniform, - pub tile_size_uniform: D::Uniform, - pub area_lut_uniform: D::Uniform, -} - -impl FillRasterProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillRasterProgram { - let program = device.create_raster_program(resources, "fill"); - let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - let tile_size_uniform = device.get_uniform(&program, "TileSize"); - let area_lut_uniform = device.get_uniform(&program, "AreaLUT"); - FillRasterProgram { - program, - framebuffer_size_uniform, - tile_size_uniform, - area_lut_uniform, - } - } -} - -pub struct FillComputeProgram where D: Device { - pub program: D::Program, - pub dest_uniform: D::Uniform, - pub area_lut_uniform: D::Uniform, - pub first_tile_index_uniform: D::Uniform, - pub fills_storage_buffer: D::StorageBuffer, - pub next_fills_storage_buffer: D::StorageBuffer, - pub fill_tile_map_storage_buffer: D::StorageBuffer, -} - -impl FillComputeProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillComputeProgram { - let mut program = device.create_compute_program(resources, "fill"); - let local_size = ComputeDimensions { x: TILE_WIDTH, y: TILE_HEIGHT / 4, z: 1 }; - device.set_compute_program_local_size(&mut program, local_size); - - let dest_uniform = device.get_uniform(&program, "Dest"); - let area_lut_uniform = device.get_uniform(&program, "AreaLUT"); - let first_tile_index_uniform = device.get_uniform(&program, "FirstTileIndex"); - let fills_storage_buffer = device.get_storage_buffer(&program, "Fills", 0); - let next_fills_storage_buffer = device.get_storage_buffer(&program, "NextFills", 1); - let fill_tile_map_storage_buffer = device.get_storage_buffer(&program, "FillTileMap", 2); - - FillComputeProgram { - program, - dest_uniform, - area_lut_uniform, - first_tile_index_uniform, - fills_storage_buffer, - next_fills_storage_buffer, - fill_tile_map_storage_buffer, - } - } -} - -pub struct TileProgram where D: Device { - pub program: D::Program, - pub transform_uniform: D::Uniform, - pub tile_size_uniform: D::Uniform, - pub texture_metadata_uniform: D::Uniform, - pub texture_metadata_size_uniform: D::Uniform, - pub dest_texture_uniform: D::Uniform, - pub color_texture_0_uniform: D::Uniform, - pub color_texture_size_0_uniform: D::Uniform, - pub color_texture_1_uniform: D::Uniform, - pub mask_texture_0_uniform: D::Uniform, - pub mask_texture_size_0_uniform: D::Uniform, - pub gamma_lut_uniform: D::Uniform, - pub filter_params_0_uniform: D::Uniform, - pub filter_params_1_uniform: D::Uniform, - pub filter_params_2_uniform: D::Uniform, - pub framebuffer_size_uniform: D::Uniform, - pub ctrl_uniform: D::Uniform, -} - -impl TileProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> TileProgram { - let program = device.create_raster_program(resources, "tile"); - let transform_uniform = device.get_uniform(&program, "Transform"); - let tile_size_uniform = device.get_uniform(&program, "TileSize"); - let texture_metadata_uniform = device.get_uniform(&program, "TextureMetadata"); - let texture_metadata_size_uniform = device.get_uniform(&program, "TextureMetadataSize"); - let dest_texture_uniform = device.get_uniform(&program, "DestTexture"); - let color_texture_0_uniform = device.get_uniform(&program, "ColorTexture0"); - let color_texture_size_0_uniform = device.get_uniform(&program, "ColorTextureSize0"); - let color_texture_1_uniform = device.get_uniform(&program, "ColorTexture1"); - let mask_texture_0_uniform = device.get_uniform(&program, "MaskTexture0"); - let mask_texture_size_0_uniform = device.get_uniform(&program, "MaskTextureSize0"); - let gamma_lut_uniform = device.get_uniform(&program, "GammaLUT"); - let filter_params_0_uniform = device.get_uniform(&program, "FilterParams0"); - let filter_params_1_uniform = device.get_uniform(&program, "FilterParams1"); - let filter_params_2_uniform = device.get_uniform(&program, "FilterParams2"); - let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - let ctrl_uniform = device.get_uniform(&program, "Ctrl"); - TileProgram { - program, - transform_uniform, - tile_size_uniform, - texture_metadata_uniform, - texture_metadata_size_uniform, - dest_texture_uniform, - color_texture_0_uniform, - color_texture_size_0_uniform, - color_texture_1_uniform, - mask_texture_0_uniform, - mask_texture_size_0_uniform, - gamma_lut_uniform, - filter_params_0_uniform, - filter_params_1_uniform, - filter_params_2_uniform, - framebuffer_size_uniform, - ctrl_uniform, - } - } -} - -pub struct CopyTileProgram where D: Device { - pub program: D::Program, - pub transform_uniform: D::Uniform, - pub tile_size_uniform: D::Uniform, - pub framebuffer_size_uniform: D::Uniform, - pub src_uniform: D::Uniform, -} - -impl CopyTileProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> CopyTileProgram { - let program = device.create_raster_program(resources, "tile_copy"); - let transform_uniform = device.get_uniform(&program, "Transform"); - let tile_size_uniform = device.get_uniform(&program, "TileSize"); - let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - let src_uniform = device.get_uniform(&program, "Src"); - CopyTileProgram { - program, - transform_uniform, - tile_size_uniform, - framebuffer_size_uniform, - src_uniform, - } - } -} - -pub struct ClipTileProgram where D: Device { - pub program: D::Program, - pub src_uniform: D::Uniform, -} - -impl ClipTileProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> ClipTileProgram { - let program = device.create_raster_program(resources, "tile_clip"); - let src_uniform = device.get_uniform(&program, "Src"); - ClipTileProgram { program, src_uniform } - } -} - -pub struct StencilProgram -where - D: Device, -{ - pub program: D::Program, -} - -impl StencilProgram -where - D: Device, -{ - pub fn new(device: &D, resources: &dyn ResourceLoader) -> StencilProgram { - let program = device.create_raster_program(resources, "stencil"); - StencilProgram { program } - } -} - -pub struct StencilVertexArray -where - D: Device, -{ - pub vertex_array: D::VertexArray, - pub vertex_buffer: D::Buffer, - pub index_buffer: D::Buffer, -} - -impl StencilVertexArray -where - D: Device, -{ - pub fn new(device: &D, stencil_program: &StencilProgram) -> StencilVertexArray { - let vertex_array = device.create_vertex_array(); - let vertex_buffer = device.create_buffer(BufferUploadMode::Static); - let index_buffer = device.create_buffer(BufferUploadMode::Static); - - let position_attr = device.get_vertex_attr(&stencil_program.program, "Position").unwrap(); - - device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 3, - class: VertexAttrClass::Float, - attr_type: VertexAttrType::F32, - stride: 4 * 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index); - - StencilVertexArray { vertex_array, vertex_buffer, index_buffer } - } -} - -pub struct ReprojectionProgram -where - D: Device, -{ - pub program: D::Program, - pub old_transform_uniform: D::Uniform, - pub new_transform_uniform: D::Uniform, - pub texture_uniform: D::Uniform, -} - -impl ReprojectionProgram -where - D: Device, -{ - pub fn new(device: &D, resources: &dyn ResourceLoader) -> ReprojectionProgram { - let program = device.create_raster_program(resources, "reproject"); - let old_transform_uniform = device.get_uniform(&program, "OldTransform"); - let new_transform_uniform = device.get_uniform(&program, "NewTransform"); - let texture_uniform = device.get_uniform(&program, "Texture"); - - ReprojectionProgram { - program, - old_transform_uniform, - new_transform_uniform, - texture_uniform, - } - } -} - -pub struct ReprojectionVertexArray -where - D: Device, -{ - pub vertex_array: D::VertexArray, -} - -impl ReprojectionVertexArray -where - D: Device, -{ - pub fn new( - device: &D, - reprojection_program: &ReprojectionProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer, - ) -> ReprojectionVertexArray { - let vertex_array = device.create_vertex_array(); - 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); - 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/crates/pathfinder/renderer/src/gpu_data.rs b/crates/pathfinder/renderer/src/gpu_data.rs deleted file mode 100644 index fe5ae10d70..0000000000 --- a/crates/pathfinder/renderer/src/gpu_data.rs +++ /dev/null @@ -1,277 +0,0 @@ -// pathfinder/renderer/src/gpu_data.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Packed data ready to be sent to the GPU. - -use crate::builder::{ALPHA_TILES_PER_LEVEL, ALPHA_TILE_LEVEL_COUNT}; -use crate::options::BoundingQuad; -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; -use pathfinder_geometry::vector::Vector2I; -use pathfinder_gpu::TextureSamplingFlags; -use std::fmt::{Debug, Formatter, Result as DebugResult}; -use std::sync::Arc; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::time::Duration; -use std::u32; - -pub const TILE_CTRL_MASK_MASK: i32 = 0x3; -pub const TILE_CTRL_MASK_WINDING: i32 = 0x1; -pub const TILE_CTRL_MASK_EVEN_ODD: i32 = 0x2; - -pub const TILE_CTRL_MASK_0_SHIFT: i32 = 0; - -pub enum RenderCommand { - // Starts rendering a frame. - Start { - /// The number of paths that will be rendered. - path_count: usize, - - /// A bounding quad for the scene. - bounding_quad: BoundingQuad, - - /// Whether the framebuffer we're rendering to must be readable. - /// - /// This is needed if a path that renders directly to the output framebuffer (i.e. not to a - /// render target) uses one of the more exotic blend modes. - needs_readable_framebuffer: bool, - }, - - // Allocates a texture page. - AllocateTexturePage { page_id: TexturePageId, descriptor: TexturePageDescriptor }, - - // Uploads data to a texture page. - UploadTexelData { texels: Arc>, location: TextureLocation }, - - // Associates a render target with a texture page. - // - // TODO(pcwalton): Add a rect to this so we can render to subrects of a page. - DeclareRenderTarget { id: RenderTargetId, location: TextureLocation }, - - // Upload texture metadata. - UploadTextureMetadata(Vec), - - // Adds fills to the queue. - AddFills(Vec), - - // Flushes the queue of fills. - FlushFills, - - // Renders clips to the mask tile. - ClipTiles(Vec), - - // Pushes a render target onto the stack. Draw commands go to the render target on top of the - // stack. - PushRenderTarget(RenderTargetId), - - // Pops a render target from the stack. - PopRenderTarget, - - // Marks that tile compositing is about to begin. - BeginTileDrawing, - - // Draws a batch of tiles to the render target on top of the stack. - DrawTiles(TileBatch), - - // Presents a rendered frame. - Finish { cpu_build_time: Duration }, -} - -#[derive(Clone, Copy, PartialEq, Debug, Default)] -pub struct TexturePageId(pub u32); - -#[derive(Clone, Copy, Debug)] -pub struct TexturePageDescriptor { - pub size: Vector2I, -} - -#[derive(Clone, Copy, PartialEq, Debug, Default)] -pub struct TextureLocation { - pub page: TexturePageId, - pub rect: RectI, -} - -#[derive(Clone, Debug)] -pub struct TileBatch { - pub tiles: Vec, - pub color_texture: Option, - pub filter: Filter, - pub blend_mode: BlendMode, - pub tile_page: u16, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct TileBatchTexture { - pub page: TexturePageId, - pub sampling_flags: TextureSamplingFlags, - pub composite_op: PaintCompositeOp, -} - -#[derive(Clone, Copy, Debug)] -pub struct FillObjectPrimitive { - pub px: LineSegmentU4, - pub subpx: LineSegmentU8, - pub tile_x: i16, - pub tile_y: i16, -} - -#[derive(Clone, Copy, Debug)] -#[repr(C)] -pub struct TileObjectPrimitive { - pub alpha_tile_id: AlphaTileId, - pub backdrop: i8, -} - -#[derive(Clone, Copy, Debug)] -#[repr(C)] -pub struct TextureMetadataEntry { - pub color_0_transform: Transform2F, - pub base_color: ColorU, -} - -#[derive(Clone, Copy, Debug, Default)] -pub struct FillBatchEntry { - pub fill: Fill, - pub page: u16, -} - -#[derive(Clone, Copy, Debug, Default)] -#[repr(C)] -pub struct Fill { - pub subpx: LineSegmentU8, - pub px: LineSegmentU4, - pub alpha_tile_index: AlignedU16, -} - -#[derive(Clone, Debug)] -pub struct ClipBatch { - pub clips: Vec, - pub key: ClipBatchKey, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct ClipBatchKey { - pub dest_page: u16, - pub src_page: u16, - pub kind: ClipBatchKind, -} - -// Order is significant here. -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub enum ClipBatchKind { - Draw, - Clip, -} - -#[derive(Clone, Copy, Debug, Default)] -#[repr(C)] -pub struct Clip { - 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: 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)] -pub struct AlphaTileId(pub u32); - -impl AlphaTileId { - #[inline] - pub fn new(next_alpha_tile_index: &[AtomicUsize; ALPHA_TILE_LEVEL_COUNT], level: usize) - -> AlphaTileId { - let alpha_tile_index = next_alpha_tile_index[level].fetch_add(1, Ordering::Relaxed); - debug_assert!(alpha_tile_index < ALPHA_TILES_PER_LEVEL); - AlphaTileId((level * ALPHA_TILES_PER_LEVEL + alpha_tile_index) as u32) - } - - #[inline] - pub fn invalid() -> AlphaTileId { - AlphaTileId(!0) - } - - #[inline] - pub fn page(self) -> u16 { - (self.0 >> 16) as u16 - } - - #[inline] - pub fn tile(self) -> u16 { - (self.0 & 0xffff) as u16 - } - - #[inline] - pub fn is_valid(self) -> bool { - self.0 < !0 - } -} - -impl Debug for RenderCommand { - fn fmt(&self, formatter: &mut Formatter) -> DebugResult { - match *self { - RenderCommand::Start { .. } => write!(formatter, "Start"), - RenderCommand::AllocateTexturePage { page_id, descriptor: _ } => { - write!(formatter, "AllocateTexturePage({})", page_id.0) - } - RenderCommand::UploadTexelData { ref texels, location } => { - write!(formatter, "UploadTexelData(x{:?}, {:?})", texels.len(), location) - } - RenderCommand::DeclareRenderTarget { id, location } => { - write!(formatter, "DeclareRenderTarget({:?}, {:?})", id, location) - } - RenderCommand::UploadTextureMetadata(ref metadata) => { - write!(formatter, "UploadTextureMetadata(x{})", metadata.len()) - } - RenderCommand::AddFills(ref fills) => { - write!(formatter, "AddFills(x{})", fills.len()) - } - RenderCommand::FlushFills => write!(formatter, "FlushFills"), - RenderCommand::ClipTiles(ref batches) => { - write!(formatter, "ClipTiles(x{})", batches.len()) - } - RenderCommand::PushRenderTarget(render_target_id) => { - write!(formatter, "PushRenderTarget({:?})", render_target_id) - } - RenderCommand::PopRenderTarget => write!(formatter, "PopRenderTarget"), - RenderCommand::BeginTileDrawing => write!(formatter, "BeginTileDrawing"), - RenderCommand::DrawTiles(ref batch) => { - write!(formatter, - "DrawTiles(x{}, C0 {:?}, {:?})", - batch.tiles.len(), - batch.color_texture, - batch.blend_mode) - } - RenderCommand::Finish { cpu_build_time } => { - write!(formatter, "Finish({} ms)", cpu_build_time.as_secs_f64() * 1000.0) - } - } - } -} diff --git a/crates/pathfinder/renderer/src/lib.rs b/crates/pathfinder/renderer/src/lib.rs deleted file mode 100644 index b12d8fbcce..0000000000 --- a/crates/pathfinder/renderer/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -// pathfinder/renderer/src/lib.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! The CPU portion of Pathfinder's renderer. - -#[macro_use] -extern crate bitflags; -#[macro_use] -extern crate log; - -pub mod concurrent; -pub mod gpu; -pub mod gpu_data; -pub mod options; -pub mod paint; -pub mod scene; - -mod allocator; -mod builder; -mod tile_map; -mod tiles; -mod z_buffer; diff --git a/crates/pathfinder/renderer/src/options.rs b/crates/pathfinder/renderer/src/options.rs deleted file mode 100644 index 86ba541e64..0000000000 --- a/crates/pathfinder/renderer/src/options.rs +++ /dev/null @@ -1,153 +0,0 @@ -// pathfinder/renderer/src/options.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Options that control how rendering is to be performed. - -use crate::gpu_data::RenderCommand; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::transform3d::Perspective; -use pathfinder_geometry::vector::{Vector2F, Vector4F}; -use pathfinder_content::clip::PolygonClipper3D; - -pub trait RenderCommandListener: Send + Sync { - fn send(&self, command: RenderCommand); -} - -impl RenderCommandListener for F -where - F: Fn(RenderCommand) + Send + Sync, -{ - #[inline] - fn send(&self, command: RenderCommand) { - (*self)(command) - } -} - -/// Options that influence scene building. -#[derive(Clone, Default)] -pub struct BuildOptions { - pub transform: RenderTransform, - pub dilation: Vector2F, - pub subpixel_aa_enabled: bool, -} - -impl BuildOptions { - pub(crate) fn prepare(self, bounds: RectF) -> PreparedBuildOptions { - PreparedBuildOptions { - transform: self.transform.prepare(bounds), - dilation: self.dilation, - subpixel_aa_enabled: self.subpixel_aa_enabled, - } - } -} - -#[derive(Clone)] -pub enum RenderTransform { - Transform2D(Transform2F), - Perspective(Perspective), -} - -impl Default for RenderTransform { - #[inline] - fn default() -> RenderTransform { - RenderTransform::Transform2D(Transform2F::default()) - } -} - -impl RenderTransform { - fn prepare(&self, bounds: RectF) -> PreparedRenderTransform { - let perspective = match self { - RenderTransform::Transform2D(ref transform) => { - if transform.is_identity() { - return PreparedRenderTransform::None; - } - return PreparedRenderTransform::Transform2D(*transform); - } - RenderTransform::Perspective(ref perspective) => *perspective, - }; - - let mut points = vec![ - bounds.origin().to_4d(), - bounds.upper_right().to_4d(), - bounds.lower_right().to_4d(), - bounds.lower_left().to_4d(), - ]; - debug!("-----"); - debug!("bounds={:?} ORIGINAL quad={:?}", bounds, points); - for point in &mut points { - *point = perspective.transform * *point; - } - debug!("... PERSPECTIVE quad={:?}", points); - - // Compute depth. - let quad = [ - points[0].to_3d().to_4d(), - points[1].to_3d().to_4d(), - points[2].to_3d().to_4d(), - points[3].to_3d().to_4d(), - ]; - debug!("... PERSPECTIVE-DIVIDED points = {:?}", quad); - - points = PolygonClipper3D::new(points).clip(); - debug!("... CLIPPED quad={:?}", points); - for point in &mut points { - *point = point.to_3d().to_4d() - } - - let inverse_transform = perspective.transform.inverse(); - let clip_polygon = points.into_iter() - .map(|point| (inverse_transform * point).to_2d()) - .collect(); - return PreparedRenderTransform::Perspective { - perspective, - clip_polygon, - quad, - }; - } -} - -pub(crate) struct PreparedBuildOptions { - pub(crate) transform: PreparedRenderTransform, - pub(crate) dilation: Vector2F, - pub(crate) subpixel_aa_enabled: bool, -} - -impl PreparedBuildOptions { - #[inline] - pub(crate) fn bounding_quad(&self) -> BoundingQuad { - match self.transform { - PreparedRenderTransform::Perspective { quad, .. } => quad, - _ => [Vector4F::default(); 4], - } - } -} - -pub(crate) type BoundingQuad = [Vector4F; 4]; - -pub(crate) enum PreparedRenderTransform { - None, - Transform2D(Transform2F), - Perspective { - perspective: Perspective, - clip_polygon: Vec, - quad: [Vector4F; 4], - }, -} - -impl PreparedRenderTransform { - #[inline] - pub(crate) fn is_2d(&self) -> bool { - match *self { - PreparedRenderTransform::Transform2D(_) => true, - _ => false, - } - } -} diff --git a/crates/pathfinder/renderer/src/paint.rs b/crates/pathfinder/renderer/src/paint.rs deleted file mode 100644 index 8d876f3c54..0000000000 --- a/crates/pathfinder/renderer/src/paint.rs +++ /dev/null @@ -1,702 +0,0 @@ -// pathfinder/renderer/src/paint.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::allocator::{AllocationMode, TextureAllocator}; -use crate::gpu_data::{RenderCommand, TextureLocation, TextureMetadataEntry, TexturePageDescriptor}; -use crate::gpu_data::{TexturePageId, TileBatchTexture}; -use crate::scene::{RenderTarget, SceneId}; -use hashbrown::HashMap; -use pathfinder_color::ColorU; -use pathfinder_content::effects::{Filter, PatternFilter}; -use pathfinder_content::gradient::{Gradient, GradientGeometry}; -use pathfinder_content::pattern::{Pattern, PatternSource}; -use pathfinder_content::render_target::RenderTargetId; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::rect::{RectF, RectI}; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2f, vec2i}; -use pathfinder_gpu::TextureSamplingFlags; -use pathfinder_simd::default::{F32x2, F32x4}; -use std::f32; -use std::fmt::{self, Debug, Formatter}; -use std::sync::Arc; - -// The size of a gradient tile. -// -// TODO(pcwalton): Choose this size dynamically! -const GRADIENT_TILE_LENGTH: u32 = 256; - -#[derive(Clone)] -pub struct Palette { - pub paints: Vec, - render_targets: Vec, - cache: HashMap, - allocator: TextureAllocator, - scene_id: SceneId, -} - -#[derive(Clone)] -struct RenderTargetData { - render_target: RenderTarget, - metadata: RenderTargetMetadata, -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct Paint { - base_color: ColorU, - overlay: Option, -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct PaintOverlay { - composite_op: PaintCompositeOp, - contents: PaintContents, -} - -#[derive(Clone, PartialEq, Eq, Hash)] -pub enum PaintContents { - Gradient(Gradient), - Pattern(Pattern), -} - -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -pub struct PaintId(pub u16); - -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -pub struct GradientId(pub u32); - -/// How a paint is to be composited over a base color, or vice versa. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -pub enum PaintCompositeOp { - SrcIn, - DestIn, -} - -impl Debug for PaintContents { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - match *self { - PaintContents::Gradient(ref gradient) => gradient.fmt(formatter), - PaintContents::Pattern(ref pattern) => pattern.fmt(formatter), - } - } -} - -impl Palette { - #[inline] - pub fn new(scene_id: SceneId) -> Palette { - Palette { - paints: vec![], - render_targets: vec![], - cache: HashMap::new(), - allocator: TextureAllocator::new(), - scene_id, - } - } -} - -impl Paint { - #[inline] - pub fn from_color(color: ColorU) -> Paint { - Paint { base_color: color, overlay: None } - } - - #[inline] - pub fn from_gradient(gradient: Gradient) -> Paint { - Paint { - base_color: ColorU::white(), - overlay: Some(PaintOverlay { - composite_op: PaintCompositeOp::SrcIn, - contents: PaintContents::Gradient(gradient), - }), - } - } - - #[inline] - pub fn from_pattern(pattern: Pattern) -> Paint { - Paint { - base_color: ColorU::white(), - overlay: Some(PaintOverlay { - composite_op: PaintCompositeOp::SrcIn, - contents: PaintContents::Pattern(pattern), - }), - } - } - - #[inline] - pub fn black() -> Paint { - Paint::from_color(ColorU::black()) - } - - #[inline] - pub fn transparent_black() -> Paint { - Paint::from_color(ColorU::transparent_black()) - } - - pub fn is_opaque(&self) -> bool { - if !self.base_color.is_opaque() { - return false; - } - - match self.overlay { - None => true, - Some(ref overlay) => { - match overlay.contents { - PaintContents::Gradient(ref gradient) => gradient.is_opaque(), - PaintContents::Pattern(ref pattern) => pattern.is_opaque(), - } - } - } - } - - pub fn is_fully_transparent(&self) -> bool { - if !self.base_color.is_fully_transparent() { - return false; - } - - match self.overlay { - None => true, - Some(ref overlay) => { - match overlay.contents { - PaintContents::Gradient(ref gradient) => gradient.is_fully_transparent(), - PaintContents::Pattern(_) => false, - } - } - } - } - - #[inline] - pub fn is_color(&self) -> bool { - self.overlay.is_none() - } - - pub fn apply_transform(&mut self, transform: &Transform2F) { - if transform.is_identity() { - return; - } - - if let Some(ref mut overlay) = self.overlay { - match overlay.contents { - PaintContents::Gradient(ref mut gradient) => gradient.apply_transform(*transform), - PaintContents::Pattern(ref mut pattern) => pattern.apply_transform(*transform), - } - } - } - - #[inline] - pub fn base_color(&self) -> ColorU { - self.base_color - } - - #[inline] - pub fn set_base_color(&mut self, new_base_color: ColorU) { - self.base_color = new_base_color; - } - - #[inline] - pub fn overlay(&self) -> &Option { - &self.overlay - } - - #[inline] - pub fn overlay_mut(&mut self) -> &mut Option { - &mut self.overlay - } - - #[inline] - pub fn pattern(&self) -> Option<&Pattern> { - match self.overlay { - None => None, - Some(ref overlay) => { - match overlay.contents { - PaintContents::Pattern(ref pattern) => Some(pattern), - _ => None, - } - } - } - } - - #[inline] - pub fn pattern_mut(&mut self) -> Option<&mut Pattern> { - match self.overlay { - None => None, - Some(ref mut overlay) => { - match overlay.contents { - PaintContents::Pattern(ref mut pattern) => Some(pattern), - _ => None, - } - } - } - } - - #[inline] - pub fn gradient(&self) -> Option<&Gradient> { - match self.overlay { - None => None, - Some(ref overlay) => { - match overlay.contents { - PaintContents::Gradient(ref gradient) => Some(gradient), - _ => None, - } - } - } - } -} - -impl PaintOverlay { - #[inline] - pub fn contents(&self) -> &PaintContents { - &self.contents - } - - #[inline] - pub fn composite_op(&self) -> PaintCompositeOp { - self.composite_op - } - - #[inline] - pub fn set_composite_op(&mut self, new_composite_op: PaintCompositeOp) { - self.composite_op = new_composite_op - } -} - -pub struct PaintInfo { - /// The render commands needed to prepare the textures. - pub render_commands: Vec, - /// The metadata for each paint. - /// - /// The indices of this vector are paint IDs. - pub paint_metadata: Vec, - /// The metadata for each render target. - /// - /// The indices of this vector are render target IDs. - pub render_target_metadata: Vec, -} - -#[derive(Debug)] -pub struct PaintMetadata { - /// Metadata associated with the color texture, if applicable. - pub color_texture_metadata: Option, - /// The base color that the color texture gets mixed into. - pub base_color: ColorU, - /// True if this paint is fully opaque. - pub is_opaque: bool, -} - -#[derive(Debug)] -pub struct PaintColorTextureMetadata { - /// The location of the paint. - pub location: TextureLocation, - /// The scale for the page this paint is on. - pub page_scale: Vector2F, - /// The transform to apply to screen coordinates to translate them into UVs. - pub transform: Transform2F, - /// The sampling mode for the texture. - pub sampling_flags: TextureSamplingFlags, - /// The filter to be applied to this paint. - pub filter: PaintFilter, - /// How the color texture is to be composited over the base color. - pub composite_op: PaintCompositeOp, -} - -#[derive(Clone, Copy, Debug)] -pub struct RadialGradientMetadata { - /// The line segment that connects the two circles. - pub line: LineSegment2F, - /// The radii of the two circles. - pub radii: F32x2, -} - -#[derive(Clone, Copy, Debug)] -pub struct RenderTargetMetadata { - /// The location of the render target. - pub location: TextureLocation, -} - -#[derive(Debug)] -pub enum PaintFilter { - None, - RadialGradient { - /// The line segment that connects the two circles. - line: LineSegment2F, - /// The radii of the two circles. - radii: F32x2, - }, - PatternFilter(PatternFilter), -} - -impl Palette { - #[allow(clippy::trivially_copy_pass_by_ref)] - pub fn push_paint(&mut self, paint: &Paint) -> PaintId { - if let Some(paint_id) = self.cache.get(paint) { - return *paint_id; - } - - let paint_id = PaintId(self.paints.len() as u16); - self.cache.insert((*paint).clone(), paint_id); - self.paints.push((*paint).clone()); - paint_id - } - - pub fn push_render_target(&mut self, render_target: RenderTarget) -> RenderTargetId { - let id = self.render_targets.len() as u32; - - let metadata = RenderTargetMetadata { - location: self.allocator.allocate_image(render_target.size()), - }; - - self.render_targets.push(RenderTargetData { render_target, metadata }); - RenderTargetId { scene: self.scene_id.0, render_target: id } - } - - pub fn build_paint_info(&mut self, render_transform: Transform2F) -> PaintInfo { - let mut paint_metadata = vec![]; - - // Assign paint locations. - let mut gradient_tile_builder = GradientTileBuilder::new(); - let mut image_texel_info = vec![]; - for paint in &self.paints { - let allocator = &mut self.allocator; - let render_targets = &self.render_targets; - let color_texture_metadata = paint.overlay.as_ref().map(|overlay| { - match overlay.contents { - PaintContents::Gradient(ref gradient) => { - // FIXME(pcwalton): The gradient size might not be big enough. Detect this. - let location = gradient_tile_builder.allocate(allocator, gradient); - PaintColorTextureMetadata { - location, - page_scale: allocator.page_scale(location.page), - sampling_flags: TextureSamplingFlags::empty(), - filter: match gradient.geometry { - GradientGeometry::Linear(_) => PaintFilter::None, - GradientGeometry::Radial { line, radii, .. } => { - PaintFilter::RadialGradient { line, radii } - } - }, - transform: Transform2F::default(), - composite_op: overlay.composite_op(), - } - } - PaintContents::Pattern(ref pattern) => { - let location; - match *pattern.source() { - PatternSource::RenderTarget { id: render_target_id, .. } => { - let index = render_target_id.render_target as usize; - location = render_targets[index].metadata.location; - } - PatternSource::Image(ref image) => { - // TODO(pcwalton): We should be able to use tile cleverness to - // repeat inside the atlas in some cases. - let allocation_mode = AllocationMode::OwnPage; - location = allocator.allocate(image.size(), allocation_mode); - image_texel_info.push(ImageTexelInfo { - location, - texels: (*image.pixels()).clone(), - }); - } - } - - let mut sampling_flags = TextureSamplingFlags::empty(); - if pattern.repeat_x() { - sampling_flags.insert(TextureSamplingFlags::REPEAT_U); - } - if pattern.repeat_y() { - sampling_flags.insert(TextureSamplingFlags::REPEAT_V); - } - if !pattern.smoothing_enabled() { - sampling_flags.insert(TextureSamplingFlags::NEAREST_MIN | - TextureSamplingFlags::NEAREST_MAG); - } - - let filter = match pattern.filter() { - None => PaintFilter::None, - Some(pattern_filter) => PaintFilter::PatternFilter(pattern_filter), - }; - - PaintColorTextureMetadata { - location, - page_scale: allocator.page_scale(location.page), - sampling_flags, - filter, - transform: Transform2F::default(), - composite_op: overlay.composite_op(), - } - } - } - }); - - paint_metadata.push(PaintMetadata { - color_texture_metadata, - is_opaque: paint.is_opaque(), - base_color: paint.base_color(), - }); - } - - // Calculate texture transforms. - for (paint, metadata) in self.paints.iter().zip(paint_metadata.iter_mut()) { - let mut color_texture_metadata = match metadata.color_texture_metadata { - None => continue, - Some(ref mut color_texture_metadata) => color_texture_metadata, - }; - - let texture_scale = self.allocator.page_scale(color_texture_metadata.location.page); - let texture_rect = color_texture_metadata.location.rect; - color_texture_metadata.transform = match paint.overlay - .as_ref() - .expect("Why do we have color texture \ - metadata but no overlay?") - .contents { - PaintContents::Gradient(Gradient { - geometry: GradientGeometry::Linear(gradient_line), - .. - }) => { - // Project gradient line onto (0.0-1.0, v0). - let v0 = texture_rect.to_f32().center().y() * texture_scale.y(); - let dp = gradient_line.vector(); - let m0 = dp.0.concat_xy_xy(dp.0) / F32x4::splat(gradient_line.square_length()); - let m13 = m0.zw() * -gradient_line.from().0; - Transform2F::row_major(m0.x(), m0.y(), m13.x() + m13.y(), 0.0, 0.0, v0) - } - PaintContents::Gradient(Gradient { - geometry: GradientGeometry::Radial { ref transform, .. }, - .. - }) => transform.inverse(), - PaintContents::Pattern(ref pattern) => { - match pattern.source() { - PatternSource::Image(_) => { - let texture_origin_uv = - rect_to_uv(texture_rect, texture_scale).origin(); - Transform2F::from_scale(texture_scale).translate(texture_origin_uv) * - pattern.transform().inverse() - } - PatternSource::RenderTarget { .. } => { - // FIXME(pcwalton): Only do this in GL, not Metal! - let texture_origin_uv = - rect_to_uv(texture_rect, texture_scale).lower_left(); - Transform2F::from_translation(texture_origin_uv) * - Transform2F::from_scale(texture_scale * vec2f(1.0, -1.0)) * - pattern.transform().inverse() - } - } - } - }; - color_texture_metadata.transform *= render_transform; - } - - // Create texture metadata. - let texture_metadata = paint_metadata.iter().map(|paint_metadata| { - TextureMetadataEntry { - color_0_transform: match paint_metadata.color_texture_metadata { - None => Transform2F::default(), - Some(ref color_texture_metadata) => color_texture_metadata.transform, - }, - base_color: paint_metadata.base_color, - } - }).collect(); - let mut render_commands = vec![RenderCommand::UploadTextureMetadata(texture_metadata)]; - - // Allocate textures. - let mut texture_page_descriptors = vec![]; - for page_index in 0..self.allocator.page_count() { - let page_id = TexturePageId(page_index); - let page_size = self.allocator.page_size(page_id); - let descriptor = TexturePageDescriptor { size: page_size }; - texture_page_descriptors.push(descriptor); - - if self.allocator.page_is_new(page_id) { - render_commands.push(RenderCommand::AllocateTexturePage { page_id, descriptor }); - self.allocator.mark_page_as_allocated(page_id); - } - } - - // Gather up render target metadata. - let render_target_metadata: Vec<_> = self.render_targets.iter().map(|render_target_data| { - render_target_data.metadata - }).collect(); - - // Create render commands. - for (index, metadata) in render_target_metadata.iter().enumerate() { - let id = RenderTargetId { scene: self.scene_id.0, render_target: index as u32 }; - render_commands.push(RenderCommand::DeclareRenderTarget { - id, - location: metadata.location, - }); - } - gradient_tile_builder.create_render_commands(&mut render_commands); - for image_texel_info in image_texel_info { - render_commands.push(RenderCommand::UploadTexelData { - texels: image_texel_info.texels, - location: image_texel_info.location, - }); - } - - PaintInfo { render_commands, paint_metadata, render_target_metadata } - } - - pub(crate) fn append_palette(&mut self, palette: Palette) -> MergedPaletteInfo { - // Merge render targets. - let mut render_target_mapping = HashMap::new(); - for (old_render_target_index, render_target) in palette.render_targets - .into_iter() - .enumerate() { - let old_render_target_id = RenderTargetId { - scene: palette.scene_id.0, - render_target: old_render_target_index as u32, - }; - let new_render_target_id = self.push_render_target(render_target.render_target); - render_target_mapping.insert(old_render_target_id, new_render_target_id); - } - - // Merge paints. - let mut paint_mapping = HashMap::new(); - for (old_paint_index, old_paint) in palette.paints.iter().enumerate() { - let old_paint_id = PaintId(old_paint_index as u16); - let new_paint_id = match *old_paint.overlay() { - None => self.push_paint(old_paint), - Some(ref overlay) => { - match *overlay.contents() { - PaintContents::Pattern(ref pattern) => { - match pattern.source() { - PatternSource::RenderTarget { id: old_render_target_id, size } => { - let mut new_pattern = - Pattern::from_render_target(*old_render_target_id, *size); - new_pattern.set_filter(pattern.filter()); - new_pattern.apply_transform(pattern.transform()); - new_pattern.set_repeat_x(pattern.repeat_x()); - new_pattern.set_repeat_y(pattern.repeat_y()); - new_pattern.set_smoothing_enabled(pattern.smoothing_enabled()); - self.push_paint(&Paint::from_pattern(new_pattern)) - } - _ => self.push_paint(old_paint), - } - } - _ => self.push_paint(old_paint), - } - } - }; - paint_mapping.insert(old_paint_id, new_paint_id); - } - - MergedPaletteInfo { render_target_mapping, paint_mapping } - } -} - -pub(crate) struct MergedPaletteInfo { - pub(crate) render_target_mapping: HashMap, - pub(crate) paint_mapping: HashMap, -} - -impl PaintMetadata { - pub(crate) fn filter(&self) -> Filter { - match self.color_texture_metadata { - None => Filter::None, - Some(ref color_metadata) => { - match color_metadata.filter { - PaintFilter::None => Filter::None, - PaintFilter::RadialGradient { line, radii } => { - let uv_rect = rect_to_uv(color_metadata.location.rect, - color_metadata.page_scale).contract( - vec2f(0.0, color_metadata.page_scale.y() * 0.5)); - Filter::RadialGradient { line, radii, uv_origin: uv_rect.origin() } - } - PaintFilter::PatternFilter(pattern_filter) => { - Filter::PatternFilter(pattern_filter) - } - } - } - } - } - - pub(crate) fn tile_batch_texture(&self) -> Option { - self.color_texture_metadata.as_ref().map(PaintColorTextureMetadata::as_tile_batch_texture) - } -} - -fn rect_to_uv(rect: RectI, texture_scale: Vector2F) -> RectF { - rect.to_f32() * texture_scale -} - -// Gradient allocation - -struct GradientTileBuilder { - tiles: Vec, -} - -struct GradientTile { - texels: Vec, - page: TexturePageId, - next_index: u32, -} - -impl GradientTileBuilder { - fn new() -> GradientTileBuilder { - GradientTileBuilder { tiles: vec![] } - } - - fn allocate(&mut self, allocator: &mut TextureAllocator, gradient: &Gradient) - -> TextureLocation { - if self.tiles.is_empty() || - self.tiles.last().unwrap().next_index == GRADIENT_TILE_LENGTH { - let size = Vector2I::splat(GRADIENT_TILE_LENGTH as i32); - let area = size.x() as usize * size.y() as usize; - self.tiles.push(GradientTile { - texels: vec![ColorU::black(); area], - page: allocator.allocate(size, AllocationMode::OwnPage).page, - next_index: 0, - }) - } - - let mut data = self.tiles.last_mut().unwrap(); - let location = TextureLocation { - page: data.page, - rect: RectI::new(vec2i(0, data.next_index as i32), - vec2i(GRADIENT_TILE_LENGTH as i32, 1)), - }; - data.next_index += 1; - - // FIXME(pcwalton): Paint transparent if gradient line has zero size, per spec. - // TODO(pcwalton): Optimize this: - // 1. Calculate ∇t up front and use differencing in the inner loop. - // 2. Go four pixels at a time with SIMD. - let first_address = location.rect.origin_y() as usize * GRADIENT_TILE_LENGTH as usize; - for x in 0..(GRADIENT_TILE_LENGTH as i32) { - let t = (x as f32 + 0.5) / GRADIENT_TILE_LENGTH as f32; - data.texels[first_address + x as usize] = gradient.sample(t); - } - - location - } - - fn create_render_commands(self, render_commands: &mut Vec) { - for tile in self.tiles { - render_commands.push(RenderCommand::UploadTexelData { - texels: Arc::new(tile.texels), - location: TextureLocation { - rect: RectI::new(vec2i(0, 0), Vector2I::splat(GRADIENT_TILE_LENGTH as i32)), - page: tile.page, - }, - }); - } - } -} - -struct ImageTexelInfo { - location: TextureLocation, - texels: Arc>, -} - -impl PaintColorTextureMetadata { - pub(crate) fn as_tile_batch_texture(&self) -> TileBatchTexture { - TileBatchTexture { - page: self.location.page, - sampling_flags: self.sampling_flags, - composite_op: self.composite_op, - } - } -} diff --git a/crates/pathfinder/renderer/src/scene.rs b/crates/pathfinder/renderer/src/scene.rs deleted file mode 100644 index 8a30e914bd..0000000000 --- a/crates/pathfinder/renderer/src/scene.rs +++ /dev/null @@ -1,419 +0,0 @@ -// pathfinder/renderer/src/scene.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A set of paths to be rendered. - -use crate::builder::SceneBuilder; -use crate::concurrent::executor::Executor; -use crate::options::{BuildOptions, PreparedBuildOptions}; -use crate::options::{PreparedRenderTransform, RenderCommandListener}; -use crate::paint::{MergedPaletteInfo, Paint, PaintId, PaintInfo, Palette}; -use pathfinder_content::effects::BlendMode; -use pathfinder_content::fill::FillRule; -use pathfinder_content::outline::Outline; -use pathfinder_content::render_target::RenderTargetId; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::vector::{Vector2I, vec2f}; -use std::sync::atomic::{AtomicUsize, Ordering}; - -static NEXT_SCENE_ID: AtomicUsize = AtomicUsize::new(0); - -#[derive(Clone)] -pub struct Scene { - pub(crate) display_list: Vec, - pub(crate) paths: Vec, - pub(crate) clip_paths: Vec, - palette: Palette, - bounds: RectF, - view_box: RectF, - id: SceneId, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct SceneId(pub u32); - -impl Scene { - #[inline] - pub fn new() -> Scene { - let scene_id = SceneId(NEXT_SCENE_ID.fetch_add(1, Ordering::Relaxed) as u32); - Scene { - display_list: vec![], - paths: vec![], - clip_paths: vec![], - palette: Palette::new(scene_id), - bounds: RectF::default(), - view_box: RectF::default(), - id: scene_id, - } - } - - pub fn push_path(&mut self, path: DrawPath) { - let path_index = self.paths.len() as u32; - self.paths.push(path); - self.push_path_with_index(path_index); - } - - fn push_path_with_index(&mut self, path_index: u32) { - self.bounds = self.bounds.union_rect(self.paths[path_index as usize].outline.bounds()); - - if let Some(DisplayItem::DrawPaths { - start_index: _, - ref mut end_index - }) = self.display_list.last_mut() { - *end_index = path_index + 1; - } else { - self.display_list.push(DisplayItem::DrawPaths { - start_index: path_index, - end_index: path_index + 1, - }); - } - } - - pub fn push_clip_path(&mut self, clip_path: ClipPath) -> ClipPathId { - self.bounds = self.bounds.union_rect(clip_path.outline.bounds()); - let clip_path_id = ClipPathId(self.clip_paths.len() as u32); - self.clip_paths.push(clip_path); - clip_path_id - } - - pub fn push_render_target(&mut self, render_target: RenderTarget) -> RenderTargetId { - let render_target_id = self.palette.push_render_target(render_target); - self.display_list.push(DisplayItem::PushRenderTarget(render_target_id)); - render_target_id - } - - pub fn pop_render_target(&mut self) { - self.display_list.push(DisplayItem::PopRenderTarget); - } - - pub fn append_scene(&mut self, scene: Scene) { - let MergedPaletteInfo { - render_target_mapping, - paint_mapping, - } = self.palette.append_palette(scene.palette); - - // Merge clip paths. - let mut clip_path_mapping = Vec::with_capacity(scene.clip_paths.len()); - for clip_path in scene.clip_paths { - clip_path_mapping.push(self.clip_paths.len()); - self.clip_paths.push(clip_path); - } - - // Merge draw paths. - let mut draw_path_mapping = Vec::with_capacity(scene.paths.len()); - for draw_path in scene.paths { - draw_path_mapping.push(self.paths.len() as u32); - self.paths.push(DrawPath { - outline: draw_path.outline, - paint: paint_mapping[&draw_path.paint], - clip_path: draw_path.clip_path.map(|clip_path_id| { - ClipPathId(clip_path_mapping[clip_path_id.0 as usize] as u32) - }), - fill_rule: draw_path.fill_rule, - blend_mode: draw_path.blend_mode, - name: draw_path.name, - }); - } - - // Merge display items. - for display_item in scene.display_list { - match display_item { - DisplayItem::PushRenderTarget(old_render_target_id) => { - let new_render_target_id = render_target_mapping[&old_render_target_id]; - self.display_list.push(DisplayItem::PushRenderTarget(new_render_target_id)); - } - DisplayItem::PopRenderTarget => { - self.display_list.push(DisplayItem::PopRenderTarget); - } - DisplayItem::DrawPaths { - start_index: old_start_path_index, - end_index: old_end_path_index, - } => { - for old_path_index in old_start_path_index..old_end_path_index { - self.push_path_with_index(draw_path_mapping[old_path_index as usize]) - } - } - } - } - } - - #[inline] - pub fn build_paint_info(&mut self, render_transform: Transform2F) -> PaintInfo { - self.palette.build_paint_info(render_transform) - } - - #[allow(clippy::trivially_copy_pass_by_ref)] - pub fn push_paint(&mut self, paint: &Paint) -> PaintId { - self.palette.push_paint(paint) - } - - #[inline] - pub fn path_count(&self) -> usize { - self.paths.len() - } - - #[inline] - pub fn bounds(&self) -> RectF { - self.bounds - } - - #[inline] - pub fn set_bounds(&mut self, new_bounds: RectF) { - self.bounds = new_bounds; - } - - #[inline] - pub fn view_box(&self) -> RectF { - self.view_box - } - - #[inline] - pub fn set_view_box(&mut self, new_view_box: RectF) { - self.view_box = new_view_box; - } - - pub(crate) fn apply_render_options( - &self, - original_outline: &Outline, - options: &PreparedBuildOptions, - ) -> Outline { - let effective_view_box = self.effective_view_box(options); - - let mut outline; - match options.transform { - PreparedRenderTransform::Perspective { - ref perspective, - ref clip_polygon, - .. - } => { - if original_outline.is_outside_polygon(clip_polygon) { - outline = Outline::new(); - } else { - outline = (*original_outline).clone(); - outline.close_all_contours(); - outline.clip_against_polygon(clip_polygon); - outline.apply_perspective(perspective); - - // TODO(pcwalton): Support subpixel AA in 3D. - } - } - _ => { - // TODO(pcwalton): Short circuit. - outline = (*original_outline).clone(); - outline.close_all_contours(); - if options.transform.is_2d() || options.subpixel_aa_enabled { - let mut transform = match options.transform { - PreparedRenderTransform::Transform2D(transform) => transform, - PreparedRenderTransform::None => Transform2F::default(), - PreparedRenderTransform::Perspective { .. } => unreachable!(), - }; - if options.subpixel_aa_enabled { - transform *= Transform2F::from_scale(vec2f(3.0, 1.0)) - } - outline.transform(&transform); - } - outline.clip_against_rect(effective_view_box); - } - } - - if !options.dilation.is_zero() { - outline.dilate(options.dilation); - } - - // TODO(pcwalton): Fold this into previous passes to avoid unnecessary clones during - // monotonic conversion. - outline.prepare_for_tiling(self.effective_view_box(options)); - outline - } - - #[inline] - pub(crate) fn effective_view_box(&self, render_options: &PreparedBuildOptions) -> RectF { - if render_options.subpixel_aa_enabled { - self.view_box * vec2f(3.0, 1.0) - } else { - self.view_box - } - } - - #[inline] - pub fn build(&mut self, - options: BuildOptions, - listener: Box, - executor: &E) - where E: Executor { - let prepared_options = options.prepare(self.bounds); - SceneBuilder::new(self, &prepared_options, listener).build(executor) - } - - pub fn paths<'a>(&'a self) -> PathIter { - PathIter { - scene: self, - pos: 0 - } - } -} - -pub struct PathIter<'a> { - scene: &'a Scene, - pos: usize -} - -impl<'a> Iterator for PathIter<'a> { - type Item = (&'a Paint, &'a Outline, &'a str); - fn next(&mut self) -> Option { - let item = self.scene.paths.get(self.pos).map(|path_object| { - ( - self.scene.palette.paints.get(path_object.paint.0 as usize).unwrap(), - &path_object.outline, - &*path_object.name - ) - }); - self.pos += 1; - item - } -} - -#[derive(Clone, Debug)] -pub struct DrawPath { - outline: Outline, - paint: PaintId, - clip_path: Option, - fill_rule: FillRule, - blend_mode: BlendMode, - name: String, -} - -#[derive(Clone, Debug)] -pub struct ClipPath { - outline: Outline, - fill_rule: FillRule, - name: String, -} - -#[derive(Clone, Copy, Debug)] -pub struct ClipPathId(pub u32); - -#[derive(Clone, Debug)] -pub struct RenderTarget { - size: Vector2I, - name: String, -} - -/// Drawing commands. -#[derive(Clone, Debug)] -pub enum DisplayItem { - /// Draws paths to the render target on top of the stack. - DrawPaths { start_index: u32, end_index: u32 }, - - /// Pushes a render target onto the top of the stack. - PushRenderTarget(RenderTargetId), - - /// Pops a render target from the stack. - PopRenderTarget, -} - -impl DrawPath { - #[inline] - pub fn new(outline: Outline, paint: PaintId) -> DrawPath { - DrawPath { - outline, - paint, - clip_path: None, - fill_rule: FillRule::Winding, - blend_mode: BlendMode::SrcOver, - name: String::new(), - } - } - - #[inline] - pub fn outline(&self) -> &Outline { - &self.outline - } - - #[inline] - pub(crate) fn clip_path(&self) -> Option { - self.clip_path - } - - #[inline] - pub fn set_clip_path(&mut self, new_clip_path: Option) { - self.clip_path = new_clip_path - } - - #[inline] - pub(crate) fn paint(&self) -> PaintId { - self.paint - } - - #[inline] - pub(crate) fn fill_rule(&self) -> FillRule { - self.fill_rule - } - - #[inline] - pub fn set_fill_rule(&mut self, new_fill_rule: FillRule) { - self.fill_rule = new_fill_rule - } - - #[inline] - pub(crate) fn blend_mode(&self) -> BlendMode { - self.blend_mode - } - - #[inline] - pub fn set_blend_mode(&mut self, new_blend_mode: BlendMode) { - self.blend_mode = new_blend_mode - } - - #[inline] - pub fn set_name(&mut self, new_name: String) { - self.name = new_name - } -} - -impl ClipPath { - #[inline] - pub fn new(outline: Outline) -> ClipPath { - ClipPath { outline, fill_rule: FillRule::Winding, name: String::new() } - } - - #[inline] - pub fn outline(&self) -> &Outline { - &self.outline - } - - #[inline] - pub(crate) fn fill_rule(&self) -> FillRule { - self.fill_rule - } - - #[inline] - pub fn set_fill_rule(&mut self, new_fill_rule: FillRule) { - self.fill_rule = new_fill_rule - } - - #[inline] - pub fn set_name(&mut self, new_name: String) { - self.name = new_name - } -} - -impl RenderTarget { - #[inline] - pub fn new(size: Vector2I, name: String) -> RenderTarget { - RenderTarget { size, name } - } - - #[inline] - pub fn size(&self) -> Vector2I { - self.size - } -} diff --git a/crates/pathfinder/renderer/src/tile_map.rs b/crates/pathfinder/renderer/src/tile_map.rs deleted file mode 100644 index 8b86a8589d..0000000000 --- a/crates/pathfinder/renderer/src/tile_map.rs +++ /dev/null @@ -1,70 +0,0 @@ -// pathfinder/renderer/src/tile_map.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use pathfinder_geometry::rect::RectI; -use pathfinder_geometry::vector::{Vector2I, vec2i}; - -#[derive(Debug)] -pub struct DenseTileMap { - pub data: Vec, - pub rect: RectI, -} - -impl DenseTileMap { - #[inline] - pub fn new(rect: RectI) -> DenseTileMap - where - T: Copy + Clone + Default, - { - let length = rect.size().x() as usize * rect.size().y() as usize; - DenseTileMap { - data: vec![T::default(); length], - rect, - } - } - - #[inline] - pub fn from_builder(build: F, rect: RectI) -> DenseTileMap - where - F: FnMut(usize) -> T, - { - let length = rect.size().x() as usize * rect.size().y() as usize; - DenseTileMap { - data: (0..length).map(build).collect(), - rect, - } - } - - #[inline] - pub fn get(&self, coords: Vector2I) -> Option<&T> { - self.coords_to_index(coords).and_then(|index| self.data.get(index)) - } - - #[inline] - pub fn coords_to_index(&self, coords: Vector2I) -> Option { - if self.rect.contains_point(coords) { - Some(self.coords_to_index_unchecked(coords)) - } else { - None - } - } - - #[inline] - pub fn coords_to_index_unchecked(&self, coords: Vector2I) -> usize { - (coords.y() - self.rect.min_y()) as usize * self.rect.size().x() as usize - + (coords.x() - self.rect.min_x()) as usize - } - - #[inline] - pub fn index_to_coords(&self, index: usize) -> Vector2I { - let (width, index) = (self.rect.size().x(), index as i32); - self.rect.origin() + vec2i(index % width, index / width) - } -} diff --git a/crates/pathfinder/renderer/src/tiles.rs b/crates/pathfinder/renderer/src/tiles.rs deleted file mode 100644 index 678e60191f..0000000000 --- a/crates/pathfinder/renderer/src/tiles.rs +++ /dev/null @@ -1,701 +0,0 @@ -// pathfinder/renderer/src/tiles.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::builder::{BuiltPath, ObjectBuilder, Occluder, SceneBuilder, SolidTiles}; -use crate::gpu_data::{AlphaTileId, TileObjectPrimitive}; -use crate::paint::{PaintId, PaintMetadata}; -use pathfinder_content::effects::BlendMode; -use pathfinder_content::fill::FillRule; -use pathfinder_content::outline::{Contour, Outline, PointIndex}; -use pathfinder_content::segment::Segment; -use pathfinder_content::sorted_vector::SortedVector; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::rect::{RectF, RectI}; -use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2f, vec2i}; -use std::cmp::Ordering; -use std::mem; - -// TODO(pcwalton): Make this configurable. -const FLATTENING_TOLERANCE: f32 = 0.1; - -pub const TILE_WIDTH: u32 = 16; -pub const TILE_HEIGHT: u32 = 16; - -pub(crate) struct Tiler<'a, 'b> { - scene_builder: &'a SceneBuilder<'b, 'a>, - pub(crate) object_builder: ObjectBuilder, - outline: &'a Outline, - path_info: TilingPathInfo<'a>, - - point_queue: SortedVector, - active_edges: SortedVector, - old_active_edges: Vec, -} - -#[derive(Clone, Copy)] -pub(crate) enum TilingPathInfo<'a> { - Clip, - Draw(DrawTilingPathInfo<'a>), -} - -#[derive(Clone, Copy)] -pub(crate) struct DrawTilingPathInfo<'a> { - pub(crate) paint_id: PaintId, - pub(crate) paint_metadata: &'a PaintMetadata, - pub(crate) blend_mode: BlendMode, - pub(crate) built_clip_path: Option<&'a BuiltPath>, - pub(crate) fill_rule: FillRule, -} - -impl<'a, 'b> Tiler<'a, 'b> { - #[allow(clippy::or_fun_call)] - pub(crate) fn new( - scene_builder: &'a SceneBuilder<'b, 'a>, - outline: &'a Outline, - fill_rule: FillRule, - view_box: RectF, - path_info: TilingPathInfo<'a>, - ) -> Tiler<'a, 'b> { - let bounds = outline - .bounds() - .intersection(view_box) - .unwrap_or(RectF::default()); - let object_builder = ObjectBuilder::new(bounds, view_box, fill_rule, &path_info); - - Tiler { - scene_builder, - object_builder, - outline, - path_info, - - point_queue: SortedVector::new(), - active_edges: SortedVector::new(), - old_active_edges: vec![], - } - } - - pub(crate) fn generate_tiles(&mut self) { - // Initialize the point queue. - self.init_point_queue(); - - // Reset active edges. - self.active_edges.clear(); - self.old_active_edges.clear(); - - // Generate strips. - let tile_rect = self.object_builder.tile_rect(); - for strip_origin_y in tile_rect.min_y()..tile_rect.max_y() { - self.generate_strip(strip_origin_y); - } - - // Pack and cull. - self.pack_and_cull(); - - // Done! - debug!("{:#?}", self.object_builder.built_path); - } - - fn generate_strip(&mut self, strip_origin_y: i32) { - // Process old active edges. - self.process_old_active_edges(strip_origin_y); - - // Add new active edges. - let strip_max_y = ((i32::from(strip_origin_y) + 1) * TILE_HEIGHT as i32) as f32; - while let Some(queued_endpoint) = self.point_queue.peek() { - // We're done when we see an endpoint that belongs to the next tile strip. - // - // Note that this test must be `>`, not `>=`, in order to make sure we don't miss - // active edges that lie precisely on the tile strip boundary. - if queued_endpoint.y > strip_max_y { - break; - } - - self.add_new_active_edge(strip_origin_y); - } - } - - fn pack_and_cull(&mut self) { - let draw_tiling_path_info = match self.path_info { - TilingPathInfo::Clip => return, - TilingPathInfo::Draw(draw_tiling_path_info) => draw_tiling_path_info, - }; - - let blend_mode_is_destructive = draw_tiling_path_info.blend_mode.is_destructive(); - - for (draw_tile_index, draw_tile) in self.object_builder - .built_path - .tiles - .data - .iter() - .enumerate() { - let packed_tile = PackedTile::new(draw_tile_index as u32, - draw_tile, - &draw_tiling_path_info, - &self.object_builder); - - match packed_tile.tile_type { - TileType::Solid => { - match self.object_builder.built_path.solid_tiles { - SolidTiles::Occluders(ref mut occluders) => { - occluders.push(Occluder::new(packed_tile.tile_coords)); - } - SolidTiles::Regular(ref mut solid_tiles) => { - packed_tile.add_to(solid_tiles, - &mut self.object_builder.built_path.clip_tiles, - &draw_tiling_path_info, - &self.scene_builder); - } - } - } - TileType::SingleMask => { - debug_assert_ne!(packed_tile.draw_tile.alpha_tile_id.page(), !0); - packed_tile.add_to(&mut self.object_builder.built_path.single_mask_tiles, - &mut self.object_builder.built_path.clip_tiles, - &draw_tiling_path_info, - &self.scene_builder); - } - TileType::Empty if blend_mode_is_destructive => { - packed_tile.add_to(&mut self.object_builder.built_path.empty_tiles, - &mut self.object_builder.built_path.clip_tiles, - &draw_tiling_path_info, - &self.scene_builder); - } - TileType::Empty => { - // Just cull. - } - } - } - } - - fn process_old_active_edges(&mut self, tile_y: i32) { - let mut current_tile_x = self.object_builder.tile_rect().min_x(); - let mut current_subtile_x = 0.0; - let mut current_winding = 0; - - debug_assert!(self.old_active_edges.is_empty()); - mem::swap(&mut self.old_active_edges, &mut self.active_edges.array); - - // FIXME(pcwalton): Yuck. - let mut last_segment_x = -9999.0; - - let tile_top = (i32::from(tile_y) * TILE_HEIGHT as i32) as f32; - - debug!("---------- tile y {}({}) ----------", tile_y, tile_top); - debug!("old active edges: {:#?}", self.old_active_edges); - - for mut active_edge in self.old_active_edges.drain(..) { - // Determine x-intercept and winding. - let segment_x = active_edge.crossing.x(); - let edge_winding = - if active_edge.segment.baseline.from_y() < active_edge.segment.baseline.to_y() { - 1 - } else { - -1 - }; - - debug!( - "tile Y {}({}): segment_x={} edge_winding={} current_tile_x={} \ - current_subtile_x={} current_winding={}", - tile_y, - tile_top, - segment_x, - edge_winding, - current_tile_x, - current_subtile_x, - current_winding - ); - debug!( - "... segment={:#?} crossing={:?}", - active_edge.segment, active_edge.crossing - ); - - // FIXME(pcwalton): Remove this debug code! - debug_assert!(segment_x >= last_segment_x); - last_segment_x = segment_x; - - // Do initial subtile fill, if necessary. - let segment_tile_x = f32::floor(segment_x) as i32 / TILE_WIDTH as i32; - if current_tile_x < segment_tile_x && current_subtile_x > 0.0 { - let current_x = - (i32::from(current_tile_x) * TILE_WIDTH as i32) as f32 + current_subtile_x; - let tile_right_x = ((i32::from(current_tile_x) + 1) * TILE_WIDTH as i32) as f32; - let current_tile_coords = vec2i(current_tile_x, tile_y); - self.object_builder.add_active_fill( - self.scene_builder, - current_x, - tile_right_x, - current_winding, - current_tile_coords, - ); - current_tile_x += 1; - current_subtile_x = 0.0; - } - - // Move over to the correct tile, filling in as we go. - while current_tile_x < segment_tile_x { - debug!( - "... emitting backdrop {} @ tile {}", - current_winding, current_tile_x - ); - let current_tile_coords = vec2i(current_tile_x, tile_y); - if let Some(tile_index) = self.object_builder - .tile_coords_to_local_index(current_tile_coords) { - // FIXME(pcwalton): Handle winding overflow. - self.object_builder.built_path.tiles.data[tile_index as usize].backdrop = - current_winding as i8; - } - - current_tile_x += 1; - current_subtile_x = 0.0; - } - - // Do final subtile fill, if necessary. - debug_assert_eq!(current_tile_x, segment_tile_x); - let segment_subtile_x = - segment_x - (i32::from(current_tile_x) * TILE_WIDTH as i32) as f32; - if segment_subtile_x > current_subtile_x { - let current_x = - (i32::from(current_tile_x) * TILE_WIDTH as i32) as f32 + current_subtile_x; - let current_tile_coords = vec2i(current_tile_x, tile_y); - self.object_builder.add_active_fill( - self.scene_builder, - current_x, - segment_x, - current_winding, - current_tile_coords, - ); - current_subtile_x = segment_subtile_x; - } - - // Update winding. - current_winding += edge_winding; - - // Process the edge. - debug!("about to process existing active edge {:#?}", active_edge); - debug_assert!(f32::abs(active_edge.crossing.y() - tile_top) < 0.1); - active_edge.process(self.scene_builder, &mut self.object_builder, tile_y); - if !active_edge.segment.is_none() { - self.active_edges.push(active_edge); - } - } - } - - fn add_new_active_edge(&mut self, tile_y: i32) { - let outline = &self.outline; - let point_index = self.point_queue.pop().unwrap().point_index; - - let contour = &outline.contours()[point_index.contour() as usize]; - - // TODO(pcwalton): Could use a bitset of processed edges… - let prev_endpoint_index = contour.prev_endpoint_index_of(point_index.point()); - let next_endpoint_index = contour.next_endpoint_index_of(point_index.point()); - - debug!( - "adding new active edge, tile_y={} point_index={} prev={} next={} pos={:?} \ - prevpos={:?} nextpos={:?}", - tile_y, - point_index.point(), - prev_endpoint_index, - next_endpoint_index, - contour.position_of(point_index.point()), - contour.position_of(prev_endpoint_index), - contour.position_of(next_endpoint_index) - ); - - if contour.point_is_logically_above(point_index.point(), prev_endpoint_index) { - debug!("... adding prev endpoint"); - - process_active_segment( - contour, - prev_endpoint_index, - &mut self.active_edges, - self.scene_builder, - &mut self.object_builder, - tile_y, - ); - - self.point_queue.push(QueuedEndpoint { - point_index: PointIndex::new(point_index.contour(), prev_endpoint_index), - y: contour.position_of(prev_endpoint_index).y(), - }); - - debug!("... done adding prev endpoint"); - } - - if contour.point_is_logically_above(point_index.point(), next_endpoint_index) { - debug!( - "... adding next endpoint {} -> {}", - point_index.point(), - next_endpoint_index - ); - - process_active_segment( - contour, - point_index.point(), - &mut self.active_edges, - self.scene_builder, - &mut self.object_builder, - tile_y, - ); - - self.point_queue.push(QueuedEndpoint { - point_index: PointIndex::new(point_index.contour(), next_endpoint_index), - y: contour.position_of(next_endpoint_index).y(), - }); - - debug!("... done adding next endpoint"); - } - } - - fn init_point_queue(&mut self) { - // Find MIN points. - self.point_queue.clear(); - for (contour_index, contour) in self.outline.contours().iter().enumerate() { - let contour_index = contour_index as u32; - let mut cur_endpoint_index = 0; - let mut prev_endpoint_index = contour.prev_endpoint_index_of(cur_endpoint_index); - let mut next_endpoint_index = contour.next_endpoint_index_of(cur_endpoint_index); - loop { - if contour.point_is_logically_above(cur_endpoint_index, prev_endpoint_index) - && contour.point_is_logically_above(cur_endpoint_index, next_endpoint_index) - { - self.point_queue.push(QueuedEndpoint { - point_index: PointIndex::new(contour_index, cur_endpoint_index), - y: contour.position_of(cur_endpoint_index).y(), - }); - } - - if cur_endpoint_index >= next_endpoint_index { - break; - } - - prev_endpoint_index = cur_endpoint_index; - cur_endpoint_index = next_endpoint_index; - next_endpoint_index = contour.next_endpoint_index_of(cur_endpoint_index); - } - } - } -} - -impl<'a> TilingPathInfo<'a> { - pub(crate) fn has_destructive_blend_mode(&self) -> bool { - match *self { - TilingPathInfo::Draw(ref draw_tiling_path_info) => { - draw_tiling_path_info.blend_mode.is_destructive() - } - TilingPathInfo::Clip => false, - } - } -} - -pub(crate) struct PackedTile<'a> { - pub(crate) tile_type: TileType, - pub(crate) tile_coords: Vector2I, - pub(crate) draw_tile: &'a TileObjectPrimitive, - pub(crate) clip_tile: Option<&'a TileObjectPrimitive>, -} - -#[derive(Clone, Copy, PartialEq)] -pub(crate) enum TileType { - Solid, - Empty, - SingleMask, -} - -impl<'a> PackedTile<'a> { - fn new(draw_tile_index: u32, - draw_tile: &'a TileObjectPrimitive, - draw_tiling_path_info: &DrawTilingPathInfo<'a>, - object_builder: &ObjectBuilder) - -> PackedTile<'a> { - let tile_coords = object_builder.local_tile_index_to_coords(draw_tile_index as u32); - - // First, if the draw tile is empty, cull it regardless of clip. - if draw_tile.is_solid() { - match (object_builder.built_path.fill_rule, draw_tile.backdrop) { - (FillRule::Winding, 0) => { - return PackedTile { - tile_type: TileType::Empty, - tile_coords, - draw_tile, - clip_tile: None, - }; - } - (FillRule::Winding, _) => {} - (FillRule::EvenOdd, backdrop) if backdrop % 2 == 0 => { - return PackedTile { - tile_type: TileType::Empty, - tile_coords, - draw_tile, - clip_tile: None, - }; - } - (FillRule::EvenOdd, _) => {} - } - } - - // Figure out what clip tile we need, if any. - let clip_tile = match draw_tiling_path_info.built_clip_path { - None => None, - Some(built_clip_path) => { - match built_clip_path.tiles.get(tile_coords) { - None => { - // This tile is outside of the bounds of the clip path entirely. We can - // cull it. - return PackedTile { - tile_type: TileType::Empty, - tile_coords, - draw_tile, - clip_tile: None, - }; - } - Some(clip_tile) if clip_tile.is_solid() => { - if clip_tile.backdrop != 0 { - // The clip tile is fully opaque, so this tile isn't clipped at - // all. - None - } else { - // This tile is completely clipped out. Cull it. - return PackedTile { - tile_type: TileType::Empty, - tile_coords, - draw_tile, - clip_tile: None, - }; - } - } - Some(clip_tile) => Some(clip_tile), - } - } - }; - - // Choose a tile type. - match clip_tile { - None if draw_tile.is_solid() => { - // This is a solid tile that completely occludes the background. - PackedTile { tile_type: TileType::Solid, tile_coords, draw_tile, clip_tile } - } - None => { - // We have a draw tile and no clip tile. - PackedTile { - tile_type: TileType::SingleMask, - tile_coords, - draw_tile, - clip_tile: None, - } - } - Some(clip_tile) if draw_tile.is_solid() => { - // We have a solid draw tile and a clip tile. This is effectively the same as - // having a draw tile and no clip tile. - // - // FIXME(pcwalton): This doesn't preserve the fill rule of the clip path! - PackedTile { - tile_type: TileType::SingleMask, - tile_coords, - draw_tile: clip_tile, - clip_tile: None, - } - } - Some(clip_tile) => { - // We have both a draw and clip mask. Composite them together. - PackedTile { - tile_type: TileType::SingleMask, - tile_coords, - draw_tile, - clip_tile: Some(clip_tile), - } - } - } - } -} - -pub fn round_rect_out_to_tile_bounds(rect: RectF) -> RectI { - (rect * vec2f(1.0 / TILE_WIDTH as f32, 1.0 / TILE_HEIGHT as f32)).round_out().to_i32() -} - -fn process_active_segment( - contour: &Contour, - from_endpoint_index: u32, - active_edges: &mut SortedVector, - builder: &SceneBuilder, - object_builder: &mut ObjectBuilder, - tile_y: i32, -) { - let mut active_edge = ActiveEdge::from_segment(&contour.segment_after(from_endpoint_index)); - debug!("... process_active_segment({:#?})", active_edge); - active_edge.process(builder, object_builder, tile_y); - if !active_edge.segment.is_none() { - debug!("... ... pushing resulting active edge: {:#?}", active_edge); - active_edges.push(active_edge); - } -} - -// Queued endpoints - -#[derive(PartialEq)] -struct QueuedEndpoint { - point_index: PointIndex, - y: f32, -} - -impl Eq for QueuedEndpoint {} - -impl PartialOrd for QueuedEndpoint { - fn partial_cmp(&self, other: &QueuedEndpoint) -> Option { - // NB: Reversed! - (other.y, other.point_index).partial_cmp(&(self.y, self.point_index)) - } -} - -// Active edges - -#[derive(Clone, PartialEq, Debug)] -struct ActiveEdge { - segment: Segment, - // TODO(pcwalton): Shrink `crossing` down to just one f32? - crossing: Vector2F, -} - -impl ActiveEdge { - fn from_segment(segment: &Segment) -> ActiveEdge { - let crossing = if segment.baseline.from_y() < segment.baseline.to_y() { - segment.baseline.from() - } else { - segment.baseline.to() - }; - ActiveEdge::from_segment_and_crossing(segment, crossing) - } - - fn from_segment_and_crossing(segment: &Segment, crossing: Vector2F) -> ActiveEdge { - ActiveEdge { segment: *segment, crossing } - } - - fn process(&mut self, - builder: &SceneBuilder, - object_builder: &mut ObjectBuilder, - tile_y: i32) { - let tile_bottom = ((i32::from(tile_y) + 1) * TILE_HEIGHT as i32) as f32; - debug!( - "process_active_edge({:#?}, tile_y={}({}))", - self, tile_y, tile_bottom - ); - - let mut segment = self.segment; - let winding = segment.baseline.y_winding(); - - if segment.is_line() { - let line_segment = segment.as_line_segment(); - self.segment = - match self.process_line_segment(line_segment, builder, object_builder, tile_y) { - Some(lower_part) => Segment::line(lower_part), - None => Segment::none(), - }; - return; - } - - // TODO(pcwalton): Don't degree elevate! - if !segment.is_cubic() { - segment = segment.to_cubic(); - } - - // If necessary, draw initial line. - if self.crossing.y() < segment.baseline.min_y() { - let first_line_segment = - LineSegment2F::new(self.crossing, segment.baseline.upper_point()).orient(winding); - if self.process_line_segment(first_line_segment, builder, object_builder, tile_y) - .is_some() { - return; - } - } - - let mut oriented_segment = segment.orient(winding); - loop { - let mut split_t = 1.0; - let mut before_segment = oriented_segment; - let mut after_segment = None; - - while !before_segment - .as_cubic_segment() - .is_flat(FLATTENING_TOLERANCE) - { - let next_t = 0.5 * split_t; - let (before, after) = oriented_segment.as_cubic_segment().split(next_t); - before_segment = before; - after_segment = Some(after); - split_t = next_t; - } - - debug!( - "... tile_y={} winding={} segment={:?} t={} before_segment={:?} - after_segment={:?}", - tile_y, winding, segment, split_t, before_segment, after_segment - ); - - let line = before_segment.baseline.orient(winding); - match self.process_line_segment(line, builder, object_builder, tile_y) { - Some(lower_part) if split_t == 1.0 => { - self.segment = Segment::line(lower_part); - return; - } - None if split_t == 1.0 => { - self.segment = Segment::none(); - return; - } - Some(_) => { - self.segment = after_segment.unwrap().orient(winding); - return; - } - None => oriented_segment = after_segment.unwrap(), - } - } - } - - fn process_line_segment( - &mut self, - line_segment: LineSegment2F, - builder: &SceneBuilder, - object_builder: &mut ObjectBuilder, - tile_y: i32, - ) -> Option { - let tile_bottom = ((i32::from(tile_y) + 1) * TILE_HEIGHT as i32) as f32; - debug!( - "process_line_segment({:?}, tile_y={}) tile_bottom={}", - line_segment, tile_y, tile_bottom - ); - - if line_segment.max_y() <= tile_bottom { - object_builder.generate_fill_primitives_for_line(builder, line_segment, tile_y); - return None; - } - - let (upper_part, lower_part) = line_segment.split_at_y(tile_bottom); - object_builder.generate_fill_primitives_for_line(builder, upper_part, tile_y); - self.crossing = lower_part.upper_point(); - Some(lower_part) - } -} - -impl PartialOrd for ActiveEdge { - fn partial_cmp(&self, other: &ActiveEdge) -> Option { - self.crossing.x().partial_cmp(&other.crossing.x()) - } -} - -impl Default for TileObjectPrimitive { - #[inline] - fn default() -> TileObjectPrimitive { - TileObjectPrimitive { backdrop: 0, alpha_tile_id: AlphaTileId::invalid() } - } -} - -impl TileObjectPrimitive { - #[inline] - pub fn is_solid(&self) -> bool { !self.alpha_tile_id.is_valid() } -} diff --git a/crates/pathfinder/renderer/src/z_buffer.rs b/crates/pathfinder/renderer/src/z_buffer.rs deleted file mode 100644 index 291ffafc35..0000000000 --- a/crates/pathfinder/renderer/src/z_buffer.rs +++ /dev/null @@ -1,123 +0,0 @@ -// pathfinder/renderer/src/z_buffer.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Software occlusion culling. - -use crate::builder::Occluder; -use crate::gpu_data::{Tile, TileBatch}; -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; - -pub(crate) struct ZBuffer { - buffer: DenseTileMap, - depth_metadata: VecMap, -} - -pub(crate) struct SolidTiles { - pub(crate) batches: Vec, -} - -#[derive(Clone, Copy)] -pub(crate) struct DepthMetadata { - pub(crate) paint_id: PaintId, -} -impl ZBuffer { - pub(crate) fn new(view_box: RectF) -> ZBuffer { - let tile_rect = tiles::round_rect_out_to_tile_bounds(view_box); - ZBuffer { - buffer: DenseTileMap::from_builder(|_| 0, tile_rect), - depth_metadata: VecMap::new(), - } - } - - pub(crate) fn test(&self, coords: Vector2I, depth: u32) -> bool { - let tile_index = self.buffer.coords_to_index_unchecked(coords); - self.buffer.data[tile_index as usize] < depth - } - - pub(crate) fn update(&mut self, - solid_tiles: &[Occluder], - depth: u32, - metadata: DepthMetadata) { - self.depth_metadata.insert(depth as usize, metadata); - for solid_tile in solid_tiles { - let tile_index = self.buffer.coords_to_index_unchecked(solid_tile.coords); - let z_dest = &mut self.buffer.data[tile_index as usize]; - *z_dest = u32::max(*z_dest, depth); - } - } - - pub(crate) fn build_solid_tiles(&self, paint_metadata: &[PaintMetadata]) -> SolidTiles { - let mut solid_tiles = SolidTiles { batches: vec![] }; - - for tile_index in 0..self.buffer.data.len() { - let depth = self.buffer.data[tile_index]; - if depth == 0 { - continue; - } - - let tile_coords = self.buffer.index_to_coords(tile_index); - - let depth_metadata = self.depth_metadata[depth as usize]; - let paint_id = depth_metadata.paint_id; - let paint_metadata = &paint_metadata[paint_id.0 as usize]; - - let tile_position = tile_coords + self.buffer.rect.origin(); - - // Create a batch if necessary. - let paint_tile_batch_texture = paint_metadata.tile_batch_texture(); - let paint_filter = paint_metadata.filter(); - match solid_tiles.batches.last() { - Some(TileBatch { color_texture: tile_batch_texture, filter: tile_filter, .. }) if - *tile_batch_texture == paint_tile_batch_texture && - *tile_filter == paint_filter => {} - _ => { - // Batch break. - // - // TODO(pcwalton): We could be more aggressive with batching here, since we - // know there are no overlaps. - solid_tiles.batches.push(TileBatch { - color_texture: paint_tile_batch_texture, - tiles: vec![], - filter: paint_filter, - blend_mode: BlendMode::default(), - tile_page: !0, - }); - } - } - - let batch = solid_tiles.batches.last_mut().unwrap(); - batch.tiles.push(Tile::new_solid_from_paint_id(tile_position, paint_id)); - } - - solid_tiles - } -} - -impl Tile { - pub(crate) fn new_solid_from_paint_id(tile_origin: Vector2I, paint_id: PaintId) -> Tile { - Tile { - 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 as AlignedU16, - } - } -} diff --git a/crates/pathfinder/resources/Cargo.toml b/crates/pathfinder/resources/Cargo.toml deleted file mode 100644 index 6068f0619d..0000000000 --- a/crates/pathfinder/resources/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "pathfinder_resources" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -description = "Shaders, textures, etc. for the Pathfinder vector graphics library" -license = "MIT/Apache-2.0" -repository = "https://github.com/servo/pathfinder" -homepage = "https://github.com/servo/pathfinder" - -[dependencies] diff --git a/crates/pathfinder/resources/MANIFEST b/crates/pathfinder/resources/MANIFEST deleted file mode 100644 index fbe946fdb7..0000000000 --- a/crates/pathfinder/resources/MANIFEST +++ /dev/null @@ -1,106 +0,0 @@ -# This file must contain the paths of all resources that are used by the Pathfinder library. -# -# When you add a new resource, make sure to add it to this file. - -debug-fonts/regular.json -shaders/gl3/blit.fs.glsl -shaders/gl3/blit.vs.glsl -shaders/gl3/clear.fs.glsl -shaders/gl3/clear.vs.glsl -shaders/gl3/debug_solid.fs.glsl -shaders/gl3/debug_solid.vs.glsl -shaders/gl3/debug_texture.fs.glsl -shaders/gl3/debug_texture.vs.glsl -shaders/gl3/demo_ground.fs.glsl -shaders/gl3/demo_ground.vs.glsl -shaders/gl3/fill.fs.glsl -shaders/gl3/fill.vs.glsl -shaders/gl3/reproject.fs.glsl -shaders/gl3/reproject.vs.glsl -shaders/gl3/stencil.fs.glsl -shaders/gl3/stencil.vs.glsl -shaders/gl3/tile.fs.glsl -shaders/gl3/tile.vs.glsl -shaders/gl3/tile_clip.fs.glsl -shaders/gl3/tile_clip.vs.glsl -shaders/gl3/tile_copy.fs.glsl -shaders/gl3/tile_copy.vs.glsl -shaders/gl4/blit.fs.glsl -shaders/gl4/blit.vs.glsl -shaders/gl4/clear.fs.glsl -shaders/gl4/clear.vs.glsl -shaders/gl4/debug_solid.fs.glsl -shaders/gl4/debug_solid.vs.glsl -shaders/gl4/debug_texture.fs.glsl -shaders/gl4/debug_texture.vs.glsl -shaders/gl4/demo_ground.fs.glsl -shaders/gl4/demo_ground.vs.glsl -shaders/gl4/fill.fs.glsl -shaders/gl4/fill.vs.glsl -shaders/gl4/reproject.fs.glsl -shaders/gl4/reproject.vs.glsl -shaders/gl4/stencil.fs.glsl -shaders/gl4/stencil.vs.glsl -shaders/gl4/tile.fs.glsl -shaders/gl4/tile.vs.glsl -shaders/gl4/tile_clip.fs.glsl -shaders/gl4/tile_clip.vs.glsl -shaders/gl4/tile_copy.fs.glsl -shaders/gl4/tile_copy.vs.glsl -shaders/metal/blit.fs.metal -shaders/metal/blit.vs.metal -shaders/metal/clear.fs.metal -shaders/metal/clear.vs.metal -shaders/metal/debug_solid.fs.metal -shaders/metal/debug_solid.vs.metal -shaders/metal/debug_texture.fs.metal -shaders/metal/debug_texture.vs.metal -shaders/metal/demo_ground.fs.metal -shaders/metal/demo_ground.vs.metal -shaders/metal/fill.fs.metal -shaders/metal/fill.vs.metal -shaders/metal/reproject.fs.metal -shaders/metal/reproject.vs.metal -shaders/metal/stencil.fs.metal -shaders/metal/stencil.vs.metal -shaders/metal/tile.fs.metal -shaders/metal/tile.vs.metal -shaders/metal/tile_clip.fs.metal -shaders/metal/tile_clip.vs.metal -shaders/metal/tile_copy.fs.metal -shaders/metal/tile_copy.vs.metal -shaders/vulkan/blit.fs.spv -shaders/vulkan/blit.vs.spv -shaders/vulkan/clear.fs.spv -shaders/vulkan/clear.vs.spv -shaders/vulkan/debug_solid.fs.spv -shaders/vulkan/debug_solid.vs.spv -shaders/vulkan/debug_texture.fs.spv -shaders/vulkan/debug_texture.vs.spv -shaders/vulkan/demo_ground.fs.spv -shaders/vulkan/demo_ground.vs.spv -shaders/vulkan/fill.fs.spv -shaders/vulkan/fill.vs.spv -shaders/vulkan/reproject.fs.spv -shaders/vulkan/reproject.vs.spv -shaders/vulkan/stencil.fs.spv -shaders/vulkan/stencil.vs.spv -shaders/vulkan/tile.fs.spv -shaders/vulkan/tile.vs.spv -shaders/vulkan/tile_clip.fs.spv -shaders/vulkan/tile_clip.vs.spv -shaders/vulkan/tile_copy.fs.spv -shaders/vulkan/tile_copy.vs.spv -textures/area-lut.png -textures/debug-corner-fill.png -textures/debug-corner-outline.png -textures/debug-font.png -textures/demo-background.png -textures/demo-effects.png -textures/demo-open.png -textures/demo-rotate.png -textures/demo-screenshot.png -textures/demo-zoom-actual-size.png -textures/demo-zoom-in.png -textures/demo-zoom-out.png -textures/gamma-lut.png diff --git a/crates/pathfinder/resources/build.rs b/crates/pathfinder/resources/build.rs deleted file mode 100644 index 0912c1adce..0000000000 --- a/crates/pathfinder/resources/build.rs +++ /dev/null @@ -1,51 +0,0 @@ -// pathfinder/resources/build.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::env; -use std::fs::File; -use std::io::{BufRead, BufReader, Write}; -use std::path::Path; - -fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); - let dest_path = Path::new(&out_dir).join("manifest.rs"); - let mut dest = File::create(dest_path).unwrap(); - let cwd = env::current_dir().unwrap(); - - writeln!(&mut dest, "// Generated by `pathfinder/resources/build.rs`. Do not edit!\n").unwrap(); - writeln!(&mut dest, - "pub static RESOURCES: &'static [(&'static str, &'static [u8])] = &[").unwrap(); - - let src = BufReader::new(File::open("MANIFEST").unwrap()); - for line in src.lines() { - let line = line.unwrap(); - let line = line.trim_start().trim_end(); - if line.is_empty() || line.starts_with("#") { - continue; - } - - let escaped_path = line.escape_default().to_string(); - let mut full_path = cwd.clone(); - full_path.push(line); - let escaped_full_path = full_path.to_str().unwrap().escape_default().to_string(); - - writeln!(&mut dest, - " (\"{}\", include_bytes!(\"{}\")),", - escaped_path, - escaped_full_path).unwrap(); - - println!("cargo:rerun-if-changed={}", line); - } - - writeln!(&mut dest, "];").unwrap(); - - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=MANIFEST"); -} diff --git a/crates/pathfinder/resources/debug-fonts/regular.json b/crates/pathfinder/resources/debug-fonts/regular.json deleted file mode 100644 index e2da3c18af..0000000000 --- a/crates/pathfinder/resources/debug-fonts/regular.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "name": "D-DIN", - "size": 28, - "bold": false, - "italic": false, - "width": 512, - "height": 128, - "characters": { - "0":{"x":338,"y":0,"width":18,"height":30,"originX":0,"originY":28,"advance":18}, - "1":{"x":30,"y":64,"width":11,"height":29,"originX":0,"originY":28,"advance":12}, - "2":{"x":490,"y":35,"width":17,"height":29,"originX":0,"originY":28,"advance":17}, - "3":{"x":356,"y":0,"width":18,"height":30,"originX":0,"originY":28,"advance":18}, - "4":{"x":398,"y":35,"width":19,"height":29,"originX":0,"originY":28,"advance":19}, - "5":{"x":374,"y":0,"width":18,"height":30,"originX":0,"originY":28,"advance":18}, - "6":{"x":392,"y":0,"width":18,"height":30,"originX":0,"originY":28,"advance":18}, - "7":{"x":436,"y":35,"width":18,"height":29,"originX":1,"originY":28,"advance":16}, - "8":{"x":319,"y":0,"width":19,"height":30,"originX":0,"originY":28,"advance":19}, - "9":{"x":454,"y":35,"width":18,"height":29,"originX":0,"originY":28,"advance":18}, - " ":{"x":147,"y":93,"width":3,"height":3,"originX":1,"originY":1,"advance":8}, - "!":{"x":62,"y":64,"width":7,"height":29,"originX":-1,"originY":28,"advance":9}, - "\"":{"x":52,"y":93,"width":12,"height":12,"originX":0,"originY":28,"advance":11}, - "#":{"x":233,"y":35,"width":21,"height":29,"originX":1,"originY":28,"advance":19}, - "$":{"x":138,"y":0,"width":18,"height":34,"originX":1,"originY":30,"advance":17}, - "%":{"x":156,"y":0,"width":31,"height":30,"originX":0,"originY":28,"advance":31}, - "&":{"x":187,"y":0,"width":22,"height":30,"originX":0,"originY":28,"advance":22}, - "'":{"x":64,"y":93,"width":6,"height":12,"originX":0,"originY":28,"advance":6}, - "(":{"x":59,"y":0,"width":10,"height":35,"originX":0,"originY":30,"advance":11}, - ")":{"x":48,"y":0,"width":11,"height":35,"originX":0,"originY":30,"advance":11}, - "*":{"x":19,"y":93,"width":14,"height":14,"originX":0,"originY":28,"advance":14}, - "+":{"x":432,"y":64,"width":19,"height":19,"originX":0,"originY":20,"advance":19}, - ",":{"x":70,"y":93,"width":6,"height":11,"originX":0,"originY":5,"advance":6}, - "-":{"x":105,"y":93,"width":14,"height":6,"originX":0,"originY":16,"advance":15}, - ".":{"x":119,"y":93,"width":7,"height":6,"originX":0,"originY":5,"advance":7}, - "/":{"x":446,"y":0,"width":14,"height":30,"originX":0,"originY":28,"advance":15}, - ":":{"x":470,"y":64,"width":7,"height":19,"originX":0,"originY":18,"advance":7}, - ";":{"x":171,"y":64,"width":7,"height":24,"originX":0,"originY":18,"advance":7}, - "<":{"x":477,"y":64,"width":19,"height":17,"originX":0,"originY":19,"advance":19}, - "=":{"x":33,"y":93,"width":19,"height":13,"originX":0,"originY":17,"advance":19}, - ">":{"x":0,"y":93,"width":19,"height":17,"originX":0,"originY":19,"advance":19}, - "?":{"x":0,"y":64,"width":17,"height":29,"originX":1,"originY":28,"advance":16}, - "@":{"x":106,"y":0,"width":32,"height":34,"originX":0,"originY":28,"advance":32}, - "A":{"x":26,"y":35,"width":25,"height":29,"originX":2,"originY":28,"advance":22}, - "B":{"x":254,"y":35,"width":21,"height":29,"originX":-1,"originY":28,"advance":23}, - "C":{"x":209,"y":0,"width":22,"height":30,"originX":0,"originY":28,"advance":23}, - "D":{"x":145,"y":35,"width":22,"height":29,"originX":-1,"originY":28,"advance":23}, - "E":{"x":338,"y":35,"width":20,"height":29,"originX":-1,"originY":28,"advance":20}, - "F":{"x":358,"y":35,"width":20,"height":29,"originX":-1,"originY":28,"advance":20}, - "G":{"x":231,"y":0,"width":22,"height":30,"originX":0,"originY":28,"advance":23}, - "H":{"x":275,"y":35,"width":21,"height":29,"originX":-1,"originY":28,"advance":23}, - "I":{"x":69,"y":64,"width":7,"height":29,"originX":-1,"originY":28,"advance":9}, - "J":{"x":41,"y":64,"width":11,"height":29,"originX":1,"originY":28,"advance":12}, - "K":{"x":76,"y":35,"width":23,"height":29,"originX":-1,"originY":28,"advance":22}, - "L":{"x":378,"y":35,"width":20,"height":29,"originX":-1,"originY":28,"advance":20}, - "M":{"x":0,"y":35,"width":26,"height":29,"originX":-1,"originY":28,"advance":28}, - "N":{"x":99,"y":35,"width":23,"height":29,"originX":-1,"originY":28,"advance":25}, - "O":{"x":253,"y":0,"width":22,"height":30,"originX":0,"originY":28,"advance":23}, - "P":{"x":296,"y":35,"width":21,"height":29,"originX":-1,"originY":28,"advance":22}, - "Q":{"x":0,"y":0,"width":22,"height":35,"originX":0,"originY":28,"advance":23}, - "R":{"x":167,"y":35,"width":22,"height":29,"originX":-1,"originY":28,"advance":22}, - "S":{"x":275,"y":0,"width":22,"height":30,"originX":1,"originY":28,"advance":20}, - "T":{"x":189,"y":35,"width":22,"height":29,"originX":2,"originY":28,"advance":18}, - "U":{"x":297,"y":0,"width":22,"height":30,"originX":-1,"originY":28,"advance":24}, - "V":{"x":122,"y":35,"width":23,"height":29,"originX":2,"originY":28,"advance":19}, - "W":{"x":474,"y":0,"width":33,"height":29,"originX":2,"originY":28,"advance":30}, - "X":{"x":51,"y":35,"width":25,"height":29,"originX":2,"originY":28,"advance":21}, - "Y":{"x":211,"y":35,"width":22,"height":29,"originX":2,"originY":28,"advance":19}, - "Z":{"x":317,"y":35,"width":21,"height":29,"originX":1,"originY":28,"advance":19}, - "[":{"x":69,"y":0,"width":10,"height":35,"originX":-1,"originY":30,"advance":11}, - "\\":{"x":460,"y":0,"width":14,"height":30,"originX":0,"originY":28,"advance":15}, - "]":{"x":79,"y":0,"width":10,"height":35,"originX":0,"originY":30,"advance":11}, - "^":{"x":451,"y":64,"width":19,"height":19,"originX":0,"originY":28,"advance":19}, - "_":{"x":126,"y":93,"width":21,"height":5,"originX":2,"originY":0,"advance":17}, - "`":{"x":95,"y":93,"width":10,"height":8,"originX":-4,"originY":28,"advance":19}, - "a":{"x":235,"y":64,"width":18,"height":23,"originX":0,"originY":21,"advance":19}, - "b":{"x":410,"y":0,"width":18,"height":30,"originX":-1,"originY":28,"advance":19}, - "c":{"x":178,"y":64,"width":19,"height":23,"originX":0,"originY":21,"advance":19}, - "d":{"x":428,"y":0,"width":18,"height":30,"originX":0,"originY":28,"advance":19}, - "e":{"x":197,"y":64,"width":19,"height":23,"originX":0,"originY":21,"advance":19}, - "f":{"x":17,"y":64,"width":13,"height":29,"originX":0,"originY":28,"advance":12}, - "g":{"x":96,"y":64,"width":18,"height":28,"originX":0,"originY":21,"advance":19}, - "h":{"x":472,"y":35,"width":18,"height":29,"originX":-1,"originY":28,"advance":19}, - "i":{"x":150,"y":64,"width":7,"height":28,"originX":-1,"originY":27,"advance":9}, - "j":{"x":89,"y":0,"width":10,"height":35,"originX":3,"originY":28,"advance":8}, - "k":{"x":417,"y":35,"width":19,"height":29,"originX":-1,"originY":28,"advance":18}, - "l":{"x":52,"y":64,"width":10,"height":29,"originX":-1,"originY":28,"advance":10}, - "m":{"x":289,"y":64,"width":29,"height":22,"originX":-1,"originY":21,"advance":31}, - "n":{"x":366,"y":64,"width":18,"height":22,"originX":-1,"originY":21,"advance":19}, - "o":{"x":216,"y":64,"width":19,"height":23,"originX":0,"originY":21,"advance":19}, - "p":{"x":114,"y":64,"width":18,"height":28,"originX":-1,"originY":21,"advance":19}, - "q":{"x":132,"y":64,"width":18,"height":28,"originX":0,"originY":21,"advance":19}, - "r":{"x":419,"y":64,"width":13,"height":22,"originX":-1,"originY":21,"advance":13}, - "s":{"x":253,"y":64,"width":18,"height":23,"originX":0,"originY":21,"advance":17}, - "t":{"x":157,"y":64,"width":14,"height":27,"originX":1,"originY":26,"advance":13}, - "u":{"x":271,"y":64,"width":18,"height":23,"originX":-1,"originY":21,"advance":19}, - "v":{"x":347,"y":64,"width":19,"height":22,"originX":1,"originY":21,"advance":16}, - "w":{"x":318,"y":64,"width":29,"height":22,"originX":1,"originY":21,"advance":27}, - "x":{"x":384,"y":64,"width":18,"height":22,"originX":1,"originY":21,"advance":16}, - "y":{"x":76,"y":64,"width":20,"height":28,"originX":2,"originY":21,"advance":16}, - "z":{"x":402,"y":64,"width":17,"height":22,"originX":0,"originY":21,"advance":17}, - "{":{"x":22,"y":0,"width":13,"height":35,"originX":0,"originY":30,"advance":13}, - "|":{"x":99,"y":0,"width":7,"height":35,"originX":-2,"originY":30,"advance":11}, - "}":{"x":35,"y":0,"width":13,"height":35,"originX":0,"originY":30,"advance":13}, - "~":{"x":76,"y":93,"width":19,"height":9,"originX":0,"originY":15,"advance":19} - } -} diff --git a/crates/pathfinder/resources/fonts/LICENSE-APACHE b/crates/pathfinder/resources/fonts/LICENSE-APACHE deleted file mode 100644 index 75b52484ea..0000000000 --- a/crates/pathfinder/resources/fonts/LICENSE-APACHE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/crates/pathfinder/resources/fonts/LICENSE-SIL b/crates/pathfinder/resources/fonts/LICENSE-SIL deleted file mode 100644 index ec2cdcae2a..0000000000 --- a/crates/pathfinder/resources/fonts/LICENSE-SIL +++ /dev/null @@ -1,49 +0,0 @@ -Copyright 2011 Red Hat, Inc., -with Reserved Font Name OVERPASS. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. - -The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the copyright statement(s). - -"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. - -"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. - -5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/crates/pathfinder/resources/fonts/NotoEmoji-Regular.ttf b/crates/pathfinder/resources/fonts/NotoEmoji-Regular.ttf deleted file mode 100644 index 19b7badf4a..0000000000 Binary files a/crates/pathfinder/resources/fonts/NotoEmoji-Regular.ttf and /dev/null differ diff --git a/crates/pathfinder/resources/fonts/Overpass-Regular.otf b/crates/pathfinder/resources/fonts/Overpass-Regular.otf deleted file mode 100644 index c9531c0e49..0000000000 Binary files a/crates/pathfinder/resources/fonts/Overpass-Regular.otf and /dev/null differ diff --git a/crates/pathfinder/resources/fonts/Roboto-Bold.ttf b/crates/pathfinder/resources/fonts/Roboto-Bold.ttf deleted file mode 100644 index d998cf5b46..0000000000 Binary files a/crates/pathfinder/resources/fonts/Roboto-Bold.ttf and /dev/null differ diff --git a/crates/pathfinder/resources/fonts/Roboto-Regular.ttf b/crates/pathfinder/resources/fonts/Roboto-Regular.ttf deleted file mode 100644 index 2b6392ffe8..0000000000 Binary files a/crates/pathfinder/resources/fonts/Roboto-Regular.ttf and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/README.md b/crates/pathfinder/resources/shaders/README.md deleted file mode 100644 index 24bff80f7d..0000000000 --- a/crates/pathfinder/resources/shaders/README.md +++ /dev/null @@ -1,7 +0,0 @@ -This directory contains postprocessed versions of the shaders in the top-level -`shaders/` directory, for convenience. Don't modify the shaders here; instead -modify the corresponding shaders in `shaders/` and rerun `make` in that -directory. - -You will need `glslangValidator` and `spirv-cross` installed to execute the -Makefile. On macOS, you can get these with `brew install glslang spirv-cross`. diff --git a/crates/pathfinder/resources/shaders/gl3/blit.fs.glsl b/crates/pathfinder/resources/shaders/gl3/blit.fs.glsl deleted file mode 100644 index 806d714951..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/blit.fs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform sampler2D SPIRV_Cross_CombineduSrcuSampler; - -in vec2 vTexCoord; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - vec4 color = texture(SPIRV_Cross_CombineduSrcuSampler, vTexCoord); - oFragColor = vec4(color.xyz * color.w, color.w); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/blit.vs.glsl b/crates/pathfinder/resources/shaders/gl3/blit.vs.glsl deleted file mode 100644 index 7efaa8cdc4..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/blit.vs.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(location = 0) in ivec2 aPosition; -out vec2 vTexCoord; - -void main() -{ - vec2 texCoord = vec2(aPosition); - vTexCoord = texCoord; - gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), vec2(aPosition)), 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/clear.fs.glsl b/crates/pathfinder/resources/shaders/gl3/clear.fs.glsl deleted file mode 100644 index bfc45445dc..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/clear.fs.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uColor[1]; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - oFragColor = vec4(uColor[0].xyz, 1.0) * uColor[0].w; -} - diff --git a/crates/pathfinder/resources/shaders/gl3/clear.vs.glsl b/crates/pathfinder/resources/shaders/gl3/clear.vs.glsl deleted file mode 100644 index 76b85239b9..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/clear.vs.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uRect[1]; -uniform vec4 uFramebufferSize[1]; -layout(location = 0) in ivec2 aPosition; - -void main() -{ - vec2 position = ((mix(uRect[0].xy, uRect[0].zw, vec2(aPosition)) / uFramebufferSize[0].xy) * 2.0) - vec2(1.0); - gl_Position = vec4(position.x, -position.y, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/debug_solid.fs.glsl b/crates/pathfinder/resources/shaders/gl3/debug_solid.fs.glsl deleted file mode 100644 index bfc45445dc..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/debug_solid.fs.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uColor[1]; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - oFragColor = vec4(uColor[0].xyz, 1.0) * uColor[0].w; -} - diff --git a/crates/pathfinder/resources/shaders/gl3/debug_solid.vs.glsl b/crates/pathfinder/resources/shaders/gl3/debug_solid.vs.glsl deleted file mode 100644 index 705fbc5efb..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/debug_solid.vs.glsl +++ /dev/null @@ -1,13 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uFramebufferSize[1]; -layout(location = 0) in ivec2 aPosition; - -void main() -{ - vec2 position = ((vec2(aPosition) / uFramebufferSize[0].xy) * 2.0) - vec2(1.0); - gl_Position = vec4(position.x, -position.y, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/debug_texture.fs.glsl b/crates/pathfinder/resources/shaders/gl3/debug_texture.fs.glsl deleted file mode 100644 index 7a23aec868..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/debug_texture.fs.glsl +++ /dev/null @@ -1,16 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uColor[1]; -uniform sampler2D SPIRV_Cross_CombineduTextureuSampler; - -in vec2 vTexCoord; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - float alpha = texture(SPIRV_Cross_CombineduTextureuSampler, vTexCoord).x * uColor[0].w; - oFragColor = vec4(uColor[0].xyz, 1.0) * alpha; -} - diff --git a/crates/pathfinder/resources/shaders/gl3/debug_texture.vs.glsl b/crates/pathfinder/resources/shaders/gl3/debug_texture.vs.glsl deleted file mode 100644 index e8965d26f7..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/debug_texture.vs.glsl +++ /dev/null @@ -1,17 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uTextureSize[1]; -uniform vec4 uFramebufferSize[1]; -out vec2 vTexCoord; -layout(location = 1) in ivec2 aTexCoord; -layout(location = 0) in ivec2 aPosition; - -void main() -{ - vTexCoord = vec2(aTexCoord) / uTextureSize[0].xy; - vec2 position = ((vec2(aPosition) / uFramebufferSize[0].xy) * 2.0) - vec2(1.0); - gl_Position = vec4(position.x, -position.y, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/demo_ground.fs.glsl b/crates/pathfinder/resources/shaders/gl3/demo_ground.fs.glsl deleted file mode 100644 index f33c5b98b1..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/demo_ground.fs.glsl +++ /dev/null @@ -1,24 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uGridlineColor[1]; -uniform vec4 uGroundColor[1]; -in vec2 vTexCoord; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - vec2 texCoordPx = fract(vTexCoord) / fwidth(vTexCoord); - vec4 _28; - if (any(lessThanEqual(texCoordPx, vec2(1.0)))) - { - _28 = uGridlineColor[0]; - } - else - { - _28 = uGroundColor[0]; - } - oFragColor = _28; -} - diff --git a/crates/pathfinder/resources/shaders/gl3/demo_ground.vs.glsl b/crates/pathfinder/resources/shaders/gl3/demo_ground.vs.glsl deleted file mode 100644 index c87472beac..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/demo_ground.vs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform ivec4 uGridlineCount[1]; -uniform vec4 uTransform[4]; -out vec2 vTexCoord; -layout(location = 0) in ivec2 aPosition; - -void main() -{ - vTexCoord = vec2(aPosition * ivec2(uGridlineCount[0].x)); - gl_Position = mat4(uTransform[0], uTransform[1], uTransform[2], uTransform[3]) * vec4(ivec4(aPosition.x, 0, aPosition.y, 1)); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/fill.fs.glsl b/crates/pathfinder/resources/shaders/gl3/fill.fs.glsl deleted file mode 100644 index b7c0dee338..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/fill.fs.glsl +++ /dev/null @@ -1,32 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform sampler2D SPIRV_Cross_CombineduAreaLUTuSampler; - -layout(location = 0) out vec4 oFragColor; -in vec2 vFrom; -in vec2 vTo; - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D SPIRV_Cross_CombinedareaLUTareaLUTSampler) -{ - bvec2 _34 = bvec2(from.x < to.x); - vec2 left = vec2(_34.x ? from.x : to.x, _34.y ? from.y : to.y); - bvec2 _44 = bvec2(from.x < to.x); - vec2 right = vec2(_44.x ? to.x : from.x, _44.y ? to.y : from.y); - vec2 window = clamp(vec2(from.x, to.x), vec2(-0.5), vec2(0.5)); - float offset = mix(window.x, window.y, 0.5) - left.x; - float t = offset / (right.x - left.x); - float y = mix(left.y, right.y, t); - float d = (right.y - left.y) / (right.x - left.x); - float dX = window.x - window.y; - return texture(SPIRV_Cross_CombinedareaLUTareaLUTSampler, vec2(y + 8.0, abs(d * dX)) / vec2(16.0)) * dX; -} - -void main() -{ - vec2 param = vFrom; - vec2 param_1 = vTo; - oFragColor = computeCoverage(param, param_1, SPIRV_Cross_CombineduAreaLUTuSampler); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/fill.vs.glsl b/crates/pathfinder/resources/shaders/gl3/fill.vs.glsl deleted file mode 100644 index a112aeca2f..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/fill.vs.glsl +++ /dev/null @@ -1,54 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uTileSize[1]; -uniform vec4 uFramebufferSize[1]; -layout(location = 5) in uint aTileIndex; -layout(location = 3) in uint aFromPx; -layout(location = 1) in vec2 aFromSubpx; -layout(location = 4) in uint aToPx; -layout(location = 2) in vec2 aToSubpx; -layout(location = 0) in uvec2 aTessCoord; -out vec2 vFrom; -out vec2 vTo; - -vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) -{ - uint tilesPerRow = uint(stencilTextureWidth / uTileSize[0].x); - uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return (vec2(tileOffset) * uTileSize[0].xy) * vec2(1.0, 0.25); -} - -void main() -{ - uint param = aTileIndex; - float param_1 = uFramebufferSize[0].x; - vec2 tileOrigin = computeTileOffset(param, param_1); - vec2 from = vec2(float(aFromPx & 15u), float(aFromPx >> 4u)) + aFromSubpx; - vec2 to = vec2(float(aToPx & 15u), float(aToPx >> 4u)) + aToSubpx; - vec2 position; - if (aTessCoord.x == 0u) - { - position.x = floor(min(from.x, to.x)); - } - else - { - position.x = ceil(max(from.x, to.x)); - } - if (aTessCoord.y == 0u) - { - position.y = floor(min(from.y, to.y)); - } - else - { - position.y = uTileSize[0].y; - } - position.y = floor(position.y * 0.25); - vec2 offset = vec2(0.0, 1.5) - (position * vec2(1.0, 4.0)); - vFrom = from + offset; - vTo = to + offset; - vec2 globalPosition = (((tileOrigin + position) / uFramebufferSize[0].xy) * 2.0) - vec2(1.0); - gl_Position = vec4(globalPosition, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/reproject.fs.glsl b/crates/pathfinder/resources/shaders/gl3/reproject.fs.glsl deleted file mode 100644 index 5803ed2bc8..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/reproject.fs.glsl +++ /dev/null @@ -1,17 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uOldTransform[4]; -uniform sampler2D SPIRV_Cross_CombineduTextureuSampler; - -in vec2 vTexCoord; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - vec4 normTexCoord = mat4(uOldTransform[0], uOldTransform[1], uOldTransform[2], uOldTransform[3]) * vec4(vTexCoord, 0.0, 1.0); - vec2 texCoord = ((normTexCoord.xy / vec2(normTexCoord.w)) + vec2(1.0)) * 0.5; - oFragColor = texture(SPIRV_Cross_CombineduTextureuSampler, texCoord); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/reproject.vs.glsl b/crates/pathfinder/resources/shaders/gl3/reproject.vs.glsl deleted file mode 100644 index 8cb538d474..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/reproject.vs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uNewTransform[4]; -layout(location = 0) in ivec2 aPosition; -out vec2 vTexCoord; - -void main() -{ - vec2 position = vec2(aPosition); - vTexCoord = position; - gl_Position = mat4(uNewTransform[0], uNewTransform[1], uNewTransform[2], uNewTransform[3]) * vec4(position, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/stencil.fs.glsl b/crates/pathfinder/resources/shaders/gl3/stencil.fs.glsl deleted file mode 100644 index c9a19890dc..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/stencil.fs.glsl +++ /dev/null @@ -1,11 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(location = 0) out vec4 oFragColor; - -void main() -{ - oFragColor = vec4(1.0, 0.0, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/stencil.vs.glsl b/crates/pathfinder/resources/shaders/gl3/stencil.vs.glsl deleted file mode 100644 index f56fba14ef..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/stencil.vs.glsl +++ /dev/null @@ -1,11 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(location = 0) in vec3 aPosition; - -void main() -{ - gl_Position = vec4(aPosition, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/tile.fs.glsl b/crates/pathfinder/resources/shaders/gl3/tile.fs.glsl deleted file mode 100644 index ad5011885f..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/tile.fs.glsl +++ /dev/null @@ -1,571 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uMaskTextureSize0[1]; -uniform vec4 uColorTextureSize0[1]; -uniform vec4 uFramebufferSize[1]; -uniform vec4 uFilterParams0[1]; -uniform vec4 uFilterParams1[1]; -uniform vec4 uFilterParams2[1]; -uniform ivec4 uCtrl[1]; -uniform sampler2D SPIRV_Cross_CombineduMaskTexture0uSampler; -uniform sampler2D SPIRV_Cross_CombineduColorTexture0uSampler; -uniform sampler2D SPIRV_Cross_CombineduGammaLUTuSampler; -uniform sampler2D SPIRV_Cross_CombineduDestTextureuSampler; - -in vec3 vMaskTexCoord0; -in vec4 vBaseColor; -in vec2 vColorTexCoord0; -layout(location = 0) out vec4 oFragColor; -in float vTileCtrl; - -float sampleMask(float maskAlpha, vec2 maskTextureSize, vec3 maskTexCoord, int maskCtrl, sampler2D SPIRV_Cross_CombinedmaskTextureuSampler) -{ - if (maskCtrl == 0) - { - return maskAlpha; - } - ivec2 maskTexCoordI = ivec2(floor(maskTexCoord.xy)); - vec4 texel = texture(SPIRV_Cross_CombinedmaskTextureuSampler, (vec2(maskTexCoordI / ivec2(1, 4)) + vec2(0.5)) / maskTextureSize); - float coverage = texel[maskTexCoordI.y % 4] + maskTexCoord.z; - if ((maskCtrl & 1) != 0) - { - coverage = abs(coverage); - } - else - { - coverage = 1.0 - abs(1.0 - mod(coverage, 2.0)); - } - return min(maskAlpha, coverage); -} - -vec4 filterRadialGradient(vec2 colorTexCoord, vec2 colorTextureSize, vec2 fragCoord, vec2 framebufferSize, vec4 filterParams0, vec4 filterParams1, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - vec2 lineFrom = filterParams0.xy; - vec2 lineVector = filterParams0.zw; - vec2 radii = filterParams1.xy; - vec2 uvOrigin = filterParams1.zw; - vec2 dP = colorTexCoord - lineFrom; - vec2 dC = lineVector; - float dR = radii.y - radii.x; - float a = dot(dC, dC) - (dR * dR); - float b = dot(dP, dC) + (radii.x * dR); - float c = dot(dP, dP) - (radii.x * radii.x); - float discrim = (b * b) - (a * c); - vec4 color = vec4(0.0); - if (abs(discrim) >= 9.9999997473787516355514526367188e-06) - { - vec2 ts = vec2((vec2(1.0, -1.0) * sqrt(discrim)) + vec2(b)) / vec2(a); - if (ts.x > ts.y) - { - ts = ts.yx; - } - float _566; - if (ts.x >= 0.0) - { - _566 = ts.x; - } - else - { - _566 = ts.y; - } - float t = _566; - color = texture(SPIRV_Cross_CombinedcolorTextureuSampler, uvOrigin + vec2(clamp(t, 0.0, 1.0), 0.0)); - } - return color; -} - -vec4 filterBlur(vec2 colorTexCoord, vec2 colorTextureSize, vec4 filterParams0, vec4 filterParams1, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - vec2 srcOffsetScale = filterParams0.xy / colorTextureSize; - int support = int(filterParams0.z); - vec3 gaussCoeff = filterParams1.xyz; - float gaussSum = gaussCoeff.x; - vec4 color = texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord) * gaussCoeff.x; - vec2 _615 = gaussCoeff.xy * gaussCoeff.yz; - gaussCoeff = vec3(_615.x, _615.y, gaussCoeff.z); - for (int i = 1; i <= support; i += 2) - { - float gaussPartialSum = gaussCoeff.x; - vec2 _635 = gaussCoeff.xy * gaussCoeff.yz; - gaussCoeff = vec3(_635.x, _635.y, gaussCoeff.z); - gaussPartialSum += gaussCoeff.x; - vec2 srcOffset = srcOffsetScale * (float(i) + (gaussCoeff.x / gaussPartialSum)); - color += ((texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord - srcOffset) + texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord + srcOffset)) * gaussPartialSum); - gaussSum += (2.0 * gaussPartialSum); - vec2 _679 = gaussCoeff.xy * gaussCoeff.yz; - gaussCoeff = vec3(_679.x, _679.y, gaussCoeff.z); - } - return color / vec4(gaussSum); -} - -float filterTextSample1Tap(float offset, vec2 colorTexCoord, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - return texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord + vec2(offset, 0.0)).x; -} - -void filterTextSample9Tap(out vec4 outAlphaLeft, out float outAlphaCenter, out vec4 outAlphaRight, vec2 colorTexCoord, vec4 kernel, float onePixel, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - bool wide = kernel.x > 0.0; - float _243; - if (wide) - { - float param = (-4.0) * onePixel; - vec2 param_1 = colorTexCoord; - _243 = filterTextSample1Tap(param, param_1, SPIRV_Cross_CombinedcolorTextureuSampler); - } - else - { - _243 = 0.0; - } - float param_2 = (-3.0) * onePixel; - vec2 param_3 = colorTexCoord; - float param_4 = (-2.0) * onePixel; - vec2 param_5 = colorTexCoord; - float param_6 = (-1.0) * onePixel; - vec2 param_7 = colorTexCoord; - outAlphaLeft = vec4(_243, filterTextSample1Tap(param_2, param_3, SPIRV_Cross_CombinedcolorTextureuSampler), filterTextSample1Tap(param_4, param_5, SPIRV_Cross_CombinedcolorTextureuSampler), filterTextSample1Tap(param_6, param_7, SPIRV_Cross_CombinedcolorTextureuSampler)); - float param_8 = 0.0; - vec2 param_9 = colorTexCoord; - outAlphaCenter = filterTextSample1Tap(param_8, param_9, SPIRV_Cross_CombinedcolorTextureuSampler); - float param_10 = 1.0 * onePixel; - vec2 param_11 = colorTexCoord; - float param_12 = 2.0 * onePixel; - vec2 param_13 = colorTexCoord; - float param_14 = 3.0 * onePixel; - vec2 param_15 = colorTexCoord; - float _303; - if (wide) - { - float param_16 = 4.0 * onePixel; - vec2 param_17 = colorTexCoord; - _303 = filterTextSample1Tap(param_16, param_17, SPIRV_Cross_CombinedcolorTextureuSampler); - } - else - { - _303 = 0.0; - } - outAlphaRight = vec4(filterTextSample1Tap(param_10, param_11, SPIRV_Cross_CombinedcolorTextureuSampler), filterTextSample1Tap(param_12, param_13, SPIRV_Cross_CombinedcolorTextureuSampler), filterTextSample1Tap(param_14, param_15, SPIRV_Cross_CombinedcolorTextureuSampler), _303); -} - -float filterTextConvolve7Tap(vec4 alpha0, vec3 alpha1, vec4 kernel) -{ - return dot(alpha0, kernel) + dot(alpha1, kernel.zyx); -} - -float filterTextGammaCorrectChannel(float bgColor, float fgColor, sampler2D SPIRV_Cross_CombinedgammaLUTuSampler) -{ - return texture(SPIRV_Cross_CombinedgammaLUTuSampler, vec2(fgColor, 1.0 - bgColor)).x; -} - -vec3 filterTextGammaCorrect(vec3 bgColor, vec3 fgColor, sampler2D SPIRV_Cross_CombinedgammaLUTuSampler) -{ - float param = bgColor.x; - float param_1 = fgColor.x; - float param_2 = bgColor.y; - float param_3 = fgColor.y; - float param_4 = bgColor.z; - float param_5 = fgColor.z; - return vec3(filterTextGammaCorrectChannel(param, param_1, SPIRV_Cross_CombinedgammaLUTuSampler), filterTextGammaCorrectChannel(param_2, param_3, SPIRV_Cross_CombinedgammaLUTuSampler), filterTextGammaCorrectChannel(param_4, param_5, SPIRV_Cross_CombinedgammaLUTuSampler)); -} - -vec4 filterText(vec2 colorTexCoord, vec2 colorTextureSize, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler, sampler2D SPIRV_Cross_CombinedgammaLUTuSampler) -{ - vec4 kernel = filterParams0; - vec3 bgColor = filterParams1.xyz; - vec3 fgColor = filterParams2.xyz; - bool gammaCorrectionEnabled = filterParams2.w != 0.0; - vec3 alpha; - if (kernel.w == 0.0) - { - alpha = texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord).xxx; - } - else - { - vec2 param_3 = colorTexCoord; - vec4 param_4 = kernel; - float param_5 = 1.0 / colorTextureSize.x; - vec4 param; - float param_1; - vec4 param_2; - filterTextSample9Tap(param, param_1, param_2, param_3, param_4, param_5, SPIRV_Cross_CombinedcolorTextureuSampler); - vec4 alphaLeft = param; - float alphaCenter = param_1; - vec4 alphaRight = param_2; - vec4 param_6 = alphaLeft; - vec3 param_7 = vec3(alphaCenter, alphaRight.xy); - vec4 param_8 = kernel; - float r = filterTextConvolve7Tap(param_6, param_7, param_8); - vec4 param_9 = vec4(alphaLeft.yzw, alphaCenter); - vec3 param_10 = alphaRight.xyz; - vec4 param_11 = kernel; - float g = filterTextConvolve7Tap(param_9, param_10, param_11); - vec4 param_12 = vec4(alphaLeft.zw, alphaCenter, alphaRight.x); - vec3 param_13 = alphaRight.yzw; - vec4 param_14 = kernel; - float b = filterTextConvolve7Tap(param_12, param_13, param_14); - alpha = vec3(r, g, b); - } - if (gammaCorrectionEnabled) - { - vec3 param_15 = bgColor; - vec3 param_16 = alpha; - alpha = filterTextGammaCorrect(param_15, param_16, SPIRV_Cross_CombinedgammaLUTuSampler); - } - return vec4(mix(bgColor, fgColor, alpha), 1.0); -} - -vec4 sampleColor(vec2 colorTexCoord, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - return texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord); -} - -vec4 filterNone(vec2 colorTexCoord, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - vec2 param = colorTexCoord; - return sampleColor(param, SPIRV_Cross_CombinedcolorTextureuSampler); -} - -vec4 filterColor(vec2 colorTexCoord, vec2 colorTextureSize, vec2 fragCoord, vec2 framebufferSize, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, int colorFilter, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler, sampler2D SPIRV_Cross_CombinedgammaLUTuSampler) -{ - switch (colorFilter) - { - case 1: - { - vec2 param = colorTexCoord; - vec2 param_1 = colorTextureSize; - vec2 param_2 = fragCoord; - vec2 param_3 = framebufferSize; - vec4 param_4 = filterParams0; - vec4 param_5 = filterParams1; - return filterRadialGradient(param, param_1, param_2, param_3, param_4, param_5, SPIRV_Cross_CombinedcolorTextureuSampler); - } - case 3: - { - vec2 param_6 = colorTexCoord; - vec2 param_7 = colorTextureSize; - vec4 param_8 = filterParams0; - vec4 param_9 = filterParams1; - return filterBlur(param_6, param_7, param_8, param_9, SPIRV_Cross_CombinedcolorTextureuSampler); - } - case 2: - { - vec2 param_10 = colorTexCoord; - vec2 param_11 = colorTextureSize; - vec4 param_12 = filterParams0; - vec4 param_13 = filterParams1; - vec4 param_14 = filterParams2; - return filterText(param_10, param_11, param_12, param_13, param_14, SPIRV_Cross_CombinedcolorTextureuSampler, SPIRV_Cross_CombinedgammaLUTuSampler); - } - } - vec2 param_15 = colorTexCoord; - return filterNone(param_15, SPIRV_Cross_CombinedcolorTextureuSampler); -} - -vec4 combineColor0(vec4 destColor, vec4 srcColor, int op) -{ - switch (op) - { - case 1: - { - return vec4(srcColor.xyz, srcColor.w * destColor.w); - } - case 2: - { - return vec4(destColor.xyz, srcColor.w * destColor.w); - } - } - return destColor; -} - -vec3 compositeScreen(vec3 destColor, vec3 srcColor) -{ - return (destColor + srcColor) - (destColor * srcColor); -} - -vec3 compositeSelect(bvec3 cond, vec3 ifTrue, vec3 ifFalse) -{ - float _745; - if (cond.x) - { - _745 = ifTrue.x; - } - else - { - _745 = ifFalse.x; - } - float _756; - if (cond.y) - { - _756 = ifTrue.y; - } - else - { - _756 = ifFalse.y; - } - float _767; - if (cond.z) - { - _767 = ifTrue.z; - } - else - { - _767 = ifFalse.z; - } - return vec3(_745, _756, _767); -} - -vec3 compositeHardLight(vec3 destColor, vec3 srcColor) -{ - vec3 param = destColor; - vec3 param_1 = (vec3(2.0) * srcColor) - vec3(1.0); - bvec3 param_2 = lessThanEqual(srcColor, vec3(0.5)); - vec3 param_3 = (destColor * vec3(2.0)) * srcColor; - vec3 param_4 = compositeScreen(param, param_1); - return compositeSelect(param_2, param_3, param_4); -} - -vec3 compositeColorDodge(vec3 destColor, vec3 srcColor) -{ - bvec3 destZero = equal(destColor, vec3(0.0)); - bvec3 srcOne = equal(srcColor, vec3(1.0)); - bvec3 param = srcOne; - vec3 param_1 = vec3(1.0); - vec3 param_2 = destColor / (vec3(1.0) - srcColor); - bvec3 param_3 = destZero; - vec3 param_4 = vec3(0.0); - vec3 param_5 = compositeSelect(param, param_1, param_2); - return compositeSelect(param_3, param_4, param_5); -} - -vec3 compositeSoftLight(vec3 destColor, vec3 srcColor) -{ - bvec3 param = lessThanEqual(destColor, vec3(0.25)); - vec3 param_1 = ((((vec3(16.0) * destColor) - vec3(12.0)) * destColor) + vec3(4.0)) * destColor; - vec3 param_2 = sqrt(destColor); - vec3 darkenedDestColor = compositeSelect(param, param_1, param_2); - bvec3 param_3 = lessThanEqual(srcColor, vec3(0.5)); - vec3 param_4 = destColor * (vec3(1.0) - destColor); - vec3 param_5 = darkenedDestColor - destColor; - vec3 factor = compositeSelect(param_3, param_4, param_5); - return destColor + (((srcColor * 2.0) - vec3(1.0)) * factor); -} - -float compositeDivide(float num, float denom) -{ - float _781; - if (denom != 0.0) - { - _781 = num / denom; - } - else - { - _781 = 0.0; - } - return _781; -} - -vec3 compositeRGBToHSL(vec3 rgb) -{ - float v = max(max(rgb.x, rgb.y), rgb.z); - float xMin = min(min(rgb.x, rgb.y), rgb.z); - float c = v - xMin; - float l = mix(xMin, v, 0.5); - vec3 _887; - if (rgb.x == v) - { - _887 = vec3(0.0, rgb.yz); - } - else - { - vec3 _900; - if (rgb.y == v) - { - _900 = vec3(2.0, rgb.zx); - } - else - { - _900 = vec3(4.0, rgb.xy); - } - _887 = _900; - } - vec3 terms = _887; - float param = ((terms.x * c) + terms.y) - terms.z; - float param_1 = c; - float h = 1.0471975803375244140625 * compositeDivide(param, param_1); - float param_2 = c; - float param_3 = v; - float s = compositeDivide(param_2, param_3); - return vec3(h, s, l); -} - -vec3 compositeHSL(vec3 destColor, vec3 srcColor, int op) -{ - switch (op) - { - case 12: - { - return vec3(srcColor.x, destColor.y, destColor.z); - } - case 13: - { - return vec3(destColor.x, srcColor.y, destColor.z); - } - case 14: - { - return vec3(srcColor.x, srcColor.y, destColor.z); - } - default: - { - return vec3(destColor.x, destColor.y, srcColor.z); - } - } -} - -vec3 compositeHSLToRGB(vec3 hsl) -{ - float a = hsl.y * min(hsl.z, 1.0 - hsl.z); - vec3 ks = mod(vec3(0.0, 8.0, 4.0) + vec3(hsl.x * 1.90985929965972900390625), vec3(12.0)); - return hsl.zzz - (clamp(min(ks - vec3(3.0), vec3(9.0) - ks), vec3(-1.0), vec3(1.0)) * a); -} - -vec3 compositeRGB(vec3 destColor, vec3 srcColor, int op) -{ - switch (op) - { - case 1: - { - return destColor * srcColor; - } - case 2: - { - vec3 param = destColor; - vec3 param_1 = srcColor; - return compositeScreen(param, param_1); - } - case 3: - { - vec3 param_2 = srcColor; - vec3 param_3 = destColor; - return compositeHardLight(param_2, param_3); - } - case 4: - { - return min(destColor, srcColor); - } - case 5: - { - return max(destColor, srcColor); - } - case 6: - { - vec3 param_4 = destColor; - vec3 param_5 = srcColor; - return compositeColorDodge(param_4, param_5); - } - case 7: - { - vec3 param_6 = vec3(1.0) - destColor; - vec3 param_7 = vec3(1.0) - srcColor; - return vec3(1.0) - compositeColorDodge(param_6, param_7); - } - case 8: - { - vec3 param_8 = destColor; - vec3 param_9 = srcColor; - return compositeHardLight(param_8, param_9); - } - case 9: - { - vec3 param_10 = destColor; - vec3 param_11 = srcColor; - return compositeSoftLight(param_10, param_11); - } - case 10: - { - return abs(destColor - srcColor); - } - case 11: - { - return (destColor + srcColor) - ((vec3(2.0) * destColor) * srcColor); - } - case 12: - case 13: - case 14: - case 15: - { - vec3 param_12 = destColor; - vec3 param_13 = srcColor; - vec3 param_14 = compositeRGBToHSL(param_12); - vec3 param_15 = compositeRGBToHSL(param_13); - int param_16 = op; - vec3 param_17 = compositeHSL(param_14, param_15, param_16); - return compositeHSLToRGB(param_17); - } - } - return srcColor; -} - -vec4 composite(vec4 srcColor, vec2 destTextureSize, vec2 fragCoord, int op, sampler2D SPIRV_Cross_CombineddestTextureuSampler) -{ - if (op == 0) - { - return srcColor; - } - vec2 destTexCoord = fragCoord / destTextureSize; - vec4 destColor = texture(SPIRV_Cross_CombineddestTextureuSampler, destTexCoord); - vec3 param = destColor.xyz; - vec3 param_1 = srcColor.xyz; - int param_2 = op; - vec3 blendedRGB = compositeRGB(param, param_1, param_2); - return vec4(((srcColor.xyz * (srcColor.w * (1.0 - destColor.w))) + (blendedRGB * (srcColor.w * destColor.w))) + (destColor.xyz * (1.0 - srcColor.w)), 1.0); -} - -void calculateColor(int tileCtrl, int ctrl) -{ - int maskCtrl0 = (tileCtrl >> 0) & 3; - float maskAlpha = 1.0; - float param = maskAlpha; - vec2 param_1 = uMaskTextureSize0[0].xy; - vec3 param_2 = vMaskTexCoord0; - int param_3 = maskCtrl0; - maskAlpha = sampleMask(param, param_1, param_2, param_3, SPIRV_Cross_CombineduMaskTexture0uSampler); - vec4 color = vBaseColor; - int color0Combine = (ctrl >> 6) & 3; - if (color0Combine != 0) - { - int color0Filter = (ctrl >> 4) & 3; - vec2 param_4 = vColorTexCoord0; - vec2 param_5 = uColorTextureSize0[0].xy; - vec2 param_6 = gl_FragCoord.xy; - vec2 param_7 = uFramebufferSize[0].xy; - vec4 param_8 = uFilterParams0[0]; - vec4 param_9 = uFilterParams1[0]; - vec4 param_10 = uFilterParams2[0]; - int param_11 = color0Filter; - vec4 color0 = filterColor(param_4, param_5, param_6, param_7, param_8, param_9, param_10, param_11, SPIRV_Cross_CombineduColorTexture0uSampler, SPIRV_Cross_CombineduGammaLUTuSampler); - vec4 param_12 = color; - vec4 param_13 = color0; - int param_14 = color0Combine; - color = combineColor0(param_12, param_13, param_14); - } - color.w *= maskAlpha; - int compositeOp = (ctrl >> 8) & 15; - vec4 param_15 = color; - vec2 param_16 = uFramebufferSize[0].xy; - vec2 param_17 = gl_FragCoord.xy; - int param_18 = compositeOp; - color = composite(param_15, param_16, param_17, param_18, SPIRV_Cross_CombineduDestTextureuSampler); - vec3 _1389 = color.xyz * color.w; - color = vec4(_1389.x, _1389.y, _1389.z, color.w); - oFragColor = color; -} - -void main() -{ - int param = int(vTileCtrl); - int param_1 = uCtrl[0].x; - calculateColor(param, param_1); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/tile.vs.glsl b/crates/pathfinder/resources/shaders/gl3/tile.vs.glsl deleted file mode 100644 index 39df49168b..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/tile.vs.glsl +++ /dev/null @@ -1,41 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uTileSize[1]; -uniform ivec4 uTextureMetadataSize[1]; -uniform vec4 uTransform[4]; -uniform sampler2D SPIRV_Cross_CombineduTextureMetadatauSampler; - -layout(location = 1) in ivec2 aTileOrigin; -layout(location = 0) in ivec2 aTileOffset; -layout(location = 2) in uvec2 aMaskTexCoord0; -layout(location = 4) in int aColor; -out vec2 vColorTexCoord0; -out vec3 vMaskTexCoord0; -layout(location = 3) in ivec2 aMaskBackdrop; -out vec4 vBaseColor; -out float vTileCtrl; -layout(location = 5) in int aTileCtrl; - -void main() -{ - vec2 tileOrigin = vec2(aTileOrigin); - vec2 tileOffset = vec2(aTileOffset); - vec2 position = (tileOrigin + tileOffset) * uTileSize[0].xy; - vec2 maskTexCoord0 = (vec2(aMaskTexCoord0) + tileOffset) * uTileSize[0].xy; - vec2 textureMetadataScale = vec2(1.0) / vec2(uTextureMetadataSize[0].xy); - vec2 metadataEntryCoord = vec2(float((aColor % 128) * 4), float(aColor / 128)); - vec2 colorTexMatrix0Coord = (metadataEntryCoord + vec2(0.5)) * textureMetadataScale; - vec2 colorTexOffsetsCoord = (metadataEntryCoord + vec2(1.5, 0.5)) * textureMetadataScale; - vec2 baseColorCoord = (metadataEntryCoord + vec2(2.5, 0.5)) * textureMetadataScale; - vec4 colorTexMatrix0 = textureLod(SPIRV_Cross_CombineduTextureMetadatauSampler, colorTexMatrix0Coord, 0.0); - vec4 colorTexOffsets = textureLod(SPIRV_Cross_CombineduTextureMetadatauSampler, colorTexOffsetsCoord, 0.0); - vec4 baseColor = textureLod(SPIRV_Cross_CombineduTextureMetadatauSampler, baseColorCoord, 0.0); - vColorTexCoord0 = (mat2(vec2(colorTexMatrix0.xy), vec2(colorTexMatrix0.zw)) * position) + colorTexOffsets.xy; - vMaskTexCoord0 = vec3(maskTexCoord0, float(aMaskBackdrop.x)); - vBaseColor = baseColor; - vTileCtrl = float(aTileCtrl); - gl_Position = mat4(uTransform[0], uTransform[1], uTransform[2], uTransform[3]) * vec4(position, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/tile_clip.fs.glsl b/crates/pathfinder/resources/shaders/gl3/tile_clip.fs.glsl deleted file mode 100644 index 5bbb7a2593..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/tile_clip.fs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform sampler2D SPIRV_Cross_CombineduSrcuSampler; - -layout(location = 0) out vec4 oFragColor; -in vec2 vTexCoord; -in float vBackdrop; - -void main() -{ - oFragColor = clamp(abs(texture(SPIRV_Cross_CombineduSrcuSampler, vTexCoord) + vec4(vBackdrop)), vec4(0.0), vec4(1.0)); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/tile_clip.vs.glsl b/crates/pathfinder/resources/shaders/gl3/tile_clip.vs.glsl deleted file mode 100644 index 9cf2b9b012..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/tile_clip.vs.glsl +++ /dev/null @@ -1,20 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(location = 1) in ivec2 aDestTileOrigin; -layout(location = 0) in ivec2 aTileOffset; -layout(location = 2) in ivec2 aSrcTileOrigin; -out vec2 vTexCoord; -out float vBackdrop; -layout(location = 3) in int aSrcBackdrop; - -void main() -{ - vec2 destPosition = vec2(aDestTileOrigin + aTileOffset) / vec2(256.0); - vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset) / vec2(256.0); - vTexCoord = srcPosition; - vBackdrop = float(aSrcBackdrop); - gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), destPosition), 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/tile_copy.fs.glsl b/crates/pathfinder/resources/shaders/gl3/tile_copy.fs.glsl deleted file mode 100644 index 015b6ec45f..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/tile_copy.fs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uFramebufferSize[1]; -uniform sampler2D SPIRV_Cross_CombineduSrcuSampler; - -layout(location = 0) out vec4 oFragColor; - -void main() -{ - vec2 texCoord = gl_FragCoord.xy / uFramebufferSize[0].xy; - oFragColor = texture(SPIRV_Cross_CombineduSrcuSampler, texCoord); -} - diff --git a/crates/pathfinder/resources/shaders/gl3/tile_copy.vs.glsl b/crates/pathfinder/resources/shaders/gl3/tile_copy.vs.glsl deleted file mode 100644 index d20f31e406..0000000000 --- a/crates/pathfinder/resources/shaders/gl3/tile_copy.vs.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uTileSize[1]; -uniform vec4 uTransform[4]; -layout(location = 0) in ivec2 aTilePosition; - -void main() -{ - vec2 position = vec2(aTilePosition) * uTileSize[0].xy; - gl_Position = mat4(uTransform[0], uTransform[1], uTransform[2], uTransform[3]) * vec4(position, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/blit.fs.glsl b/crates/pathfinder/resources/shaders/gl4/blit.fs.glsl deleted file mode 100644 index 1a9b2d9f13..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/blit.fs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(binding = 0) uniform sampler2D SPIRV_Cross_CombineduSrcuSampler; - -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - vec4 color = texture(SPIRV_Cross_CombineduSrcuSampler, vTexCoord); - oFragColor = vec4(color.xyz * color.w, color.w); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/blit.vs.glsl b/crates/pathfinder/resources/shaders/gl4/blit.vs.glsl deleted file mode 100644 index 0a3bf222e4..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/blit.vs.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(location = 0) in ivec2 aPosition; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - vec2 texCoord = vec2(aPosition); - vTexCoord = texCoord; - gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), vec2(aPosition)), 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/clear.fs.glsl b/crates/pathfinder/resources/shaders/gl4/clear.fs.glsl deleted file mode 100644 index bfc45445dc..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/clear.fs.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uColor[1]; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - oFragColor = vec4(uColor[0].xyz, 1.0) * uColor[0].w; -} - diff --git a/crates/pathfinder/resources/shaders/gl4/clear.vs.glsl b/crates/pathfinder/resources/shaders/gl4/clear.vs.glsl deleted file mode 100644 index 76b85239b9..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/clear.vs.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uRect[1]; -uniform vec4 uFramebufferSize[1]; -layout(location = 0) in ivec2 aPosition; - -void main() -{ - vec2 position = ((mix(uRect[0].xy, uRect[0].zw, vec2(aPosition)) / uFramebufferSize[0].xy) * 2.0) - vec2(1.0); - gl_Position = vec4(position.x, -position.y, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/debug_solid.fs.glsl b/crates/pathfinder/resources/shaders/gl4/debug_solid.fs.glsl deleted file mode 100644 index bfc45445dc..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/debug_solid.fs.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uColor[1]; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - oFragColor = vec4(uColor[0].xyz, 1.0) * uColor[0].w; -} - diff --git a/crates/pathfinder/resources/shaders/gl4/debug_solid.vs.glsl b/crates/pathfinder/resources/shaders/gl4/debug_solid.vs.glsl deleted file mode 100644 index 705fbc5efb..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/debug_solid.vs.glsl +++ /dev/null @@ -1,13 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uFramebufferSize[1]; -layout(location = 0) in ivec2 aPosition; - -void main() -{ - vec2 position = ((vec2(aPosition) / uFramebufferSize[0].xy) * 2.0) - vec2(1.0); - gl_Position = vec4(position.x, -position.y, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/debug_texture.fs.glsl b/crates/pathfinder/resources/shaders/gl4/debug_texture.fs.glsl deleted file mode 100644 index c35786c4d7..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/debug_texture.fs.glsl +++ /dev/null @@ -1,16 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uColor[1]; -layout(binding = 2) uniform sampler2D SPIRV_Cross_CombineduTextureuSampler; - -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - float alpha = texture(SPIRV_Cross_CombineduTextureuSampler, vTexCoord).x * uColor[0].w; - oFragColor = vec4(uColor[0].xyz, 1.0) * alpha; -} - diff --git a/crates/pathfinder/resources/shaders/gl4/debug_texture.vs.glsl b/crates/pathfinder/resources/shaders/gl4/debug_texture.vs.glsl deleted file mode 100644 index 0097733723..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/debug_texture.vs.glsl +++ /dev/null @@ -1,17 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uTextureSize[1]; -uniform vec4 uFramebufferSize[1]; -layout(location = 0) out vec2 vTexCoord; -layout(location = 1) in ivec2 aTexCoord; -layout(location = 0) in ivec2 aPosition; - -void main() -{ - vTexCoord = vec2(aTexCoord) / uTextureSize[0].xy; - vec2 position = ((vec2(aPosition) / uFramebufferSize[0].xy) * 2.0) - vec2(1.0); - gl_Position = vec4(position.x, -position.y, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/demo_ground.fs.glsl b/crates/pathfinder/resources/shaders/gl4/demo_ground.fs.glsl deleted file mode 100644 index 2c4c3168e3..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/demo_ground.fs.glsl +++ /dev/null @@ -1,24 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uGridlineColor[1]; -uniform vec4 uGroundColor[1]; -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - vec2 texCoordPx = fract(vTexCoord) / fwidth(vTexCoord); - vec4 _28; - if (any(lessThanEqual(texCoordPx, vec2(1.0)))) - { - _28 = uGridlineColor[0]; - } - else - { - _28 = uGroundColor[0]; - } - oFragColor = _28; -} - diff --git a/crates/pathfinder/resources/shaders/gl4/demo_ground.vs.glsl b/crates/pathfinder/resources/shaders/gl4/demo_ground.vs.glsl deleted file mode 100644 index ab3fce9c6b..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/demo_ground.vs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform ivec4 uGridlineCount[1]; -uniform vec4 uTransform[4]; -layout(location = 0) out vec2 vTexCoord; -layout(location = 0) in ivec2 aPosition; - -void main() -{ - vTexCoord = vec2(aPosition * ivec2(uGridlineCount[0].x)); - gl_Position = mat4(uTransform[0], uTransform[1], uTransform[2], uTransform[3]) * vec4(ivec4(aPosition.x, 0, aPosition.y, 1)); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/fill.cs.glsl b/crates/pathfinder/resources/shaders/gl4/fill.cs.glsl deleted file mode 100644 index ebdbcb8cb6..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/fill.cs.glsl +++ /dev/null @@ -1,65 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - -layout(local_size_x = 16, local_size_y = 4, local_size_z = 1) in; - -uniform ivec4 uFirstTileIndex[1]; -layout(binding = 6, std430) restrict readonly buffer bFillTileMap -{ - int iFillTileMap[]; -} _159; - -layout(binding = 4, std430) restrict readonly buffer bFills -{ - uvec2 iFills[]; -} _180; - -layout(binding = 5, std430) restrict readonly buffer bNextFills -{ - int iNextFills[]; -} _264; - -layout(binding = 0) uniform writeonly image2D uDest; -layout(binding = 1) uniform sampler2D SPIRV_Cross_CombineduAreaLUTuSampler; - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D SPIRV_Cross_CombinedareaLUTareaLUTSampler) -{ - bvec2 _34 = bvec2(from.x < to.x); - vec2 left = vec2(_34.x ? from.x : to.x, _34.y ? from.y : to.y); - bvec2 _44 = bvec2(from.x < to.x); - vec2 right = vec2(_44.x ? to.x : from.x, _44.y ? to.y : from.y); - vec2 window = clamp(vec2(from.x, to.x), vec2(-0.5), vec2(0.5)); - float offset = mix(window.x, window.y, 0.5) - left.x; - float t = offset / (right.x - left.x); - float y = mix(left.y, right.y, t); - float d = (right.y - left.y) / (right.x - left.x); - float dX = window.x - window.y; - return textureLod(SPIRV_Cross_CombinedareaLUTareaLUTSampler, vec2(y + 8.0, abs(d * dX)) / vec2(16.0), 0.0) * dX; -} - -void main() -{ - ivec2 tileSubCoord = ivec2(gl_LocalInvocationID.xy) * ivec2(1, 4); - uint tileIndexOffset = gl_WorkGroupID.z; - uint tileIndex = tileIndexOffset + uint(uFirstTileIndex[0].x); - int fillIndex = _159.iFillTileMap[tileIndex]; - if (fillIndex < 0) - { - return; - } - vec4 coverages = vec4(0.0); - do - { - uvec2 fill = _180.iFills[fillIndex]; - vec2 from = vec2(float(fill.y & 15u), float((fill.y >> 4u) & 15u)) + (vec2(float(fill.x & 255u), float((fill.x >> 8u) & 255u)) / vec2(256.0)); - vec2 to = vec2(float((fill.y >> 8u) & 15u), float((fill.y >> 12u) & 15u)) + (vec2(float((fill.x >> 16u) & 255u), float((fill.x >> 24u) & 255u)) / vec2(256.0)); - vec2 param = from - (vec2(tileSubCoord) + vec2(0.5)); - vec2 param_1 = to - (vec2(tileSubCoord) + vec2(0.5)); - coverages += computeCoverage(param, param_1, SPIRV_Cross_CombineduAreaLUTuSampler); - fillIndex = _264.iNextFills[fillIndex]; - } while (fillIndex >= 0); - ivec2 tileOrigin = ivec2(int(tileIndex & 255u), int((tileIndex >> 8u) & 255u)) * ivec2(16, 4); - ivec2 destCoord = tileOrigin + ivec2(gl_LocalInvocationID.xy); - imageStore(uDest, destCoord, coverages); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/fill.fs.glsl b/crates/pathfinder/resources/shaders/gl4/fill.fs.glsl deleted file mode 100644 index 01c47c1651..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/fill.fs.glsl +++ /dev/null @@ -1,32 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(binding = 2) uniform sampler2D SPIRV_Cross_CombineduAreaLUTuSampler; - -layout(location = 0) out vec4 oFragColor; -layout(location = 0) in vec2 vFrom; -layout(location = 1) in vec2 vTo; - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D SPIRV_Cross_CombinedareaLUTareaLUTSampler) -{ - bvec2 _34 = bvec2(from.x < to.x); - vec2 left = vec2(_34.x ? from.x : to.x, _34.y ? from.y : to.y); - bvec2 _44 = bvec2(from.x < to.x); - vec2 right = vec2(_44.x ? to.x : from.x, _44.y ? to.y : from.y); - vec2 window = clamp(vec2(from.x, to.x), vec2(-0.5), vec2(0.5)); - float offset = mix(window.x, window.y, 0.5) - left.x; - float t = offset / (right.x - left.x); - float y = mix(left.y, right.y, t); - float d = (right.y - left.y) / (right.x - left.x); - float dX = window.x - window.y; - return texture(SPIRV_Cross_CombinedareaLUTareaLUTSampler, vec2(y + 8.0, abs(d * dX)) / vec2(16.0)) * dX; -} - -void main() -{ - vec2 param = vFrom; - vec2 param_1 = vTo; - oFragColor = computeCoverage(param, param_1, SPIRV_Cross_CombineduAreaLUTuSampler); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/fill.vs.glsl b/crates/pathfinder/resources/shaders/gl4/fill.vs.glsl deleted file mode 100644 index 73baecd0c5..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/fill.vs.glsl +++ /dev/null @@ -1,54 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uTileSize[1]; -uniform vec4 uFramebufferSize[1]; -layout(location = 5) in uint aTileIndex; -layout(location = 3) in uint aFromPx; -layout(location = 1) in vec2 aFromSubpx; -layout(location = 4) in uint aToPx; -layout(location = 2) in vec2 aToSubpx; -layout(location = 0) in uvec2 aTessCoord; -layout(location = 0) out vec2 vFrom; -layout(location = 1) out vec2 vTo; - -vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) -{ - uint tilesPerRow = uint(stencilTextureWidth / uTileSize[0].x); - uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return (vec2(tileOffset) * uTileSize[0].xy) * vec2(1.0, 0.25); -} - -void main() -{ - uint param = aTileIndex; - float param_1 = uFramebufferSize[0].x; - vec2 tileOrigin = computeTileOffset(param, param_1); - vec2 from = vec2(float(aFromPx & 15u), float(aFromPx >> 4u)) + aFromSubpx; - vec2 to = vec2(float(aToPx & 15u), float(aToPx >> 4u)) + aToSubpx; - vec2 position; - if (aTessCoord.x == 0u) - { - position.x = floor(min(from.x, to.x)); - } - else - { - position.x = ceil(max(from.x, to.x)); - } - if (aTessCoord.y == 0u) - { - position.y = floor(min(from.y, to.y)); - } - else - { - position.y = uTileSize[0].y; - } - position.y = floor(position.y * 0.25); - vec2 offset = vec2(0.0, 1.5) - (position * vec2(1.0, 4.0)); - vFrom = from + offset; - vTo = to + offset; - vec2 globalPosition = (((tileOrigin + position) / uFramebufferSize[0].xy) * 2.0) - vec2(1.0); - gl_Position = vec4(globalPosition, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/reproject.fs.glsl b/crates/pathfinder/resources/shaders/gl4/reproject.fs.glsl deleted file mode 100644 index efcd612731..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/reproject.fs.glsl +++ /dev/null @@ -1,17 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uOldTransform[4]; -layout(binding = 2) uniform sampler2D SPIRV_Cross_CombineduTextureuSampler; - -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 oFragColor; - -void main() -{ - vec4 normTexCoord = mat4(uOldTransform[0], uOldTransform[1], uOldTransform[2], uOldTransform[3]) * vec4(vTexCoord, 0.0, 1.0); - vec2 texCoord = ((normTexCoord.xy / vec2(normTexCoord.w)) + vec2(1.0)) * 0.5; - oFragColor = texture(SPIRV_Cross_CombineduTextureuSampler, texCoord); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/reproject.vs.glsl b/crates/pathfinder/resources/shaders/gl4/reproject.vs.glsl deleted file mode 100644 index d4d7378a8e..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/reproject.vs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uNewTransform[4]; -layout(location = 0) in ivec2 aPosition; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - vec2 position = vec2(aPosition); - vTexCoord = position; - gl_Position = mat4(uNewTransform[0], uNewTransform[1], uNewTransform[2], uNewTransform[3]) * vec4(position, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/stencil.fs.glsl b/crates/pathfinder/resources/shaders/gl4/stencil.fs.glsl deleted file mode 100644 index c9a19890dc..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/stencil.fs.glsl +++ /dev/null @@ -1,11 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(location = 0) out vec4 oFragColor; - -void main() -{ - oFragColor = vec4(1.0, 0.0, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/stencil.vs.glsl b/crates/pathfinder/resources/shaders/gl4/stencil.vs.glsl deleted file mode 100644 index f56fba14ef..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/stencil.vs.glsl +++ /dev/null @@ -1,11 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(location = 0) in vec3 aPosition; - -void main() -{ - gl_Position = vec4(aPosition, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/tile.fs.glsl b/crates/pathfinder/resources/shaders/gl4/tile.fs.glsl deleted file mode 100644 index 293cb6da15..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/tile.fs.glsl +++ /dev/null @@ -1,571 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uMaskTextureSize0[1]; -uniform vec4 uColorTextureSize0[1]; -uniform vec4 uFramebufferSize[1]; -uniform vec4 uFilterParams0[1]; -uniform vec4 uFilterParams1[1]; -uniform vec4 uFilterParams2[1]; -uniform ivec4 uCtrl[1]; -layout(binding = 2) uniform sampler2D SPIRV_Cross_CombineduMaskTexture0uSampler; -layout(binding = 1) uniform sampler2D SPIRV_Cross_CombineduColorTexture0uSampler; -layout(binding = 4) uniform sampler2D SPIRV_Cross_CombineduGammaLUTuSampler; -layout(binding = 3) uniform sampler2D SPIRV_Cross_CombineduDestTextureuSampler; - -layout(location = 0) in vec3 vMaskTexCoord0; -layout(location = 2) in vec4 vBaseColor; -layout(location = 1) in vec2 vColorTexCoord0; -layout(location = 0) out vec4 oFragColor; -layout(location = 3) in float vTileCtrl; - -float sampleMask(float maskAlpha, vec2 maskTextureSize, vec3 maskTexCoord, int maskCtrl, sampler2D SPIRV_Cross_CombinedmaskTextureuSampler) -{ - if (maskCtrl == 0) - { - return maskAlpha; - } - ivec2 maskTexCoordI = ivec2(floor(maskTexCoord.xy)); - vec4 texel = texture(SPIRV_Cross_CombinedmaskTextureuSampler, (vec2(maskTexCoordI / ivec2(1, 4)) + vec2(0.5)) / maskTextureSize); - float coverage = texel[maskTexCoordI.y % 4] + maskTexCoord.z; - if ((maskCtrl & 1) != 0) - { - coverage = abs(coverage); - } - else - { - coverage = 1.0 - abs(1.0 - mod(coverage, 2.0)); - } - return min(maskAlpha, coverage); -} - -vec4 filterRadialGradient(vec2 colorTexCoord, vec2 colorTextureSize, vec2 fragCoord, vec2 framebufferSize, vec4 filterParams0, vec4 filterParams1, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - vec2 lineFrom = filterParams0.xy; - vec2 lineVector = filterParams0.zw; - vec2 radii = filterParams1.xy; - vec2 uvOrigin = filterParams1.zw; - vec2 dP = colorTexCoord - lineFrom; - vec2 dC = lineVector; - float dR = radii.y - radii.x; - float a = dot(dC, dC) - (dR * dR); - float b = dot(dP, dC) + (radii.x * dR); - float c = dot(dP, dP) - (radii.x * radii.x); - float discrim = (b * b) - (a * c); - vec4 color = vec4(0.0); - if (abs(discrim) >= 9.9999997473787516355514526367188e-06) - { - vec2 ts = vec2((vec2(1.0, -1.0) * sqrt(discrim)) + vec2(b)) / vec2(a); - if (ts.x > ts.y) - { - ts = ts.yx; - } - float _566; - if (ts.x >= 0.0) - { - _566 = ts.x; - } - else - { - _566 = ts.y; - } - float t = _566; - color = texture(SPIRV_Cross_CombinedcolorTextureuSampler, uvOrigin + vec2(clamp(t, 0.0, 1.0), 0.0)); - } - return color; -} - -vec4 filterBlur(vec2 colorTexCoord, vec2 colorTextureSize, vec4 filterParams0, vec4 filterParams1, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - vec2 srcOffsetScale = filterParams0.xy / colorTextureSize; - int support = int(filterParams0.z); - vec3 gaussCoeff = filterParams1.xyz; - float gaussSum = gaussCoeff.x; - vec4 color = texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord) * gaussCoeff.x; - vec2 _615 = gaussCoeff.xy * gaussCoeff.yz; - gaussCoeff = vec3(_615.x, _615.y, gaussCoeff.z); - for (int i = 1; i <= support; i += 2) - { - float gaussPartialSum = gaussCoeff.x; - vec2 _635 = gaussCoeff.xy * gaussCoeff.yz; - gaussCoeff = vec3(_635.x, _635.y, gaussCoeff.z); - gaussPartialSum += gaussCoeff.x; - vec2 srcOffset = srcOffsetScale * (float(i) + (gaussCoeff.x / gaussPartialSum)); - color += ((texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord - srcOffset) + texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord + srcOffset)) * gaussPartialSum); - gaussSum += (2.0 * gaussPartialSum); - vec2 _679 = gaussCoeff.xy * gaussCoeff.yz; - gaussCoeff = vec3(_679.x, _679.y, gaussCoeff.z); - } - return color / vec4(gaussSum); -} - -float filterTextSample1Tap(float offset, vec2 colorTexCoord, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - return texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord + vec2(offset, 0.0)).x; -} - -void filterTextSample9Tap(out vec4 outAlphaLeft, out float outAlphaCenter, out vec4 outAlphaRight, vec2 colorTexCoord, vec4 kernel, float onePixel, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - bool wide = kernel.x > 0.0; - float _243; - if (wide) - { - float param = (-4.0) * onePixel; - vec2 param_1 = colorTexCoord; - _243 = filterTextSample1Tap(param, param_1, SPIRV_Cross_CombinedcolorTextureuSampler); - } - else - { - _243 = 0.0; - } - float param_2 = (-3.0) * onePixel; - vec2 param_3 = colorTexCoord; - float param_4 = (-2.0) * onePixel; - vec2 param_5 = colorTexCoord; - float param_6 = (-1.0) * onePixel; - vec2 param_7 = colorTexCoord; - outAlphaLeft = vec4(_243, filterTextSample1Tap(param_2, param_3, SPIRV_Cross_CombinedcolorTextureuSampler), filterTextSample1Tap(param_4, param_5, SPIRV_Cross_CombinedcolorTextureuSampler), filterTextSample1Tap(param_6, param_7, SPIRV_Cross_CombinedcolorTextureuSampler)); - float param_8 = 0.0; - vec2 param_9 = colorTexCoord; - outAlphaCenter = filterTextSample1Tap(param_8, param_9, SPIRV_Cross_CombinedcolorTextureuSampler); - float param_10 = 1.0 * onePixel; - vec2 param_11 = colorTexCoord; - float param_12 = 2.0 * onePixel; - vec2 param_13 = colorTexCoord; - float param_14 = 3.0 * onePixel; - vec2 param_15 = colorTexCoord; - float _303; - if (wide) - { - float param_16 = 4.0 * onePixel; - vec2 param_17 = colorTexCoord; - _303 = filterTextSample1Tap(param_16, param_17, SPIRV_Cross_CombinedcolorTextureuSampler); - } - else - { - _303 = 0.0; - } - outAlphaRight = vec4(filterTextSample1Tap(param_10, param_11, SPIRV_Cross_CombinedcolorTextureuSampler), filterTextSample1Tap(param_12, param_13, SPIRV_Cross_CombinedcolorTextureuSampler), filterTextSample1Tap(param_14, param_15, SPIRV_Cross_CombinedcolorTextureuSampler), _303); -} - -float filterTextConvolve7Tap(vec4 alpha0, vec3 alpha1, vec4 kernel) -{ - return dot(alpha0, kernel) + dot(alpha1, kernel.zyx); -} - -float filterTextGammaCorrectChannel(float bgColor, float fgColor, sampler2D SPIRV_Cross_CombinedgammaLUTuSampler) -{ - return texture(SPIRV_Cross_CombinedgammaLUTuSampler, vec2(fgColor, 1.0 - bgColor)).x; -} - -vec3 filterTextGammaCorrect(vec3 bgColor, vec3 fgColor, sampler2D SPIRV_Cross_CombinedgammaLUTuSampler) -{ - float param = bgColor.x; - float param_1 = fgColor.x; - float param_2 = bgColor.y; - float param_3 = fgColor.y; - float param_4 = bgColor.z; - float param_5 = fgColor.z; - return vec3(filterTextGammaCorrectChannel(param, param_1, SPIRV_Cross_CombinedgammaLUTuSampler), filterTextGammaCorrectChannel(param_2, param_3, SPIRV_Cross_CombinedgammaLUTuSampler), filterTextGammaCorrectChannel(param_4, param_5, SPIRV_Cross_CombinedgammaLUTuSampler)); -} - -vec4 filterText(vec2 colorTexCoord, vec2 colorTextureSize, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler, sampler2D SPIRV_Cross_CombinedgammaLUTuSampler) -{ - vec4 kernel = filterParams0; - vec3 bgColor = filterParams1.xyz; - vec3 fgColor = filterParams2.xyz; - bool gammaCorrectionEnabled = filterParams2.w != 0.0; - vec3 alpha; - if (kernel.w == 0.0) - { - alpha = texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord).xxx; - } - else - { - vec2 param_3 = colorTexCoord; - vec4 param_4 = kernel; - float param_5 = 1.0 / colorTextureSize.x; - vec4 param; - float param_1; - vec4 param_2; - filterTextSample9Tap(param, param_1, param_2, param_3, param_4, param_5, SPIRV_Cross_CombinedcolorTextureuSampler); - vec4 alphaLeft = param; - float alphaCenter = param_1; - vec4 alphaRight = param_2; - vec4 param_6 = alphaLeft; - vec3 param_7 = vec3(alphaCenter, alphaRight.xy); - vec4 param_8 = kernel; - float r = filterTextConvolve7Tap(param_6, param_7, param_8); - vec4 param_9 = vec4(alphaLeft.yzw, alphaCenter); - vec3 param_10 = alphaRight.xyz; - vec4 param_11 = kernel; - float g = filterTextConvolve7Tap(param_9, param_10, param_11); - vec4 param_12 = vec4(alphaLeft.zw, alphaCenter, alphaRight.x); - vec3 param_13 = alphaRight.yzw; - vec4 param_14 = kernel; - float b = filterTextConvolve7Tap(param_12, param_13, param_14); - alpha = vec3(r, g, b); - } - if (gammaCorrectionEnabled) - { - vec3 param_15 = bgColor; - vec3 param_16 = alpha; - alpha = filterTextGammaCorrect(param_15, param_16, SPIRV_Cross_CombinedgammaLUTuSampler); - } - return vec4(mix(bgColor, fgColor, alpha), 1.0); -} - -vec4 sampleColor(vec2 colorTexCoord, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - return texture(SPIRV_Cross_CombinedcolorTextureuSampler, colorTexCoord); -} - -vec4 filterNone(vec2 colorTexCoord, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler) -{ - vec2 param = colorTexCoord; - return sampleColor(param, SPIRV_Cross_CombinedcolorTextureuSampler); -} - -vec4 filterColor(vec2 colorTexCoord, vec2 colorTextureSize, vec2 fragCoord, vec2 framebufferSize, vec4 filterParams0, vec4 filterParams1, vec4 filterParams2, int colorFilter, sampler2D SPIRV_Cross_CombinedcolorTextureuSampler, sampler2D SPIRV_Cross_CombinedgammaLUTuSampler) -{ - switch (colorFilter) - { - case 1: - { - vec2 param = colorTexCoord; - vec2 param_1 = colorTextureSize; - vec2 param_2 = fragCoord; - vec2 param_3 = framebufferSize; - vec4 param_4 = filterParams0; - vec4 param_5 = filterParams1; - return filterRadialGradient(param, param_1, param_2, param_3, param_4, param_5, SPIRV_Cross_CombinedcolorTextureuSampler); - } - case 3: - { - vec2 param_6 = colorTexCoord; - vec2 param_7 = colorTextureSize; - vec4 param_8 = filterParams0; - vec4 param_9 = filterParams1; - return filterBlur(param_6, param_7, param_8, param_9, SPIRV_Cross_CombinedcolorTextureuSampler); - } - case 2: - { - vec2 param_10 = colorTexCoord; - vec2 param_11 = colorTextureSize; - vec4 param_12 = filterParams0; - vec4 param_13 = filterParams1; - vec4 param_14 = filterParams2; - return filterText(param_10, param_11, param_12, param_13, param_14, SPIRV_Cross_CombinedcolorTextureuSampler, SPIRV_Cross_CombinedgammaLUTuSampler); - } - } - vec2 param_15 = colorTexCoord; - return filterNone(param_15, SPIRV_Cross_CombinedcolorTextureuSampler); -} - -vec4 combineColor0(vec4 destColor, vec4 srcColor, int op) -{ - switch (op) - { - case 1: - { - return vec4(srcColor.xyz, srcColor.w * destColor.w); - } - case 2: - { - return vec4(destColor.xyz, srcColor.w * destColor.w); - } - } - return destColor; -} - -vec3 compositeScreen(vec3 destColor, vec3 srcColor) -{ - return (destColor + srcColor) - (destColor * srcColor); -} - -vec3 compositeSelect(bvec3 cond, vec3 ifTrue, vec3 ifFalse) -{ - float _745; - if (cond.x) - { - _745 = ifTrue.x; - } - else - { - _745 = ifFalse.x; - } - float _756; - if (cond.y) - { - _756 = ifTrue.y; - } - else - { - _756 = ifFalse.y; - } - float _767; - if (cond.z) - { - _767 = ifTrue.z; - } - else - { - _767 = ifFalse.z; - } - return vec3(_745, _756, _767); -} - -vec3 compositeHardLight(vec3 destColor, vec3 srcColor) -{ - vec3 param = destColor; - vec3 param_1 = (vec3(2.0) * srcColor) - vec3(1.0); - bvec3 param_2 = lessThanEqual(srcColor, vec3(0.5)); - vec3 param_3 = (destColor * vec3(2.0)) * srcColor; - vec3 param_4 = compositeScreen(param, param_1); - return compositeSelect(param_2, param_3, param_4); -} - -vec3 compositeColorDodge(vec3 destColor, vec3 srcColor) -{ - bvec3 destZero = equal(destColor, vec3(0.0)); - bvec3 srcOne = equal(srcColor, vec3(1.0)); - bvec3 param = srcOne; - vec3 param_1 = vec3(1.0); - vec3 param_2 = destColor / (vec3(1.0) - srcColor); - bvec3 param_3 = destZero; - vec3 param_4 = vec3(0.0); - vec3 param_5 = compositeSelect(param, param_1, param_2); - return compositeSelect(param_3, param_4, param_5); -} - -vec3 compositeSoftLight(vec3 destColor, vec3 srcColor) -{ - bvec3 param = lessThanEqual(destColor, vec3(0.25)); - vec3 param_1 = ((((vec3(16.0) * destColor) - vec3(12.0)) * destColor) + vec3(4.0)) * destColor; - vec3 param_2 = sqrt(destColor); - vec3 darkenedDestColor = compositeSelect(param, param_1, param_2); - bvec3 param_3 = lessThanEqual(srcColor, vec3(0.5)); - vec3 param_4 = destColor * (vec3(1.0) - destColor); - vec3 param_5 = darkenedDestColor - destColor; - vec3 factor = compositeSelect(param_3, param_4, param_5); - return destColor + (((srcColor * 2.0) - vec3(1.0)) * factor); -} - -float compositeDivide(float num, float denom) -{ - float _781; - if (denom != 0.0) - { - _781 = num / denom; - } - else - { - _781 = 0.0; - } - return _781; -} - -vec3 compositeRGBToHSL(vec3 rgb) -{ - float v = max(max(rgb.x, rgb.y), rgb.z); - float xMin = min(min(rgb.x, rgb.y), rgb.z); - float c = v - xMin; - float l = mix(xMin, v, 0.5); - vec3 _887; - if (rgb.x == v) - { - _887 = vec3(0.0, rgb.yz); - } - else - { - vec3 _900; - if (rgb.y == v) - { - _900 = vec3(2.0, rgb.zx); - } - else - { - _900 = vec3(4.0, rgb.xy); - } - _887 = _900; - } - vec3 terms = _887; - float param = ((terms.x * c) + terms.y) - terms.z; - float param_1 = c; - float h = 1.0471975803375244140625 * compositeDivide(param, param_1); - float param_2 = c; - float param_3 = v; - float s = compositeDivide(param_2, param_3); - return vec3(h, s, l); -} - -vec3 compositeHSL(vec3 destColor, vec3 srcColor, int op) -{ - switch (op) - { - case 12: - { - return vec3(srcColor.x, destColor.y, destColor.z); - } - case 13: - { - return vec3(destColor.x, srcColor.y, destColor.z); - } - case 14: - { - return vec3(srcColor.x, srcColor.y, destColor.z); - } - default: - { - return vec3(destColor.x, destColor.y, srcColor.z); - } - } -} - -vec3 compositeHSLToRGB(vec3 hsl) -{ - float a = hsl.y * min(hsl.z, 1.0 - hsl.z); - vec3 ks = mod(vec3(0.0, 8.0, 4.0) + vec3(hsl.x * 1.90985929965972900390625), vec3(12.0)); - return hsl.zzz - (clamp(min(ks - vec3(3.0), vec3(9.0) - ks), vec3(-1.0), vec3(1.0)) * a); -} - -vec3 compositeRGB(vec3 destColor, vec3 srcColor, int op) -{ - switch (op) - { - case 1: - { - return destColor * srcColor; - } - case 2: - { - vec3 param = destColor; - vec3 param_1 = srcColor; - return compositeScreen(param, param_1); - } - case 3: - { - vec3 param_2 = srcColor; - vec3 param_3 = destColor; - return compositeHardLight(param_2, param_3); - } - case 4: - { - return min(destColor, srcColor); - } - case 5: - { - return max(destColor, srcColor); - } - case 6: - { - vec3 param_4 = destColor; - vec3 param_5 = srcColor; - return compositeColorDodge(param_4, param_5); - } - case 7: - { - vec3 param_6 = vec3(1.0) - destColor; - vec3 param_7 = vec3(1.0) - srcColor; - return vec3(1.0) - compositeColorDodge(param_6, param_7); - } - case 8: - { - vec3 param_8 = destColor; - vec3 param_9 = srcColor; - return compositeHardLight(param_8, param_9); - } - case 9: - { - vec3 param_10 = destColor; - vec3 param_11 = srcColor; - return compositeSoftLight(param_10, param_11); - } - case 10: - { - return abs(destColor - srcColor); - } - case 11: - { - return (destColor + srcColor) - ((vec3(2.0) * destColor) * srcColor); - } - case 12: - case 13: - case 14: - case 15: - { - vec3 param_12 = destColor; - vec3 param_13 = srcColor; - vec3 param_14 = compositeRGBToHSL(param_12); - vec3 param_15 = compositeRGBToHSL(param_13); - int param_16 = op; - vec3 param_17 = compositeHSL(param_14, param_15, param_16); - return compositeHSLToRGB(param_17); - } - } - return srcColor; -} - -vec4 composite(vec4 srcColor, vec2 destTextureSize, vec2 fragCoord, int op, sampler2D SPIRV_Cross_CombineddestTextureuSampler) -{ - if (op == 0) - { - return srcColor; - } - vec2 destTexCoord = fragCoord / destTextureSize; - vec4 destColor = texture(SPIRV_Cross_CombineddestTextureuSampler, destTexCoord); - vec3 param = destColor.xyz; - vec3 param_1 = srcColor.xyz; - int param_2 = op; - vec3 blendedRGB = compositeRGB(param, param_1, param_2); - return vec4(((srcColor.xyz * (srcColor.w * (1.0 - destColor.w))) + (blendedRGB * (srcColor.w * destColor.w))) + (destColor.xyz * (1.0 - srcColor.w)), 1.0); -} - -void calculateColor(int tileCtrl, int ctrl) -{ - int maskCtrl0 = (tileCtrl >> 0) & 3; - float maskAlpha = 1.0; - float param = maskAlpha; - vec2 param_1 = uMaskTextureSize0[0].xy; - vec3 param_2 = vMaskTexCoord0; - int param_3 = maskCtrl0; - maskAlpha = sampleMask(param, param_1, param_2, param_3, SPIRV_Cross_CombineduMaskTexture0uSampler); - vec4 color = vBaseColor; - int color0Combine = (ctrl >> 6) & 3; - if (color0Combine != 0) - { - int color0Filter = (ctrl >> 4) & 3; - vec2 param_4 = vColorTexCoord0; - vec2 param_5 = uColorTextureSize0[0].xy; - vec2 param_6 = gl_FragCoord.xy; - vec2 param_7 = uFramebufferSize[0].xy; - vec4 param_8 = uFilterParams0[0]; - vec4 param_9 = uFilterParams1[0]; - vec4 param_10 = uFilterParams2[0]; - int param_11 = color0Filter; - vec4 color0 = filterColor(param_4, param_5, param_6, param_7, param_8, param_9, param_10, param_11, SPIRV_Cross_CombineduColorTexture0uSampler, SPIRV_Cross_CombineduGammaLUTuSampler); - vec4 param_12 = color; - vec4 param_13 = color0; - int param_14 = color0Combine; - color = combineColor0(param_12, param_13, param_14); - } - color.w *= maskAlpha; - int compositeOp = (ctrl >> 8) & 15; - vec4 param_15 = color; - vec2 param_16 = uFramebufferSize[0].xy; - vec2 param_17 = gl_FragCoord.xy; - int param_18 = compositeOp; - color = composite(param_15, param_16, param_17, param_18, SPIRV_Cross_CombineduDestTextureuSampler); - vec3 _1389 = color.xyz * color.w; - color = vec4(_1389.x, _1389.y, _1389.z, color.w); - oFragColor = color; -} - -void main() -{ - int param = int(vTileCtrl); - int param_1 = uCtrl[0].x; - calculateColor(param, param_1); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/tile.vs.glsl b/crates/pathfinder/resources/shaders/gl4/tile.vs.glsl deleted file mode 100644 index 443710a2f9..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/tile.vs.glsl +++ /dev/null @@ -1,41 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uTileSize[1]; -uniform ivec4 uTextureMetadataSize[1]; -uniform vec4 uTransform[4]; -layout(binding = 2) uniform sampler2D SPIRV_Cross_CombineduTextureMetadatauSampler; - -layout(location = 1) in ivec2 aTileOrigin; -layout(location = 0) in ivec2 aTileOffset; -layout(location = 2) in uvec2 aMaskTexCoord0; -layout(location = 4) in int aColor; -layout(location = 1) out vec2 vColorTexCoord0; -layout(location = 0) out vec3 vMaskTexCoord0; -layout(location = 3) in ivec2 aMaskBackdrop; -layout(location = 2) out vec4 vBaseColor; -layout(location = 3) out float vTileCtrl; -layout(location = 5) in int aTileCtrl; - -void main() -{ - vec2 tileOrigin = vec2(aTileOrigin); - vec2 tileOffset = vec2(aTileOffset); - vec2 position = (tileOrigin + tileOffset) * uTileSize[0].xy; - vec2 maskTexCoord0 = (vec2(aMaskTexCoord0) + tileOffset) * uTileSize[0].xy; - vec2 textureMetadataScale = vec2(1.0) / vec2(uTextureMetadataSize[0].xy); - vec2 metadataEntryCoord = vec2(float((aColor % 128) * 4), float(aColor / 128)); - vec2 colorTexMatrix0Coord = (metadataEntryCoord + vec2(0.5)) * textureMetadataScale; - vec2 colorTexOffsetsCoord = (metadataEntryCoord + vec2(1.5, 0.5)) * textureMetadataScale; - vec2 baseColorCoord = (metadataEntryCoord + vec2(2.5, 0.5)) * textureMetadataScale; - vec4 colorTexMatrix0 = textureLod(SPIRV_Cross_CombineduTextureMetadatauSampler, colorTexMatrix0Coord, 0.0); - vec4 colorTexOffsets = textureLod(SPIRV_Cross_CombineduTextureMetadatauSampler, colorTexOffsetsCoord, 0.0); - vec4 baseColor = textureLod(SPIRV_Cross_CombineduTextureMetadatauSampler, baseColorCoord, 0.0); - vColorTexCoord0 = (mat2(vec2(colorTexMatrix0.xy), vec2(colorTexMatrix0.zw)) * position) + colorTexOffsets.xy; - vMaskTexCoord0 = vec3(maskTexCoord0, float(aMaskBackdrop.x)); - vBaseColor = baseColor; - vTileCtrl = float(aTileCtrl); - gl_Position = mat4(uTransform[0], uTransform[1], uTransform[2], uTransform[3]) * vec4(position, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/tile_clip.fs.glsl b/crates/pathfinder/resources/shaders/gl4/tile_clip.fs.glsl deleted file mode 100644 index 871231fc0f..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/tile_clip.fs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(binding = 0) uniform sampler2D SPIRV_Cross_CombineduSrcuSampler; - -layout(location = 0) out vec4 oFragColor; -layout(location = 0) in vec2 vTexCoord; -layout(location = 1) in float vBackdrop; - -void main() -{ - oFragColor = clamp(abs(texture(SPIRV_Cross_CombineduSrcuSampler, vTexCoord) + vec4(vBackdrop)), vec4(0.0), vec4(1.0)); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/tile_clip.vs.glsl b/crates/pathfinder/resources/shaders/gl4/tile_clip.vs.glsl deleted file mode 100644 index bf6c55d9ea..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/tile_clip.vs.glsl +++ /dev/null @@ -1,20 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -layout(location = 1) in ivec2 aDestTileOrigin; -layout(location = 0) in ivec2 aTileOffset; -layout(location = 2) in ivec2 aSrcTileOrigin; -layout(location = 0) out vec2 vTexCoord; -layout(location = 1) out float vBackdrop; -layout(location = 3) in int aSrcBackdrop; - -void main() -{ - vec2 destPosition = vec2(aDestTileOrigin + aTileOffset) / vec2(256.0); - vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset) / vec2(256.0); - vTexCoord = srcPosition; - vBackdrop = float(aSrcBackdrop); - gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), destPosition), 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/tile_copy.fs.glsl b/crates/pathfinder/resources/shaders/gl4/tile_copy.fs.glsl deleted file mode 100644 index 48abe4391d..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/tile_copy.fs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uFramebufferSize[1]; -layout(binding = 3) uniform sampler2D SPIRV_Cross_CombineduSrcuSampler; - -layout(location = 0) out vec4 oFragColor; - -void main() -{ - vec2 texCoord = gl_FragCoord.xy / uFramebufferSize[0].xy; - oFragColor = texture(SPIRV_Cross_CombineduSrcuSampler, texCoord); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/tile_copy.vs.glsl b/crates/pathfinder/resources/shaders/gl4/tile_copy.vs.glsl deleted file mode 100644 index d20f31e406..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/tile_copy.vs.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - -uniform vec4 uTileSize[1]; -uniform vec4 uTransform[4]; -layout(location = 0) in ivec2 aTilePosition; - -void main() -{ - vec2 position = vec2(aTilePosition) * uTileSize[0].xy; - gl_Position = mat4(uTransform[0], uTransform[1], uTransform[2], uTransform[3]) * vec4(position, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/gl4/tile_fill.cs.glsl b/crates/pathfinder/resources/shaders/gl4/tile_fill.cs.glsl deleted file mode 100644 index 025f2e2b92..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/tile_fill.cs.glsl +++ /dev/null @@ -1,782 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -#extension GL_GOOGLE_include_directive : enable - -precision highp float; -precision highp sampler2D; - -layout(local_size_x = 16, local_size_y = 4)in; - -layout(rgba8)uniform image2D uDestImage; -uniform sampler2D uTextureMetadata; -uniform ivec2 uTextureMetadataSize; -uniform sampler2D uColorTexture0; -uniform sampler2D uMaskTexture0; -uniform sampler2D uGammaLUT; -uniform vec2 uTileSize; -uniform vec4 uFilterParams0; -uniform vec4 uFilterParams1; -uniform vec4 uFilterParams2; -uniform vec2 uFramebufferSize; -uniform vec2 uColorTextureSize0; -uniform int uCtrl; -uniform sampler2D uAreaLUT; - -layout(std430, binding = 0)buffer bFills { - restrict readonly uvec2 iFills[]; -}; - -layout(std430, binding = 1)buffer bNextFills { - restrict readonly int iNextFills[]; -}; - -layout(std430, binding = 2)buffer bFillTileMap { - restrict readonly int iFillTileMap[]; -}; - -layout(std430, binding = 3)buffer bTiles { - restrict readonly uint iTiles[]; -}; - -layout(std430, binding = 4)buffer bNextTiles { - restrict readonly int iNextTiles[]; -}; - -layout(std430, binding = 5)buffer bFirstTiles { - restrict readonly int iFirstTiles[]; -}; - - - - - - - - - - - - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){ - - vec2 left = from . x < to . x ? from : to, right = from . x < to . x ? to : from; - - - vec2 window = clamp(vec2(from . x, to . x), - 0.5, 0.5); - float offset = mix(window . x, window . y, 0.5)- left . x; - float t = offset /(right . x - left . x); - - - float y = mix(left . y, right . y, t); - float d =(right . y - left . y)/(right . x - left . x); - - - float dX = window . x - window . y; - return texture(areaLUT, vec2(y + 8.0, abs(d * dX))/ 16.0)* dX; -} - - - - - - - - - - - - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT); - -ivec2 calculateTileOrigin(uint tileIndex){ - return ivec2(tileIndex & 0xff,(tileIndex >> 8u)& 0xff)* 16; -} - -vec4 calculateFillAlpha(ivec2 tileSubCoord, uint tileIndex){ - int fillIndex = iFillTileMap[tileIndex]; - if(fillIndex < 0) - return vec4(0.0); - - vec4 coverages = vec4(0.0); - do { - uvec2 fill = iFills[fillIndex]; - vec2 from = vec2(fill . y & 0xf,(fill . y >> 4u)& 0xf)+ - vec2(fill . x & 0xff,(fill . x >> 8u)& 0xff)/ 256.0; - vec2 to = vec2((fill . y >> 8u)& 0xf,(fill . y >> 12u)& 0xf)+ - vec2((fill . x >> 16u)& 0xff,(fill . x >> 24u)& 0xff)/ 256.0; - - coverages += computeCoverage(from -(vec2(tileSubCoord)+ vec2(0.5)), - to -(vec2(tileSubCoord)+ vec2(0.5)), - uAreaLUT); - - fillIndex = iNextFills[fillIndex]; - } while(fillIndex >= 0); - - return coverages; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord){ - return texture(colorTexture, colorTexCoord); -} - - - -vec4 combineColor0(vec4 destColor, vec4 srcColor, int op){ - switch(op){ - case 0x1 : - return vec4(srcColor . rgb, srcColor . a * destColor . a); - case 0x2 : - return vec4(destColor . rgb, srcColor . a * destColor . a); - } - return destColor; -} - - - -float filterTextSample1Tap(float offset, sampler2D colorTexture, vec2 colorTexCoord){ - return texture(colorTexture, colorTexCoord + vec2(offset, 0.0)). r; -} - - -void filterTextSample9Tap(out vec4 outAlphaLeft, - out float outAlphaCenter, - out vec4 outAlphaRight, - sampler2D colorTexture, - vec2 colorTexCoord, - vec4 kernel, - float onePixel){ - bool wide = kernel . x > 0.0; - outAlphaLeft = - vec4(wide ? filterTextSample1Tap(- 4.0 * onePixel, colorTexture, colorTexCoord): 0.0, - filterTextSample1Tap(- 3.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(- 2.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(- 1.0 * onePixel, colorTexture, colorTexCoord)); - outAlphaCenter = filterTextSample1Tap(0.0, colorTexture, colorTexCoord); - outAlphaRight = - vec4(filterTextSample1Tap(1.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(2.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(3.0 * onePixel, colorTexture, colorTexCoord), - wide ? filterTextSample1Tap(4.0 * onePixel, colorTexture, colorTexCoord): 0.0); -} - -float filterTextConvolve7Tap(vec4 alpha0, vec3 alpha1, vec4 kernel){ - return dot(alpha0, kernel)+ dot(alpha1, kernel . zyx); -} - -float filterTextGammaCorrectChannel(float bgColor, float fgColor, sampler2D gammaLUT){ - return texture(gammaLUT, vec2(fgColor, 1.0 - bgColor)). r; -} - - -vec3 filterTextGammaCorrect(vec3 bgColor, vec3 fgColor, sampler2D gammaLUT){ - return vec3(filterTextGammaCorrectChannel(bgColor . r, fgColor . r, gammaLUT), - filterTextGammaCorrectChannel(bgColor . g, fgColor . g, gammaLUT), - filterTextGammaCorrectChannel(bgColor . b, fgColor . b, gammaLUT)); -} - - - - - - -vec4 filterText(vec2 colorTexCoord, - sampler2D colorTexture, - sampler2D gammaLUT, - vec2 colorTextureSize, - vec4 filterParams0, - vec4 filterParams1, - vec4 filterParams2){ - - vec4 kernel = filterParams0; - vec3 bgColor = filterParams1 . rgb; - vec3 fgColor = filterParams2 . rgb; - bool gammaCorrectionEnabled = filterParams2 . a != 0.0; - - - vec3 alpha; - if(kernel . w == 0.0){ - alpha = texture(colorTexture, colorTexCoord). rrr; - } else { - vec4 alphaLeft, alphaRight; - float alphaCenter; - filterTextSample9Tap(alphaLeft, - alphaCenter, - alphaRight, - colorTexture, - colorTexCoord, - kernel, - 1.0 / colorTextureSize . x); - - float r = filterTextConvolve7Tap(alphaLeft, vec3(alphaCenter, alphaRight . xy), kernel); - float g = filterTextConvolve7Tap(vec4(alphaLeft . yzw, alphaCenter), alphaRight . xyz, kernel); - float b = filterTextConvolve7Tap(vec4(alphaLeft . zw, alphaCenter, alphaRight . x), - alphaRight . yzw, - kernel); - - alpha = vec3(r, g, b); - } - - - if(gammaCorrectionEnabled) - alpha = filterTextGammaCorrect(bgColor, alpha, gammaLUT); - - - return vec4(mix(bgColor, fgColor, alpha), 1.0); -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -vec4 filterRadialGradient(vec2 colorTexCoord, - sampler2D colorTexture, - vec2 colorTextureSize, - vec2 fragCoord, - vec2 framebufferSize, - vec4 filterParams0, - vec4 filterParams1){ - vec2 lineFrom = filterParams0 . xy, lineVector = filterParams0 . zw; - vec2 radii = filterParams1 . xy, uvOrigin = filterParams1 . zw; - - vec2 dP = colorTexCoord - lineFrom, dC = lineVector; - float dR = radii . y - radii . x; - - float a = dot(dC, dC)- dR * dR; - float b = dot(dP, dC)+ radii . x * dR; - float c = dot(dP, dP)- radii . x * radii . x; - float discrim = b * b - a * c; - - vec4 color = vec4(0.0); - if(abs(discrim)>= 0.00001){ - vec2 ts = vec2(sqrt(discrim)* vec2(1.0, - 1.0)+ vec2(b))/ vec2(a); - if(ts . x > ts . y) - ts = ts . yx; - float t = ts . x >= 0.0 ? ts . x : ts . y; - color = texture(colorTexture, uvOrigin + vec2(clamp(t, 0.0, 1.0), 0.0)); - } - - return color; -} - - - - - - -vec4 filterBlur(vec2 colorTexCoord, - sampler2D colorTexture, - vec2 colorTextureSize, - vec4 filterParams0, - vec4 filterParams1){ - - vec2 srcOffsetScale = filterParams0 . xy / colorTextureSize; - int support = int(filterParams0 . z); - vec3 gaussCoeff = filterParams1 . xyz; - - - float gaussSum = gaussCoeff . x; - vec4 color = texture(colorTexture, colorTexCoord)* gaussCoeff . x; - gaussCoeff . xy *= gaussCoeff . yz; - - - - - - - - - - for(int i = 1;i <= support;i += 2){ - float gaussPartialSum = gaussCoeff . x; - gaussCoeff . xy *= gaussCoeff . yz; - gaussPartialSum += gaussCoeff . x; - - vec2 srcOffset = srcOffsetScale *(float(i)+ gaussCoeff . x / gaussPartialSum); - color +=(texture(colorTexture, colorTexCoord - srcOffset)+ - texture(colorTexture, colorTexCoord + srcOffset))* gaussPartialSum; - - gaussSum += 2.0 * gaussPartialSum; - gaussCoeff . xy *= gaussCoeff . yz; - } - - - return color / gaussSum; -} - -vec4 filterNone(vec2 colorTexCoord, sampler2D colorTexture){ - return sampleColor(colorTexture, colorTexCoord); -} - -vec4 filterColor(vec2 colorTexCoord, - sampler2D colorTexture, - sampler2D gammaLUT, - vec2 colorTextureSize, - vec2 fragCoord, - vec2 framebufferSize, - vec4 filterParams0, - vec4 filterParams1, - vec4 filterParams2, - int colorFilter){ - switch(colorFilter){ - case 0x1 : - return filterRadialGradient(colorTexCoord, - colorTexture, - colorTextureSize, - fragCoord, - framebufferSize, - filterParams0, - filterParams1); - case 0x3 : - return filterBlur(colorTexCoord, - colorTexture, - colorTextureSize, - filterParams0, - filterParams1); - case 0x2 : - return filterText(colorTexCoord, - colorTexture, - gammaLUT, - colorTextureSize, - filterParams0, - filterParams1, - filterParams2); - } - return filterNone(colorTexCoord, colorTexture); -} - - - -vec3 compositeSelect(bvec3 cond, vec3 ifTrue, vec3 ifFalse){ - return vec3(cond . x ? ifTrue . x : ifFalse . x, - cond . y ? ifTrue . y : ifFalse . y, - cond . z ? ifTrue . z : ifFalse . z); -} - -float compositeDivide(float num, float denom){ - return denom != 0.0 ? num / denom : 0.0; -} - -vec3 compositeColorDodge(vec3 destColor, vec3 srcColor){ - bvec3 destZero = equal(destColor, vec3(0.0)), srcOne = equal(srcColor, vec3(1.0)); - return compositeSelect(destZero, - vec3(0.0), - compositeSelect(srcOne, vec3(1.0), destColor /(vec3(1.0)- srcColor))); -} - - -vec3 compositeHSLToRGB(vec3 hsl){ - float a = hsl . y * min(hsl . z, 1.0 - hsl . z); - vec3 ks = mod(vec3(0.0, 8.0, 4.0)+ vec3(hsl . x * 1.9098593171027443), 12.0); - return hsl . zzz - clamp(min(ks - vec3(3.0), vec3(9.0)- ks), - 1.0, 1.0)* a; -} - - -vec3 compositeRGBToHSL(vec3 rgb){ - float v = max(max(rgb . r, rgb . g), rgb . b), xMin = min(min(rgb . r, rgb . g), rgb . b); - float c = v - xMin, l = mix(xMin, v, 0.5); - vec3 terms = rgb . r == v ? vec3(0.0, rgb . gb): - rgb . g == v ? vec3(2.0, rgb . br): - vec3(4.0, rgb . rg); - float h = 1.0471975511965976 * compositeDivide(terms . x * c + terms . y - terms . z, c); - float s = compositeDivide(c, v); - return vec3(h, s, l); -} - -vec3 compositeScreen(vec3 destColor, vec3 srcColor){ - return destColor + srcColor - destColor * srcColor; -} - -vec3 compositeHardLight(vec3 destColor, vec3 srcColor){ - return compositeSelect(lessThanEqual(srcColor, vec3(0.5)), - destColor * vec3(2.0)* srcColor, - compositeScreen(destColor, vec3(2.0)* srcColor - vec3(1.0))); -} - -vec3 compositeSoftLight(vec3 destColor, vec3 srcColor){ - vec3 darkenedDestColor = - compositeSelect(lessThanEqual(destColor, vec3(0.25)), - ((vec3(16.0)* destColor - 12.0)* destColor + 4.0)* destColor, - sqrt(destColor)); - vec3 factor = compositeSelect(lessThanEqual(srcColor, vec3(0.5)), - destColor *(vec3(1.0)- destColor), - darkenedDestColor - destColor); - return destColor +(srcColor * 2.0 - 1.0)* factor; -} - -vec3 compositeHSL(vec3 destColor, vec3 srcColor, int op){ - switch(op){ - case 0xc : - return vec3(srcColor . x, destColor . y, destColor . z); - case 0xd : - return vec3(destColor . x, srcColor . y, destColor . z); - case 0xe : - return vec3(srcColor . x, srcColor . y, destColor . z); - default : - return vec3(destColor . x, destColor . y, srcColor . z); - } -} - -vec3 compositeRGB(vec3 destColor, vec3 srcColor, int op){ - switch(op){ - case 0x1 : - return destColor * srcColor; - case 0x2 : - return compositeScreen(destColor, srcColor); - case 0x3 : - return compositeHardLight(srcColor, destColor); - case 0x4 : - return min(destColor, srcColor); - case 0x5 : - return max(destColor, srcColor); - case 0x6 : - return compositeColorDodge(destColor, srcColor); - case 0x7 : - return vec3(1.0)- compositeColorDodge(vec3(1.0)- destColor, vec3(1.0)- srcColor); - case 0x8 : - return compositeHardLight(destColor, srcColor); - case 0x9 : - return compositeSoftLight(destColor, srcColor); - case 0xa : - return abs(destColor - srcColor); - case 0xb : - return destColor + srcColor - vec3(2.0)* destColor * srcColor; - case 0xc : - case 0xd : - case 0xe : - case 0xf : - return compositeHSLToRGB(compositeHSL(compositeRGBToHSL(destColor), - compositeRGBToHSL(srcColor), - op)); - } - return srcColor; -} - -vec4 composite(vec4 srcColor, - sampler2D destTexture, - vec2 destTextureSize, - vec2 fragCoord, - int op){ - if(op == 0x0) - return srcColor; - - - vec2 destTexCoord = fragCoord / destTextureSize; - vec4 destColor = texture(destTexture, destTexCoord); - vec3 blendedRGB = compositeRGB(destColor . rgb, srcColor . rgb, op); - return vec4(srcColor . a *(1.0 - destColor . a)* srcColor . rgb + - srcColor . a * destColor . a * blendedRGB + - (1.0 - srcColor . a)* destColor . rgb, - 1.0); -} - - - -float sampleMask(float maskAlpha, - sampler2D maskTexture, - vec2 maskTextureSize, - vec3 maskTexCoord, - int maskCtrl){ - if(maskCtrl == 0) - return maskAlpha; - - ivec2 maskTexCoordI = ivec2(floor(maskTexCoord . xy)); - vec4 texel = texture(maskTexture,(vec2(maskTexCoordI / ivec2(1, 4))+ 0.5)/ maskTextureSize); - float coverage = texel[maskTexCoordI . y % 4]+ maskTexCoord . z; - - if((maskCtrl & 0x1)!= 0) - coverage = abs(coverage); - else - coverage = 1.0 - abs(1.0 - mod(coverage, 2.0)); - return min(maskAlpha, coverage); -} - - - -vec4 calculateColorWithMaskAlpha(float maskAlpha, - vec4 baseColor, - vec2 colorTexCoord0, - vec2 fragCoord, - int ctrl){ - - vec4 color = baseColor; - int color0Combine =(ctrl >> 6)& - 0x3; - if(color0Combine != 0){ - int color0Filter =(ctrl >> 4)& 0x3; - vec4 color0 = filterColor(colorTexCoord0, - uColorTexture0, - uGammaLUT, - uColorTextureSize0, - fragCoord, - uFramebufferSize, - uFilterParams0, - uFilterParams1, - uFilterParams2, - color0Filter); - color = combineColor0(color, color0, color0Combine); - } - - - color . a *= maskAlpha; - - - - - - - - - - color . rgb *= color . a; - return color; -} - - - - - - - - - - - - -void lookupTextureMetadata(int color, - out mat2 outColorTexMatrix0, - out vec4 outColorTexOffsets, - out vec4 outBaseColor){ - vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize); - vec2 metadataEntryCoord = vec2(color % 128 * 4, color / 128); - vec2 colorTexMatrix0Coord =(metadataEntryCoord + vec2(0.5, 0.5))* textureMetadataScale; - vec2 colorTexOffsetsCoord =(metadataEntryCoord + vec2(1.5, 0.5))* textureMetadataScale; - vec2 baseColorCoord =(metadataEntryCoord + vec2(2.5, 0.5))* textureMetadataScale; - outColorTexMatrix0 = mat2(texture(uTextureMetadata, colorTexMatrix0Coord)); - outColorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord); - outBaseColor = texture(uTextureMetadata, baseColorCoord); -} - - - - -void main(){ - int maskCtrl0 =(uCtrl >> 0)& 0x1; - - vec4 colors[4]= { vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0)}; - ivec2 tileSubCoord = ivec2(gl_LocalInvocationID . xy)* ivec2(1, 4); - ivec2 tileOrigin = ivec2(0); - - int tileIndex = iFirstTiles[gl_WorkGroupID . z]; - int overlapCount = 0; - - while(tileIndex >= 0){ - overlapCount ++; - - uint tileCoord = iTiles[tileIndex * 3 + 0]; - uint maskTexCoord = iTiles[tileIndex * 3 + 1]; - uint colorCtrl = iTiles[tileIndex * 3 + 2]; - - tileOrigin = ivec2(int(tileCoord & 0xffff), int(tileCoord >> 16)); - - int ctrl = int(uCtrl); - int tileColor = int(colorCtrl & 0xffff); - int tileCtrl = int(colorCtrl >> 16); - - mat2 colorTexMatrix0; - vec4 colorTexOffsets; - vec4 baseColor; - lookupTextureMetadata(tileColor, colorTexMatrix0, colorTexOffsets, baseColor); - - int maskTileCtrl0 =(tileCtrl >> 0)& 0x3; - - vec4 maskAlphas = vec4(1.0); - if(maskCtrl0 != 0 && maskTileCtrl0 != 0){ - uint maskTileIndex0 = maskTexCoord & 0xffff; - int maskTileBackdrop0 = int(maskTexCoord << 8)>> 24; - maskAlphas = clamp(abs(calculateFillAlpha(tileSubCoord, maskTileIndex0)+ - float(maskTileBackdrop0)), 0.0, 1.0); - } - - for(int yOffset = 0;yOffset < 4;yOffset ++){ - - ivec2 fragCoordI = tileOrigin * ivec2(uTileSize)+ tileSubCoord + ivec2(0, yOffset); - vec2 fragCoord = vec2(fragCoordI)+ vec2(0.5); - vec2 colorTexCoord0 = colorTexMatrix0 * fragCoord + colorTexOffsets . xy; - vec4 color = calculateColorWithMaskAlpha(maskAlphas[yOffset], - baseColor, - colorTexCoord0, - fragCoord, - ctrl); - colors[yOffset]= colors[yOffset]*(1.0 - color . a)+ color; - } - - tileIndex = iNextTiles[tileIndex]; - } - - for(int yOffset = 0;yOffset < 4;yOffset ++){ - ivec2 fragCoord = tileOrigin * ivec2(uTileSize)+ tileSubCoord + ivec2(0, yOffset); - - - vec4 color = colors[yOffset]; - if(color . a < 1.0) - color = imageLoad(uDestImage, fragCoord)*(1.0 - color . a)+ color; - imageStore(uDestImage, fragCoord, color); - } -} - diff --git a/crates/pathfinder/resources/shaders/gl4/tile_fill.fs.glsl b/crates/pathfinder/resources/shaders/gl4/tile_fill.fs.glsl deleted file mode 100644 index 88b566ff7a..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/tile_fill.fs.glsl +++ /dev/null @@ -1,708 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -#extension GL_GOOGLE_include_directive : enable - -precision highp float; -precision highp sampler2D; - -uniform sampler2D uColorTexture0; -uniform sampler2D uMaskTexture0; -uniform sampler2D uDestTexture; -uniform sampler2D uGammaLUT; -uniform vec4 uFilterParams0; -uniform vec4 uFilterParams1; -uniform vec4 uFilterParams2; -uniform vec2 uFramebufferSize; -uniform vec2 uColorTextureSize0; -uniform int uCtrl; -uniform sampler2D uAreaLUT; - -layout(std430, binding = 0)buffer bFills { - restrict readonly uvec2 iFills[]; -}; - -layout(std430, binding = 1)buffer bNextFills { - restrict readonly int iNextFills[]; -}; - -layout(std430, binding = 2)buffer bFillTileMap { - restrict readonly int iFillTileMap[]; -}; - -in vec2 vTileSubCoord; -flat in uint vMaskTileIndex0; -flat in int vMaskTileBackdrop0; -in vec2 vColorTexCoord0; -in vec4 vBaseColor; -in float vTileCtrl; - -out vec4 oFragColor; - - - - - - - - - - - - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){ - - vec2 left = from . x < to . x ? from : to, right = from . x < to . x ? to : from; - - - vec2 window = clamp(vec2(from . x, to . x), - 0.5, 0.5); - float offset = mix(window . x, window . y, 0.5)- left . x; - float t = offset /(right . x - left . x); - - - float y = mix(left . y, right . y, t); - float d =(right . y - left . y)/(right . x - left . x); - - - float dX = window . x - window . y; - return texture(areaLUT, vec2(y + 8.0, abs(d * dX))/ 16.0)* dX; -} - - - - - - - - - - - - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT); - -ivec2 calculateTileOrigin(uint tileIndex){ - return ivec2(tileIndex & 0xff,(tileIndex >> 8u)& 0xff)* 16; -} - -vec4 calculateFillAlpha(ivec2 tileSubCoord, uint tileIndex){ - int fillIndex = iFillTileMap[tileIndex]; - if(fillIndex < 0) - return vec4(0.0); - - vec4 coverages = vec4(0.0); - do { - uvec2 fill = iFills[fillIndex]; - vec2 from = vec2(fill . y & 0xf,(fill . y >> 4u)& 0xf)+ - vec2(fill . x & 0xff,(fill . x >> 8u)& 0xff)/ 256.0; - vec2 to = vec2((fill . y >> 8u)& 0xf,(fill . y >> 12u)& 0xf)+ - vec2((fill . x >> 16u)& 0xff,(fill . x >> 24u)& 0xff)/ 256.0; - - coverages += computeCoverage(from -(vec2(tileSubCoord)+ vec2(0.5)), - to -(vec2(tileSubCoord)+ vec2(0.5)), - uAreaLUT); - - fillIndex = iNextFills[fillIndex]; - } while(fillIndex >= 0); - - return coverages; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord){ - return texture(colorTexture, colorTexCoord); -} - - - -vec4 combineColor0(vec4 destColor, vec4 srcColor, int op){ - switch(op){ - case 0x1 : - return vec4(srcColor . rgb, srcColor . a * destColor . a); - case 0x2 : - return vec4(destColor . rgb, srcColor . a * destColor . a); - } - return destColor; -} - - - -float filterTextSample1Tap(float offset, sampler2D colorTexture, vec2 colorTexCoord){ - return texture(colorTexture, colorTexCoord + vec2(offset, 0.0)). r; -} - - -void filterTextSample9Tap(out vec4 outAlphaLeft, - out float outAlphaCenter, - out vec4 outAlphaRight, - sampler2D colorTexture, - vec2 colorTexCoord, - vec4 kernel, - float onePixel){ - bool wide = kernel . x > 0.0; - outAlphaLeft = - vec4(wide ? filterTextSample1Tap(- 4.0 * onePixel, colorTexture, colorTexCoord): 0.0, - filterTextSample1Tap(- 3.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(- 2.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(- 1.0 * onePixel, colorTexture, colorTexCoord)); - outAlphaCenter = filterTextSample1Tap(0.0, colorTexture, colorTexCoord); - outAlphaRight = - vec4(filterTextSample1Tap(1.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(2.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(3.0 * onePixel, colorTexture, colorTexCoord), - wide ? filterTextSample1Tap(4.0 * onePixel, colorTexture, colorTexCoord): 0.0); -} - -float filterTextConvolve7Tap(vec4 alpha0, vec3 alpha1, vec4 kernel){ - return dot(alpha0, kernel)+ dot(alpha1, kernel . zyx); -} - -float filterTextGammaCorrectChannel(float bgColor, float fgColor, sampler2D gammaLUT){ - return texture(gammaLUT, vec2(fgColor, 1.0 - bgColor)). r; -} - - -vec3 filterTextGammaCorrect(vec3 bgColor, vec3 fgColor, sampler2D gammaLUT){ - return vec3(filterTextGammaCorrectChannel(bgColor . r, fgColor . r, gammaLUT), - filterTextGammaCorrectChannel(bgColor . g, fgColor . g, gammaLUT), - filterTextGammaCorrectChannel(bgColor . b, fgColor . b, gammaLUT)); -} - - - - - - -vec4 filterText(vec2 colorTexCoord, - sampler2D colorTexture, - sampler2D gammaLUT, - vec2 colorTextureSize, - vec4 filterParams0, - vec4 filterParams1, - vec4 filterParams2){ - - vec4 kernel = filterParams0; - vec3 bgColor = filterParams1 . rgb; - vec3 fgColor = filterParams2 . rgb; - bool gammaCorrectionEnabled = filterParams2 . a != 0.0; - - - vec3 alpha; - if(kernel . w == 0.0){ - alpha = texture(colorTexture, colorTexCoord). rrr; - } else { - vec4 alphaLeft, alphaRight; - float alphaCenter; - filterTextSample9Tap(alphaLeft, - alphaCenter, - alphaRight, - colorTexture, - colorTexCoord, - kernel, - 1.0 / colorTextureSize . x); - - float r = filterTextConvolve7Tap(alphaLeft, vec3(alphaCenter, alphaRight . xy), kernel); - float g = filterTextConvolve7Tap(vec4(alphaLeft . yzw, alphaCenter), alphaRight . xyz, kernel); - float b = filterTextConvolve7Tap(vec4(alphaLeft . zw, alphaCenter, alphaRight . x), - alphaRight . yzw, - kernel); - - alpha = vec3(r, g, b); - } - - - if(gammaCorrectionEnabled) - alpha = filterTextGammaCorrect(bgColor, alpha, gammaLUT); - - - return vec4(mix(bgColor, fgColor, alpha), 1.0); -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -vec4 filterRadialGradient(vec2 colorTexCoord, - sampler2D colorTexture, - vec2 colorTextureSize, - vec2 fragCoord, - vec2 framebufferSize, - vec4 filterParams0, - vec4 filterParams1){ - vec2 lineFrom = filterParams0 . xy, lineVector = filterParams0 . zw; - vec2 radii = filterParams1 . xy, uvOrigin = filterParams1 . zw; - - vec2 dP = colorTexCoord - lineFrom, dC = lineVector; - float dR = radii . y - radii . x; - - float a = dot(dC, dC)- dR * dR; - float b = dot(dP, dC)+ radii . x * dR; - float c = dot(dP, dP)- radii . x * radii . x; - float discrim = b * b - a * c; - - vec4 color = vec4(0.0); - if(abs(discrim)>= 0.00001){ - vec2 ts = vec2(sqrt(discrim)* vec2(1.0, - 1.0)+ vec2(b))/ vec2(a); - if(ts . x > ts . y) - ts = ts . yx; - float t = ts . x >= 0.0 ? ts . x : ts . y; - color = texture(colorTexture, uvOrigin + vec2(clamp(t, 0.0, 1.0), 0.0)); - } - - return color; -} - - - - - - -vec4 filterBlur(vec2 colorTexCoord, - sampler2D colorTexture, - vec2 colorTextureSize, - vec4 filterParams0, - vec4 filterParams1){ - - vec2 srcOffsetScale = filterParams0 . xy / colorTextureSize; - int support = int(filterParams0 . z); - vec3 gaussCoeff = filterParams1 . xyz; - - - float gaussSum = gaussCoeff . x; - vec4 color = texture(colorTexture, colorTexCoord)* gaussCoeff . x; - gaussCoeff . xy *= gaussCoeff . yz; - - - - - - - - - - for(int i = 1;i <= support;i += 2){ - float gaussPartialSum = gaussCoeff . x; - gaussCoeff . xy *= gaussCoeff . yz; - gaussPartialSum += gaussCoeff . x; - - vec2 srcOffset = srcOffsetScale *(float(i)+ gaussCoeff . x / gaussPartialSum); - color +=(texture(colorTexture, colorTexCoord - srcOffset)+ - texture(colorTexture, colorTexCoord + srcOffset))* gaussPartialSum; - - gaussSum += 2.0 * gaussPartialSum; - gaussCoeff . xy *= gaussCoeff . yz; - } - - - return color / gaussSum; -} - -vec4 filterNone(vec2 colorTexCoord, sampler2D colorTexture){ - return sampleColor(colorTexture, colorTexCoord); -} - -vec4 filterColor(vec2 colorTexCoord, - sampler2D colorTexture, - sampler2D gammaLUT, - vec2 colorTextureSize, - vec2 fragCoord, - vec2 framebufferSize, - vec4 filterParams0, - vec4 filterParams1, - vec4 filterParams2, - int colorFilter){ - switch(colorFilter){ - case 0x1 : - return filterRadialGradient(colorTexCoord, - colorTexture, - colorTextureSize, - fragCoord, - framebufferSize, - filterParams0, - filterParams1); - case 0x3 : - return filterBlur(colorTexCoord, - colorTexture, - colorTextureSize, - filterParams0, - filterParams1); - case 0x2 : - return filterText(colorTexCoord, - colorTexture, - gammaLUT, - colorTextureSize, - filterParams0, - filterParams1, - filterParams2); - } - return filterNone(colorTexCoord, colorTexture); -} - - - -vec3 compositeSelect(bvec3 cond, vec3 ifTrue, vec3 ifFalse){ - return vec3(cond . x ? ifTrue . x : ifFalse . x, - cond . y ? ifTrue . y : ifFalse . y, - cond . z ? ifTrue . z : ifFalse . z); -} - -float compositeDivide(float num, float denom){ - return denom != 0.0 ? num / denom : 0.0; -} - -vec3 compositeColorDodge(vec3 destColor, vec3 srcColor){ - bvec3 destZero = equal(destColor, vec3(0.0)), srcOne = equal(srcColor, vec3(1.0)); - return compositeSelect(destZero, - vec3(0.0), - compositeSelect(srcOne, vec3(1.0), destColor /(vec3(1.0)- srcColor))); -} - - -vec3 compositeHSLToRGB(vec3 hsl){ - float a = hsl . y * min(hsl . z, 1.0 - hsl . z); - vec3 ks = mod(vec3(0.0, 8.0, 4.0)+ vec3(hsl . x * 1.9098593171027443), 12.0); - return hsl . zzz - clamp(min(ks - vec3(3.0), vec3(9.0)- ks), - 1.0, 1.0)* a; -} - - -vec3 compositeRGBToHSL(vec3 rgb){ - float v = max(max(rgb . r, rgb . g), rgb . b), xMin = min(min(rgb . r, rgb . g), rgb . b); - float c = v - xMin, l = mix(xMin, v, 0.5); - vec3 terms = rgb . r == v ? vec3(0.0, rgb . gb): - rgb . g == v ? vec3(2.0, rgb . br): - vec3(4.0, rgb . rg); - float h = 1.0471975511965976 * compositeDivide(terms . x * c + terms . y - terms . z, c); - float s = compositeDivide(c, v); - return vec3(h, s, l); -} - -vec3 compositeScreen(vec3 destColor, vec3 srcColor){ - return destColor + srcColor - destColor * srcColor; -} - -vec3 compositeHardLight(vec3 destColor, vec3 srcColor){ - return compositeSelect(lessThanEqual(srcColor, vec3(0.5)), - destColor * vec3(2.0)* srcColor, - compositeScreen(destColor, vec3(2.0)* srcColor - vec3(1.0))); -} - -vec3 compositeSoftLight(vec3 destColor, vec3 srcColor){ - vec3 darkenedDestColor = - compositeSelect(lessThanEqual(destColor, vec3(0.25)), - ((vec3(16.0)* destColor - 12.0)* destColor + 4.0)* destColor, - sqrt(destColor)); - vec3 factor = compositeSelect(lessThanEqual(srcColor, vec3(0.5)), - destColor *(vec3(1.0)- destColor), - darkenedDestColor - destColor); - return destColor +(srcColor * 2.0 - 1.0)* factor; -} - -vec3 compositeHSL(vec3 destColor, vec3 srcColor, int op){ - switch(op){ - case 0xc : - return vec3(srcColor . x, destColor . y, destColor . z); - case 0xd : - return vec3(destColor . x, srcColor . y, destColor . z); - case 0xe : - return vec3(srcColor . x, srcColor . y, destColor . z); - default : - return vec3(destColor . x, destColor . y, srcColor . z); - } -} - -vec3 compositeRGB(vec3 destColor, vec3 srcColor, int op){ - switch(op){ - case 0x1 : - return destColor * srcColor; - case 0x2 : - return compositeScreen(destColor, srcColor); - case 0x3 : - return compositeHardLight(srcColor, destColor); - case 0x4 : - return min(destColor, srcColor); - case 0x5 : - return max(destColor, srcColor); - case 0x6 : - return compositeColorDodge(destColor, srcColor); - case 0x7 : - return vec3(1.0)- compositeColorDodge(vec3(1.0)- destColor, vec3(1.0)- srcColor); - case 0x8 : - return compositeHardLight(destColor, srcColor); - case 0x9 : - return compositeSoftLight(destColor, srcColor); - case 0xa : - return abs(destColor - srcColor); - case 0xb : - return destColor + srcColor - vec3(2.0)* destColor * srcColor; - case 0xc : - case 0xd : - case 0xe : - case 0xf : - return compositeHSLToRGB(compositeHSL(compositeRGBToHSL(destColor), - compositeRGBToHSL(srcColor), - op)); - } - return srcColor; -} - -vec4 composite(vec4 srcColor, - sampler2D destTexture, - vec2 destTextureSize, - vec2 fragCoord, - int op){ - if(op == 0x0) - return srcColor; - - - vec2 destTexCoord = fragCoord / destTextureSize; - vec4 destColor = texture(destTexture, destTexCoord); - vec3 blendedRGB = compositeRGB(destColor . rgb, srcColor . rgb, op); - return vec4(srcColor . a *(1.0 - destColor . a)* srcColor . rgb + - srcColor . a * destColor . a * blendedRGB + - (1.0 - srcColor . a)* destColor . rgb, - 1.0); -} - - - -float sampleMask(float maskAlpha, - sampler2D maskTexture, - vec2 maskTextureSize, - vec3 maskTexCoord, - int maskCtrl){ - if(maskCtrl == 0) - return maskAlpha; - - ivec2 maskTexCoordI = ivec2(floor(maskTexCoord . xy)); - vec4 texel = texture(maskTexture,(vec2(maskTexCoordI / ivec2(1, 4))+ 0.5)/ maskTextureSize); - float coverage = texel[maskTexCoordI . y % 4]+ maskTexCoord . z; - - if((maskCtrl & 0x1)!= 0) - coverage = abs(coverage); - else - coverage = 1.0 - abs(1.0 - mod(coverage, 2.0)); - return min(maskAlpha, coverage); -} - - - -vec4 calculateColorWithMaskAlpha(float maskAlpha, - vec4 baseColor, - vec2 colorTexCoord0, - vec2 fragCoord, - int ctrl){ - - vec4 color = baseColor; - int color0Combine =(ctrl >> 6)& - 0x3; - if(color0Combine != 0){ - int color0Filter =(ctrl >> 4)& 0x3; - vec4 color0 = filterColor(colorTexCoord0, - uColorTexture0, - uGammaLUT, - uColorTextureSize0, - fragCoord, - uFramebufferSize, - uFilterParams0, - uFilterParams1, - uFilterParams2, - color0Filter); - color = combineColor0(color, color0, color0Combine); - } - - - color . a *= maskAlpha; - - - - - - - - - - color . rgb *= color . a; - return color; -} - - -vec4 calculateColor(int tileCtrl, int ctrl){ - float maskAlpha = 1.0; - int maskCtrl0 =(ctrl >> 0)& 0x1; - int maskTileCtrl0 =(tileCtrl >> 0)& 0x3; - uint maskTileIndex0 = vMaskTileIndex0; - if(maskCtrl0 != 0 && maskTileCtrl0 != 0){ - ivec2 tileSubCoord = ivec2(floor(vTileSubCoord)); - vec4 alphas = calculateFillAlpha(tileSubCoord, maskTileIndex0)+ float(vMaskTileBackdrop0); - maskAlpha = alphas . x; - } - return calculateColorWithMaskAlpha(maskAlpha, - vBaseColor, - vColorTexCoord0, - gl_FragCoord . xy, - ctrl); -} - - - - - -void main(){ - oFragColor = calculateColor(int(vTileCtrl), uCtrl); - -} - diff --git a/crates/pathfinder/resources/shaders/gl4/tile_fill.vs.glsl b/crates/pathfinder/resources/shaders/gl4/tile_fill.vs.glsl deleted file mode 100644 index 1c089c0905..0000000000 --- a/crates/pathfinder/resources/shaders/gl4/tile_fill.vs.glsl +++ /dev/null @@ -1,58 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -precision highp float; -precision highp sampler2D; - -uniform mat4 uTransform; -uniform vec2 uTileSize; -uniform sampler2D uTextureMetadata; -uniform ivec2 uTextureMetadataSize; - -in ivec2 aTileOffset; -in ivec2 aTileOrigin; -in uint aMaskTileIndex0; -in ivec2 aMaskBackdrop; -in int aColor; -in int aTileCtrl; - -out vec2 vTileSubCoord; -flat out uint vMaskTileIndex0; -flat out int vMaskTileBackdrop0; -out vec2 vColorTexCoord0; -out vec4 vBaseColor; -out float vTileCtrl; - -void main(){ - vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); - vec2 position =(tileOrigin + tileOffset)* uTileSize; - - vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize); - vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); - vec2 colorTexMatrix0Coord =(metadataEntryCoord + vec2(0.5, 0.5))* textureMetadataScale; - vec2 colorTexOffsetsCoord =(metadataEntryCoord + vec2(1.5, 0.5))* textureMetadataScale; - vec2 baseColorCoord =(metadataEntryCoord + vec2(2.5, 0.5))* textureMetadataScale; - vec4 colorTexMatrix0 = texture(uTextureMetadata, colorTexMatrix0Coord); - vec4 colorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord); - vec4 baseColor = texture(uTextureMetadata, baseColorCoord); - - vTileSubCoord = tileOffset * vec2(16.0); - vColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy; - vMaskTileIndex0 = aMaskTileIndex0; - vMaskTileBackdrop0 = aMaskBackdrop . x; - vBaseColor = baseColor; - vTileCtrl = float(aTileCtrl); - gl_Position = uTransform * vec4(position, 0.0, 1.0); -} - diff --git a/crates/pathfinder/resources/shaders/metal/blit.fs.metal b/crates/pathfinder/resources/shaders/metal/blit.fs.metal deleted file mode 100644 index 7ccae45247..0000000000 --- a/crates/pathfinder/resources/shaders/metal/blit.fs.metal +++ /dev/null @@ -1,24 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -struct main0_in -{ - float2 vTexCoord [[user(locn0)]]; -}; - -fragment main0_out main0(main0_in in [[stage_in]], texture2d uSrc [[texture(0)]], sampler uSampler [[sampler(0)]]) -{ - main0_out out = {}; - float4 color = uSrc.sample(uSampler, in.vTexCoord); - out.oFragColor = float4(color.xyz * color.w, color.w); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/blit.vs.metal b/crates/pathfinder/resources/shaders/metal/blit.vs.metal deleted file mode 100644 index 701d97f0f1..0000000000 --- a/crates/pathfinder/resources/shaders/metal/blit.vs.metal +++ /dev/null @@ -1,27 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct main0_out -{ - float2 vTexCoord [[user(locn0)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aPosition [[attribute(0)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]]) -{ - main0_out out = {}; - float2 texCoord = float2(in.aPosition); - texCoord.y = 1.0 - texCoord.y; - out.vTexCoord = texCoord; - out.gl_Position = float4(mix(float2(-1.0), float2(1.0), float2(in.aPosition)), 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/clear.fs.metal b/crates/pathfinder/resources/shaders/metal/clear.fs.metal deleted file mode 100644 index f4d373c281..0000000000 --- a/crates/pathfinder/resources/shaders/metal/clear.fs.metal +++ /dev/null @@ -1,23 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uColor -{ - float4 color; -}; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -fragment main0_out main0(constant uColor& _12 [[buffer(0)]]) -{ - main0_out out = {}; - out.oFragColor = float4(_12.color.xyz, 1.0) * _12.color.w; - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/clear.vs.metal b/crates/pathfinder/resources/shaders/metal/clear.vs.metal deleted file mode 100644 index 7f4126fe01..0000000000 --- a/crates/pathfinder/resources/shaders/metal/clear.vs.metal +++ /dev/null @@ -1,34 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uRect -{ - float4 rect; -}; - -struct uFramebufferSize -{ - float2 framebufferSize; -}; - -struct main0_out -{ - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aPosition [[attribute(0)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]], constant uRect& _13 [[buffer(0)]], constant uFramebufferSize& _31 [[buffer(1)]]) -{ - main0_out out = {}; - float2 position = ((mix(_13.rect.xy, _13.rect.zw, float2(in.aPosition)) / _31.framebufferSize) * 2.0) - float2(1.0); - out.gl_Position = float4(position.x, -position.y, 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/debug_solid.fs.metal b/crates/pathfinder/resources/shaders/metal/debug_solid.fs.metal deleted file mode 100644 index f4d373c281..0000000000 --- a/crates/pathfinder/resources/shaders/metal/debug_solid.fs.metal +++ /dev/null @@ -1,23 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uColor -{ - float4 color; -}; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -fragment main0_out main0(constant uColor& _12 [[buffer(0)]]) -{ - main0_out out = {}; - out.oFragColor = float4(_12.color.xyz, 1.0) * _12.color.w; - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/debug_solid.vs.metal b/crates/pathfinder/resources/shaders/metal/debug_solid.vs.metal deleted file mode 100644 index 7c3d808683..0000000000 --- a/crates/pathfinder/resources/shaders/metal/debug_solid.vs.metal +++ /dev/null @@ -1,29 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uFramebufferSize -{ - float2 framebufferSize; -}; - -struct main0_out -{ - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aPosition [[attribute(0)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]], constant uFramebufferSize& _18 [[buffer(0)]]) -{ - main0_out out = {}; - float2 position = ((float2(in.aPosition) / _18.framebufferSize) * 2.0) - float2(1.0); - out.gl_Position = float4(position.x, -position.y, 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/debug_texture.fs.metal b/crates/pathfinder/resources/shaders/metal/debug_texture.fs.metal deleted file mode 100644 index 7d3443a2f2..0000000000 --- a/crates/pathfinder/resources/shaders/metal/debug_texture.fs.metal +++ /dev/null @@ -1,29 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uColor -{ - float4 color; -}; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -struct main0_in -{ - float2 vTexCoord [[user(locn0)]]; -}; - -fragment main0_out main0(main0_in in [[stage_in]], constant uColor& _30 [[buffer(0)]], texture2d uTexture [[texture(0)]], sampler uSampler [[sampler(0)]]) -{ - main0_out out = {}; - float alpha = uTexture.sample(uSampler, in.vTexCoord).x * _30.color.w; - out.oFragColor = float4(_30.color.xyz, 1.0) * alpha; - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/debug_texture.vs.metal b/crates/pathfinder/resources/shaders/metal/debug_texture.vs.metal deleted file mode 100644 index 85e44c4c58..0000000000 --- a/crates/pathfinder/resources/shaders/metal/debug_texture.vs.metal +++ /dev/null @@ -1,37 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uTextureSize -{ - float2 _textureSize; -}; - -struct uFramebufferSize -{ - float2 framebufferSize; -}; - -struct main0_out -{ - float2 vTexCoord [[user(locn0)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aPosition [[attribute(0)]]; - int2 aTexCoord [[attribute(1)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]], constant uTextureSize& _18 [[buffer(0)]], constant uFramebufferSize& _31 [[buffer(1)]]) -{ - main0_out out = {}; - out.vTexCoord = float2(in.aTexCoord) / _18._textureSize; - float2 position = ((float2(in.aPosition) / _31.framebufferSize) * 2.0) - float2(1.0); - out.gl_Position = float4(position.x, -position.y, 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/demo_ground.fs.metal b/crates/pathfinder/resources/shaders/metal/demo_ground.fs.metal deleted file mode 100644 index 3cc7970440..0000000000 --- a/crates/pathfinder/resources/shaders/metal/demo_ground.fs.metal +++ /dev/null @@ -1,43 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uGridlineColor -{ - float4 gridlineColor; -}; - -struct uGroundColor -{ - float4 groundColor; -}; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -struct main0_in -{ - float2 vTexCoord [[user(locn0)]]; -}; - -fragment main0_out main0(main0_in in [[stage_in]], constant uGridlineColor& _33 [[buffer(0)]], constant uGroundColor& _42 [[buffer(1)]]) -{ - main0_out out = {}; - float2 texCoordPx = fract(in.vTexCoord) / fwidth(in.vTexCoord); - float4 _28; - if (any(texCoordPx <= float2(1.0))) - { - _28 = _33.gridlineColor; - } - else - { - _28 = _42.groundColor; - } - out.oFragColor = _28; - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/demo_ground.vs.metal b/crates/pathfinder/resources/shaders/metal/demo_ground.vs.metal deleted file mode 100644 index 24dc8e6fa9..0000000000 --- a/crates/pathfinder/resources/shaders/metal/demo_ground.vs.metal +++ /dev/null @@ -1,35 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uGridlineCount -{ - int gridlineCount; -}; - -struct uTransform -{ - float4x4 transform; -}; - -struct main0_out -{ - float2 vTexCoord [[user(locn0)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aPosition [[attribute(0)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]], constant uGridlineCount& _17 [[buffer(0)]], constant uTransform& _35 [[buffer(1)]]) -{ - main0_out out = {}; - out.vTexCoord = float2(in.aPosition * int2(_17.gridlineCount)); - out.gl_Position = _35.transform * float4(int4(in.aPosition.x, 0, in.aPosition.y, 1)); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/fill.cs.metal b/crates/pathfinder/resources/shaders/metal/fill.cs.metal deleted file mode 100644 index a6e16e550d..0000000000 --- a/crates/pathfinder/resources/shaders/metal/fill.cs.metal +++ /dev/null @@ -1,70 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#pragma clang diagnostic ignored "-Wmissing-prototypes" - -#include -#include - -using namespace metal; - -struct uFirstTileIndex -{ - int firstTileIndex; -}; - -struct bFillTileMap -{ - int iFillTileMap[1]; -}; - -struct bFills -{ - uint2 iFills[1]; -}; - -struct bNextFills -{ - int iNextFills[1]; -}; - -constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(16u, 4u, 1u); - -static inline __attribute__((always_inline)) -float4 computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d areaLUT, thread const sampler areaLUTSampler) -{ - float2 left = select(to, from, bool2(from.x < to.x)); - float2 right = select(from, to, bool2(from.x < to.x)); - float2 window = fast::clamp(float2(from.x, to.x), float2(-0.5), float2(0.5)); - float offset = mix(window.x, window.y, 0.5) - left.x; - float t = offset / (right.x - left.x); - float y = mix(left.y, right.y, t); - float d = (right.y - left.y) / (right.x - left.x); - float dX = window.x - window.y; - return areaLUT.sample(areaLUTSampler, (float2(y + 8.0, abs(d * dX)) / float2(16.0)), level(0.0)) * dX; -} - -kernel void main0(constant uFirstTileIndex& _147 [[buffer(0)]], const device bFillTileMap& _159 [[buffer(1)]], const device bFills& _180 [[buffer(2)]], const device bNextFills& _264 [[buffer(3)]], texture2d uAreaLUT [[texture(0)]], texture2d uDest [[texture(1)]], sampler uSampler [[sampler(0)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]) -{ - int2 tileSubCoord = int2(gl_LocalInvocationID.xy) * int2(1, 4); - uint tileIndexOffset = gl_WorkGroupID.z; - uint tileIndex = tileIndexOffset + uint(_147.firstTileIndex); - int fillIndex = _159.iFillTileMap[tileIndex]; - if (fillIndex < 0) - { - return; - } - float4 coverages = float4(0.0); - do - { - uint2 fill = _180.iFills[fillIndex]; - float2 from = float2(float(fill.y & 15u), float((fill.y >> 4u) & 15u)) + (float2(float(fill.x & 255u), float((fill.x >> 8u) & 255u)) / float2(256.0)); - float2 to = float2(float((fill.y >> 8u) & 15u), float((fill.y >> 12u) & 15u)) + (float2(float((fill.x >> 16u) & 255u), float((fill.x >> 24u) & 255u)) / float2(256.0)); - float2 param = from - (float2(tileSubCoord) + float2(0.5)); - float2 param_1 = to - (float2(tileSubCoord) + float2(0.5)); - coverages += computeCoverage(param, param_1, uAreaLUT, uSampler); - fillIndex = _264.iNextFills[fillIndex]; - } while (fillIndex >= 0); - int2 tileOrigin = int2(int(tileIndex & 255u), int((tileIndex >> 8u) & 255u)) * int2(16, 4); - int2 destCoord = tileOrigin + int2(gl_LocalInvocationID.xy); - uDest.write(coverages, uint2(destCoord)); -} - diff --git a/crates/pathfinder/resources/shaders/metal/fill.fs.metal b/crates/pathfinder/resources/shaders/metal/fill.fs.metal deleted file mode 100644 index 707127376f..0000000000 --- a/crates/pathfinder/resources/shaders/metal/fill.fs.metal +++ /dev/null @@ -1,42 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#pragma clang diagnostic ignored "-Wmissing-prototypes" - -#include -#include - -using namespace metal; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -struct main0_in -{ - float2 vFrom [[user(locn0)]]; - float2 vTo [[user(locn1)]]; -}; - -static inline __attribute__((always_inline)) -float4 computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d areaLUT, thread const sampler areaLUTSampler) -{ - float2 left = select(to, from, bool2(from.x < to.x)); - float2 right = select(from, to, bool2(from.x < to.x)); - float2 window = fast::clamp(float2(from.x, to.x), float2(-0.5), float2(0.5)); - float offset = mix(window.x, window.y, 0.5) - left.x; - float t = offset / (right.x - left.x); - float y = mix(left.y, right.y, t); - float d = (right.y - left.y) / (right.x - left.x); - float dX = window.x - window.y; - return areaLUT.sample(areaLUTSampler, (float2(y + 8.0, abs(d * dX)) / float2(16.0))) * dX; -} - -fragment main0_out main0(main0_in in [[stage_in]], texture2d uAreaLUT [[texture(0)]], sampler uSampler [[sampler(0)]]) -{ - main0_out out = {}; - float2 param = in.vFrom; - float2 param_1 = in.vTo; - out.oFragColor = computeCoverage(param, param_1, uAreaLUT, uSampler); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/fill.vs.metal b/crates/pathfinder/resources/shaders/metal/fill.vs.metal deleted file mode 100644 index 46404c296f..0000000000 --- a/crates/pathfinder/resources/shaders/metal/fill.vs.metal +++ /dev/null @@ -1,78 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#pragma clang diagnostic ignored "-Wmissing-prototypes" - -#include -#include - -using namespace metal; - -struct uTileSize -{ - float2 tileSize; -}; - -struct uFramebufferSize -{ - float2 framebufferSize; -}; - -struct main0_out -{ - float2 vFrom [[user(locn0)]]; - float2 vTo [[user(locn1)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - uint2 aTessCoord [[attribute(0)]]; - float2 aFromSubpx [[attribute(1)]]; - float2 aToSubpx [[attribute(2)]]; - uint aFromPx [[attribute(3)]]; - uint aToPx [[attribute(4)]]; - uint aTileIndex [[attribute(5)]]; -}; - -static inline __attribute__((always_inline)) -float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, constant uTileSize& v_20) -{ - uint tilesPerRow = uint(stencilTextureWidth / v_20.tileSize.x); - uint2 tileOffset = uint2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return (float2(tileOffset) * v_20.tileSize) * float2(1.0, 0.25); -} - -vertex main0_out main0(main0_in in [[stage_in]], constant uTileSize& v_20 [[buffer(0)]], constant uFramebufferSize& _57 [[buffer(1)]]) -{ - main0_out out = {}; - uint param = in.aTileIndex; - float param_1 = _57.framebufferSize.x; - float2 tileOrigin = computeTileOffset(param, param_1, v_20); - float2 from = float2(float(in.aFromPx & 15u), float(in.aFromPx >> 4u)) + in.aFromSubpx; - float2 to = float2(float(in.aToPx & 15u), float(in.aToPx >> 4u)) + in.aToSubpx; - float2 position; - if (in.aTessCoord.x == 0u) - { - position.x = floor(fast::min(from.x, to.x)); - } - else - { - position.x = ceil(fast::max(from.x, to.x)); - } - if (in.aTessCoord.y == 0u) - { - position.y = floor(fast::min(from.y, to.y)); - } - else - { - position.y = v_20.tileSize.y; - } - position.y = floor(position.y * 0.25); - float2 offset = float2(0.0, 1.5) - (position * float2(1.0, 4.0)); - out.vFrom = from + offset; - out.vTo = to + offset; - float2 globalPosition = (((tileOrigin + position) / _57.framebufferSize) * 2.0) - float2(1.0); - globalPosition.y = -globalPosition.y; - out.gl_Position = float4(globalPosition, 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/reproject.fs.metal b/crates/pathfinder/resources/shaders/metal/reproject.fs.metal deleted file mode 100644 index e39a88ecf5..0000000000 --- a/crates/pathfinder/resources/shaders/metal/reproject.fs.metal +++ /dev/null @@ -1,30 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uOldTransform -{ - float4x4 oldTransform; -}; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -struct main0_in -{ - float2 vTexCoord [[user(locn0)]]; -}; - -fragment main0_out main0(main0_in in [[stage_in]], constant uOldTransform& _13 [[buffer(0)]], texture2d uTexture [[texture(0)]], sampler uSampler [[sampler(0)]]) -{ - main0_out out = {}; - float4 normTexCoord = _13.oldTransform * float4(in.vTexCoord, 0.0, 1.0); - float2 texCoord = ((normTexCoord.xy / float2(normTexCoord.w)) + float2(1.0)) * 0.5; - out.oFragColor = uTexture.sample(uSampler, texCoord); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/reproject.vs.metal b/crates/pathfinder/resources/shaders/metal/reproject.vs.metal deleted file mode 100644 index a7cf025e0d..0000000000 --- a/crates/pathfinder/resources/shaders/metal/reproject.vs.metal +++ /dev/null @@ -1,32 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uNewTransform -{ - float4x4 newTransform; -}; - -struct main0_out -{ - float2 vTexCoord [[user(locn0)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aPosition [[attribute(0)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]], constant uNewTransform& _36 [[buffer(0)]]) -{ - main0_out out = {}; - float2 position = float2(in.aPosition); - out.vTexCoord = position; - position.y = 1.0 - position.y; - out.gl_Position = _36.newTransform * float4(position, 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/stencil.fs.metal b/crates/pathfinder/resources/shaders/metal/stencil.fs.metal deleted file mode 100644 index 999cc7e160..0000000000 --- a/crates/pathfinder/resources/shaders/metal/stencil.fs.metal +++ /dev/null @@ -1,18 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -fragment main0_out main0() -{ - main0_out out = {}; - out.oFragColor = float4(1.0, 0.0, 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/stencil.vs.metal b/crates/pathfinder/resources/shaders/metal/stencil.vs.metal deleted file mode 100644 index 6b6182d4b2..0000000000 --- a/crates/pathfinder/resources/shaders/metal/stencil.vs.metal +++ /dev/null @@ -1,23 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct main0_out -{ - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - float3 aPosition [[attribute(0)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]]) -{ - main0_out out = {}; - out.gl_Position = float4(in.aPosition, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/tile.fs.metal b/crates/pathfinder/resources/shaders/metal/tile.fs.metal deleted file mode 100644 index e2ac151910..0000000000 --- a/crates/pathfinder/resources/shaders/metal/tile.fs.metal +++ /dev/null @@ -1,639 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#pragma clang diagnostic ignored "-Wmissing-prototypes" - -#include -#include - -using namespace metal; - -struct uMaskTextureSize0 -{ - float2 iMaskTextureSize0; -}; - -struct uColorTextureSize0 -{ - float2 iColorTextureSize0; -}; - -struct uFramebufferSize -{ - float2 iFramebufferSize; -}; - -struct uFilterParams0 -{ - float4 iFilterParams0; -}; - -struct uFilterParams1 -{ - float4 iFilterParams1; -}; - -struct uFilterParams2 -{ - float4 iFilterParams2; -}; - -struct uCtrl -{ - int iCtrl; -}; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -struct main0_in -{ - float3 vMaskTexCoord0 [[user(locn0)]]; - float2 vColorTexCoord0 [[user(locn1)]]; - float4 vBaseColor [[user(locn2)]]; - float vTileCtrl [[user(locn3)]]; -}; - -// Implementation of the GLSL mod() function, which is slightly different than Metal fmod() -template -inline Tx mod(Tx x, Ty y) -{ - return x - y * floor(x / y); -} - -static inline __attribute__((always_inline)) -float sampleMask(thread const float& maskAlpha, thread const texture2d maskTexture, thread const float2& maskTextureSize, thread const float3& maskTexCoord, thread const int& maskCtrl, thread sampler uSampler) -{ - if (maskCtrl == 0) - { - return maskAlpha; - } - int2 maskTexCoordI = int2(floor(maskTexCoord.xy)); - float4 texel = maskTexture.sample(uSampler, ((float2(maskTexCoordI / int2(1, 4)) + float2(0.5)) / maskTextureSize)); - float coverage = texel[maskTexCoordI.y % 4] + maskTexCoord.z; - if ((maskCtrl & 1) != 0) - { - coverage = abs(coverage); - } - else - { - coverage = 1.0 - abs(1.0 - mod(coverage, 2.0)); - } - return fast::min(maskAlpha, coverage); -} - -static inline __attribute__((always_inline)) -float4 filterRadialGradient(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const float2& colorTextureSize, thread const float2& fragCoord, thread const float2& framebufferSize, thread const float4& filterParams0, thread const float4& filterParams1, thread sampler uSampler) -{ - float2 lineFrom = filterParams0.xy; - float2 lineVector = filterParams0.zw; - float2 radii = filterParams1.xy; - float2 uvOrigin = filterParams1.zw; - float2 dP = colorTexCoord - lineFrom; - float2 dC = lineVector; - float dR = radii.y - radii.x; - float a = dot(dC, dC) - (dR * dR); - float b = dot(dP, dC) + (radii.x * dR); - float c = dot(dP, dP) - (radii.x * radii.x); - float discrim = (b * b) - (a * c); - float4 color = float4(0.0); - if (abs(discrim) >= 9.9999997473787516355514526367188e-06) - { - float2 ts = float2((float2(1.0, -1.0) * sqrt(discrim)) + float2(b)) / float2(a); - if (ts.x > ts.y) - { - ts = ts.yx; - } - float _566; - if (ts.x >= 0.0) - { - _566 = ts.x; - } - else - { - _566 = ts.y; - } - float t = _566; - color = colorTexture.sample(uSampler, (uvOrigin + float2(fast::clamp(t, 0.0, 1.0), 0.0))); - } - return color; -} - -static inline __attribute__((always_inline)) -float4 filterBlur(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const float2& colorTextureSize, thread const float4& filterParams0, thread const float4& filterParams1, thread sampler uSampler) -{ - float2 srcOffsetScale = filterParams0.xy / colorTextureSize; - int support = int(filterParams0.z); - float3 gaussCoeff = filterParams1.xyz; - float gaussSum = gaussCoeff.x; - float4 color = colorTexture.sample(uSampler, colorTexCoord) * gaussCoeff.x; - float2 _615 = gaussCoeff.xy * gaussCoeff.yz; - gaussCoeff = float3(_615.x, _615.y, gaussCoeff.z); - for (int i = 1; i <= support; i += 2) - { - float gaussPartialSum = gaussCoeff.x; - float2 _635 = gaussCoeff.xy * gaussCoeff.yz; - gaussCoeff = float3(_635.x, _635.y, gaussCoeff.z); - gaussPartialSum += gaussCoeff.x; - float2 srcOffset = srcOffsetScale * (float(i) + (gaussCoeff.x / gaussPartialSum)); - color += ((colorTexture.sample(uSampler, (colorTexCoord - srcOffset)) + colorTexture.sample(uSampler, (colorTexCoord + srcOffset))) * gaussPartialSum); - gaussSum += (2.0 * gaussPartialSum); - float2 _679 = gaussCoeff.xy * gaussCoeff.yz; - gaussCoeff = float3(_679.x, _679.y, gaussCoeff.z); - } - return color / float4(gaussSum); -} - -static inline __attribute__((always_inline)) -float filterTextSample1Tap(thread const float& offset, thread const texture2d colorTexture, thread const float2& colorTexCoord, thread sampler uSampler) -{ - return colorTexture.sample(uSampler, (colorTexCoord + float2(offset, 0.0))).x; -} - -static inline __attribute__((always_inline)) -void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCenter, thread float4& outAlphaRight, thread const texture2d colorTexture, thread const float2& colorTexCoord, thread const float4& kernel0, thread const float& onePixel, thread sampler uSampler) -{ - bool wide = kernel0.x > 0.0; - float _243; - if (wide) - { - float param = (-4.0) * onePixel; - float2 param_1 = colorTexCoord; - _243 = filterTextSample1Tap(param, colorTexture, param_1, uSampler); - } - else - { - _243 = 0.0; - } - float param_2 = (-3.0) * onePixel; - float2 param_3 = colorTexCoord; - float param_4 = (-2.0) * onePixel; - float2 param_5 = colorTexCoord; - float param_6 = (-1.0) * onePixel; - float2 param_7 = colorTexCoord; - outAlphaLeft = float4(_243, filterTextSample1Tap(param_2, colorTexture, param_3, uSampler), filterTextSample1Tap(param_4, colorTexture, param_5, uSampler), filterTextSample1Tap(param_6, colorTexture, param_7, uSampler)); - float param_8 = 0.0; - float2 param_9 = colorTexCoord; - outAlphaCenter = filterTextSample1Tap(param_8, colorTexture, param_9, uSampler); - float param_10 = 1.0 * onePixel; - float2 param_11 = colorTexCoord; - float param_12 = 2.0 * onePixel; - float2 param_13 = colorTexCoord; - float param_14 = 3.0 * onePixel; - float2 param_15 = colorTexCoord; - float _303; - if (wide) - { - float param_16 = 4.0 * onePixel; - float2 param_17 = colorTexCoord; - _303 = filterTextSample1Tap(param_16, colorTexture, param_17, uSampler); - } - else - { - _303 = 0.0; - } - outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, param_11, uSampler), filterTextSample1Tap(param_12, colorTexture, param_13, uSampler), filterTextSample1Tap(param_14, colorTexture, param_15, uSampler), _303); -} - -static inline __attribute__((always_inline)) -float filterTextConvolve7Tap(thread const float4& alpha0, thread const float3& alpha1, thread const float4& kernel0) -{ - return dot(alpha0, kernel0) + dot(alpha1, kernel0.zyx); -} - -static inline __attribute__((always_inline)) -float filterTextGammaCorrectChannel(thread const float& bgColor, thread const float& fgColor, thread const texture2d gammaLUT, thread sampler uSampler) -{ - return gammaLUT.sample(uSampler, float2(fgColor, 1.0 - bgColor)).x; -} - -static inline __attribute__((always_inline)) -float3 filterTextGammaCorrect(thread const float3& bgColor, thread const float3& fgColor, thread const texture2d gammaLUT, thread sampler uSampler) -{ - float param = bgColor.x; - float param_1 = fgColor.x; - float param_2 = bgColor.y; - float param_3 = fgColor.y; - float param_4 = bgColor.z; - float param_5 = fgColor.z; - return float3(filterTextGammaCorrectChannel(param, param_1, gammaLUT, uSampler), filterTextGammaCorrectChannel(param_2, param_3, gammaLUT, uSampler), filterTextGammaCorrectChannel(param_4, param_5, gammaLUT, uSampler)); -} - -static inline __attribute__((always_inline)) -float4 filterText(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const texture2d gammaLUT, thread const float2& colorTextureSize, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread sampler uSampler) -{ - float4 kernel0 = filterParams0; - float3 bgColor = filterParams1.xyz; - float3 fgColor = filterParams2.xyz; - bool gammaCorrectionEnabled = filterParams2.w != 0.0; - float3 alpha; - if (kernel0.w == 0.0) - { - alpha = colorTexture.sample(uSampler, colorTexCoord).xxx; - } - else - { - float2 param_3 = colorTexCoord; - float4 param_4 = kernel0; - float param_5 = 1.0 / colorTextureSize.x; - float4 param; - float param_1; - float4 param_2; - filterTextSample9Tap(param, param_1, param_2, colorTexture, param_3, param_4, param_5, uSampler); - float4 alphaLeft = param; - float alphaCenter = param_1; - float4 alphaRight = param_2; - float4 param_6 = alphaLeft; - float3 param_7 = float3(alphaCenter, alphaRight.xy); - float4 param_8 = kernel0; - float r = filterTextConvolve7Tap(param_6, param_7, param_8); - float4 param_9 = float4(alphaLeft.yzw, alphaCenter); - float3 param_10 = alphaRight.xyz; - float4 param_11 = kernel0; - float g = filterTextConvolve7Tap(param_9, param_10, param_11); - float4 param_12 = float4(alphaLeft.zw, alphaCenter, alphaRight.x); - float3 param_13 = alphaRight.yzw; - float4 param_14 = kernel0; - float b = filterTextConvolve7Tap(param_12, param_13, param_14); - alpha = float3(r, g, b); - } - if (gammaCorrectionEnabled) - { - float3 param_15 = bgColor; - float3 param_16 = alpha; - alpha = filterTextGammaCorrect(param_15, param_16, gammaLUT, uSampler); - } - return float4(mix(bgColor, fgColor, alpha), 1.0); -} - -static inline __attribute__((always_inline)) -float4 sampleColor(thread const texture2d colorTexture, thread const float2& colorTexCoord, thread sampler uSampler) -{ - return colorTexture.sample(uSampler, colorTexCoord); -} - -static inline __attribute__((always_inline)) -float4 filterNone(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread sampler uSampler) -{ - float2 param = colorTexCoord; - return sampleColor(colorTexture, param, uSampler); -} - -static inline __attribute__((always_inline)) -float4 filterColor(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const texture2d gammaLUT, thread const float2& colorTextureSize, thread const float2& fragCoord, thread const float2& framebufferSize, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const int& colorFilter, thread sampler uSampler) -{ - switch (colorFilter) - { - case 1: - { - float2 param = colorTexCoord; - float2 param_1 = colorTextureSize; - float2 param_2 = fragCoord; - float2 param_3 = framebufferSize; - float4 param_4 = filterParams0; - float4 param_5 = filterParams1; - return filterRadialGradient(param, colorTexture, param_1, param_2, param_3, param_4, param_5, uSampler); - } - case 3: - { - float2 param_6 = colorTexCoord; - float2 param_7 = colorTextureSize; - float4 param_8 = filterParams0; - float4 param_9 = filterParams1; - return filterBlur(param_6, colorTexture, param_7, param_8, param_9, uSampler); - } - case 2: - { - float2 param_10 = colorTexCoord; - float2 param_11 = colorTextureSize; - float4 param_12 = filterParams0; - float4 param_13 = filterParams1; - float4 param_14 = filterParams2; - return filterText(param_10, colorTexture, gammaLUT, param_11, param_12, param_13, param_14, uSampler); - } - } - float2 param_15 = colorTexCoord; - return filterNone(param_15, colorTexture, uSampler); -} - -static inline __attribute__((always_inline)) -float4 combineColor0(thread const float4& destColor, thread const float4& srcColor, thread const int& op) -{ - switch (op) - { - case 1: - { - return float4(srcColor.xyz, srcColor.w * destColor.w); - } - case 2: - { - return float4(destColor.xyz, srcColor.w * destColor.w); - } - } - return destColor; -} - -static inline __attribute__((always_inline)) -float3 compositeScreen(thread const float3& destColor, thread const float3& srcColor) -{ - return (destColor + srcColor) - (destColor * srcColor); -} - -static inline __attribute__((always_inline)) -float3 compositeSelect(thread const bool3& cond, thread const float3& ifTrue, thread const float3& ifFalse) -{ - float _745; - if (cond.x) - { - _745 = ifTrue.x; - } - else - { - _745 = ifFalse.x; - } - float _756; - if (cond.y) - { - _756 = ifTrue.y; - } - else - { - _756 = ifFalse.y; - } - float _767; - if (cond.z) - { - _767 = ifTrue.z; - } - else - { - _767 = ifFalse.z; - } - return float3(_745, _756, _767); -} - -static inline __attribute__((always_inline)) -float3 compositeHardLight(thread const float3& destColor, thread const float3& srcColor) -{ - float3 param = destColor; - float3 param_1 = (float3(2.0) * srcColor) - float3(1.0); - bool3 param_2 = srcColor <= float3(0.5); - float3 param_3 = (destColor * float3(2.0)) * srcColor; - float3 param_4 = compositeScreen(param, param_1); - return compositeSelect(param_2, param_3, param_4); -} - -static inline __attribute__((always_inline)) -float3 compositeColorDodge(thread const float3& destColor, thread const float3& srcColor) -{ - bool3 destZero = destColor == float3(0.0); - bool3 srcOne = srcColor == float3(1.0); - bool3 param = srcOne; - float3 param_1 = float3(1.0); - float3 param_2 = destColor / (float3(1.0) - srcColor); - bool3 param_3 = destZero; - float3 param_4 = float3(0.0); - float3 param_5 = compositeSelect(param, param_1, param_2); - return compositeSelect(param_3, param_4, param_5); -} - -static inline __attribute__((always_inline)) -float3 compositeSoftLight(thread const float3& destColor, thread const float3& srcColor) -{ - bool3 param = destColor <= float3(0.25); - float3 param_1 = ((((float3(16.0) * destColor) - float3(12.0)) * destColor) + float3(4.0)) * destColor; - float3 param_2 = sqrt(destColor); - float3 darkenedDestColor = compositeSelect(param, param_1, param_2); - bool3 param_3 = srcColor <= float3(0.5); - float3 param_4 = destColor * (float3(1.0) - destColor); - float3 param_5 = darkenedDestColor - destColor; - float3 factor = compositeSelect(param_3, param_4, param_5); - return destColor + (((srcColor * 2.0) - float3(1.0)) * factor); -} - -static inline __attribute__((always_inline)) -float compositeDivide(thread const float& num, thread const float& denom) -{ - float _781; - if (denom != 0.0) - { - _781 = num / denom; - } - else - { - _781 = 0.0; - } - return _781; -} - -static inline __attribute__((always_inline)) -float3 compositeRGBToHSL(thread const float3& rgb) -{ - float v = fast::max(fast::max(rgb.x, rgb.y), rgb.z); - float xMin = fast::min(fast::min(rgb.x, rgb.y), rgb.z); - float c = v - xMin; - float l = mix(xMin, v, 0.5); - float3 _887; - if (rgb.x == v) - { - _887 = float3(0.0, rgb.yz); - } - else - { - float3 _900; - if (rgb.y == v) - { - _900 = float3(2.0, rgb.zx); - } - else - { - _900 = float3(4.0, rgb.xy); - } - _887 = _900; - } - float3 terms = _887; - float param = ((terms.x * c) + terms.y) - terms.z; - float param_1 = c; - float h = 1.0471975803375244140625 * compositeDivide(param, param_1); - float param_2 = c; - float param_3 = v; - float s = compositeDivide(param_2, param_3); - return float3(h, s, l); -} - -static inline __attribute__((always_inline)) -float3 compositeHSL(thread const float3& destColor, thread const float3& srcColor, thread const int& op) -{ - switch (op) - { - case 12: - { - return float3(srcColor.x, destColor.y, destColor.z); - } - case 13: - { - return float3(destColor.x, srcColor.y, destColor.z); - } - case 14: - { - return float3(srcColor.x, srcColor.y, destColor.z); - } - default: - { - return float3(destColor.x, destColor.y, srcColor.z); - } - } -} - -static inline __attribute__((always_inline)) -float3 compositeHSLToRGB(thread const float3& hsl) -{ - float a = hsl.y * fast::min(hsl.z, 1.0 - hsl.z); - float3 ks = mod(float3(0.0, 8.0, 4.0) + float3(hsl.x * 1.90985929965972900390625), float3(12.0)); - return hsl.zzz - (fast::clamp(fast::min(ks - float3(3.0), float3(9.0) - ks), float3(-1.0), float3(1.0)) * a); -} - -static inline __attribute__((always_inline)) -float3 compositeRGB(thread const float3& destColor, thread const float3& srcColor, thread const int& op) -{ - switch (op) - { - case 1: - { - return destColor * srcColor; - } - case 2: - { - float3 param = destColor; - float3 param_1 = srcColor; - return compositeScreen(param, param_1); - } - case 3: - { - float3 param_2 = srcColor; - float3 param_3 = destColor; - return compositeHardLight(param_2, param_3); - } - case 4: - { - return fast::min(destColor, srcColor); - } - case 5: - { - return fast::max(destColor, srcColor); - } - case 6: - { - float3 param_4 = destColor; - float3 param_5 = srcColor; - return compositeColorDodge(param_4, param_5); - } - case 7: - { - float3 param_6 = float3(1.0) - destColor; - float3 param_7 = float3(1.0) - srcColor; - return float3(1.0) - compositeColorDodge(param_6, param_7); - } - case 8: - { - float3 param_8 = destColor; - float3 param_9 = srcColor; - return compositeHardLight(param_8, param_9); - } - case 9: - { - float3 param_10 = destColor; - float3 param_11 = srcColor; - return compositeSoftLight(param_10, param_11); - } - case 10: - { - return abs(destColor - srcColor); - } - case 11: - { - return (destColor + srcColor) - ((float3(2.0) * destColor) * srcColor); - } - case 12: - case 13: - case 14: - case 15: - { - float3 param_12 = destColor; - float3 param_13 = srcColor; - float3 param_14 = compositeRGBToHSL(param_12); - float3 param_15 = compositeRGBToHSL(param_13); - int param_16 = op; - float3 param_17 = compositeHSL(param_14, param_15, param_16); - return compositeHSLToRGB(param_17); - } - } - return srcColor; -} - -static inline __attribute__((always_inline)) -float4 composite(thread const float4& srcColor, thread const texture2d destTexture, thread const float2& destTextureSize, thread const float2& fragCoord, thread const int& op, thread sampler uSampler) -{ - if (op == 0) - { - return srcColor; - } - float2 destTexCoord = fragCoord / destTextureSize; - float4 destColor = destTexture.sample(uSampler, destTexCoord); - float3 param = destColor.xyz; - float3 param_1 = srcColor.xyz; - int param_2 = op; - float3 blendedRGB = compositeRGB(param, param_1, param_2); - return float4(((srcColor.xyz * (srcColor.w * (1.0 - destColor.w))) + (blendedRGB * (srcColor.w * destColor.w))) + (destColor.xyz * (1.0 - srcColor.w)), 1.0); -} - -static inline __attribute__((always_inline)) -void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread sampler uSampler, thread texture2d uMaskTexture0, constant uMaskTextureSize0& v_1279, thread float3& vMaskTexCoord0, thread float4& vBaseColor, thread float2& vColorTexCoord0, thread texture2d uColorTexture0, thread texture2d uGammaLUT, constant uColorTextureSize0& v_1317, thread float4& gl_FragCoord, constant uFramebufferSize& v_1321, constant uFilterParams0& v_1324, constant uFilterParams1& v_1327, constant uFilterParams2& v_1330, thread texture2d uDestTexture, thread float4& oFragColor) -{ - int maskCtrl0 = (tileCtrl >> 0) & 3; - float maskAlpha = 1.0; - float param = maskAlpha; - float2 param_1 = v_1279.iMaskTextureSize0; - float3 param_2 = vMaskTexCoord0; - int param_3 = maskCtrl0; - maskAlpha = sampleMask(param, uMaskTexture0, param_1, param_2, param_3, uSampler); - float4 color = vBaseColor; - int color0Combine = (ctrl >> 6) & 3; - if (color0Combine != 0) - { - int color0Filter = (ctrl >> 4) & 3; - float2 param_4 = vColorTexCoord0; - float2 param_5 = v_1317.iColorTextureSize0; - float2 param_6 = gl_FragCoord.xy; - float2 param_7 = v_1321.iFramebufferSize; - float4 param_8 = v_1324.iFilterParams0; - float4 param_9 = v_1327.iFilterParams1; - float4 param_10 = v_1330.iFilterParams2; - int param_11 = color0Filter; - float4 color0 = filterColor(param_4, uColorTexture0, uGammaLUT, param_5, param_6, param_7, param_8, param_9, param_10, param_11, uSampler); - float4 param_12 = color; - float4 param_13 = color0; - int param_14 = color0Combine; - color = combineColor0(param_12, param_13, param_14); - } - color.w *= maskAlpha; - int compositeOp = (ctrl >> 8) & 15; - float4 param_15 = color; - float2 param_16 = v_1321.iFramebufferSize; - float2 param_17 = gl_FragCoord.xy; - int param_18 = compositeOp; - color = composite(param_15, uDestTexture, param_16, param_17, param_18, uSampler); - float3 _1389 = color.xyz * color.w; - color = float4(_1389.x, _1389.y, _1389.z, color.w); - oFragColor = color; -} - -fragment main0_out main0(main0_in in [[stage_in]], constant uMaskTextureSize0& v_1279 [[buffer(0)]], constant uColorTextureSize0& v_1317 [[buffer(1)]], constant uFramebufferSize& v_1321 [[buffer(2)]], constant uFilterParams0& v_1324 [[buffer(3)]], constant uFilterParams1& v_1327 [[buffer(4)]], constant uFilterParams2& v_1330 [[buffer(5)]], constant uCtrl& _1401 [[buffer(6)]], texture2d uMaskTexture0 [[texture(0)]], texture2d uColorTexture0 [[texture(1)]], texture2d uGammaLUT [[texture(2)]], texture2d uDestTexture [[texture(3)]], sampler uSampler [[sampler(0)]], float4 gl_FragCoord [[position]]) -{ - main0_out out = {}; - int param = int(in.vTileCtrl); - int param_1 = _1401.iCtrl; - calculateColor(param, param_1, uSampler, uMaskTexture0, v_1279, in.vMaskTexCoord0, in.vBaseColor, in.vColorTexCoord0, uColorTexture0, uGammaLUT, v_1317, gl_FragCoord, v_1321, v_1324, v_1327, v_1330, uDestTexture, out.oFragColor); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/tile.vs.metal b/crates/pathfinder/resources/shaders/metal/tile.vs.metal deleted file mode 100644 index 35a40cc57f..0000000000 --- a/crates/pathfinder/resources/shaders/metal/tile.vs.metal +++ /dev/null @@ -1,63 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uTileSize -{ - float2 tileSize; -}; - -struct uTextureMetadataSize -{ - int2 textureMetadataSize; -}; - -struct uTransform -{ - float4x4 transform; -}; - -struct main0_out -{ - float3 vMaskTexCoord0 [[user(locn0)]]; - float2 vColorTexCoord0 [[user(locn1)]]; - float4 vBaseColor [[user(locn2)]]; - float vTileCtrl [[user(locn3)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aTileOffset [[attribute(0)]]; - int2 aTileOrigin [[attribute(1)]]; - uint2 aMaskTexCoord0 [[attribute(2)]]; - int2 aMaskBackdrop [[attribute(3)]]; - int aColor [[attribute(4)]]; - int aTileCtrl [[attribute(5)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]], constant uTileSize& _26 [[buffer(0)]], constant uTextureMetadataSize& _49 [[buffer(1)]], constant uTransform& _161 [[buffer(2)]], texture2d uTextureMetadata [[texture(0)]], sampler uSampler [[sampler(0)]]) -{ - main0_out out = {}; - float2 tileOrigin = float2(in.aTileOrigin); - float2 tileOffset = float2(in.aTileOffset); - float2 position = (tileOrigin + tileOffset) * _26.tileSize; - float2 maskTexCoord0 = (float2(in.aMaskTexCoord0) + tileOffset) * _26.tileSize; - float2 textureMetadataScale = float2(1.0) / float2(_49.textureMetadataSize); - float2 metadataEntryCoord = float2(float((in.aColor % 128) * 4), float(in.aColor / 128)); - float2 colorTexMatrix0Coord = (metadataEntryCoord + float2(0.5)) * textureMetadataScale; - float2 colorTexOffsetsCoord = (metadataEntryCoord + float2(1.5, 0.5)) * textureMetadataScale; - float2 baseColorCoord = (metadataEntryCoord + float2(2.5, 0.5)) * textureMetadataScale; - float4 colorTexMatrix0 = uTextureMetadata.sample(uSampler, colorTexMatrix0Coord, level(0.0)); - float4 colorTexOffsets = uTextureMetadata.sample(uSampler, colorTexOffsetsCoord, level(0.0)); - float4 baseColor = uTextureMetadata.sample(uSampler, baseColorCoord, level(0.0)); - out.vColorTexCoord0 = (float2x2(float2(colorTexMatrix0.xy), float2(colorTexMatrix0.zw)) * position) + colorTexOffsets.xy; - out.vMaskTexCoord0 = float3(maskTexCoord0, float(in.aMaskBackdrop.x)); - out.vBaseColor = baseColor; - out.vTileCtrl = float(in.aTileCtrl); - out.gl_Position = _161.transform * float4(position, 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/tile_clip.fs.metal b/crates/pathfinder/resources/shaders/metal/tile_clip.fs.metal deleted file mode 100644 index 03baf4b4d0..0000000000 --- a/crates/pathfinder/resources/shaders/metal/tile_clip.fs.metal +++ /dev/null @@ -1,24 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -struct main0_in -{ - float2 vTexCoord [[user(locn0)]]; - float vBackdrop [[user(locn1)]]; -}; - -fragment main0_out main0(main0_in in [[stage_in]], texture2d uSrc [[texture(0)]], sampler uSampler [[sampler(0)]]) -{ - main0_out out = {}; - out.oFragColor = fast::clamp(abs(uSrc.sample(uSampler, in.vTexCoord) + float4(in.vBackdrop)), float4(0.0), float4(1.0)); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/tile_clip.vs.metal b/crates/pathfinder/resources/shaders/metal/tile_clip.vs.metal deleted file mode 100644 index 3e3a6baf7c..0000000000 --- a/crates/pathfinder/resources/shaders/metal/tile_clip.vs.metal +++ /dev/null @@ -1,32 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct main0_out -{ - float2 vTexCoord [[user(locn0)]]; - float vBackdrop [[user(locn1)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aTileOffset [[attribute(0)]]; - int2 aDestTileOrigin [[attribute(1)]]; - int2 aSrcTileOrigin [[attribute(2)]]; - int aSrcBackdrop [[attribute(3)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]]) -{ - main0_out out = {}; - float2 destPosition = float2(in.aDestTileOrigin + in.aTileOffset) / float2(256.0); - float2 srcPosition = float2(in.aSrcTileOrigin + in.aTileOffset) / float2(256.0); - out.vTexCoord = srcPosition; - out.vBackdrop = float(in.aSrcBackdrop); - out.gl_Position = float4(mix(float2(-1.0), float2(1.0), destPosition), 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/tile_copy.fs.metal b/crates/pathfinder/resources/shaders/metal/tile_copy.fs.metal deleted file mode 100644 index 4106ef58b5..0000000000 --- a/crates/pathfinder/resources/shaders/metal/tile_copy.fs.metal +++ /dev/null @@ -1,24 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uFramebufferSize -{ - float2 framebufferSize; -}; - -struct main0_out -{ - float4 oFragColor [[color(0)]]; -}; - -fragment main0_out main0(constant uFramebufferSize& _17 [[buffer(0)]], texture2d uSrc [[texture(0)]], sampler uSampler [[sampler(0)]], float4 gl_FragCoord [[position]]) -{ - main0_out out = {}; - float2 texCoord = gl_FragCoord.xy / _17.framebufferSize; - out.oFragColor = uSrc.sample(uSampler, texCoord); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/metal/tile_copy.vs.metal b/crates/pathfinder/resources/shaders/metal/tile_copy.vs.metal deleted file mode 100644 index baa3b90263..0000000000 --- a/crates/pathfinder/resources/shaders/metal/tile_copy.vs.metal +++ /dev/null @@ -1,34 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct uTileSize -{ - float2 tileSize; -}; - -struct uTransform -{ - float4x4 transform; -}; - -struct main0_out -{ - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aTilePosition [[attribute(0)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]], constant uTileSize& _18 [[buffer(0)]], constant uTransform& _34 [[buffer(1)]]) -{ - main0_out out = {}; - float2 position = float2(in.aTilePosition) * _18.tileSize; - out.gl_Position = _34.transform * float4(position, 0.0, 1.0); - return out; -} - diff --git a/crates/pathfinder/resources/shaders/vulkan/blit.fs.spv b/crates/pathfinder/resources/shaders/vulkan/blit.fs.spv deleted file mode 100644 index dca202be50..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/blit.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/blit.vs.spv b/crates/pathfinder/resources/shaders/vulkan/blit.vs.spv deleted file mode 100644 index 354b57fbf1..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/blit.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/clear.fs.spv b/crates/pathfinder/resources/shaders/vulkan/clear.fs.spv deleted file mode 100644 index a03bd936c0..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/clear.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/clear.vs.spv b/crates/pathfinder/resources/shaders/vulkan/clear.vs.spv deleted file mode 100644 index 4a75e1d19b..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/clear.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/debug_solid.fs.spv b/crates/pathfinder/resources/shaders/vulkan/debug_solid.fs.spv deleted file mode 100644 index c2c23b843d..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/debug_solid.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/debug_solid.vs.spv b/crates/pathfinder/resources/shaders/vulkan/debug_solid.vs.spv deleted file mode 100644 index 850396e992..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/debug_solid.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/debug_texture.fs.spv b/crates/pathfinder/resources/shaders/vulkan/debug_texture.fs.spv deleted file mode 100644 index 526a0c377e..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/debug_texture.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/debug_texture.vs.spv b/crates/pathfinder/resources/shaders/vulkan/debug_texture.vs.spv deleted file mode 100644 index 9a5ab3739d..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/debug_texture.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/demo_ground.fs.spv b/crates/pathfinder/resources/shaders/vulkan/demo_ground.fs.spv deleted file mode 100644 index eecbff831e..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/demo_ground.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/demo_ground.vs.spv b/crates/pathfinder/resources/shaders/vulkan/demo_ground.vs.spv deleted file mode 100644 index 998fc9eaeb..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/demo_ground.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/fill.cs.spv b/crates/pathfinder/resources/shaders/vulkan/fill.cs.spv deleted file mode 100644 index 3531bf25da..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/fill.cs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/fill.fs.spv b/crates/pathfinder/resources/shaders/vulkan/fill.fs.spv deleted file mode 100644 index f8e75b74a6..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/fill.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/fill.vs.spv b/crates/pathfinder/resources/shaders/vulkan/fill.vs.spv deleted file mode 100644 index 5ab3299b1e..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/fill.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/reproject.fs.spv b/crates/pathfinder/resources/shaders/vulkan/reproject.fs.spv deleted file mode 100644 index e40464c805..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/reproject.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/reproject.vs.spv b/crates/pathfinder/resources/shaders/vulkan/reproject.vs.spv deleted file mode 100644 index 1104e14b75..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/reproject.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/stencil.fs.spv b/crates/pathfinder/resources/shaders/vulkan/stencil.fs.spv deleted file mode 100644 index 63f7fd7d32..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/stencil.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/stencil.vs.spv b/crates/pathfinder/resources/shaders/vulkan/stencil.vs.spv deleted file mode 100644 index 6fc53e39d2..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/stencil.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/tile.fs.spv b/crates/pathfinder/resources/shaders/vulkan/tile.fs.spv deleted file mode 100644 index ec9928be02..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/tile.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/tile.vs.spv b/crates/pathfinder/resources/shaders/vulkan/tile.vs.spv deleted file mode 100644 index 9aa290e96f..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/tile.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/tile_clip.fs.spv b/crates/pathfinder/resources/shaders/vulkan/tile_clip.fs.spv deleted file mode 100644 index f1169cdb2c..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/tile_clip.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/tile_clip.vs.spv b/crates/pathfinder/resources/shaders/vulkan/tile_clip.vs.spv deleted file mode 100644 index e6618d85f5..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/tile_clip.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/tile_copy.fs.spv b/crates/pathfinder/resources/shaders/vulkan/tile_copy.fs.spv deleted file mode 100644 index f0ca4c00c4..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/tile_copy.fs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/shaders/vulkan/tile_copy.vs.spv b/crates/pathfinder/resources/shaders/vulkan/tile_copy.vs.spv deleted file mode 100644 index d48eab7232..0000000000 Binary files a/crates/pathfinder/resources/shaders/vulkan/tile_copy.vs.spv and /dev/null differ diff --git a/crates/pathfinder/resources/src/embedded.rs b/crates/pathfinder/resources/src/embedded.rs deleted file mode 100644 index e9879cde69..0000000000 --- a/crates/pathfinder/resources/src/embedded.rs +++ /dev/null @@ -1,34 +0,0 @@ -// pathfinder/resources/src/embedded.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Embeds needed resources statically in the binary. - -use crate::ResourceLoader; -use std::io::{Error as IOError, ErrorKind}; - -include!(concat!(env!("OUT_DIR"), "/manifest.rs")); - -pub struct EmbeddedResourceLoader; - -impl EmbeddedResourceLoader { - #[inline] - pub fn new() -> EmbeddedResourceLoader { - EmbeddedResourceLoader - } -} - -impl ResourceLoader for EmbeddedResourceLoader { - fn slurp(&self, virtual_path: &str) -> Result, IOError> { - match RESOURCES.iter().filter(|&(path, _)| *path == virtual_path).next() { - Some((_, data)) => Ok(data.to_vec()), - None => Err(IOError::from(ErrorKind::NotFound)), - } - } -} diff --git a/crates/pathfinder/resources/src/fs.rs b/crates/pathfinder/resources/src/fs.rs deleted file mode 100644 index 37ffec91bb..0000000000 --- a/crates/pathfinder/resources/src/fs.rs +++ /dev/null @@ -1,62 +0,0 @@ -// pathfinder/resources/src/fs.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Reads resources from the filesystem. - -use crate::ResourceLoader; -use std::env; -use std::fs::File; -use std::io::{Error as IOError, Read}; -use std::path::PathBuf; - -pub struct FilesystemResourceLoader { - pub directory: PathBuf, -} - -impl FilesystemResourceLoader { - pub fn locate() -> FilesystemResourceLoader { - let mut parent_directory = env::current_dir().unwrap(); - loop { - // So ugly :( - let mut resources_directory = parent_directory.clone(); - resources_directory.push("resources"); - if resources_directory.is_dir() { - let mut shaders_directory = resources_directory.clone(); - let mut textures_directory = resources_directory.clone(); - shaders_directory.push("shaders"); - textures_directory.push("textures"); - if shaders_directory.is_dir() && textures_directory.is_dir() { - return FilesystemResourceLoader { - directory: resources_directory, - }; - } - } - - if !parent_directory.pop() { - break; - } - } - - panic!("No suitable `resources/` directory found!"); - } -} - -impl ResourceLoader for FilesystemResourceLoader { - fn slurp(&self, virtual_path: &str) -> Result, IOError> { - let mut path = self.directory.clone(); - virtual_path - .split('/') - .for_each(|segment| path.push(segment)); - - let mut data = vec![]; - File::open(&path)?.read_to_end(&mut data)?; - Ok(data) - } -} diff --git a/crates/pathfinder/resources/src/lib.rs b/crates/pathfinder/resources/src/lib.rs deleted file mode 100644 index 33fe80c5eb..0000000000 --- a/crates/pathfinder/resources/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -// pathfinder/resources/src/lib.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! An abstraction for reading resources. -//! -//! This accomplishes two purposes over just using the filesystem to locate shaders and so forth: -//! -//! 1. Downstream users of Pathfinder shouldn't be burdened with having to install the resources -//! alongside their binary. -//! -//! 2. There may not be a traditional filesystem available, as for example is the case on Android. - -use std::io::Error as IOError; - -pub mod embedded; -pub mod fs; - -pub trait ResourceLoader { - /// This is deliberately not a `Path`, because these are virtual paths - /// that do not necessarily correspond to real paths on a filesystem. - fn slurp(&self, path: &str) -> Result, IOError>; -} diff --git a/crates/pathfinder/resources/svg/Ghostscript_Tiger.svg b/crates/pathfinder/resources/svg/Ghostscript_Tiger.svg deleted file mode 100644 index 033611d911..0000000000 --- a/crates/pathfinder/resources/svg/Ghostscript_Tiger.svg +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/crates/pathfinder/resources/svg/julius-caesar-with-bg.svg b/crates/pathfinder/resources/svg/julius-caesar-with-bg.svg deleted file mode 100644 index bdcd8f2a0f..0000000000 --- a/crates/pathfinder/resources/svg/julius-caesar-with-bg.svg +++ /dev/null @@ -1,10599 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/crates/pathfinder/resources/svg/julius-caesar.svg b/crates/pathfinder/resources/svg/julius-caesar.svg deleted file mode 100644 index 89ece6ce66..0000000000 --- a/crates/pathfinder/resources/svg/julius-caesar.svg +++ /dev/null @@ -1,1478 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/crates/pathfinder/resources/svg/magicleap-quickstart-p03.svg b/crates/pathfinder/resources/svg/magicleap-quickstart-p03.svg deleted file mode 100644 index dce06ca02e..0000000000 --- a/crates/pathfinder/resources/svg/magicleap-quickstart-p03.svg +++ /dev/null @@ -1,2685 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/crates/pathfinder/resources/svg/material_design_icons.svg b/crates/pathfinder/resources/svg/material_design_icons.svg deleted file mode 100644 index e9d98180be..0000000000 --- a/crates/pathfinder/resources/svg/material_design_icons.svg +++ /dev/null @@ -1,2862 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/crates/pathfinder/resources/svg/nba-notext.svg b/crates/pathfinder/resources/svg/nba-notext.svg deleted file mode 100644 index 898650f51f..0000000000 --- a/crates/pathfinder/resources/svg/nba-notext.svg +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/crates/pathfinder/resources/svg/paper.svg b/crates/pathfinder/resources/svg/paper.svg deleted file mode 100644 index 5544d478a2..0000000000 --- a/crates/pathfinder/resources/svg/paper.svg +++ /dev/null @@ -1,25021 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/crates/pathfinder/resources/svg/pathfinder-magicleap-demo.svg b/crates/pathfinder/resources/svg/pathfinder-magicleap-demo.svg deleted file mode 100644 index d27cbf3516..0000000000 --- a/crates/pathfinder/resources/svg/pathfinder-magicleap-demo.svg +++ /dev/null @@ -1,4106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/crates/pathfinder/resources/svg/pathfinder_logo.svg b/crates/pathfinder/resources/svg/pathfinder_logo.svg deleted file mode 100644 index ebae08bc0c..0000000000 --- a/crates/pathfinder/resources/svg/pathfinder_logo.svg +++ /dev/null @@ -1,115 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/crates/pathfinder/resources/swf/tiger-flat.swf b/crates/pathfinder/resources/swf/tiger-flat.swf deleted file mode 100644 index 70127188f5..0000000000 Binary files a/crates/pathfinder/resources/swf/tiger-flat.swf and /dev/null differ diff --git a/crates/pathfinder/resources/swf/tiger.swf b/crates/pathfinder/resources/swf/tiger.swf deleted file mode 100644 index 9bb17c65a7..0000000000 Binary files a/crates/pathfinder/resources/swf/tiger.swf and /dev/null differ diff --git a/crates/pathfinder/resources/textures/area-lut.png b/crates/pathfinder/resources/textures/area-lut.png deleted file mode 100644 index 19b31cbfcd..0000000000 Binary files a/crates/pathfinder/resources/textures/area-lut.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/debug-corner-fill.png b/crates/pathfinder/resources/textures/debug-corner-fill.png deleted file mode 100644 index 499770473f..0000000000 Binary files a/crates/pathfinder/resources/textures/debug-corner-fill.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/debug-corner-outline.png b/crates/pathfinder/resources/textures/debug-corner-outline.png deleted file mode 100644 index f3bce5267f..0000000000 Binary files a/crates/pathfinder/resources/textures/debug-corner-outline.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/debug-font.png b/crates/pathfinder/resources/textures/debug-font.png deleted file mode 100644 index 82641e97f4..0000000000 Binary files a/crates/pathfinder/resources/textures/debug-font.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/demo-background.png b/crates/pathfinder/resources/textures/demo-background.png deleted file mode 100644 index c1d067373e..0000000000 Binary files a/crates/pathfinder/resources/textures/demo-background.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/demo-effects.png b/crates/pathfinder/resources/textures/demo-effects.png deleted file mode 100644 index 70a0a5e7d8..0000000000 Binary files a/crates/pathfinder/resources/textures/demo-effects.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/demo-open.png b/crates/pathfinder/resources/textures/demo-open.png deleted file mode 100644 index aa53bf09b3..0000000000 Binary files a/crates/pathfinder/resources/textures/demo-open.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/demo-rotate.png b/crates/pathfinder/resources/textures/demo-rotate.png deleted file mode 100644 index ae83112030..0000000000 Binary files a/crates/pathfinder/resources/textures/demo-rotate.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/demo-screenshot.png b/crates/pathfinder/resources/textures/demo-screenshot.png deleted file mode 100644 index 61fe995164..0000000000 Binary files a/crates/pathfinder/resources/textures/demo-screenshot.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/demo-zoom-actual-size.png b/crates/pathfinder/resources/textures/demo-zoom-actual-size.png deleted file mode 100644 index a7013e6e31..0000000000 Binary files a/crates/pathfinder/resources/textures/demo-zoom-actual-size.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/demo-zoom-in.png b/crates/pathfinder/resources/textures/demo-zoom-in.png deleted file mode 100644 index 1518f8a5aa..0000000000 Binary files a/crates/pathfinder/resources/textures/demo-zoom-in.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/demo-zoom-out.png b/crates/pathfinder/resources/textures/demo-zoom-out.png deleted file mode 100644 index e97ee503b4..0000000000 Binary files a/crates/pathfinder/resources/textures/demo-zoom-out.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/example-nanovg.png b/crates/pathfinder/resources/textures/example-nanovg.png deleted file mode 100644 index 84b2acc1c0..0000000000 Binary files a/crates/pathfinder/resources/textures/example-nanovg.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/gamma-lut.png b/crates/pathfinder/resources/textures/gamma-lut.png deleted file mode 100644 index ff0cad1579..0000000000 Binary files a/crates/pathfinder/resources/textures/gamma-lut.png and /dev/null differ diff --git a/crates/pathfinder/resources/textures/pathfinder-logo.png b/crates/pathfinder/resources/textures/pathfinder-logo.png deleted file mode 100644 index c17f5d4431..0000000000 Binary files a/crates/pathfinder/resources/textures/pathfinder-logo.png and /dev/null differ diff --git a/crates/pathfinder/shaders/Makefile b/crates/pathfinder/shaders/Makefile deleted file mode 100644 index 67aebe9226..0000000000 --- a/crates/pathfinder/shaders/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -TARGET_DIR?=../resources/shaders - -EMPTY= - -SHADERS=\ - blit.fs.glsl \ - blit.vs.glsl \ - clear.fs.glsl \ - clear.vs.glsl \ - debug_solid.fs.glsl \ - debug_solid.vs.glsl \ - debug_texture.fs.glsl \ - debug_texture.vs.glsl \ - demo_ground.fs.glsl \ - demo_ground.vs.glsl \ - fill.fs.glsl \ - fill.vs.glsl \ - reproject.fs.glsl \ - reproject.vs.glsl \ - stencil.fs.glsl \ - stencil.vs.glsl \ - tile.fs.glsl \ - tile.vs.glsl \ - tile_clip.fs.glsl \ - tile_clip.vs.glsl \ - tile_copy.fs.glsl \ - tile_copy.vs.glsl \ - $(EMPTY) - -COMPUTE_SHADERS=\ - fill.cs.glsl \ - $(EMPTY) - -INCLUDES=\ - fill.inc.glsl \ - $(EMPTY) - -OUT=\ - $(SHADERS:%=$(TARGET_DIR)/gl3/%) \ - $(SHADERS:%=$(TARGET_DIR)/gl4/%) \ - $(SHADERS:%.glsl=$(TARGET_DIR)/metal/%.metal) \ - $(SHADERS:%.glsl=build/metal/%.spv) \ - $(SHADERS:%.glsl=$(TARGET_DIR)/vulkan/%.spv) \ - $(COMPUTE_SHADERS:%.glsl=$(TARGET_DIR)/metal/%.metal) \ - $(COMPUTE_SHADERS:%.glsl=build/metal/%.spv) \ - $(COMPUTE_SHADERS:%.glsl=$(TARGET_DIR)/gl4/%.glsl) \ - $(COMPUTE_SHADERS:%.glsl=$(TARGET_DIR)/vulkan/%.spv) \ - $(EMPTY) - -GLSL_3_VERSION=330 -GLSL_4_VERSION=430 -GLSLANGFLAGS=--auto-map-locations -I. -GLSLANGFLAGS_METAL=$(GLSLANGFLAGS) -DPF_ORIGIN_UPPER_LEFT=1 -GLSLANGFLAGS_VULKAN=$(GLSLANGFLAGS) - -SPIRVCROSS?=spirv-cross -SPIRVCROSSFLAGS_METAL=--msl --msl-version 020100 -SPIRVCROSSFLAGS_GL3=--version $(GLSL_3_VERSION) --no-420pack-extension --glsl-emit-ubo-as-plain-uniforms --flatten-ubo --combined-samplers-inherit-bindings -SPIRVCROSSFLAGS_GL4=--version $(GLSL_4_VERSION) --glsl-emit-ubo-as-plain-uniforms --flatten-ubo --combined-samplers-inherit-bindings - -GLSL_VERSION_HEADER="\#version {{version}}" -HEADER="// Automatically generated from files in pathfinder/shaders/. Do not edit!" - -GLSL_SED_ARGS=-e "s/\#version .*//" -e "s/\#line.*$$//" - -all: $(OUT) - -.PHONY: clean - -clean: - rm -f $(OUT) - -build/metal/%.fs.spv: %.fs.glsl $(INCLUDES) - mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -V -S frag -o $@ $< - -build/metal/%.vs.spv: %.vs.glsl $(INCLUDES) - mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -V -S vert -o $@ $< - -build/metal/%.cs.spv: %.cs.glsl $(INCLUDES) - mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -V -S comp -o $@ $< - -$(TARGET_DIR)/metal/%.metal: build/metal/%.spv - mkdir -p $(TARGET_DIR)/metal && echo $(HEADER) > $@ && ( $(SPIRVCROSS) $(SPIRVCROSSFLAGS_METAL) $< >> $@ ) || ( rm $@ && exit 1 ) - -$(TARGET_DIR)/vulkan/%.vs.spv: %.vs.glsl $(INCLUDES) - mkdir -p $(TARGET_DIR)/vulkan && glslangValidator $(GLSLANGFLAGS_VULKAN) -V -S vert -o $@ $< - -$(TARGET_DIR)/vulkan/%.fs.spv: %.fs.glsl $(INCLUDES) - mkdir -p $(TARGET_DIR)/vulkan && glslangValidator $(GLSLANGFLAGS_VULKAN) -V -S frag -o $@ $< - -$(TARGET_DIR)/vulkan/%.cs.spv: %.cs.glsl $(INCLUDES) - mkdir -p $(TARGET_DIR)/vulkan && glslangValidator $(GLSLANGFLAGS_VULKAN) -V -S comp -o $@ $< - -$(TARGET_DIR)/gl3/%.glsl: $(TARGET_DIR)/vulkan/%.spv - mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( $(SPIRVCROSS) $(SPIRVCROSSFLAGS_GL3) $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 ) - -$(TARGET_DIR)/gl4/%.glsl: $(TARGET_DIR)/vulkan/%.spv - mkdir -p $(TARGET_DIR)/gl4 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( $(SPIRVCROSS) $(SPIRVCROSSFLAGS_GL4) $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 ) \ No newline at end of file diff --git a/crates/pathfinder/shaders/blit.fs.glsl b/crates/pathfinder/shaders/blit.fs.glsl deleted file mode 100644 index 027a3f1104..0000000000 --- a/crates/pathfinder/shaders/blit.fs.glsl +++ /dev/null @@ -1,29 +0,0 @@ -#version 450 - -// pathfinder/shaders/blit.fs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=0) uniform texture2D uSrc; -layout(set=0, binding=1) uniform sampler uSampler; - -in vec2 vTexCoord; - -out vec4 oFragColor; - -void main() { - vec4 color = texture(sampler2D(uSrc, uSampler), vTexCoord); - oFragColor = vec4(color.rgb * color.a, color.a); -} diff --git a/crates/pathfinder/shaders/blit.vs.glsl b/crates/pathfinder/shaders/blit.vs.glsl deleted file mode 100644 index cd83081a13..0000000000 --- a/crates/pathfinder/shaders/blit.vs.glsl +++ /dev/null @@ -1,30 +0,0 @@ -#version 450 - -// pathfinder/shaders/blit.vs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -in ivec2 aPosition; - -out vec2 vTexCoord; - -void main() { - vec2 texCoord = vec2(aPosition); -#ifdef PF_ORIGIN_UPPER_LEFT - texCoord.y = 1.0 - texCoord.y; -#endif - vTexCoord = texCoord; - gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), vec2(aPosition)), 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/build/metal/blit.fs.spv b/crates/pathfinder/shaders/build/metal/blit.fs.spv deleted file mode 100644 index dca202be50..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/blit.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/blit.vs.spv b/crates/pathfinder/shaders/build/metal/blit.vs.spv deleted file mode 100644 index e90ae9386c..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/blit.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/clear.fs.spv b/crates/pathfinder/shaders/build/metal/clear.fs.spv deleted file mode 100644 index a03bd936c0..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/clear.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/clear.vs.spv b/crates/pathfinder/shaders/build/metal/clear.vs.spv deleted file mode 100644 index 4a75e1d19b..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/clear.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/debug_solid.fs.spv b/crates/pathfinder/shaders/build/metal/debug_solid.fs.spv deleted file mode 100644 index c2c23b843d..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/debug_solid.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/debug_solid.vs.spv b/crates/pathfinder/shaders/build/metal/debug_solid.vs.spv deleted file mode 100644 index 850396e992..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/debug_solid.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/debug_texture.fs.spv b/crates/pathfinder/shaders/build/metal/debug_texture.fs.spv deleted file mode 100644 index 526a0c377e..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/debug_texture.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/debug_texture.vs.spv b/crates/pathfinder/shaders/build/metal/debug_texture.vs.spv deleted file mode 100644 index 9a5ab3739d..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/debug_texture.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/demo_ground.fs.spv b/crates/pathfinder/shaders/build/metal/demo_ground.fs.spv deleted file mode 100644 index eecbff831e..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/demo_ground.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/demo_ground.vs.spv b/crates/pathfinder/shaders/build/metal/demo_ground.vs.spv deleted file mode 100644 index 998fc9eaeb..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/demo_ground.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/fill.cs.spv b/crates/pathfinder/shaders/build/metal/fill.cs.spv deleted file mode 100644 index 3531bf25da..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/fill.cs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/fill.fs.spv b/crates/pathfinder/shaders/build/metal/fill.fs.spv deleted file mode 100644 index f8e75b74a6..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/fill.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/fill.vs.spv b/crates/pathfinder/shaders/build/metal/fill.vs.spv deleted file mode 100644 index ab6a2f0fe7..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/fill.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/reproject.fs.spv b/crates/pathfinder/shaders/build/metal/reproject.fs.spv deleted file mode 100644 index e40464c805..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/reproject.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/reproject.vs.spv b/crates/pathfinder/shaders/build/metal/reproject.vs.spv deleted file mode 100644 index 6653c5aff2..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/reproject.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/stencil.fs.spv b/crates/pathfinder/shaders/build/metal/stencil.fs.spv deleted file mode 100644 index 63f7fd7d32..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/stencil.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/stencil.vs.spv b/crates/pathfinder/shaders/build/metal/stencil.vs.spv deleted file mode 100644 index 6fc53e39d2..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/stencil.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/tile.fs.spv b/crates/pathfinder/shaders/build/metal/tile.fs.spv deleted file mode 100644 index ec9928be02..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/tile.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/tile.vs.spv b/crates/pathfinder/shaders/build/metal/tile.vs.spv deleted file mode 100644 index 9aa290e96f..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/tile.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/tile_clip.fs.spv b/crates/pathfinder/shaders/build/metal/tile_clip.fs.spv deleted file mode 100644 index f1169cdb2c..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/tile_clip.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/tile_clip.vs.spv b/crates/pathfinder/shaders/build/metal/tile_clip.vs.spv deleted file mode 100644 index e6618d85f5..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/tile_clip.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/tile_copy.fs.spv b/crates/pathfinder/shaders/build/metal/tile_copy.fs.spv deleted file mode 100644 index f0ca4c00c4..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/tile_copy.fs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/build/metal/tile_copy.vs.spv b/crates/pathfinder/shaders/build/metal/tile_copy.vs.spv deleted file mode 100644 index d48eab7232..0000000000 Binary files a/crates/pathfinder/shaders/build/metal/tile_copy.vs.spv and /dev/null differ diff --git a/crates/pathfinder/shaders/clear.fs.glsl b/crates/pathfinder/shaders/clear.fs.glsl deleted file mode 100644 index c46ab5dcb8..0000000000 --- a/crates/pathfinder/shaders/clear.fs.glsl +++ /dev/null @@ -1,27 +0,0 @@ -#version 450 - -// pathfinder/shaders/clear.fs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=2) uniform uColor { - vec4 color; -}; - -out vec4 oFragColor; - -void main() { - oFragColor = vec4(color.rgb, 1.0) * color.a; -} diff --git a/crates/pathfinder/shaders/clear.vs.glsl b/crates/pathfinder/shaders/clear.vs.glsl deleted file mode 100644 index 1e169bb32c..0000000000 --- a/crates/pathfinder/shaders/clear.vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -#version 450 - -// pathfinder/shaders/clear.vs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=0) uniform uRect { - vec4 rect; -}; -layout(set=0, binding=1) uniform uFramebufferSize { - vec2 framebufferSize; -}; - -in ivec2 aPosition; - -void main() { - vec2 position = mix(rect.xy, rect.zw, vec2(aPosition)) / framebufferSize * 2.0 - 1.0; - gl_Position = vec4(position.x, -position.y, 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/debug_solid.fs.glsl b/crates/pathfinder/shaders/debug_solid.fs.glsl deleted file mode 100644 index 556449dee2..0000000000 --- a/crates/pathfinder/shaders/debug_solid.fs.glsl +++ /dev/null @@ -1,27 +0,0 @@ -#version 450 - -// pathfinder/shaders/debug_solid.fs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=1) uniform uColor { - vec4 color; -}; - -out vec4 oFragColor; - -void main() { - oFragColor = vec4(color.rgb, 1.0) * color.a; -} diff --git a/crates/pathfinder/shaders/debug_solid.vs.glsl b/crates/pathfinder/shaders/debug_solid.vs.glsl deleted file mode 100644 index 3bf49b72a6..0000000000 --- a/crates/pathfinder/shaders/debug_solid.vs.glsl +++ /dev/null @@ -1,28 +0,0 @@ -#version 450 - -// pathfinder/shaders/debug_solid.vs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=0) uniform uFramebufferSize { - vec2 framebufferSize; -}; - -in ivec2 aPosition; - -void main() { - vec2 position = vec2(aPosition) / framebufferSize * 2.0 - 1.0; - gl_Position = vec4(position.x, -position.y, 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/debug_texture.fs.glsl b/crates/pathfinder/shaders/debug_texture.fs.glsl deleted file mode 100644 index bdffc15c0f..0000000000 --- a/crates/pathfinder/shaders/debug_texture.fs.glsl +++ /dev/null @@ -1,32 +0,0 @@ -#version 450 - -// pathfinder/shaders/debug_texture.fs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=2) uniform texture2D uTexture; -layout(set=0, binding=3) uniform sampler uSampler; -layout(set=0, binding=4) uniform uColor { - vec4 color; -}; - -in vec2 vTexCoord; - -out vec4 oFragColor; - -void main() { - float alpha = texture(sampler2D(uTexture, uSampler), vTexCoord).r * color.a; - oFragColor = alpha * vec4(color.rgb, 1.0); -} diff --git a/crates/pathfinder/shaders/debug_texture.vs.glsl b/crates/pathfinder/shaders/debug_texture.vs.glsl deleted file mode 100644 index 0b9ac6b9d7..0000000000 --- a/crates/pathfinder/shaders/debug_texture.vs.glsl +++ /dev/null @@ -1,35 +0,0 @@ -#version 450 - -// pathfinder/shaders/debug_texture.vs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=0) uniform uFramebufferSize { - vec2 framebufferSize; -}; -layout(set=0, binding=1) uniform uTextureSize { - vec2 textureSize; -}; - -in ivec2 aPosition; -in ivec2 aTexCoord; - -out vec2 vTexCoord; - -void main() { - vTexCoord = vec2(aTexCoord) / textureSize; - vec2 position = vec2(aPosition) / framebufferSize * 2.0 - 1.0; - gl_Position = vec4(position.x, -position.y, 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/demo_ground.fs.glsl b/crates/pathfinder/shaders/demo_ground.fs.glsl deleted file mode 100644 index 86f1977221..0000000000 --- a/crates/pathfinder/shaders/demo_ground.fs.glsl +++ /dev/null @@ -1,33 +0,0 @@ -#version 450 - -// pathfinder/resources/shaders/demo_ground.fs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=2) uniform uGroundColor { - vec4 groundColor; -}; -layout(set=0, binding=3) uniform uGridlineColor { - vec4 gridlineColor; -}; - -in vec2 vTexCoord; - -out vec4 oFragColor; - -void main() { - vec2 texCoordPx = fract(vTexCoord) / fwidth(vTexCoord); - oFragColor = any(lessThanEqual(texCoordPx, vec2(1.0))) ? gridlineColor : groundColor; -} diff --git a/crates/pathfinder/shaders/demo_ground.vs.glsl b/crates/pathfinder/shaders/demo_ground.vs.glsl deleted file mode 100644 index 2ee19ee2cd..0000000000 --- a/crates/pathfinder/shaders/demo_ground.vs.glsl +++ /dev/null @@ -1,33 +0,0 @@ -#version 450 - -// pathfinder/resources/shaders/demo_ground.vs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=0) uniform uTransform { - mat4 transform; -}; -layout(set=0, binding=1) uniform uGridlineCount { - int gridlineCount; -}; - -in ivec2 aPosition; - -out vec2 vTexCoord; - -void main() { - vTexCoord = vec2(aPosition * gridlineCount); - gl_Position = transform * vec4(ivec4(aPosition.x, 0, aPosition.y, 1)); -} diff --git a/crates/pathfinder/shaders/fill.cs.glsl b/crates/pathfinder/shaders/fill.cs.glsl deleted file mode 100644 index d03de86573..0000000000 --- a/crates/pathfinder/shaders/fill.cs.glsl +++ /dev/null @@ -1,72 +0,0 @@ -#version 430 - -// pathfinder/shaders/fill.cs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#extension GL_GOOGLE_include_directive : enable - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -#include "fill.inc.glsl" - -layout(local_size_x = 16, local_size_y = 4) in; - -layout (set=0, binding = 0) uniform writeonly image2D uDest; -layout (set=0, binding = 1) uniform texture2D uAreaLUT; -layout (set=0, binding = 2) uniform sampler uSampler; -layout (set=0, binding = 3) uniform uFirstTileIndex { - int firstTileIndex; -}; - -layout(std430, set=0, binding = 4) buffer bFills { - restrict readonly uvec2 iFills[]; -}; - -layout(std430, set=0, binding = 5) buffer bNextFills { - restrict readonly int iNextFills[]; -}; - -layout(std430, set=0, binding = 6) buffer bFillTileMap { - restrict readonly int iFillTileMap[]; -}; - -void main() { - ivec2 tileSubCoord = ivec2(gl_LocalInvocationID.xy) * ivec2(1, 4); - uint tileIndexOffset = gl_WorkGroupID.z; - - uint tileIndex = tileIndexOffset + uint(firstTileIndex); - - int fillIndex = iFillTileMap[tileIndex]; - if (fillIndex < 0) - return; - - vec4 coverages = vec4(0.0); - do { - uvec2 fill = iFills[fillIndex]; - vec2 from = vec2(fill.y & 0xf, (fill.y >> 4u) & 0xf) + - vec2(fill.x & 0xff, (fill.x >> 8u) & 0xff) / 256.0; - vec2 to = vec2((fill.y >> 8u) & 0xf, (fill.y >> 12u) & 0xf) + - vec2((fill.x >> 16u) & 0xff, (fill.x >> 24u) & 0xff) / 256.0; - - coverages += computeCoverage(from - (vec2(tileSubCoord) + vec2(0.5)), - to - (vec2(tileSubCoord) + vec2(0.5)), - uAreaLUT, uSampler); - - fillIndex = iNextFills[fillIndex]; - } while (fillIndex >= 0); - - ivec2 tileOrigin = ivec2(tileIndex & 0xff, (tileIndex >> 8u) & 0xff) * ivec2(16, 4); - ivec2 destCoord = tileOrigin + ivec2(gl_LocalInvocationID.xy); - imageStore(uDest, destCoord, coverages); -} diff --git a/crates/pathfinder/shaders/fill.fs.glsl b/crates/pathfinder/shaders/fill.fs.glsl deleted file mode 100644 index 74428d81a5..0000000000 --- a/crates/pathfinder/shaders/fill.fs.glsl +++ /dev/null @@ -1,33 +0,0 @@ -#version 450 - -// pathfinder/shaders/fill.fs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#extension GL_GOOGLE_include_directive : enable - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -#include "fill.inc.glsl" - -layout(set=0, binding=2) uniform texture2D uAreaLUT; -layout(set=0, binding=3) uniform sampler uSampler; - -in vec2 vFrom; -in vec2 vTo; - -out vec4 oFragColor; - -void main() { - oFragColor = computeCoverage(vFrom, vTo, uAreaLUT, uSampler); -} diff --git a/crates/pathfinder/shaders/fill.inc.glsl b/crates/pathfinder/shaders/fill.inc.glsl deleted file mode 100644 index 5f0f68768b..0000000000 --- a/crates/pathfinder/shaders/fill.inc.glsl +++ /dev/null @@ -1,27 +0,0 @@ -// pathfinder/shaders/fill.inc.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -vec4 computeCoverage(vec2 from, vec2 to, texture2D areaLUT, sampler areaLUTSampler) { - // Determine winding, and sort into a consistent order so we only need to find one root below. - vec2 left = from.x < to.x ? from : to, right = from.x < to.x ? to : from; - - // Shoot a vertical ray toward the curve. - vec2 window = clamp(vec2(from.x, to.x), -0.5, 0.5); - float offset = mix(window.x, window.y, 0.5) - left.x; - float t = offset / (right.x - left.x); - - // Compute position and derivative to form a line approximation. - float y = mix(left.y, right.y, t); - float d = (right.y - left.y) / (right.x - left.x); - - // Look up area under that line, and scale horizontally to the window size. - float dX = window.x - window.y; - return texture(sampler2D(areaLUT, areaLUTSampler), vec2(y + 8.0, abs(d * dX)) / 16.0) * dX; -} diff --git a/crates/pathfinder/shaders/fill.vs.glsl b/crates/pathfinder/shaders/fill.vs.glsl deleted file mode 100644 index 1db1005e79..0000000000 --- a/crates/pathfinder/shaders/fill.vs.glsl +++ /dev/null @@ -1,72 +0,0 @@ -#version 450 - -// pathfinder/shaders/fill.vs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(std140, set=0, binding=0) uniform uFramebufferSize { - vec2 framebufferSize; -}; -layout(std140, set=0, binding=1) uniform uTileSize { - vec2 tileSize; -}; - -in uvec2 aTessCoord; -in vec2 aFromSubpx; -in vec2 aToSubpx; -in uint aFromPx; -in uint aToPx; -in uint aTileIndex; - -out vec2 vFrom; -out vec2 vTo; - -vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { - uint tilesPerRow = uint(stencilTextureWidth / tileSize.x); - uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return vec2(tileOffset) * tileSize * vec2(1.0, 0.25); -} - -void main() { - vec2 tileOrigin = computeTileOffset(aTileIndex, framebufferSize.x); - - vec2 from = vec2(aFromPx & 15u, aFromPx >> 4u) + aFromSubpx; - vec2 to = vec2(aToPx & 15u, aToPx >> 4u) + aToSubpx; - - vec2 position; - if (aTessCoord.x == 0u) - position.x = floor(min(from.x, to.x)); - else - position.x = ceil(max(from.x, to.x)); - if (aTessCoord.y == 0u) - position.y = floor(min(from.y, to.y)); - else - position.y = tileSize.y; - position.y = floor(position.y * 0.25); - - // Since each fragment corresponds to 4 pixels on a scanline, the varying interpolation will - // land the fragment halfway between the four-pixel strip, at pixel offset 2.0. But we want to - // do our coverage calculation on the center of the first pixel in the strip instead, at pixel - // offset 0.5. This adjustment of 1.5 accomplishes that. - vec2 offset = vec2(0.0, 1.5) - position * vec2(1.0, 4.0); - vFrom = from + offset; - vTo = to + offset; - - vec2 globalPosition = (tileOrigin + position) / framebufferSize * 2.0 - 1.0; -#ifdef PF_ORIGIN_UPPER_LEFT - globalPosition.y = -globalPosition.y; -#endif - gl_Position = vec4(globalPosition, 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/reproject.fs.glsl b/crates/pathfinder/shaders/reproject.fs.glsl deleted file mode 100644 index ef604ff20d..0000000000 --- a/crates/pathfinder/shaders/reproject.fs.glsl +++ /dev/null @@ -1,33 +0,0 @@ -#version 450 - -// pathfinder/shaders/reproject.fs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=1) uniform uOldTransform { - mat4 oldTransform; -}; -layout(set=0, binding=2) uniform texture2D uTexture; -layout(set=0, binding=3) uniform sampler uSampler; - -in vec2 vTexCoord; - -out vec4 oFragColor; - -void main() { - vec4 normTexCoord = oldTransform * vec4(vTexCoord, 0.0, 1.0); - vec2 texCoord = ((normTexCoord.xy / normTexCoord.w) + 1.0) * 0.5; - oFragColor = texture(sampler2D(uTexture, uSampler), texCoord); -} diff --git a/crates/pathfinder/shaders/reproject.vs.glsl b/crates/pathfinder/shaders/reproject.vs.glsl deleted file mode 100644 index a1385be72e..0000000000 --- a/crates/pathfinder/shaders/reproject.vs.glsl +++ /dev/null @@ -1,36 +0,0 @@ -#version 450 - -// pathfinder/shaders/reproject.vs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=0) uniform uNewTransform { - mat4 newTransform; -}; - -in ivec2 aPosition; - -out vec2 vTexCoord; - -void main() { - vec2 position = vec2(aPosition); - vTexCoord = position; - -#ifdef PF_ORIGIN_UPPER_LEFT - // FIXME(pcwalton): This is wrong. - position.y = 1.0 - position.y; -#endif - gl_Position = newTransform * vec4(position, 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/stencil.fs.glsl b/crates/pathfinder/shaders/stencil.fs.glsl deleted file mode 100644 index 5522e683e6..0000000000 --- a/crates/pathfinder/shaders/stencil.fs.glsl +++ /dev/null @@ -1,24 +0,0 @@ -#version 450 - -// pathfinder/shaders/stencil.fs.glsl -// -// Copyright © 2018 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -out vec4 oFragColor; - -void main() { - // This should be color masked out. - oFragColor = vec4(1.0, 0.0, 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/stencil.vs.glsl b/crates/pathfinder/shaders/stencil.vs.glsl deleted file mode 100644 index 802635ee88..0000000000 --- a/crates/pathfinder/shaders/stencil.vs.glsl +++ /dev/null @@ -1,23 +0,0 @@ -#version 450 - -// pathfinder/shaders/stencil.vs.glsl -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -in vec3 aPosition; - -void main() { - gl_Position = vec4(aPosition, 1.0); -} diff --git a/crates/pathfinder/shaders/tile.fs.glsl b/crates/pathfinder/shaders/tile.fs.glsl deleted file mode 100644 index 3d5a604c5a..0000000000 --- a/crates/pathfinder/shaders/tile.fs.glsl +++ /dev/null @@ -1,627 +0,0 @@ -#version 450 - -// pathfinder/shaders/tile.fs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Mask UV 0 Mask UV 1 -// + + -// | | -// +-----v-----+ +-----v-----+ -// | | MIN | | -// | Mask 0 +-----> Mask 1 +------+ -// | | | | | -// +-----------+ +-----------+ v +-------------+ -// Apply | | GPU -// Mask +----> Composite +---->Blender -// ^ | | -// +-----------+ +-----------+ | +-------------+ -// | | | | | -// | Color 0 +-----> Color 1 +------+ -// | Filter | × | | -// | | | | -// +-----^-----+ +-----^-----+ -// | | -// + + -// Color UV 0 Color UV 1 - -#extension GL_GOOGLE_include_directive : enable - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -#define EPSILON 0.00001 - -#define FRAC_6_PI 1.9098593171027443 -#define FRAC_PI_3 1.0471975511965976 - -#define TILE_CTRL_MASK_MASK 0x3 -#define TILE_CTRL_MASK_WINDING 0x1 -#define TILE_CTRL_MASK_EVEN_ODD 0x2 - -#define TILE_CTRL_MASK_0_SHIFT 0 - -#define COMBINER_CTRL_COLOR_COMBINE_MASK 0x3 -#define COMBINER_CTRL_COLOR_COMBINE_SRC_IN 0x1 -#define COMBINER_CTRL_COLOR_COMBINE_DEST_IN 0x2 - -#define COMBINER_CTRL_FILTER_MASK 0x3 -#define COMBINER_CTRL_FILTER_RADIAL_GRADIENT 0x1 -#define COMBINER_CTRL_FILTER_TEXT 0x2 -#define COMBINER_CTRL_FILTER_BLUR 0x3 - -#define COMBINER_CTRL_COMPOSITE_MASK 0xf -#define COMBINER_CTRL_COMPOSITE_NORMAL 0x0 -#define COMBINER_CTRL_COMPOSITE_MULTIPLY 0x1 -#define COMBINER_CTRL_COMPOSITE_SCREEN 0x2 -#define COMBINER_CTRL_COMPOSITE_OVERLAY 0x3 -#define COMBINER_CTRL_COMPOSITE_DARKEN 0x4 -#define COMBINER_CTRL_COMPOSITE_LIGHTEN 0x5 -#define COMBINER_CTRL_COMPOSITE_COLOR_DODGE 0x6 -#define COMBINER_CTRL_COMPOSITE_COLOR_BURN 0x7 -#define COMBINER_CTRL_COMPOSITE_HARD_LIGHT 0x8 -#define COMBINER_CTRL_COMPOSITE_SOFT_LIGHT 0x9 -#define COMBINER_CTRL_COMPOSITE_DIFFERENCE 0xa -#define COMBINER_CTRL_COMPOSITE_EXCLUSION 0xb -#define COMBINER_CTRL_COMPOSITE_HUE 0xc -#define COMBINER_CTRL_COMPOSITE_SATURATION 0xd -#define COMBINER_CTRL_COMPOSITE_COLOR 0xe -#define COMBINER_CTRL_COMPOSITE_LUMINOSITY 0xf - -#define COMBINER_CTRL_COLOR_FILTER_SHIFT 4 -#define COMBINER_CTRL_COLOR_COMBINE_SHIFT 6 -#define COMBINER_CTRL_COMPOSITE_SHIFT 8 - -layout(set=1, binding=0) uniform sampler uSampler; -layout(set=1, binding=1) uniform texture2D uColorTexture0; -layout(set=1, binding=2) uniform texture2D uMaskTexture0; -layout(set=1, binding=3) uniform texture2D uDestTexture; -layout(set=1, binding=4) uniform texture2D uGammaLUT; - -layout(set=2, binding=0) uniform uColorTextureSize0 { - vec2 iColorTextureSize0; -}; -layout(set=2, binding=1) uniform uMaskTextureSize0 { - vec2 iMaskTextureSize0; -}; -layout(set=2, binding=2) uniform uFilterParams0 { - vec4 iFilterParams0; -}; -layout(set=2, binding=3) uniform uFilterParams1 { - vec4 iFilterParams1; -}; -layout(set=2, binding=4) uniform uFilterParams2 { - vec4 iFilterParams2; -}; -layout(set=2, binding=5) uniform uFramebufferSize { - vec2 iFramebufferSize; -}; -layout(set=2, binding=6) uniform uCtrl { - int iCtrl; -}; - -in vec3 vMaskTexCoord0; -in vec2 vColorTexCoord0; -in vec4 vBaseColor; -in float vTileCtrl; - -out vec4 oFragColor; - -// Color sampling - -vec4 sampleColor(texture2D colorTexture, vec2 colorTexCoord) { - return texture(sampler2D(colorTexture, uSampler), colorTexCoord); -} - -// Color combining - -vec4 combineColor0(vec4 destColor, vec4 srcColor, int op) { - switch (op) { - case COMBINER_CTRL_COLOR_COMBINE_SRC_IN: - return vec4(srcColor.rgb, srcColor.a * destColor.a); - case COMBINER_CTRL_COLOR_COMBINE_DEST_IN: - return vec4(destColor.rgb, srcColor.a * destColor.a); - } - return destColor; -} - -// Text filter - -float filterTextSample1Tap(float offset, texture2D colorTexture, vec2 colorTexCoord) { - return texture(sampler2D(colorTexture, uSampler), colorTexCoord + vec2(offset, 0.0)).r; -} - -// Samples 9 taps around the current pixel. -void filterTextSample9Tap(out vec4 outAlphaLeft, - out float outAlphaCenter, - out vec4 outAlphaRight, - texture2D colorTexture, - vec2 colorTexCoord, - vec4 kernel, - float onePixel) { - bool wide = kernel.x > 0.0; - outAlphaLeft = - vec4(wide ? filterTextSample1Tap(-4.0 * onePixel, colorTexture, colorTexCoord) : 0.0, - filterTextSample1Tap(-3.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(-2.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(-1.0 * onePixel, colorTexture, colorTexCoord)); - outAlphaCenter = filterTextSample1Tap(0.0, colorTexture, colorTexCoord); - outAlphaRight = - vec4(filterTextSample1Tap(1.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(2.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(3.0 * onePixel, colorTexture, colorTexCoord), - wide ? filterTextSample1Tap(4.0 * onePixel, colorTexture, colorTexCoord) : 0.0); -} - -float filterTextConvolve7Tap(vec4 alpha0, vec3 alpha1, vec4 kernel) { - return dot(alpha0, kernel) + dot(alpha1, kernel.zyx); -} - -float filterTextGammaCorrectChannel(float bgColor, float fgColor, texture2D gammaLUT) { - return texture(sampler2D(gammaLUT, uSampler), vec2(fgColor, 1.0 - bgColor)).r; -} - -// `fgColor` is in linear space. -vec3 filterTextGammaCorrect(vec3 bgColor, vec3 fgColor, texture2D gammaLUT) { - return vec3(filterTextGammaCorrectChannel(bgColor.r, fgColor.r, gammaLUT), - filterTextGammaCorrectChannel(bgColor.g, fgColor.g, gammaLUT), - filterTextGammaCorrectChannel(bgColor.b, fgColor.b, gammaLUT)); -} - -// | x y z w -// --------------+-------------------------------------------------------- -// filterParams0 | kernel[0] kernel[1] kernel[2] kernel[3] -// filterParams1 | bgColor.r bgColor.g bgColor.b - -// filterParams2 | fgColor.r fgColor.g fgColor.b gammaCorrectionEnabled -vec4 filterText(vec2 colorTexCoord, - texture2D colorTexture, - texture2D gammaLUT, - vec2 colorTextureSize, - vec4 filterParams0, - vec4 filterParams1, - vec4 filterParams2) { - // Unpack. - vec4 kernel = filterParams0; - vec3 bgColor = filterParams1.rgb; - vec3 fgColor = filterParams2.rgb; - bool gammaCorrectionEnabled = filterParams2.a != 0.0; - - // Apply defringing if necessary. - vec3 alpha; - if (kernel.w == 0.0) { - alpha = texture(sampler2D(colorTexture, uSampler), colorTexCoord).rrr; - } else { - vec4 alphaLeft, alphaRight; - float alphaCenter; - filterTextSample9Tap(alphaLeft, - alphaCenter, - alphaRight, - colorTexture, - colorTexCoord, - kernel, - 1.0 / colorTextureSize.x); - - float r = filterTextConvolve7Tap(alphaLeft, vec3(alphaCenter, alphaRight.xy), kernel); - float g = filterTextConvolve7Tap(vec4(alphaLeft.yzw, alphaCenter), alphaRight.xyz, kernel); - float b = filterTextConvolve7Tap(vec4(alphaLeft.zw, alphaCenter, alphaRight.x), - alphaRight.yzw, - kernel); - - alpha = vec3(r, g, b); - } - - // Apply gamma correction if necessary. - if (gammaCorrectionEnabled) - alpha = filterTextGammaCorrect(bgColor, alpha, gammaLUT); - - // Finish. - return vec4(mix(bgColor, fgColor, alpha), 1.0); -} - -// Other filters - -// This is based on Pixman (MIT license). Copy and pasting the excellent comment -// from there: - -// Implementation of radial gradients following the PDF specification. -// See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference -// Manual (PDF 32000-1:2008 at the time of this writing). -// -// In the radial gradient problem we are given two circles (c₁,r₁) and -// (c₂,r₂) that define the gradient itself. -// -// Mathematically the gradient can be defined as the family of circles -// -// ((1-t)·c₁ + t·(c₂), (1-t)·r₁ + t·r₂) -// -// excluding those circles whose radius would be < 0. When a point -// belongs to more than one circle, the one with a bigger t is the only -// one that contributes to its color. When a point does not belong -// to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0). -// Further limitations on the range of values for t are imposed when -// the gradient is not repeated, namely t must belong to [0,1]. -// -// The graphical result is the same as drawing the valid (radius > 0) -// circles with increasing t in [-∞, +∞] (or in [0,1] if the gradient -// is not repeated) using SOURCE operator composition. -// -// It looks like a cone pointing towards the viewer if the ending circle -// is smaller than the starting one, a cone pointing inside the page if -// the starting circle is the smaller one and like a cylinder if they -// have the same radius. -// -// What we actually do is, given the point whose color we are interested -// in, compute the t values for that point, solving for t in: -// -// length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂ -// -// Let's rewrite it in a simpler way, by defining some auxiliary -// variables: -// -// cd = c₂ - c₁ -// pd = p - c₁ -// dr = r₂ - r₁ -// length(t·cd - pd) = r₁ + t·dr -// -// which actually means -// -// hypot(t·cdx - pdx, t·cdy - pdy) = r₁ + t·dr -// -// or -// -// ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = r₁ + t·dr. -// -// If we impose (as stated earlier) that r₁ + t·dr ≥ 0, it becomes: -// -// (t·cdx - pdx)² + (t·cdy - pdy)² = (r₁ + t·dr)² -// -// where we can actually expand the squares and solve for t: -// -// t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² = -// = r₁² + 2·r₁·t·dr + t²·dr² -// -// (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + r₁·dr)t + -// (pdx² + pdy² - r₁²) = 0 -// -// A = cdx² + cdy² - dr² -// B = pdx·cdx + pdy·cdy + r₁·dr -// C = pdx² + pdy² - r₁² -// At² - 2Bt + C = 0 -// -// The solutions (unless the equation degenerates because of A = 0) are: -// -// t = (B ± ⎷(B² - A·C)) / A -// -// The solution we are going to prefer is the bigger one, unless the -// radius associated to it is negative (or it falls outside the valid t -// range). -// -// Additional observations (useful for optimizations): -// A does not depend on p -// -// A < 0 ⟺ one of the two circles completely contains the other one -// ⟺ for every p, the radii associated with the two t solutions have -// opposite sign -// -// | x y z w -// --------------+----------------------------------------------------- -// filterParams0 | lineFrom.x lineFrom.y lineVector.x lineVector.y -// filterParams1 | radii.x radii.y uvOrigin.x uvOrigin.y -// filterParams2 | - - - - -vec4 filterRadialGradient(vec2 colorTexCoord, - texture2D colorTexture, - vec2 colorTextureSize, - vec2 fragCoord, - vec2 framebufferSize, - vec4 filterParams0, - vec4 filterParams1) { - vec2 lineFrom = filterParams0.xy, lineVector = filterParams0.zw; - vec2 radii = filterParams1.xy, uvOrigin = filterParams1.zw; - - vec2 dP = colorTexCoord - lineFrom, dC = lineVector; - float dR = radii.y - radii.x; - - float a = dot(dC, dC) - dR * dR; - float b = dot(dP, dC) + radii.x * dR; - float c = dot(dP, dP) - radii.x * radii.x; - float discrim = b * b - a * c; - - vec4 color = vec4(0.0); - if (abs(discrim) >= EPSILON) { - vec2 ts = vec2(sqrt(discrim) * vec2(1.0, -1.0) + vec2(b)) / vec2(a); - if (ts.x > ts.y) - ts = ts.yx; - float t = ts.x >= 0.0 ? ts.x : ts.y; - color = texture(sampler2D(colorTexture, uSampler), uvOrigin + vec2(clamp(t, 0.0, 1.0), 0.0)); - } - - return color; -} - -// | x y z w -// --------------+---------------------------------------------------- -// filterParams0 | srcOffset.x srcOffset.y support - -// filterParams1 | gaussCoeff.x gaussCoeff.y gaussCoeff.z - -// filterParams2 | - - - - -vec4 filterBlur(vec2 colorTexCoord, - texture2D colorTexture, - vec2 colorTextureSize, - vec4 filterParams0, - vec4 filterParams1) { - // Unpack. - vec2 srcOffsetScale = filterParams0.xy / colorTextureSize; - int support = int(filterParams0.z); - vec3 gaussCoeff = filterParams1.xyz; - - // Set up our incremental calculation. - float gaussSum = gaussCoeff.x; - vec4 color = texture(sampler2D(colorTexture, uSampler), colorTexCoord) * gaussCoeff.x; - gaussCoeff.xy *= gaussCoeff.yz; - - // This is a common trick that lets us use the texture filtering hardware to evaluate two - // texels at a time. The basic principle is that, if c0 and c1 are colors of adjacent texels - // and k0 and k1 are arbitrary factors, the formula `k0 * c0 + k1 * c1` is equivalent to - // `(k0 + k1) * lerp(c0, c1, k1 / (k0 + k1))`. Linear interpolation, as performed by the - // texturing hardware when sampling adjacent pixels in one direction, evaluates - // `lerp(c0, c1, t)` where t is the offset from the texel with color `c0`. To evaluate the - // formula `k0 * c0 + k1 * c1`, therefore, we can use the texture hardware to perform linear - // interpolation with `t = k1 / (k0 + k1)`. - for (int i = 1; i <= support; i += 2) { - float gaussPartialSum = gaussCoeff.x; - gaussCoeff.xy *= gaussCoeff.yz; - gaussPartialSum += gaussCoeff.x; - - vec2 srcOffset = srcOffsetScale * (float(i) + gaussCoeff.x / gaussPartialSum); - color += (texture(sampler2D(colorTexture, uSampler), colorTexCoord - srcOffset) + - texture(sampler2D(colorTexture, uSampler), colorTexCoord + srcOffset)) * gaussPartialSum; - - gaussSum += 2.0 * gaussPartialSum; - gaussCoeff.xy *= gaussCoeff.yz; - } - - // Finish. - return color / gaussSum; -} - -vec4 filterNone(vec2 colorTexCoord, texture2D colorTexture) { - return sampleColor(colorTexture, colorTexCoord); -} - -vec4 filterColor(vec2 colorTexCoord, - texture2D colorTexture, - texture2D gammaLUT, - vec2 colorTextureSize, - vec2 fragCoord, - vec2 framebufferSize, - vec4 filterParams0, - vec4 filterParams1, - vec4 filterParams2, - int colorFilter) { - switch (colorFilter) { - case COMBINER_CTRL_FILTER_RADIAL_GRADIENT: - return filterRadialGradient(colorTexCoord, - colorTexture, - colorTextureSize, - fragCoord, - framebufferSize, - filterParams0, - filterParams1); - case COMBINER_CTRL_FILTER_BLUR: - return filterBlur(colorTexCoord, - colorTexture, - colorTextureSize, - filterParams0, - filterParams1); - case COMBINER_CTRL_FILTER_TEXT: - return filterText(colorTexCoord, - colorTexture, - gammaLUT, - colorTextureSize, - filterParams0, - filterParams1, - filterParams2); - } - return filterNone(colorTexCoord, colorTexture); -} - -// Compositing - -vec3 compositeSelect(bvec3 cond, vec3 ifTrue, vec3 ifFalse) { - return vec3(cond.x ? ifTrue.x : ifFalse.x, - cond.y ? ifTrue.y : ifFalse.y, - cond.z ? ifTrue.z : ifFalse.z); -} - -float compositeDivide(float num, float denom) { - return denom != 0.0 ? num / denom : 0.0; -} - -vec3 compositeColorDodge(vec3 destColor, vec3 srcColor) { - bvec3 destZero = equal(destColor, vec3(0.0)), srcOne = equal(srcColor, vec3(1.0)); - return compositeSelect(destZero, - vec3(0.0), - compositeSelect(srcOne, vec3(1.0), destColor / (vec3(1.0) - srcColor))); -} - -// https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB_alternative -vec3 compositeHSLToRGB(vec3 hsl) { - float a = hsl.y * min(hsl.z, 1.0 - hsl.z); - vec3 ks = mod(vec3(0.0, 8.0, 4.0) + vec3(hsl.x * FRAC_6_PI), 12.0); - return hsl.zzz - clamp(min(ks - vec3(3.0), vec3(9.0) - ks), -1.0, 1.0) * a; -} - -// https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB -vec3 compositeRGBToHSL(vec3 rgb) { - float v = max(max(rgb.r, rgb.g), rgb.b), xMin = min(min(rgb.r, rgb.g), rgb.b); - float c = v - xMin, l = mix(xMin, v, 0.5); - vec3 terms = rgb.r == v ? vec3(0.0, rgb.gb) : - rgb.g == v ? vec3(2.0, rgb.br) : - vec3(4.0, rgb.rg); - float h = FRAC_PI_3 * compositeDivide(terms.x * c + terms.y - terms.z, c); - float s = compositeDivide(c, v); - return vec3(h, s, l); -} - -vec3 compositeScreen(vec3 destColor, vec3 srcColor) { - return destColor + srcColor - destColor * srcColor; -} - -vec3 compositeHardLight(vec3 destColor, vec3 srcColor) { - return compositeSelect(lessThanEqual(srcColor, vec3(0.5)), - destColor * vec3(2.0) * srcColor, - compositeScreen(destColor, vec3(2.0) * srcColor - vec3(1.0))); -} - -vec3 compositeSoftLight(vec3 destColor, vec3 srcColor) { - vec3 darkenedDestColor = - compositeSelect(lessThanEqual(destColor, vec3(0.25)), - ((vec3(16.0) * destColor - 12.0) * destColor + 4.0) * destColor, - sqrt(destColor)); - vec3 factor = compositeSelect(lessThanEqual(srcColor, vec3(0.5)), - destColor * (vec3(1.0) - destColor), - darkenedDestColor - destColor); - return destColor + (srcColor * 2.0 - 1.0) * factor; -} - -vec3 compositeHSL(vec3 destColor, vec3 srcColor, int op) { - switch (op) { - case COMBINER_CTRL_COMPOSITE_HUE: - return vec3(srcColor.x, destColor.y, destColor.z); - case COMBINER_CTRL_COMPOSITE_SATURATION: - return vec3(destColor.x, srcColor.y, destColor.z); - case COMBINER_CTRL_COMPOSITE_COLOR: - return vec3(srcColor.x, srcColor.y, destColor.z); - default: - return vec3(destColor.x, destColor.y, srcColor.z); - } -} - -vec3 compositeRGB(vec3 destColor, vec3 srcColor, int op) { - switch (op) { - case COMBINER_CTRL_COMPOSITE_MULTIPLY: - return destColor * srcColor; - case COMBINER_CTRL_COMPOSITE_SCREEN: - return compositeScreen(destColor, srcColor); - case COMBINER_CTRL_COMPOSITE_OVERLAY: - return compositeHardLight(srcColor, destColor); - case COMBINER_CTRL_COMPOSITE_DARKEN: - return min(destColor, srcColor); - case COMBINER_CTRL_COMPOSITE_LIGHTEN: - return max(destColor, srcColor); - case COMBINER_CTRL_COMPOSITE_COLOR_DODGE: - return compositeColorDodge(destColor, srcColor); - case COMBINER_CTRL_COMPOSITE_COLOR_BURN: - return vec3(1.0) - compositeColorDodge(vec3(1.0) - destColor, vec3(1.0) - srcColor); - case COMBINER_CTRL_COMPOSITE_HARD_LIGHT: - return compositeHardLight(destColor, srcColor); - case COMBINER_CTRL_COMPOSITE_SOFT_LIGHT: - return compositeSoftLight(destColor, srcColor); - case COMBINER_CTRL_COMPOSITE_DIFFERENCE: - return abs(destColor - srcColor); - case COMBINER_CTRL_COMPOSITE_EXCLUSION: - return destColor + srcColor - vec3(2.0) * destColor * srcColor; - case COMBINER_CTRL_COMPOSITE_HUE: - case COMBINER_CTRL_COMPOSITE_SATURATION: - case COMBINER_CTRL_COMPOSITE_COLOR: - case COMBINER_CTRL_COMPOSITE_LUMINOSITY: - return compositeHSLToRGB(compositeHSL(compositeRGBToHSL(destColor), - compositeRGBToHSL(srcColor), - op)); - } - return srcColor; -} - -vec4 composite(vec4 srcColor, - texture2D destTexture, - vec2 destTextureSize, - vec2 fragCoord, - int op) { - if (op == COMBINER_CTRL_COMPOSITE_NORMAL) - return srcColor; - - // FIXME(pcwalton): What should the output alpha be here? - vec2 destTexCoord = fragCoord / destTextureSize; - vec4 destColor = texture(sampler2D(destTexture, uSampler), destTexCoord); - vec3 blendedRGB = compositeRGB(destColor.rgb, srcColor.rgb, op); - return vec4(srcColor.a * (1.0 - destColor.a) * srcColor.rgb + - srcColor.a * destColor.a * blendedRGB + - (1.0 - srcColor.a) * destColor.rgb, - 1.0); -} - -// Masks - -float sampleMask(float maskAlpha, - texture2D maskTexture, - vec2 maskTextureSize, - vec3 maskTexCoord, - int maskCtrl) { - if (maskCtrl == 0) - return maskAlpha; - - ivec2 maskTexCoordI = ivec2(floor(maskTexCoord.xy)); - vec4 texel = texture(sampler2D(maskTexture, uSampler), (vec2(maskTexCoordI / ivec2(1, 4)) + 0.5) / maskTextureSize); - float coverage = texel[maskTexCoordI.y % 4] + maskTexCoord.z; - - if ((maskCtrl & TILE_CTRL_MASK_WINDING) != 0) - coverage = abs(coverage); - else - coverage = 1.0 - abs(1.0 - mod(coverage, 2.0)); - return min(maskAlpha, coverage); -} - -// Main function - -void calculateColor(int tileCtrl, int ctrl) { - // Sample mask. - int maskCtrl0 = (tileCtrl >> TILE_CTRL_MASK_0_SHIFT) & TILE_CTRL_MASK_MASK; - float maskAlpha = 1.0; - maskAlpha = sampleMask(maskAlpha, uMaskTexture0, iMaskTextureSize0, vMaskTexCoord0, maskCtrl0); - - // Sample color. - vec4 color = vBaseColor; - int color0Combine = (ctrl >> COMBINER_CTRL_COLOR_COMBINE_SHIFT) & - COMBINER_CTRL_COLOR_COMBINE_MASK; - if (color0Combine != 0) { - int color0Filter = (ctrl >> COMBINER_CTRL_COLOR_FILTER_SHIFT) & COMBINER_CTRL_FILTER_MASK; - vec4 color0 = filterColor(vColorTexCoord0, - uColorTexture0, - uGammaLUT, - iColorTextureSize0, - gl_FragCoord.xy, - iFramebufferSize, - iFilterParams0, - iFilterParams1, - iFilterParams2, - color0Filter); - color = combineColor0(color, color0, color0Combine); - } - - // Apply mask. - color.a *= maskAlpha; - - // Apply composite. - int compositeOp = (ctrl >> COMBINER_CTRL_COMPOSITE_SHIFT) & COMBINER_CTRL_COMPOSITE_MASK; - color = composite(color, uDestTexture, iFramebufferSize, gl_FragCoord.xy, compositeOp); - - // Premultiply alpha. - color.rgb *= color.a; - oFragColor = color; -} - -// Entry point -// -// TODO(pcwalton): Generate this dynamically. - -void main() { - calculateColor(int(vTileCtrl), iCtrl); -} diff --git a/crates/pathfinder/shaders/tile.vs.glsl b/crates/pathfinder/shaders/tile.vs.glsl deleted file mode 100644 index 5d817c9252..0000000000 --- a/crates/pathfinder/shaders/tile.vs.glsl +++ /dev/null @@ -1,63 +0,0 @@ -#version 450 - -// pathfinder/shaders/tile.vs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=0) uniform uTransform { - mat4 transform; -}; -layout(set=0, binding=1) uniform uTileSize { - vec2 tileSize; -}; -layout(set=0, binding=2) uniform texture2D uTextureMetadata; -layout(set=0, binding=3) uniform sampler uSampler; -layout(set=0, binding=4) uniform uTextureMetadataSize { - ivec2 textureMetadataSize; -}; - -in ivec2 aTileOffset; -in ivec2 aTileOrigin; -in uvec2 aMaskTexCoord0; -in ivec2 aMaskBackdrop; -in int aColor; -in int aTileCtrl; - -out vec3 vMaskTexCoord0; -out vec2 vColorTexCoord0; -out vec4 vBaseColor; -out float vTileCtrl; - -void main() { - vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); - vec2 position = (tileOrigin + tileOffset) * tileSize; - - vec2 maskTexCoord0 = (vec2(aMaskTexCoord0) + tileOffset) * tileSize; - - vec2 textureMetadataScale = vec2(1.0) / vec2(textureMetadataSize); - vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); - vec2 colorTexMatrix0Coord = (metadataEntryCoord + vec2(0.5, 0.5)) * textureMetadataScale; - vec2 colorTexOffsetsCoord = (metadataEntryCoord + vec2(1.5, 0.5)) * textureMetadataScale; - vec2 baseColorCoord = (metadataEntryCoord + vec2(2.5, 0.5)) * textureMetadataScale; - vec4 colorTexMatrix0 = texture(sampler2D(uTextureMetadata, uSampler), colorTexMatrix0Coord); - vec4 colorTexOffsets = texture(sampler2D(uTextureMetadata, uSampler), colorTexOffsetsCoord); - vec4 baseColor = texture(sampler2D(uTextureMetadata, uSampler), baseColorCoord); - - vColorTexCoord0 = mat2(colorTexMatrix0) * position + colorTexOffsets.xy; - vMaskTexCoord0 = vec3(maskTexCoord0, float(aMaskBackdrop.x)); - vBaseColor = baseColor; - vTileCtrl = float(aTileCtrl); - gl_Position = transform * vec4(position, 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/tile_clip.fs.glsl b/crates/pathfinder/shaders/tile_clip.fs.glsl deleted file mode 100644 index 352548561e..0000000000 --- a/crates/pathfinder/shaders/tile_clip.fs.glsl +++ /dev/null @@ -1,29 +0,0 @@ -#version 450 - -// pathfinder/shaders/tile_clip.fs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=0) uniform texture2D uSrc; -layout(set=0, binding=1) uniform sampler uSampler; - -in vec2 vTexCoord; -in float vBackdrop; - -out vec4 oFragColor; - -void main() { - oFragColor = clamp(abs(texture(sampler2D(uSrc, uSampler), vTexCoord) + vBackdrop), 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/tile_clip.vs.glsl b/crates/pathfinder/shaders/tile_clip.vs.glsl deleted file mode 100644 index b0c19a704b..0000000000 --- a/crates/pathfinder/shaders/tile_clip.vs.glsl +++ /dev/null @@ -1,33 +0,0 @@ -#version 450 - -// pathfinder/shaders/tile_clip.vs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -in ivec2 aTileOffset; -in ivec2 aDestTileOrigin; -in ivec2 aSrcTileOrigin; -in int aSrcBackdrop; - -out vec2 vTexCoord; -out float vBackdrop; - -void main() { - vec2 destPosition = vec2(aDestTileOrigin + aTileOffset) / vec2(256.0); - vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset) / vec2(256.0); - vTexCoord = srcPosition; - vBackdrop = float(aSrcBackdrop); - gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), destPosition), 0.0, 1.0); -} diff --git a/crates/pathfinder/shaders/tile_copy.fs.glsl b/crates/pathfinder/shaders/tile_copy.fs.glsl deleted file mode 100644 index 4494995c15..0000000000 --- a/crates/pathfinder/shaders/tile_copy.fs.glsl +++ /dev/null @@ -1,30 +0,0 @@ -#version 450 - -// pathfinder/shaders/tile_copy.fs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=2) uniform uFramebufferSize { - vec2 framebufferSize; -}; -layout(set=0, binding=3) uniform texture2D uSrc; -layout(set=0, binding=4) uniform sampler uSampler; - -out vec4 oFragColor; - -void main() { - vec2 texCoord = gl_FragCoord.xy / framebufferSize; - oFragColor = texture(sampler2D(uSrc, uSampler), texCoord); -} diff --git a/crates/pathfinder/shaders/tile_copy.vs.glsl b/crates/pathfinder/shaders/tile_copy.vs.glsl deleted file mode 100644 index 5b0515c32c..0000000000 --- a/crates/pathfinder/shaders/tile_copy.vs.glsl +++ /dev/null @@ -1,31 +0,0 @@ -#version 450 - -// pathfinder/shaders/tile_copy.vs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -layout(set=0, binding=0) uniform uTransform { - mat4 transform; -}; -layout(set=0, binding=1) uniform uTileSize { - vec2 tileSize; -}; - -in ivec2 aTilePosition; - -void main() { - vec2 position = vec2(aTilePosition) * tileSize; - gl_Position = transform * vec4(position, 0.0, 1.0); -} diff --git a/crates/pathfinder/simd/Cargo.toml b/crates/pathfinder/simd/Cargo.toml deleted file mode 100644 index 77b01d0e4e..0000000000 --- a/crates/pathfinder/simd/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "pathfinder_simd" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -build = "build.rs" -description = "A simple SIMD library" -license = "MIT/Apache-2.0" -repository = "https://github.com/servo/pathfinder" -homepage = "https://github.com/servo/pathfinder" - -[features] -pf-no-simd = [] - -[dependencies] - -[build-dependencies] -rustc_version = "0.2" diff --git a/crates/pathfinder/simd/build.rs b/crates/pathfinder/simd/build.rs deleted file mode 100644 index e7128bbad2..0000000000 --- a/crates/pathfinder/simd/build.rs +++ /dev/null @@ -1,26 +0,0 @@ -// pathfinder/simd/build.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate rustc_version; - -use rustc_version::Channel; - -fn main() { - // Assert we haven't travelled back in time - assert!(rustc_version::version().unwrap().major >= 1); - - // Set cfg flags depending on release channel - match rustc_version::version_meta().unwrap().channel { - Channel::Nightly => { - println!("cargo:rustc-cfg=pf_rustc_nightly"); - } - _ => {} - } -} diff --git a/crates/pathfinder/simd/src/arm/mod.rs b/crates/pathfinder/simd/src/arm/mod.rs deleted file mode 100644 index 3fa5c7dac5..0000000000 --- a/crates/pathfinder/simd/src/arm/mod.rs +++ /dev/null @@ -1,849 +0,0 @@ -// pathfinder/simd/src/arm.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::arch::aarch64::{self, float32x2_t, float32x4_t, int32x2_t, int32x4_t}; -use std::arch::aarch64::{uint32x2_t, uint32x4_t}; -use std::f32; -use std::fmt::{self, Debug, Formatter}; -use std::mem; -use std::ops::{Add, BitAnd, BitOr, Div, Index, IndexMut, Mul, Shr, Sub}; - -mod swizzle_f32x4; -mod swizzle_i32x4; - -// Two 32-bit floats - -#[derive(Clone, Copy)] -pub struct F32x2(pub float32x2_t); - -impl F32x2 { - // Constructors - - #[inline] - pub fn new(a: f32, b: f32) -> F32x2 { - unsafe { F32x2(mem::transmute([a, b])) } - } - - #[inline] - pub fn splat(x: f32) -> F32x2 { - F32x2::new(x, x) - } - - // Basic operations - - #[inline] - pub fn approx_recip(self) -> F32x2 { - unsafe { F32x2(vrecpe_v2f32(self.0)) } - } - - #[inline] - pub fn min(self, other: F32x2) -> F32x2 { - unsafe { F32x2(simd_fmin(self.0, other.0)) } - } - - #[inline] - pub fn max(self, other: F32x2) -> F32x2 { - unsafe { F32x2(simd_fmax(self.0, other.0)) } - } - - #[inline] - pub fn clamp(self, min: F32x2, max: F32x2) -> F32x2 { - self.max(min).min(max) - } - - #[inline] - pub fn abs(self) -> F32x2 { - unsafe { F32x2(fabs_v2f32(self.0)) } - } - - #[inline] - pub fn floor(self) -> F32x2 { - unsafe { F32x2(floor_v2f32(self.0)) } - } - - #[inline] - pub fn ceil(self) -> F32x2 { - unsafe { F32x2(ceil_v2f32(self.0)) } - } - - #[inline] - pub fn sqrt(self) -> F32x2 { - unsafe { F32x2(sqrt_v2f32(self.0)) } - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: F32x2) -> U32x2 { - unsafe { U32x2(simd_eq(self.0, other.0)) } - } - - #[inline] - pub fn packed_gt(self, other: F32x2) -> U32x2 { - unsafe { U32x2(simd_gt(self.0, other.0)) } - } - - #[inline] - pub fn packed_lt(self, other: F32x2) -> U32x2 { - unsafe { U32x2(simd_lt(self.0, other.0)) } - } - - #[inline] - pub fn packed_le(self, other: F32x2) -> U32x2 { - unsafe { U32x2(simd_le(self.0, other.0)) } - } - - // Conversions - - #[inline] - pub fn to_f32x4(self) -> F32x4 { - self.concat_xy_xy(F32x2::default()) - } - - /// Converts these packed floats to integers via rounding. - #[inline] - pub fn to_i32x2(self) -> I32x2 { - unsafe { I32x2(simd_cast(round_v2f32(self.0))) } - } - - #[inline] - pub fn to_i32x4(self) -> I32x4 { - self.to_i32x2().concat_xy_xy(I32x2::default()) - } - - // Swizzle - - #[inline] - pub fn yx(self) -> F32x2 { - unsafe { F32x2(simd_shuffle2(self.0, self.0, [1, 0])) } - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: F32x2) -> F32x4 { - unsafe { F32x4(simd_shuffle4(self.0, other.0, [0, 1, 0, 1])) } - } -} - -impl Default for F32x2 { - #[inline] - fn default() -> F32x2 { - F32x2::new(0.0, 0.0) - } -} - -impl Debug for F32x2 { - #[inline] - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "<{}, {}>", self[0], self[1]) - } -} - -impl Index for F32x2 { - type Output = f32; - #[inline] - fn index(&self, index: usize) -> &f32 { - unsafe { - assert!(index < 2); - let ptr = &self.0 as *const float32x2_t as *const f32; - mem::transmute::<*const f32, &f32>(ptr.offset(index as isize)) - } - } -} - -impl IndexMut for F32x2 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut f32 { - unsafe { - assert!(index < 2); - let ptr = &mut self.0 as *mut float32x2_t as *mut f32; - mem::transmute::<*mut f32, &mut f32>(ptr.offset(index as isize)) - } - } -} - - -impl Add for F32x2 { - type Output = F32x2; - #[inline] - fn add(self, other: F32x2) -> F32x2 { - unsafe { F32x2(simd_add(self.0, other.0)) } - } -} - -impl Div for F32x2 { - type Output = F32x2; - #[inline] - fn div(self, other: F32x2) -> F32x2 { - unsafe { F32x2(simd_div(self.0, other.0)) } - } -} - -impl Mul for F32x2 { - type Output = F32x2; - #[inline] - fn mul(self, other: F32x2) -> F32x2 { - unsafe { F32x2(simd_mul(self.0, other.0)) } - } -} - -impl Sub for F32x2 { - type Output = F32x2; - #[inline] - fn sub(self, other: F32x2) -> F32x2 { - unsafe { F32x2(simd_sub(self.0, other.0)) } - } -} - -// Four 32-bit floats - -#[derive(Clone, Copy)] -pub struct F32x4(pub float32x4_t); - -impl F32x4 { - #[inline] - pub fn new(a: f32, b: f32, c: f32, d: f32) -> F32x4 { - unsafe { F32x4(mem::transmute([a, b, c, d])) } - } - - #[inline] - pub fn splat(x: f32) -> F32x4 { - F32x4::new(x, x, x, x) - } - - // Basic operations - - #[inline] - pub fn approx_recip(self) -> F32x4 { - unsafe { F32x4(vrecpe_v4f32(self.0)) } - } - - #[inline] - pub fn min(self, other: F32x4) -> F32x4 { - unsafe { F32x4(simd_fmin(self.0, other.0)) } - } - - #[inline] - pub fn max(self, other: F32x4) -> F32x4 { - unsafe { F32x4(simd_fmax(self.0, other.0)) } - } - - #[inline] - pub fn clamp(self, min: F32x4, max: F32x4) -> F32x4 { - self.max(min).min(max) - } - - #[inline] - pub fn abs(self) -> F32x4 { - unsafe { F32x4(fabs_v4f32(self.0)) } - } - - #[inline] - pub fn floor(self) -> F32x4 { - unsafe { F32x4(floor_v4f32(self.0)) } - } - - #[inline] - pub fn ceil(self) -> F32x4 { - unsafe { F32x4(ceil_v4f32(self.0)) } - } - - #[inline] - pub fn sqrt(self) -> F32x4 { - unsafe { F32x4(sqrt_v4f32(self.0)) } - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: F32x4) -> U32x4 { - unsafe { U32x4(simd_eq(self.0, other.0)) } - } - - #[inline] - pub fn packed_gt(self, other: F32x4) -> U32x4 { - unsafe { U32x4(simd_gt(self.0, other.0)) } - } - - #[inline] - pub fn packed_le(self, other: F32x4) -> U32x4 { - unsafe { U32x4(simd_le(self.0, other.0)) } - } - - #[inline] - pub fn packed_lt(self, other: F32x4) -> U32x4 { - unsafe { U32x4(simd_lt(self.0, other.0)) } - } - - // Swizzle conversions - - #[inline] - pub fn xy(self) -> F32x2 { - unsafe { F32x2(simd_shuffle2(self.0, self.0, [0, 1])) } - } - - #[inline] - pub fn yx(self) -> F32x2 { - unsafe { F32x2(simd_shuffle2(self.0, self.0, [1, 0])) } - } - - #[inline] - pub fn xw(self) -> F32x2 { - unsafe { F32x2(simd_shuffle2(self.0, self.0, [0, 3])) } - } - - #[inline] - pub fn zy(self) -> F32x2 { - unsafe { F32x2(simd_shuffle2(self.0, self.0, [2, 1])) } - } - - #[inline] - pub fn zw(self) -> F32x2 { - unsafe { F32x2(simd_shuffle2(self.0, self.0, [2, 3])) } - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: F32x4) -> F32x4 { - unsafe { F32x4(simd_shuffle4(self.0, other.0, [0, 1, 0, 1])) } - } - - #[inline] - pub fn concat_xy_zw(self, other: F32x4) -> F32x4 { - unsafe { F32x4(simd_shuffle4(self.0, other.0, [0, 1, 2, 3])) } - } - - #[inline] - pub fn concat_zw_zw(self, other: F32x4) -> F32x4 { - unsafe { F32x4(simd_shuffle4(self.0, other.0, [2, 3, 2, 3])) } - } - - // Conversions - - /// Converts these packed floats to integers via rounding. - #[inline] - pub fn to_i32x4(self) -> I32x4 { - unsafe { I32x4(simd_cast(round_v4f32(self.0))) } - } -} - -impl Default for F32x4 { - #[inline] - fn default() -> F32x4 { - F32x4::new(0.0, 0.0, 0.0, 0.0) - } -} - -impl Index for F32x4 { - type Output = f32; - #[inline] - fn index(&self, index: usize) -> &f32 { - unsafe { - assert!(index < 4); - let ptr = &self.0 as *const float32x4_t as *const f32; - mem::transmute::<*const f32, &f32>(ptr.offset(index as isize)) - } - } -} - -impl IndexMut for F32x4 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut f32 { - unsafe { - assert!(index < 4); - let ptr = &mut self.0 as *mut float32x4_t as *mut f32; - mem::transmute::<*mut f32, &mut f32>(ptr.offset(index as isize)) - } - } -} - -impl Debug for F32x4 { - #[inline] - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "<{}, {}, {}, {}>", self[0], self[1], self[2], self[3]) - } -} - -impl PartialEq for F32x4 { - #[inline] - fn eq(&self, other: &F32x4) -> bool { - self.packed_eq(*other).all_true() - } -} - -impl Add for F32x4 { - type Output = F32x4; - #[inline] - fn add(self, other: F32x4) -> F32x4 { - unsafe { F32x4(simd_add(self.0, other.0)) } - } -} - -impl Div for F32x4 { - type Output = F32x4; - #[inline] - fn div(self, other: F32x4) -> F32x4 { - unsafe { F32x4(simd_div(self.0, other.0)) } - } -} - -impl Mul for F32x4 { - type Output = F32x4; - #[inline] - fn mul(self, other: F32x4) -> F32x4 { - unsafe { F32x4(simd_mul(self.0, other.0)) } - } -} - -impl Sub for F32x4 { - type Output = F32x4; - #[inline] - fn sub(self, other: F32x4) -> F32x4 { - unsafe { F32x4(simd_sub(self.0, other.0)) } - } -} - -// Two 32-bit signed integers - -#[derive(Clone, Copy, Debug)] -pub struct I32x2(pub int32x2_t); - -impl I32x2 { - #[inline] - pub fn new(x: i32, y: i32) -> I32x2 { - unsafe { I32x2(mem::transmute([x, y])) } - } - - #[inline] - pub fn splat(x: i32) -> I32x2 { - I32x2::new(x, x) - } - - // Accessors - - #[inline] - pub fn x(self) -> i32 { - self[0] - } - - #[inline] - pub fn y(self) -> i32 { - self[1] - } - - #[inline] - pub fn packed_eq(self, other: I32x2) -> U32x2 { - unsafe { U32x2(simd_eq(self.0, other.0)) } - } - - // Basic operations - - #[inline] - pub fn max(self, other: I32x2) -> I32x2 { - self.to_i32x4().max(other.to_i32x4()).xy() - } - - #[inline] - pub fn min(self, other: I32x2) -> I32x2 { - self.to_i32x4().min(other.to_i32x4()).xy() - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: I32x2) -> I32x4 { - unsafe { I32x4(simd_shuffle4(self.0, other.0, [0, 1, 0, 1])) } - } - - // Conversions - - /// Converts these packed integers to floats. - #[inline] - pub fn to_f32x2(self) -> F32x2 { - unsafe { F32x2(simd_cast(self.0)) } - } - - #[inline] - pub fn to_i32x4(self) -> I32x4 { - self.concat_xy_xy(I32x2::default()) - } -} - -impl Default for I32x2 { - #[inline] - fn default() -> I32x2 { - I32x2::splat(0) - } -} - -impl PartialEq for I32x2 { - #[inline] - fn eq(&self, other: &I32x2) -> bool { - self.packed_eq(*other).all_true() - } -} - -impl Index for I32x2 { - type Output = i32; - #[inline] - fn index(&self, index: usize) -> &i32 { - unsafe { - assert!(index < 2); - let ptr = &self.0 as *const int32x2_t as *const i32; - mem::transmute::<*const i32, &i32>(ptr.offset(index as isize)) - } - } -} - -impl IndexMut for I32x2 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut i32 { - unsafe { - assert!(index < 2); - let ptr = &mut self.0 as *mut int32x2_t as *mut i32; - mem::transmute::<*mut i32, &mut i32>(ptr.offset(index as isize)) - } - } -} - -impl Add for I32x2 { - type Output = I32x2; - #[inline] - fn add(self, other: I32x2) -> I32x2 { - unsafe { I32x2(simd_add(self.0, other.0)) } - } -} - -impl Sub for I32x2 { - type Output = I32x2; - #[inline] - fn sub(self, other: I32x2) -> I32x2 { - unsafe { I32x2(simd_sub(self.0, other.0)) } - } -} - -impl Mul for I32x2 { - type Output = I32x2; - #[inline] - fn mul(self, other: I32x2) -> I32x2 { - unsafe { I32x2(simd_mul(self.0, other.0)) } - } -} - -// Four 32-bit signed integers - -#[derive(Clone, Copy, Debug)] -pub struct I32x4(pub int32x4_t); - -impl I32x4 { - #[inline] - pub fn new(a: i32, b: i32, c: i32, d: i32) -> I32x4 { - unsafe { I32x4(mem::transmute([a, b, c, d])) } - } - - #[inline] - pub fn splat(x: i32) -> I32x4 { - I32x4::new(x, x, x, x) - } - - // Basic operations - - #[inline] - pub fn max(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_cast(simd_fmax(self.to_f32x4().0, other.to_f32x4().0))) } - } - - #[inline] - pub fn min(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_cast(simd_fmin(self.to_f32x4().0, other.to_f32x4().0))) } - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: I32x4) -> U32x4 { - unsafe { U32x4(simd_eq(self.0, other.0)) } - } - - #[inline] - pub fn packed_le(self, other: I32x4) -> U32x4 { - unsafe { U32x4(simd_le(self.0, other.0)) } - } - - #[inline] - pub fn packed_lt(self, other: I32x4) -> U32x4 { - unsafe { U32x4(simd_lt(self.0, other.0)) } - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_shuffle4(self.0, other.0, [0, 1, 4, 5])) } - } - - #[inline] - pub fn concat_zw_zw(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_shuffle4(self.0, other.0, [2, 3, 6, 7])) } - } - - // Swizzle conversions - - #[inline] - pub fn xy(self) -> I32x2 { - unsafe { I32x2(simd_shuffle2(self.0, self.0, [0, 1])) } - } - - #[inline] - pub fn yx(self) -> I32x2 { - unsafe { I32x2(simd_shuffle2(self.0, self.0, [1, 0])) } - } - - #[inline] - pub fn xw(self) -> I32x2 { - unsafe { I32x2(simd_shuffle2(self.0, self.0, [0, 3])) } - } - - #[inline] - pub fn zy(self) -> I32x2 { - unsafe { I32x2(simd_shuffle2(self.0, self.0, [2, 1])) } - } - - #[inline] - pub fn zw(self) -> I32x2 { - unsafe { I32x2(simd_shuffle2(self.0, self.0, [2, 3])) } - } - - // Conversions - - /// Converts these packed integers to floats. - #[inline] - pub fn to_f32x4(self) -> F32x4 { - unsafe { F32x4(simd_cast(self.0)) } - } -} - -impl Default for I32x4 { - #[inline] - fn default() -> I32x4 { - I32x4::new(0, 0, 0, 0) - } -} - -impl Index for I32x4 { - type Output = i32; - #[inline] - fn index(&self, index: usize) -> &i32 { - unsafe { - assert!(index < 4); - let ptr = &self.0 as *const int32x4_t as *const i32; - mem::transmute::<*const i32, &i32>(ptr.offset(index as isize)) - } - } -} - -impl IndexMut for I32x4 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut i32 { - unsafe { - assert!(index < 4); - let ptr = &mut self.0 as *mut int32x4_t as *mut i32; - mem::transmute::<*mut i32, &mut i32>(ptr.offset(index as isize)) - } - } -} - -impl Add for I32x4 { - type Output = I32x4; - #[inline] - fn add(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_add(self.0, other.0)) } - } -} - -impl Sub for I32x4 { - type Output = I32x4; - #[inline] - fn sub(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_sub(self.0, other.0)) } - } -} - -impl Mul for I32x4 { - type Output = I32x4; - #[inline] - fn mul(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_mul(self.0, other.0)) } - } -} - -impl PartialEq for I32x4 { - #[inline] - fn eq(&self, other: &I32x4) -> bool { - self.packed_eq(*other).all_true() - } -} - -impl BitAnd for I32x4 { - type Output = I32x4; - #[inline] - fn bitand(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_and(self.0, other.0)) } - } -} - -impl BitOr for I32x4 { - type Output = I32x4; - #[inline] - fn bitor(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_or(self.0, other.0)) } - } -} - -impl Shr for I32x4 { - type Output = I32x4; - #[inline] - fn shr(self, other: I32x4) -> I32x4 { - unsafe { I32x4(simd_shr(self.0, other.0)) } - } -} - -// Two 32-bit unsigned integers - -#[derive(Clone, Copy)] -pub struct U32x2(pub uint32x2_t); - -impl U32x2 { - /// Returns true if both booleans in this vector are true. - /// - /// The result is *undefined* if both values in this vector are not booleans. A boolean is a - /// value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_true(&self) -> bool { - unsafe { aarch64::vminv_u32(self.0) == !0 } - } - - /// Returns true if both booleans in this vector are false. - /// - /// The result is *undefined* if both values in this vector are not booleans. A boolean is a - /// value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_false(&self) -> bool { - unsafe { aarch64::vmaxv_u32(self.0) == 0 } - } -} - -impl Index for U32x2 { - type Output = u32; - #[inline] - fn index(&self, index: usize) -> &u32 { - unsafe { - assert!(index < 2); - let ptr = &self.0 as *const uint32x2_t as *const u32; - mem::transmute::<*const u32, &u32>(ptr.offset(index as isize)) - } - } -} - -// Four 32-bit unsigned integers - -#[derive(Clone, Copy)] -pub struct U32x4(pub uint32x4_t); - -impl U32x4 { - /// Returns true if all four booleans in this vector are true. - /// - /// The result is *undefined* if all four values in this vector are not booleans. A boolean is - /// a value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_true(&self) -> bool { - unsafe { aarch64::vminvq_u32(self.0) == !0 } - } - - /// Returns true if all four booleans in this vector are false. - /// - /// The result is *undefined* if all four values in this vector are not booleans. A boolean is - /// a value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_false(&self) -> bool { - unsafe { aarch64::vmaxvq_u32(self.0) == 0 } - } -} - -impl Index for U32x4 { - type Output = u32; - #[inline] - fn index(&self, index: usize) -> &u32 { - unsafe { - assert!(index < 4); - let ptr = &self.0 as *const uint32x4_t as *const u32; - mem::transmute::<*const u32, &u32>(ptr.offset(index as isize)) - } - } -} - -// Intrinsics - -extern "platform-intrinsic" { - fn simd_add(x: T, y: T) -> T; - fn simd_div(x: T, y: T) -> T; - fn simd_mul(x: T, y: T) -> T; - fn simd_sub(x: T, y: T) -> T; - - fn simd_shr(x: T, y: T) -> T; - - fn simd_and(x: T, y: T) -> T; - fn simd_or(x: T, y: T) -> T; - - fn simd_fmin(x: T, y: T) -> T; - fn simd_fmax(x: T, y: T) -> T; - - fn simd_eq(x: T, y: T) -> U; - fn simd_gt(x: T, y: T) -> U; - fn simd_le(x: T, y: T) -> U; - fn simd_lt(x: T, y: T) -> U; - - fn simd_shuffle2(x: T, y: T, idx: [u32; 2]) -> U; - fn simd_shuffle4(x: T, y: T, idx: [u32; 4]) -> U; - - fn simd_cast(x: T) -> U; -} - -extern "C" { - #[link_name = "llvm.fabs.v2f32"] - fn fabs_v2f32(a: float32x2_t) -> float32x2_t; - #[link_name = "llvm.floor.v2f32"] - fn floor_v2f32(a: float32x2_t) -> float32x2_t; - #[link_name = "llvm.ceil.v2f32"] - fn ceil_v2f32(a: float32x2_t) -> float32x2_t; - #[link_name = "llvm.round.v2f32"] - fn round_v2f32(a: float32x2_t) -> float32x2_t; - #[link_name = "llvm.sqrt.v2f32"] - fn sqrt_v2f32(a: float32x2_t) -> float32x2_t; - - #[link_name = "llvm.fabs.v4f32"] - fn fabs_v4f32(a: float32x4_t) -> float32x4_t; - #[link_name = "llvm.floor.v4f32"] - fn floor_v4f32(a: float32x4_t) -> float32x4_t; - #[link_name = "llvm.ceil.v4f32"] - fn ceil_v4f32(a: float32x4_t) -> float32x4_t; - #[link_name = "llvm.round.v4f32"] - fn round_v4f32(a: float32x4_t) -> float32x4_t; - #[link_name = "llvm.sqrt.v4f32"] - fn sqrt_v4f32(a: float32x4_t) -> float32x4_t; - - #[link_name = "llvm.aarch64.neon.frecpe.v2f32"] - fn vrecpe_v2f32(a: float32x2_t) -> float32x2_t; - - #[link_name = "llvm.aarch64.neon.frecpe.v4f32"] - fn vrecpe_v4f32(a: float32x4_t) -> float32x4_t; -} diff --git a/crates/pathfinder/simd/src/arm/swizzle_f32x4.rs b/crates/pathfinder/simd/src/arm/swizzle_f32x4.rs deleted file mode 100644 index 78cecbd1c8..0000000000 --- a/crates/pathfinder/simd/src/arm/swizzle_f32x4.rs +++ /dev/null @@ -1,1805 +0,0 @@ -// pathfinder/simd/src/arm/swizzle_f32x4.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::arm::{self, F32x4}; - -impl F32x4 { - /// Constructs a new vector from the first, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 0, 0])) } - } - - /// Constructs a new vector from the second, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 0, 0])) } - } - - /// Constructs a new vector from the third, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 0, 0])) } - } - - /// Constructs a new vector from the fourth, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 0, 0])) } - } - - /// Constructs a new vector from the first, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 0, 0])) } - } - - /// Constructs a new vector from the second, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 0, 0])) } - } - - /// Constructs a new vector from the third, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 0, 0])) } - } - - /// Constructs a new vector from the fourth, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 0, 0])) } - } - - /// Constructs a new vector from the first, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 0, 0])) } - } - - /// Constructs a new vector from the second, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 0, 0])) } - } - - /// Constructs a new vector from the third, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 0, 0])) } - } - - /// Constructs a new vector from the fourth, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 0, 0])) } - } - - /// Constructs a new vector from the first, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 0, 0])) } - } - - /// Constructs a new vector from the second, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 0, 0])) } - } - - /// Constructs a new vector from the third, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 0, 0])) } - } - - /// Constructs a new vector from the fourth, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwxx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 0, 0])) } - } - - /// Constructs a new vector from the first, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 1, 0])) } - } - - /// Constructs a new vector from the second, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 1, 0])) } - } - - /// Constructs a new vector from the third, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 1, 0])) } - } - - /// Constructs a new vector from the fourth, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 1, 0])) } - } - - /// Constructs a new vector from the first, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 1, 0])) } - } - - /// Constructs a new vector from the second, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 1, 0])) } - } - - /// Constructs a new vector from the third, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 1, 0])) } - } - - /// Constructs a new vector from the fourth, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 1, 0])) } - } - - /// Constructs a new vector from the first, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 1, 0])) } - } - - /// Constructs a new vector from the second, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 1, 0])) } - } - - /// Constructs a new vector from the third, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 1, 0])) } - } - - /// Constructs a new vector from the fourth, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 1, 0])) } - } - - /// Constructs a new vector from the first, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 1, 0])) } - } - - /// Constructs a new vector from the second, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 1, 0])) } - } - - /// Constructs a new vector from the third, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 1, 0])) } - } - - /// Constructs a new vector from the fourth, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwyx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 1, 0])) } - } - - /// Constructs a new vector from the first, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 2, 0])) } - } - - /// Constructs a new vector from the second, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 2, 0])) } - } - - /// Constructs a new vector from the third, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 2, 0])) } - } - - /// Constructs a new vector from the fourth, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 2, 0])) } - } - - /// Constructs a new vector from the first, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 2, 0])) } - } - - /// Constructs a new vector from the second, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 2, 0])) } - } - - /// Constructs a new vector from the third, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 2, 0])) } - } - - /// Constructs a new vector from the fourth, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 2, 0])) } - } - - /// Constructs a new vector from the first, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 2, 0])) } - } - - /// Constructs a new vector from the second, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 2, 0])) } - } - - /// Constructs a new vector from the third, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 2, 0])) } - } - - /// Constructs a new vector from the fourth, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 2, 0])) } - } - - /// Constructs a new vector from the first, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 2, 0])) } - } - - /// Constructs a new vector from the second, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 2, 0])) } - } - - /// Constructs a new vector from the third, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 2, 0])) } - } - - /// Constructs a new vector from the fourth, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwzx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 2, 0])) } - } - - /// Constructs a new vector from the first, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 3, 0])) } - } - - /// Constructs a new vector from the second, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 3, 0])) } - } - - /// Constructs a new vector from the third, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 3, 0])) } - } - - /// Constructs a new vector from the fourth, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 3, 0])) } - } - - /// Constructs a new vector from the first, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xywx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 3, 0])) } - } - - /// Constructs a new vector from the second, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yywx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 3, 0])) } - } - - /// Constructs a new vector from the third, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zywx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 3, 0])) } - } - - /// Constructs a new vector from the fourth, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wywx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 3, 0])) } - } - - /// Constructs a new vector from the first, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 3, 0])) } - } - - /// Constructs a new vector from the second, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 3, 0])) } - } - - /// Constructs a new vector from the third, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 3, 0])) } - } - - /// Constructs a new vector from the fourth, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 3, 0])) } - } - - /// Constructs a new vector from the first, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 3, 0])) } - } - - /// Constructs a new vector from the second, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 3, 0])) } - } - - /// Constructs a new vector from the third, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 3, 0])) } - } - - /// Constructs a new vector from the fourth, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwwx(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 3, 0])) } - } - - /// Constructs a new vector from the first, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 0, 1])) } - } - - /// Constructs a new vector from the second, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 0, 1])) } - } - - /// Constructs a new vector from the third, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 0, 1])) } - } - - /// Constructs a new vector from the fourth, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 0, 1])) } - } - - /// Constructs a new vector from the first, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 0, 1])) } - } - - /// Constructs a new vector from the second, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 0, 1])) } - } - - /// Constructs a new vector from the third, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 0, 1])) } - } - - /// Constructs a new vector from the fourth, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 0, 1])) } - } - - /// Constructs a new vector from the first, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 0, 1])) } - } - - /// Constructs a new vector from the second, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 0, 1])) } - } - - /// Constructs a new vector from the third, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 0, 1])) } - } - - /// Constructs a new vector from the fourth, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 0, 1])) } - } - - /// Constructs a new vector from the first, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 0, 1])) } - } - - /// Constructs a new vector from the second, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 0, 1])) } - } - - /// Constructs a new vector from the third, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 0, 1])) } - } - - /// Constructs a new vector from the fourth, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwxy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 0, 1])) } - } - - /// Constructs a new vector from the first, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 1, 1])) } - } - - /// Constructs a new vector from the second, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 1, 1])) } - } - - /// Constructs a new vector from the third, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 1, 1])) } - } - - /// Constructs a new vector from the fourth, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 1, 1])) } - } - - /// Constructs a new vector from the first, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 1, 1])) } - } - - /// Constructs a new vector from the second, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 1, 1])) } - } - - /// Constructs a new vector from the third, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 1, 1])) } - } - - /// Constructs a new vector from the fourth, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 1, 1])) } - } - - /// Constructs a new vector from the first, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 1, 1])) } - } - - /// Constructs a new vector from the second, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 1, 1])) } - } - - /// Constructs a new vector from the third, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 1, 1])) } - } - - /// Constructs a new vector from the fourth, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 1, 1])) } - } - - /// Constructs a new vector from the first, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 1, 1])) } - } - - /// Constructs a new vector from the second, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 1, 1])) } - } - - /// Constructs a new vector from the third, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 1, 1])) } - } - - /// Constructs a new vector from the fourth, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwyy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 1, 1])) } - } - - /// Constructs a new vector from the first, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 2, 1])) } - } - - /// Constructs a new vector from the second, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 2, 1])) } - } - - /// Constructs a new vector from the third, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 2, 1])) } - } - - /// Constructs a new vector from the fourth, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 2, 1])) } - } - - /// Constructs a new vector from the first, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 2, 1])) } - } - - /// Constructs a new vector from the second, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 2, 1])) } - } - - /// Constructs a new vector from the third, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 2, 1])) } - } - - /// Constructs a new vector from the fourth, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 2, 1])) } - } - - /// Constructs a new vector from the first, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 2, 1])) } - } - - /// Constructs a new vector from the second, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 2, 1])) } - } - - /// Constructs a new vector from the third, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 2, 1])) } - } - - /// Constructs a new vector from the fourth, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 2, 1])) } - } - - /// Constructs a new vector from the first, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 2, 1])) } - } - - /// Constructs a new vector from the second, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 2, 1])) } - } - - /// Constructs a new vector from the third, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 2, 1])) } - } - - /// Constructs a new vector from the fourth, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwzy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 2, 1])) } - } - - /// Constructs a new vector from the first, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 3, 1])) } - } - - /// Constructs a new vector from the second, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 3, 1])) } - } - - /// Constructs a new vector from the third, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 3, 1])) } - } - - /// Constructs a new vector from the fourth, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 3, 1])) } - } - - /// Constructs a new vector from the first, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xywy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 3, 1])) } - } - - /// Constructs a new vector from the second, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yywy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 3, 1])) } - } - - /// Constructs a new vector from the third, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zywy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 3, 1])) } - } - - /// Constructs a new vector from the fourth, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wywy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 3, 1])) } - } - - /// Constructs a new vector from the first, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 3, 1])) } - } - - /// Constructs a new vector from the second, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 3, 1])) } - } - - /// Constructs a new vector from the third, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 3, 1])) } - } - - /// Constructs a new vector from the fourth, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 3, 1])) } - } - - /// Constructs a new vector from the first, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 3, 1])) } - } - - /// Constructs a new vector from the second, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 3, 1])) } - } - - /// Constructs a new vector from the third, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 3, 1])) } - } - - /// Constructs a new vector from the fourth, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwwy(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 3, 1])) } - } - - /// Constructs a new vector from the first, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 0, 2])) } - } - - /// Constructs a new vector from the second, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 0, 2])) } - } - - /// Constructs a new vector from the third, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 0, 2])) } - } - - /// Constructs a new vector from the fourth, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 0, 2])) } - } - - /// Constructs a new vector from the first, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 0, 2])) } - } - - /// Constructs a new vector from the second, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 0, 2])) } - } - - /// Constructs a new vector from the third, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 0, 2])) } - } - - /// Constructs a new vector from the fourth, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 0, 2])) } - } - - /// Constructs a new vector from the first, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 0, 2])) } - } - - /// Constructs a new vector from the second, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 0, 2])) } - } - - /// Constructs a new vector from the third, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 0, 2])) } - } - - /// Constructs a new vector from the fourth, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 0, 2])) } - } - - /// Constructs a new vector from the first, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 0, 2])) } - } - - /// Constructs a new vector from the second, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 0, 2])) } - } - - /// Constructs a new vector from the third, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 0, 2])) } - } - - /// Constructs a new vector from the fourth, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwxz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 0, 2])) } - } - - /// Constructs a new vector from the first, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 1, 2])) } - } - - /// Constructs a new vector from the second, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 1, 2])) } - } - - /// Constructs a new vector from the third, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 1, 2])) } - } - - /// Constructs a new vector from the fourth, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 1, 2])) } - } - - /// Constructs a new vector from the first, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 1, 2])) } - } - - /// Constructs a new vector from the second, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 1, 2])) } - } - - /// Constructs a new vector from the third, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 1, 2])) } - } - - /// Constructs a new vector from the fourth, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 1, 2])) } - } - - /// Constructs a new vector from the first, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 1, 2])) } - } - - /// Constructs a new vector from the second, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 1, 2])) } - } - - /// Constructs a new vector from the third, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 1, 2])) } - } - - /// Constructs a new vector from the fourth, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 1, 2])) } - } - - /// Constructs a new vector from the first, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 1, 2])) } - } - - /// Constructs a new vector from the second, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 1, 2])) } - } - - /// Constructs a new vector from the third, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 1, 2])) } - } - - /// Constructs a new vector from the fourth, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwyz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 1, 2])) } - } - - /// Constructs a new vector from the first, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 2, 2])) } - } - - /// Constructs a new vector from the second, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 2, 2])) } - } - - /// Constructs a new vector from the third, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 2, 2])) } - } - - /// Constructs a new vector from the fourth, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 2, 2])) } - } - - /// Constructs a new vector from the first, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 2, 2])) } - } - - /// Constructs a new vector from the second, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 2, 2])) } - } - - /// Constructs a new vector from the third, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 2, 2])) } - } - - /// Constructs a new vector from the fourth, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 2, 2])) } - } - - /// Constructs a new vector from the first, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 2, 2])) } - } - - /// Constructs a new vector from the second, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 2, 2])) } - } - - /// Constructs a new vector from the third, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 2, 2])) } - } - - /// Constructs a new vector from the fourth, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 2, 2])) } - } - - /// Constructs a new vector from the first, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 2, 2])) } - } - - /// Constructs a new vector from the second, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 2, 2])) } - } - - /// Constructs a new vector from the third, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 2, 2])) } - } - - /// Constructs a new vector from the fourth, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwzz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 2, 2])) } - } - - /// Constructs a new vector from the first, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 3, 2])) } - } - - /// Constructs a new vector from the second, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 3, 2])) } - } - - /// Constructs a new vector from the third, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 3, 2])) } - } - - /// Constructs a new vector from the fourth, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 3, 2])) } - } - - /// Constructs a new vector from the first, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xywz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 3, 2])) } - } - - /// Constructs a new vector from the second, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yywz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 3, 2])) } - } - - /// Constructs a new vector from the third, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zywz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 3, 2])) } - } - - /// Constructs a new vector from the fourth, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wywz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 3, 2])) } - } - - /// Constructs a new vector from the first, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 3, 2])) } - } - - /// Constructs a new vector from the second, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 3, 2])) } - } - - /// Constructs a new vector from the third, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 3, 2])) } - } - - /// Constructs a new vector from the fourth, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 3, 2])) } - } - - /// Constructs a new vector from the first, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 3, 2])) } - } - - /// Constructs a new vector from the second, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 3, 2])) } - } - - /// Constructs a new vector from the third, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 3, 2])) } - } - - /// Constructs a new vector from the fourth, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwwz(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 3, 2])) } - } - - /// Constructs a new vector from the first, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 0, 3])) } - } - - /// Constructs a new vector from the second, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 0, 3])) } - } - - /// Constructs a new vector from the third, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 0, 3])) } - } - - /// Constructs a new vector from the fourth, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 0, 3])) } - } - - /// Constructs a new vector from the first, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 0, 3])) } - } - - /// Constructs a new vector from the second, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 0, 3])) } - } - - /// Constructs a new vector from the third, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 0, 3])) } - } - - /// Constructs a new vector from the fourth, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 0, 3])) } - } - - /// Constructs a new vector from the first, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 0, 3])) } - } - - /// Constructs a new vector from the second, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 0, 3])) } - } - - /// Constructs a new vector from the third, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 0, 3])) } - } - - /// Constructs a new vector from the fourth, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 0, 3])) } - } - - /// Constructs a new vector from the first, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 0, 3])) } - } - - /// Constructs a new vector from the second, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 0, 3])) } - } - - /// Constructs a new vector from the third, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 0, 3])) } - } - - /// Constructs a new vector from the fourth, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwxw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 0, 3])) } - } - - /// Constructs a new vector from the first, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 1, 3])) } - } - - /// Constructs a new vector from the second, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 1, 3])) } - } - - /// Constructs a new vector from the third, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 1, 3])) } - } - - /// Constructs a new vector from the fourth, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 1, 3])) } - } - - /// Constructs a new vector from the first, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 1, 3])) } - } - - /// Constructs a new vector from the second, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 1, 3])) } - } - - /// Constructs a new vector from the third, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 1, 3])) } - } - - /// Constructs a new vector from the fourth, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 1, 3])) } - } - - /// Constructs a new vector from the first, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 1, 3])) } - } - - /// Constructs a new vector from the second, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 1, 3])) } - } - - /// Constructs a new vector from the third, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 1, 3])) } - } - - /// Constructs a new vector from the fourth, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 1, 3])) } - } - - /// Constructs a new vector from the first, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 1, 3])) } - } - - /// Constructs a new vector from the second, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 1, 3])) } - } - - /// Constructs a new vector from the third, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 1, 3])) } - } - - /// Constructs a new vector from the fourth, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwyw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 1, 3])) } - } - - /// Constructs a new vector from the first, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 2, 3])) } - } - - /// Constructs a new vector from the second, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 2, 3])) } - } - - /// Constructs a new vector from the third, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 2, 3])) } - } - - /// Constructs a new vector from the fourth, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 2, 3])) } - } - - /// Constructs a new vector from the first, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 2, 3])) } - } - - /// Constructs a new vector from the second, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 2, 3])) } - } - - /// Constructs a new vector from the third, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 2, 3])) } - } - - /// Constructs a new vector from the fourth, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 2, 3])) } - } - - /// Constructs a new vector from the first, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 2, 3])) } - } - - /// Constructs a new vector from the second, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 2, 3])) } - } - - /// Constructs a new vector from the third, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 2, 3])) } - } - - /// Constructs a new vector from the fourth, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 2, 3])) } - } - - /// Constructs a new vector from the first, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 2, 3])) } - } - - /// Constructs a new vector from the second, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 2, 3])) } - } - - /// Constructs a new vector from the third, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 2, 3])) } - } - - /// Constructs a new vector from the fourth, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwzw(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 2, 3])) } - } - - /// Constructs a new vector from the first, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 3, 3])) } - } - - /// Constructs a new vector from the second, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 3, 3])) } - } - - /// Constructs a new vector from the third, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 3, 3])) } - } - - /// Constructs a new vector from the fourth, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 3, 3])) } - } - - /// Constructs a new vector from the first, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 3, 3])) } - } - - /// Constructs a new vector from the second, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 3, 3])) } - } - - /// Constructs a new vector from the third, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 3, 3])) } - } - - /// Constructs a new vector from the fourth, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 3, 3])) } - } - - /// Constructs a new vector from the first, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 3, 3])) } - } - - /// Constructs a new vector from the second, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 3, 3])) } - } - - /// Constructs a new vector from the third, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 3, 3])) } - } - - /// Constructs a new vector from the fourth, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 3, 3])) } - } - - /// Constructs a new vector from the first, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 3, 3])) } - } - - /// Constructs a new vector from the second, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 3, 3])) } - } - - /// Constructs a new vector from the third, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 3, 3])) } - } - - /// Constructs a new vector from the fourth, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwww(self) -> F32x4 { - unsafe { F32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 3, 3])) } - } -} diff --git a/crates/pathfinder/simd/src/arm/swizzle_i32x4.rs b/crates/pathfinder/simd/src/arm/swizzle_i32x4.rs deleted file mode 100644 index 347b4cceec..0000000000 --- a/crates/pathfinder/simd/src/arm/swizzle_i32x4.rs +++ /dev/null @@ -1,1805 +0,0 @@ -// pathfinder/simd/src/arm/swizzle_i32x4.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::arm::{self, I32x4}; - -impl I32x4 { - /// Constructs a new vector from the first, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 0, 0])) } - } - - /// Constructs a new vector from the second, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 0, 0])) } - } - - /// Constructs a new vector from the third, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 0, 0])) } - } - - /// Constructs a new vector from the fourth, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 0, 0])) } - } - - /// Constructs a new vector from the first, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 0, 0])) } - } - - /// Constructs a new vector from the second, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 0, 0])) } - } - - /// Constructs a new vector from the third, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 0, 0])) } - } - - /// Constructs a new vector from the fourth, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 0, 0])) } - } - - /// Constructs a new vector from the first, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 0, 0])) } - } - - /// Constructs a new vector from the second, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 0, 0])) } - } - - /// Constructs a new vector from the third, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 0, 0])) } - } - - /// Constructs a new vector from the fourth, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 0, 0])) } - } - - /// Constructs a new vector from the first, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 0, 0])) } - } - - /// Constructs a new vector from the second, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 0, 0])) } - } - - /// Constructs a new vector from the third, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 0, 0])) } - } - - /// Constructs a new vector from the fourth, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwxx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 0, 0])) } - } - - /// Constructs a new vector from the first, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 1, 0])) } - } - - /// Constructs a new vector from the second, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 1, 0])) } - } - - /// Constructs a new vector from the third, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 1, 0])) } - } - - /// Constructs a new vector from the fourth, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 1, 0])) } - } - - /// Constructs a new vector from the first, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 1, 0])) } - } - - /// Constructs a new vector from the second, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 1, 0])) } - } - - /// Constructs a new vector from the third, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 1, 0])) } - } - - /// Constructs a new vector from the fourth, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 1, 0])) } - } - - /// Constructs a new vector from the first, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 1, 0])) } - } - - /// Constructs a new vector from the second, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 1, 0])) } - } - - /// Constructs a new vector from the third, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 1, 0])) } - } - - /// Constructs a new vector from the fourth, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 1, 0])) } - } - - /// Constructs a new vector from the first, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 1, 0])) } - } - - /// Constructs a new vector from the second, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 1, 0])) } - } - - /// Constructs a new vector from the third, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 1, 0])) } - } - - /// Constructs a new vector from the fourth, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwyx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 1, 0])) } - } - - /// Constructs a new vector from the first, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 2, 0])) } - } - - /// Constructs a new vector from the second, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 2, 0])) } - } - - /// Constructs a new vector from the third, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 2, 0])) } - } - - /// Constructs a new vector from the fourth, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 2, 0])) } - } - - /// Constructs a new vector from the first, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 2, 0])) } - } - - /// Constructs a new vector from the second, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 2, 0])) } - } - - /// Constructs a new vector from the third, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 2, 0])) } - } - - /// Constructs a new vector from the fourth, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 2, 0])) } - } - - /// Constructs a new vector from the first, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 2, 0])) } - } - - /// Constructs a new vector from the second, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 2, 0])) } - } - - /// Constructs a new vector from the third, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 2, 0])) } - } - - /// Constructs a new vector from the fourth, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 2, 0])) } - } - - /// Constructs a new vector from the first, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 2, 0])) } - } - - /// Constructs a new vector from the second, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 2, 0])) } - } - - /// Constructs a new vector from the third, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 2, 0])) } - } - - /// Constructs a new vector from the fourth, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwzx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 2, 0])) } - } - - /// Constructs a new vector from the first, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 3, 0])) } - } - - /// Constructs a new vector from the second, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 3, 0])) } - } - - /// Constructs a new vector from the third, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 3, 0])) } - } - - /// Constructs a new vector from the fourth, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 3, 0])) } - } - - /// Constructs a new vector from the first, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xywx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 3, 0])) } - } - - /// Constructs a new vector from the second, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yywx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 3, 0])) } - } - - /// Constructs a new vector from the third, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zywx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 3, 0])) } - } - - /// Constructs a new vector from the fourth, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wywx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 3, 0])) } - } - - /// Constructs a new vector from the first, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 3, 0])) } - } - - /// Constructs a new vector from the second, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 3, 0])) } - } - - /// Constructs a new vector from the third, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 3, 0])) } - } - - /// Constructs a new vector from the fourth, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 3, 0])) } - } - - /// Constructs a new vector from the first, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 3, 0])) } - } - - /// Constructs a new vector from the second, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 3, 0])) } - } - - /// Constructs a new vector from the third, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 3, 0])) } - } - - /// Constructs a new vector from the fourth, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwwx(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 3, 0])) } - } - - /// Constructs a new vector from the first, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 0, 1])) } - } - - /// Constructs a new vector from the second, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 0, 1])) } - } - - /// Constructs a new vector from the third, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 0, 1])) } - } - - /// Constructs a new vector from the fourth, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 0, 1])) } - } - - /// Constructs a new vector from the first, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 0, 1])) } - } - - /// Constructs a new vector from the second, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 0, 1])) } - } - - /// Constructs a new vector from the third, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 0, 1])) } - } - - /// Constructs a new vector from the fourth, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 0, 1])) } - } - - /// Constructs a new vector from the first, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 0, 1])) } - } - - /// Constructs a new vector from the second, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 0, 1])) } - } - - /// Constructs a new vector from the third, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 0, 1])) } - } - - /// Constructs a new vector from the fourth, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 0, 1])) } - } - - /// Constructs a new vector from the first, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 0, 1])) } - } - - /// Constructs a new vector from the second, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 0, 1])) } - } - - /// Constructs a new vector from the third, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 0, 1])) } - } - - /// Constructs a new vector from the fourth, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwxy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 0, 1])) } - } - - /// Constructs a new vector from the first, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 1, 1])) } - } - - /// Constructs a new vector from the second, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 1, 1])) } - } - - /// Constructs a new vector from the third, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 1, 1])) } - } - - /// Constructs a new vector from the fourth, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 1, 1])) } - } - - /// Constructs a new vector from the first, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 1, 1])) } - } - - /// Constructs a new vector from the second, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 1, 1])) } - } - - /// Constructs a new vector from the third, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 1, 1])) } - } - - /// Constructs a new vector from the fourth, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 1, 1])) } - } - - /// Constructs a new vector from the first, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 1, 1])) } - } - - /// Constructs a new vector from the second, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 1, 1])) } - } - - /// Constructs a new vector from the third, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 1, 1])) } - } - - /// Constructs a new vector from the fourth, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 1, 1])) } - } - - /// Constructs a new vector from the first, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 1, 1])) } - } - - /// Constructs a new vector from the second, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 1, 1])) } - } - - /// Constructs a new vector from the third, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 1, 1])) } - } - - /// Constructs a new vector from the fourth, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwyy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 1, 1])) } - } - - /// Constructs a new vector from the first, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 2, 1])) } - } - - /// Constructs a new vector from the second, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 2, 1])) } - } - - /// Constructs a new vector from the third, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 2, 1])) } - } - - /// Constructs a new vector from the fourth, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 2, 1])) } - } - - /// Constructs a new vector from the first, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 2, 1])) } - } - - /// Constructs a new vector from the second, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 2, 1])) } - } - - /// Constructs a new vector from the third, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 2, 1])) } - } - - /// Constructs a new vector from the fourth, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 2, 1])) } - } - - /// Constructs a new vector from the first, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 2, 1])) } - } - - /// Constructs a new vector from the second, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 2, 1])) } - } - - /// Constructs a new vector from the third, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 2, 1])) } - } - - /// Constructs a new vector from the fourth, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 2, 1])) } - } - - /// Constructs a new vector from the first, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 2, 1])) } - } - - /// Constructs a new vector from the second, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 2, 1])) } - } - - /// Constructs a new vector from the third, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 2, 1])) } - } - - /// Constructs a new vector from the fourth, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwzy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 2, 1])) } - } - - /// Constructs a new vector from the first, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 3, 1])) } - } - - /// Constructs a new vector from the second, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 3, 1])) } - } - - /// Constructs a new vector from the third, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 3, 1])) } - } - - /// Constructs a new vector from the fourth, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 3, 1])) } - } - - /// Constructs a new vector from the first, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xywy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 3, 1])) } - } - - /// Constructs a new vector from the second, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yywy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 3, 1])) } - } - - /// Constructs a new vector from the third, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zywy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 3, 1])) } - } - - /// Constructs a new vector from the fourth, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wywy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 3, 1])) } - } - - /// Constructs a new vector from the first, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 3, 1])) } - } - - /// Constructs a new vector from the second, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 3, 1])) } - } - - /// Constructs a new vector from the third, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 3, 1])) } - } - - /// Constructs a new vector from the fourth, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 3, 1])) } - } - - /// Constructs a new vector from the first, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 3, 1])) } - } - - /// Constructs a new vector from the second, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 3, 1])) } - } - - /// Constructs a new vector from the third, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 3, 1])) } - } - - /// Constructs a new vector from the fourth, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwwy(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 3, 1])) } - } - - /// Constructs a new vector from the first, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 0, 2])) } - } - - /// Constructs a new vector from the second, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 0, 2])) } - } - - /// Constructs a new vector from the third, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 0, 2])) } - } - - /// Constructs a new vector from the fourth, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 0, 2])) } - } - - /// Constructs a new vector from the first, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 0, 2])) } - } - - /// Constructs a new vector from the second, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 0, 2])) } - } - - /// Constructs a new vector from the third, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 0, 2])) } - } - - /// Constructs a new vector from the fourth, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 0, 2])) } - } - - /// Constructs a new vector from the first, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 0, 2])) } - } - - /// Constructs a new vector from the second, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 0, 2])) } - } - - /// Constructs a new vector from the third, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 0, 2])) } - } - - /// Constructs a new vector from the fourth, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 0, 2])) } - } - - /// Constructs a new vector from the first, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 0, 2])) } - } - - /// Constructs a new vector from the second, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 0, 2])) } - } - - /// Constructs a new vector from the third, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 0, 2])) } - } - - /// Constructs a new vector from the fourth, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwxz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 0, 2])) } - } - - /// Constructs a new vector from the first, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 1, 2])) } - } - - /// Constructs a new vector from the second, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 1, 2])) } - } - - /// Constructs a new vector from the third, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 1, 2])) } - } - - /// Constructs a new vector from the fourth, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 1, 2])) } - } - - /// Constructs a new vector from the first, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 1, 2])) } - } - - /// Constructs a new vector from the second, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 1, 2])) } - } - - /// Constructs a new vector from the third, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 1, 2])) } - } - - /// Constructs a new vector from the fourth, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 1, 2])) } - } - - /// Constructs a new vector from the first, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 1, 2])) } - } - - /// Constructs a new vector from the second, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 1, 2])) } - } - - /// Constructs a new vector from the third, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 1, 2])) } - } - - /// Constructs a new vector from the fourth, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 1, 2])) } - } - - /// Constructs a new vector from the first, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 1, 2])) } - } - - /// Constructs a new vector from the second, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 1, 2])) } - } - - /// Constructs a new vector from the third, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 1, 2])) } - } - - /// Constructs a new vector from the fourth, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwyz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 1, 2])) } - } - - /// Constructs a new vector from the first, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 2, 2])) } - } - - /// Constructs a new vector from the second, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 2, 2])) } - } - - /// Constructs a new vector from the third, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 2, 2])) } - } - - /// Constructs a new vector from the fourth, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 2, 2])) } - } - - /// Constructs a new vector from the first, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 2, 2])) } - } - - /// Constructs a new vector from the second, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 2, 2])) } - } - - /// Constructs a new vector from the third, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 2, 2])) } - } - - /// Constructs a new vector from the fourth, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 2, 2])) } - } - - /// Constructs a new vector from the first, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 2, 2])) } - } - - /// Constructs a new vector from the second, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 2, 2])) } - } - - /// Constructs a new vector from the third, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 2, 2])) } - } - - /// Constructs a new vector from the fourth, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 2, 2])) } - } - - /// Constructs a new vector from the first, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 2, 2])) } - } - - /// Constructs a new vector from the second, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 2, 2])) } - } - - /// Constructs a new vector from the third, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 2, 2])) } - } - - /// Constructs a new vector from the fourth, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwzz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 2, 2])) } - } - - /// Constructs a new vector from the first, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 3, 2])) } - } - - /// Constructs a new vector from the second, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 3, 2])) } - } - - /// Constructs a new vector from the third, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 3, 2])) } - } - - /// Constructs a new vector from the fourth, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 3, 2])) } - } - - /// Constructs a new vector from the first, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xywz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 3, 2])) } - } - - /// Constructs a new vector from the second, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yywz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 3, 2])) } - } - - /// Constructs a new vector from the third, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zywz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 3, 2])) } - } - - /// Constructs a new vector from the fourth, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wywz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 3, 2])) } - } - - /// Constructs a new vector from the first, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 3, 2])) } - } - - /// Constructs a new vector from the second, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 3, 2])) } - } - - /// Constructs a new vector from the third, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 3, 2])) } - } - - /// Constructs a new vector from the fourth, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 3, 2])) } - } - - /// Constructs a new vector from the first, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 3, 2])) } - } - - /// Constructs a new vector from the second, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 3, 2])) } - } - - /// Constructs a new vector from the third, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 3, 2])) } - } - - /// Constructs a new vector from the fourth, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwwz(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 3, 2])) } - } - - /// Constructs a new vector from the first, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 0, 3])) } - } - - /// Constructs a new vector from the second, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 0, 3])) } - } - - /// Constructs a new vector from the third, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 0, 3])) } - } - - /// Constructs a new vector from the fourth, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 0, 3])) } - } - - /// Constructs a new vector from the first, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 0, 3])) } - } - - /// Constructs a new vector from the second, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 0, 3])) } - } - - /// Constructs a new vector from the third, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 0, 3])) } - } - - /// Constructs a new vector from the fourth, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 0, 3])) } - } - - /// Constructs a new vector from the first, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 0, 3])) } - } - - /// Constructs a new vector from the second, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 0, 3])) } - } - - /// Constructs a new vector from the third, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 0, 3])) } - } - - /// Constructs a new vector from the fourth, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 0, 3])) } - } - - /// Constructs a new vector from the first, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 0, 3])) } - } - - /// Constructs a new vector from the second, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 0, 3])) } - } - - /// Constructs a new vector from the third, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 0, 3])) } - } - - /// Constructs a new vector from the fourth, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwxw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 0, 3])) } - } - - /// Constructs a new vector from the first, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 1, 3])) } - } - - /// Constructs a new vector from the second, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 1, 3])) } - } - - /// Constructs a new vector from the third, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 1, 3])) } - } - - /// Constructs a new vector from the fourth, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 1, 3])) } - } - - /// Constructs a new vector from the first, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 1, 3])) } - } - - /// Constructs a new vector from the second, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 1, 3])) } - } - - /// Constructs a new vector from the third, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 1, 3])) } - } - - /// Constructs a new vector from the fourth, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 1, 3])) } - } - - /// Constructs a new vector from the first, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 1, 3])) } - } - - /// Constructs a new vector from the second, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 1, 3])) } - } - - /// Constructs a new vector from the third, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 1, 3])) } - } - - /// Constructs a new vector from the fourth, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 1, 3])) } - } - - /// Constructs a new vector from the first, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 1, 3])) } - } - - /// Constructs a new vector from the second, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 1, 3])) } - } - - /// Constructs a new vector from the third, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 1, 3])) } - } - - /// Constructs a new vector from the fourth, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwyw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 1, 3])) } - } - - /// Constructs a new vector from the first, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 2, 3])) } - } - - /// Constructs a new vector from the second, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 2, 3])) } - } - - /// Constructs a new vector from the third, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 2, 3])) } - } - - /// Constructs a new vector from the fourth, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 2, 3])) } - } - - /// Constructs a new vector from the first, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 2, 3])) } - } - - /// Constructs a new vector from the second, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 2, 3])) } - } - - /// Constructs a new vector from the third, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 2, 3])) } - } - - /// Constructs a new vector from the fourth, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 2, 3])) } - } - - /// Constructs a new vector from the first, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 2, 3])) } - } - - /// Constructs a new vector from the second, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 2, 3])) } - } - - /// Constructs a new vector from the third, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 2, 3])) } - } - - /// Constructs a new vector from the fourth, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 2, 3])) } - } - - /// Constructs a new vector from the first, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 2, 3])) } - } - - /// Constructs a new vector from the second, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 2, 3])) } - } - - /// Constructs a new vector from the third, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 2, 3])) } - } - - /// Constructs a new vector from the fourth, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwzw(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 2, 3])) } - } - - /// Constructs a new vector from the first, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 0, 3, 3])) } - } - - /// Constructs a new vector from the second, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 0, 3, 3])) } - } - - /// Constructs a new vector from the third, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 0, 3, 3])) } - } - - /// Constructs a new vector from the fourth, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 0, 3, 3])) } - } - - /// Constructs a new vector from the first, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 1, 3, 3])) } - } - - /// Constructs a new vector from the second, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 1, 3, 3])) } - } - - /// Constructs a new vector from the third, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 1, 3, 3])) } - } - - /// Constructs a new vector from the fourth, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 1, 3, 3])) } - } - - /// Constructs a new vector from the first, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 2, 3, 3])) } - } - - /// Constructs a new vector from the second, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 2, 3, 3])) } - } - - /// Constructs a new vector from the third, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 2, 3, 3])) } - } - - /// Constructs a new vector from the fourth, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 2, 3, 3])) } - } - - /// Constructs a new vector from the first, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [0, 3, 3, 3])) } - } - - /// Constructs a new vector from the second, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [1, 3, 3, 3])) } - } - - /// Constructs a new vector from the third, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [2, 3, 3, 3])) } - } - - /// Constructs a new vector from the fourth, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwww(self) -> I32x4 { - unsafe { I32x4(arm::simd_shuffle4(self.0, self.0, [3, 3, 3, 3])) } - } -} diff --git a/crates/pathfinder/simd/src/extras.rs b/crates/pathfinder/simd/src/extras.rs deleted file mode 100644 index c53bbdfa5f..0000000000 --- a/crates/pathfinder/simd/src/extras.rs +++ /dev/null @@ -1,260 +0,0 @@ -// pathfinder/simd/src/extras.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::default::{F32x2, F32x4, I32x2, I32x4}; -use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; - -// Two 32-bit floats - -impl F32x2 { - // Constructors - - #[inline] - pub fn from_slice(slice: &[f32]) -> F32x2 { - F32x2::new(slice[0], slice[1]) - } - - // Accessors - - #[inline] - pub fn x(self) -> f32 { - self[0] - } - - #[inline] - pub fn y(self) -> f32 { - self[1] - } - - // Mutators - - #[inline] - pub fn set_x(&mut self, x: f32) { - self[0] = x - } - - #[inline] - pub fn set_y(&mut self, y: f32) { - self[1] = y - } - - // Comparisons - - #[inline] - pub fn approx_eq(self, other: F32x2, epsilon: f32) -> bool { - (self - other).abs().packed_gt(F32x2::splat(epsilon)).all_false() - } -} - -impl AddAssign for F32x2 { - #[inline] - fn add_assign(&mut self, other: F32x2) { - *self = *self + other - } -} - -impl SubAssign for F32x2 { - #[inline] - fn sub_assign(&mut self, other: F32x2) { - *self = *self - other - } -} - -impl MulAssign for F32x2 { - #[inline] - fn mul_assign(&mut self, other: F32x2) { - *self = *self * other - } -} - -impl Neg for F32x2 { - type Output = F32x2; - #[inline] - fn neg(self) -> F32x2 { - F32x2::default() - self - } -} - -// Four 32-bit floats - -impl F32x4 { - // Constructors - - #[inline] - pub fn from_slice(slice: &[f32]) -> F32x4 { - F32x4::new(slice[0], slice[1], slice[2], slice[3]) - } - - // Accessors - - #[inline] - pub fn x(self) -> f32 { - self[0] - } - - #[inline] - pub fn y(self) -> f32 { - self[1] - } - - #[inline] - pub fn z(self) -> f32 { - self[2] - } - - #[inline] - pub fn w(self) -> f32 { - self[3] - } - - // Mutators - - #[inline] - pub fn set_x(&mut self, x: f32) { - self[0] = x - } - - #[inline] - pub fn set_y(&mut self, y: f32) { - self[1] = y - } - - #[inline] - pub fn set_z(&mut self, z: f32) { - self[2] = z - } - - #[inline] - pub fn set_w(&mut self, w: f32) { - self[3] = w - } - - // Comparisons - - #[inline] - pub fn approx_eq(self, other: F32x4, epsilon: f32) -> bool { - (self - other).abs().packed_gt(F32x4::splat(epsilon)).all_false() - } -} - -impl AddAssign for F32x4 { - #[inline] - fn add_assign(&mut self, other: F32x4) { - *self = *self + other - } -} - -impl SubAssign for F32x4 { - #[inline] - fn sub_assign(&mut self, other: F32x4) { - *self = *self - other - } -} - -impl MulAssign for F32x4 { - #[inline] - fn mul_assign(&mut self, other: F32x4) { - *self = *self * other - } -} - -impl Neg for F32x4 { - type Output = F32x4; - #[inline] - fn neg(self) -> F32x4 { - F32x4::default() - self - } -} - -// Two 32-bit integers - -impl AddAssign for I32x2 { - #[inline] - fn add_assign(&mut self, other: I32x2) { - *self = *self + other - } -} - -impl SubAssign for I32x2 { - #[inline] - fn sub_assign(&mut self, other: I32x2) { - *self = *self - other - } -} - -impl MulAssign for I32x2 { - #[inline] - fn mul_assign(&mut self, other: I32x2) { - *self = *self * other - } -} - -impl Neg for I32x2 { - type Output = I32x2; - #[inline] - fn neg(self) -> I32x2 { - I32x2::default() - self - } -} - -// Four 32-bit integers - -impl I32x4 { - // Accessors - - #[inline] - pub fn x(self) -> i32 { - self[0] - } - - #[inline] - pub fn y(self) -> i32 { - self[1] - } - - #[inline] - pub fn z(self) -> i32 { - self[2] - } - - #[inline] - pub fn w(self) -> i32 { - self[3] - } -} - -impl AddAssign for I32x4 { - #[inline] - fn add_assign(&mut self, other: I32x4) { - *self = *self + other - } -} - -impl SubAssign for I32x4 { - #[inline] - fn sub_assign(&mut self, other: I32x4) { - *self = *self - other - } -} - -impl MulAssign for I32x4 { - #[inline] - fn mul_assign(&mut self, other: I32x4) { - *self = *self * other - } -} - -impl Neg for I32x4 { - type Output = I32x4; - #[inline] - fn neg(self) -> I32x4 { - I32x4::default() - self - } -} diff --git a/crates/pathfinder/simd/src/lib.rs b/crates/pathfinder/simd/src/lib.rs deleted file mode 100644 index cbffc2a466..0000000000 --- a/crates/pathfinder/simd/src/lib.rs +++ /dev/null @@ -1,41 +0,0 @@ -// pathfinder/simd/src/lib.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![cfg_attr(pf_rustc_nightly, feature(link_llvm_intrinsics, platform_intrinsics))] -#![cfg_attr(pf_rustc_nightly, feature(simd_ffi, stdsimd))] - -//! A minimal SIMD abstraction, usable outside of Pathfinder. - -#[cfg(all(not(feature = "pf-no-simd"), pf_rustc_nightly, target_arch = "aarch64"))] -pub use crate::arm as default; -#[cfg(any( - feature = "pf-no-simd", - not(any( - target_arch = "x86", - target_arch = "x86_64", - all(pf_rustc_nightly, target_arch = "aarch64") - )) -))] -pub use crate::scalar as default; -#[cfg(all( - not(feature = "pf-no-simd"), - any(target_arch = "x86", target_arch = "x86_64") -))] -pub use crate::x86 as default; - -#[cfg(all(pf_rustc_nightly, target_arch = "aarch64"))] -pub mod arm; -mod extras; -pub mod scalar; -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -pub mod x86; - -#[cfg(test)] -mod test; diff --git a/crates/pathfinder/simd/src/scalar/mod.rs b/crates/pathfinder/simd/src/scalar/mod.rs deleted file mode 100644 index f2849355b1..0000000000 --- a/crates/pathfinder/simd/src/scalar/mod.rs +++ /dev/null @@ -1,895 +0,0 @@ -// pathfinder/simd/src/scalar.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::f32; -use std::fmt::{self, Debug, Formatter}; -use std::ops::{Add, BitAnd, BitOr, Div, Index, IndexMut, Mul, Shr, Sub}; - -mod swizzle_f32x4; -mod swizzle_i32x4; - -// Two 32-bit floats - -#[derive(Clone, Copy, Debug, Default, PartialEq)] -pub struct F32x2(pub [f32; 2]); - -impl F32x2 { - // Constructors - - #[inline] - pub fn new(a: f32, b: f32) -> F32x2 { - F32x2([a, b]) - } - - #[inline] - pub fn splat(x: f32) -> F32x2 { - F32x2([x, x]) - } - - // Basic operations - - #[inline] - pub fn approx_recip(self) -> F32x2 { - F32x2([1.0 / self[0], 1.0 / self[1]]) - } - - #[inline] - pub fn min(self, other: F32x2) -> F32x2 { - F32x2([f32::min(self[0], other[0]), f32::min(self[1], other[1])]) - } - - #[inline] - pub fn max(self, other: F32x2) -> F32x2 { - F32x2([f32::max(self[0], other[0]), f32::max(self[1], other[1])]) - } - - #[inline] - pub fn clamp(self, min: F32x2, max: F32x2) -> F32x2 { - self.max(min).min(max) - } - - #[inline] - pub fn abs(self) -> F32x2 { - F32x2([self[0].abs(), self[1].abs()]) - } - - #[inline] - pub fn floor(self) -> F32x2 { - F32x2([self[0].floor(), self[1].floor()]) - } - - #[inline] - pub fn ceil(self) -> F32x2 { - F32x2([self[0].ceil(), self[1].ceil()]) - } - - #[inline] - pub fn sqrt(self) -> F32x2 { - F32x2([self[0].sqrt(), self[1].sqrt()]) - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: F32x2) -> U32x2 { - U32x2([ - if self[0] == other[0] { !0 } else { 0 }, - if self[1] == other[1] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_gt(self, other: F32x2) -> U32x2 { - U32x2([ - if self[0] > other[0] { !0 } else { 0 }, - if self[1] > other[1] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_lt(self, other: F32x2) -> U32x2 { - U32x2([ - if self[0] < other[0] { !0 } else { 0 }, - if self[1] < other[1] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_le(self, other: F32x2) -> U32x2 { - U32x2([ - if self[0] <= other[0] { !0 } else { 0 }, - if self[1] <= other[1] { !0 } else { 0 }, - ]) - } - - // Conversions - - #[inline] - pub fn to_f32x4(self) -> F32x4 { - F32x4([self[0] as f32, self[1] as f32, 0.0, 0.0]) - } - - /// Converts these packed floats to integers via rounding. - #[inline] - pub fn to_i32x2(self) -> I32x2 { - I32x2([self[0].round() as i32, self[1].round() as i32]) - } - - /// Converts these packed floats to integers via rounding. - #[inline] - pub fn to_i32x4(self) -> I32x4 { - I32x4([self[0].round() as i32, self[1].round() as i32, 0, 0]) - } - - // Swizzle - - #[inline] - pub fn yx(self) -> F32x2 { - F32x2([self[1], self[0]]) - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: F32x2) -> F32x4 { - F32x4([self[0], self[1], other[0], other[1]]) - } -} - -impl Index for F32x2 { - type Output = f32; - #[inline] - fn index(&self, index: usize) -> &f32 { - &self.0[index] - } -} - -impl IndexMut for F32x2 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut f32 { - &mut self.0[index] - } -} - -impl Add for F32x2 { - type Output = F32x2; - #[inline] - fn add(self, other: F32x2) -> F32x2 { - F32x2([self[0] + other[0], self[1] + other[1]]) - } -} - -impl Div for F32x2 { - type Output = F32x2; - #[inline] - fn div(self, other: F32x2) -> F32x2 { - F32x2([self[0] / other[0], self[1] / other[1]]) - } -} - -impl Mul for F32x2 { - type Output = F32x2; - #[inline] - fn mul(self, other: F32x2) -> F32x2 { - F32x2([self[0] * other[0], self[1] * other[1]]) - } -} - -impl Sub for F32x2 { - type Output = F32x2; - #[inline] - fn sub(self, other: F32x2) -> F32x2 { - F32x2([self[0] - other[0], self[1] - other[1]]) - } -} - -// Four 32-bit floats - -#[derive(Clone, Copy, Default, PartialEq)] -pub struct F32x4(pub [f32; 4]); - -impl F32x4 { - #[inline] - pub fn new(a: f32, b: f32, c: f32, d: f32) -> F32x4 { - F32x4([a, b, c, d]) - } - - #[inline] - pub fn splat(x: f32) -> F32x4 { - F32x4([x; 4]) - } - - // Basic operations - - #[inline] - pub fn approx_recip(self) -> F32x4 { - F32x4([1.0 / self[0], 1.0 / self[1], 1.0 / self[2], 1.0 / self[3]]) - } - - #[inline] - pub fn min(self, other: F32x4) -> F32x4 { - F32x4([ - self[0].min(other[0]), - self[1].min(other[1]), - self[2].min(other[2]), - self[3].min(other[3]), - ]) - } - - #[inline] - pub fn max(self, other: F32x4) -> F32x4 { - F32x4([ - self[0].max(other[0]), - self[1].max(other[1]), - self[2].max(other[2]), - self[3].max(other[3]), - ]) - } - - #[inline] - pub fn clamp(self, min: F32x4, max: F32x4) -> F32x4 { - self.max(min).min(max) - } - - #[inline] - pub fn abs(self) -> F32x4 { - F32x4([self[0].abs(), self[1].abs(), self[2].abs(), self[3].abs()]) - } - - #[inline] - pub fn floor(self) -> F32x4 { - F32x4([ - self[0].floor(), - self[1].floor(), - self[2].floor(), - self[3].floor(), - ]) - } - - #[inline] - pub fn ceil(self) -> F32x4 { - F32x4([ - self[0].ceil(), - self[1].ceil(), - self[2].ceil(), - self[3].ceil(), - ]) - } - - #[inline] - pub fn sqrt(self) -> F32x4 { - F32x4([ - self[0].sqrt(), - self[1].sqrt(), - self[2].sqrt(), - self[3].sqrt(), - ]) - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: F32x4) -> U32x4 { - U32x4([ - if self[0] == other[0] { !0 } else { 0 }, - if self[1] == other[1] { !0 } else { 0 }, - if self[2] == other[2] { !0 } else { 0 }, - if self[3] == other[3] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_gt(self, other: F32x4) -> U32x4 { - U32x4([ - if self[0] > other[0] { !0 } else { 0 }, - if self[1] > other[1] { !0 } else { 0 }, - if self[2] > other[2] { !0 } else { 0 }, - if self[3] > other[3] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_le(self, other: F32x4) -> U32x4 { - U32x4([ - if self[0] <= other[0] { !0 } else { 0 }, - if self[1] <= other[1] { !0 } else { 0 }, - if self[2] <= other[2] { !0 } else { 0 }, - if self[3] <= other[3] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_lt(self, other: F32x4) -> U32x4 { - U32x4([ - if self[0] < other[0] { !0 } else { 0 }, - if self[1] < other[1] { !0 } else { 0 }, - if self[2] < other[2] { !0 } else { 0 }, - if self[3] < other[3] { !0 } else { 0 }, - ]) - } - - /// Converts these packed floats to integers via rounding. - #[inline] - pub fn to_i32x4(self) -> I32x4 { - I32x4([ - self[0].round() as i32, - self[1].round() as i32, - self[2].round() as i32, - self[3].round() as i32, - ]) - } - - // Swizzle conversions - - #[inline] - pub fn xy(self) -> F32x2 { - F32x2([self[0], self[1]]) - } - - #[inline] - pub fn xw(self) -> F32x2 { - F32x2([self[0], self[3]]) - } - - #[inline] - pub fn yx(self) -> F32x2 { - F32x2([self[1], self[0]]) - } - - #[inline] - pub fn zy(self) -> F32x2 { - F32x2([self[2], self[1]]) - } - - #[inline] - pub fn zw(self) -> F32x2 { - F32x2([self[2], self[3]]) - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: F32x4) -> F32x4 { - F32x4([self[0], self[1], other[0], other[1]]) - } - - #[inline] - pub fn concat_xy_zw(self, other: F32x4) -> F32x4 { - F32x4([self[0], self[1], other[2], other[3]]) - } - - #[inline] - pub fn concat_zw_zw(self, other: F32x4) -> F32x4 { - F32x4([self[2], self[3], other[2], other[3]]) - } - - #[inline] - pub fn concat_wz_yx(self, other: F32x4) -> F32x4 { - F32x4([self[3], self[2], other[1], other[0]]) - } -} - -impl Index for F32x4 { - type Output = f32; - #[inline] - fn index(&self, index: usize) -> &f32 { - &self.0[index] - } -} - -impl IndexMut for F32x4 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut f32 { - &mut self.0[index] - } -} - -impl Debug for F32x4 { - #[inline] - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "<{}, {}, {}, {}>", self[0], self[1], self[2], self[3]) - } -} - -impl Add for F32x4 { - type Output = F32x4; - #[inline] - fn add(self, other: F32x4) -> F32x4 { - F32x4([ - self[0] + other[0], - self[1] + other[1], - self[2] + other[2], - self[3] + other[3], - ]) - } -} - -impl Div for F32x4 { - type Output = F32x4; - #[inline] - fn div(self, other: F32x4) -> F32x4 { - F32x4([ - self[0] / other[0], - self[1] / other[1], - self[2] / other[2], - self[3] / other[3], - ]) - } -} - -impl Mul for F32x4 { - type Output = F32x4; - #[inline] - fn mul(self, other: F32x4) -> F32x4 { - F32x4([ - self[0] * other[0], - self[1] * other[1], - self[2] * other[2], - self[3] * other[3], - ]) - } -} - -impl Sub for F32x4 { - type Output = F32x4; - #[inline] - fn sub(self, other: F32x4) -> F32x4 { - F32x4([ - self[0] - other[0], - self[1] - other[1], - self[2] - other[2], - self[3] - other[3], - ]) - } -} - -// Two 32-bit signed integers - -#[derive(Clone, Copy, Default, Debug, PartialEq)] -pub struct I32x2([i32; 2]); - -impl I32x2 { - #[inline] - pub fn new(x: i32, y: i32) -> I32x2 { - I32x2([x, y]) - } - - #[inline] - pub fn splat(x: i32) -> I32x2 { - I32x2([x, x]) - } - - // Accessors - - #[inline] - pub fn x(self) -> i32 { - self[0] - } - - #[inline] - pub fn y(self) -> i32 { - self[1] - } - - #[inline] - pub fn concat_xy_xy(self, other: I32x2) -> I32x4 { - I32x4([self[0], self[1], other[0], other[1]]) - } - - #[inline] - pub fn min(self, other: I32x2) -> I32x2 { - I32x2([ - self[0].min(other[0]), - self[1].min(other[1]), - ]) - } - - #[inline] - pub fn max(self, other: I32x2) -> I32x2 { - I32x2([ - self[0].max(other[0]), - self[1].max(other[1]), - ]) - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: I32x2) -> U32x2 { - U32x2([ - if self[0] == other[0] { !0 } else { 0 }, - if self[1] == other[1] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_gt(self, other: I32x2) -> U32x2 { - U32x2([ - if self[0] > other[0] { !0 } else { 0 }, - if self[1] > other[1] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_le(self, other: I32x2) -> U32x2 { - U32x2([ - if self[0] <= other[0] { !0 } else { 0 }, - if self[1] <= other[1] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_lt(self, other: I32x2) -> U32x2 { - U32x2([ - if self[0] < other[0] { !0 } else { 0 }, - if self[1] < other[1] { !0 } else { 0 }, - ]) - } - - // Conversions - - /// Converts these packed integers to floats. - #[inline] - pub fn to_f32x2(self) -> F32x2 { - F32x2([self[0] as f32, self[1] as f32]) - } -} - -impl Index for I32x2 { - type Output = i32; - #[inline] - fn index(&self, index: usize) -> &i32 { - &self.0[index] - } -} - -impl IndexMut for I32x2 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut i32 { - &mut self.0[index] - } -} - -impl Add for I32x2 { - type Output = I32x2; - #[inline] - fn add(self, other: I32x2) -> I32x2 { - I32x2([self[0] + other[0], self[1] + other[1]]) - } -} - -impl Sub for I32x2 { - type Output = I32x2; - #[inline] - fn sub(self, other: I32x2) -> I32x2 { - I32x2([self[0] - other[0], self[1] - other[1]]) - } -} - -impl Mul for I32x2 { - type Output = I32x2; - #[inline] - fn mul(self, other: I32x2) -> I32x2 { - I32x2([self[0] * other[0], self[1] * other[1]]) - } -} - -// Four 32-bit signed integers - -#[derive(Clone, Copy, Default, Debug, PartialEq)] -pub struct I32x4([i32; 4]); - -impl I32x4 { - #[inline] - pub fn new(a: i32, b: i32, c: i32, d: i32) -> I32x4 { - I32x4([a, b, c, d]) - } - - #[inline] - pub fn splat(x: i32) -> I32x4 { - I32x4([x; 4]) - } - - // Basic operations - - #[inline] - pub fn min(self, other: I32x4) -> I32x4 { - I32x4([ - self[0].min(other[0]), - self[1].min(other[1]), - self[2].min(other[2]), - self[3].min(other[3]), - ]) - } - - #[inline] - pub fn max(self, other: I32x4) -> I32x4 { - I32x4([ - self[0].max(other[0]), - self[1].max(other[1]), - self[2].max(other[2]), - self[3].max(other[3]), - ]) - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: I32x4) -> U32x4 { - U32x4([ - if self[0] == other[0] { !0 } else { 0 }, - if self[1] == other[1] { !0 } else { 0 }, - if self[2] == other[2] { !0 } else { 0 }, - if self[3] == other[3] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_gt(self, other: I32x4) -> U32x4 { - U32x4([ - if self[0] > other[0] { !0 } else { 0 }, - if self[1] > other[1] { !0 } else { 0 }, - if self[2] > other[2] { !0 } else { 0 }, - if self[3] > other[3] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_le(self, other: I32x4) -> U32x4 { - U32x4([ - if self[0] <= other[0] { !0 } else { 0 }, - if self[1] <= other[1] { !0 } else { 0 }, - if self[2] <= other[2] { !0 } else { 0 }, - if self[3] <= other[3] { !0 } else { 0 }, - ]) - } - - #[inline] - pub fn packed_lt(self, other: I32x4) -> U32x4 { - U32x4([ - if self[0] < other[0] { !0 } else { 0 }, - if self[1] < other[1] { !0 } else { 0 }, - if self[2] < other[2] { !0 } else { 0 }, - if self[3] < other[3] { !0 } else { 0 }, - ]) - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: I32x4) -> I32x4 { - I32x4([self[0], self[1], other[0], other[1]]) - } - - #[inline] - pub fn concat_zw_zw(self, other: I32x4) -> I32x4 { - I32x4([self[2], self[3], other[2], other[3]]) - } - - // Swizzle conversions - - #[inline] - pub fn xy(self) -> I32x2 { - I32x2([self[0], self[1]]) - } - - #[inline] - pub fn xw(self) -> I32x2 { - I32x2([self[0], self[3]]) - } - - #[inline] - pub fn zy(self) -> I32x2 { - I32x2([self[2], self[1]]) - } - - #[inline] - pub fn zw(self) -> I32x2 { - I32x2([self[2], self[3]]) - } - - // Conversions - - /// Converts these packed integers to floats. - #[inline] - pub fn to_f32x4(self) -> F32x4 { - F32x4([ - self[0] as f32, - self[1] as f32, - self[2] as f32, - self[3] as f32, - ]) - } - - /// Converts these packed signed integers to unsigned integers. - /// - /// Overflowing values will wrap around. - /// - /// FIXME(pcwalton): Should they? This will assert on overflow in debug. - #[inline] - pub fn to_u32x4(self) -> U32x4 { - U32x4([self[0] as u32, self[1] as u32, self[2] as u32, self[3] as u32]) - } -} - -impl Index for I32x4 { - type Output = i32; - #[inline] - fn index(&self, index: usize) -> &i32 { - &self.0[index] - } -} - -impl IndexMut for I32x4 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut i32 { - &mut self.0[index] - } -} - -impl Add for I32x4 { - type Output = I32x4; - #[inline] - fn add(self, other: I32x4) -> I32x4 { - I32x4([ - self[0] + other[0], - self[1] + other[1], - self[2] + other[2], - self[3] + other[3], - ]) - } -} - -impl Sub for I32x4 { - type Output = I32x4; - #[inline] - fn sub(self, other: I32x4) -> I32x4 { - I32x4([ - self[0] - other[0], - self[1] - other[1], - self[2] - other[2], - self[3] - other[3], - ]) - } -} - -impl Mul for I32x4 { - type Output = I32x4; - #[inline] - fn mul(self, other: I32x4) -> I32x4 { - I32x4([ - self[0] * other[0], - self[1] * other[1], - self[2] * other[2], - self[3] * other[3], - ]) - } -} - -impl BitAnd for I32x4 { - type Output = I32x4; - #[inline] - fn bitand(self, other: I32x4) -> I32x4 { - I32x4([self[0] & other[0], self[1] & other[1], self[2] & other[2], self[3] & other[3]]) - } -} - -impl BitOr for I32x4 { - type Output = I32x4; - #[inline] - fn bitor(self, other: I32x4) -> I32x4 { - I32x4([self[0] | other[0], self[1] | other[1], self[2] | other[2], self[3] | other[3]]) - } -} - -impl Shr for I32x4 { - type Output = I32x4; - #[inline] - fn shr(self, other: I32x4) -> I32x4 { - I32x4([ - self[0] >> other[0], - self[1] >> other[1], - self[2] >> other[2], - self[3] >> other[3], - ]) - } -} - -// Two 32-bit unsigned integers - -#[derive(Clone, Copy)] -pub struct U32x2(pub [u32; 2]); - -impl U32x2 { - /// Returns true if both booleans in this vector are true. - /// - /// The result is *undefined* if both values in this vector are not booleans. A boolean is a - /// value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_true(&self) -> bool { - self[0] == !0 && self[1] == !0 - } - - /// Returns true if both booleans in this vector are false. - /// - /// The result is *undefined* if both values in this vector are not booleans. A boolean is a - /// value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_false(&self) -> bool { - self[0] == 0 && self[1] == 0 - } -} - -impl Index for U32x2 { - type Output = u32; - #[inline] - fn index(&self, index: usize) -> &u32 { - &self.0[index] - } -} - -// Four 32-bit unsigned integers - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct U32x4(pub [u32; 4]); - -impl U32x4 { - pub fn new(a: u32, b: u32, c: u32, d: u32) -> U32x4 { - U32x4([a, b, c, d]) - } - - // Conversions - - /// Converts these packed unsigned integers to signed integers. - /// - /// Overflowing values will wrap around. - /// - /// FIXME(pcwalton): Should they? This will assert on overflow in debug. - #[inline] - pub fn to_i32x4(self) -> I32x4 { - I32x4([self[0] as i32, self[1] as i32, self[2] as i32, self[3] as i32]) - } - - // Basic operations - - /// Returns true if all four booleans in this vector are true. - /// - /// The result is *undefined* if all four values in this vector are not booleans. A boolean is - /// a value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_true(&self) -> bool { - self[0] == !0 && self[1] == !0 && self[2] == !0 && self[3] == !0 - } - - /// Returns true if all four booleans in this vector are false. - /// - /// The result is *undefined* if all four values in this vector are not booleans. A boolean is - /// a value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_false(&self) -> bool { - self[0] == 0 && self[1] == 0 && self[2] == 0 && self[3] == 0 - } -} - -impl Index for U32x4 { - type Output = u32; - #[inline] - fn index(&self, index: usize) -> &u32 { - &self.0[index] - } -} - -impl Shr for U32x4 { - type Output = U32x4; - #[inline] - fn shr(self, amount: u32) -> U32x4 { - U32x4([self[0] >> amount, self[1] >> amount, self[2] >> amount, self[3] >> amount]) - } -} diff --git a/crates/pathfinder/simd/src/scalar/swizzle_f32x4.rs b/crates/pathfinder/simd/src/scalar/swizzle_f32x4.rs deleted file mode 100644 index 595dd7468c..0000000000 --- a/crates/pathfinder/simd/src/scalar/swizzle_f32x4.rs +++ /dev/null @@ -1,1805 +0,0 @@ -// pathfinder/simd/src/scalar/swizzle_f32x4.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::scalar::F32x4; - -impl F32x4 { - /// Constructs a new vector from the first, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxxx(self) -> F32x4 { - F32x4([self[0], self[0], self[0], self[0]]) - } - - /// Constructs a new vector from the second, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxxx(self) -> F32x4 { - F32x4([self[1], self[0], self[0], self[0]]) - } - - /// Constructs a new vector from the third, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxxx(self) -> F32x4 { - F32x4([self[2], self[0], self[0], self[0]]) - } - - /// Constructs a new vector from the fourth, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxxx(self) -> F32x4 { - F32x4([self[3], self[0], self[0], self[0]]) - } - - /// Constructs a new vector from the first, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyxx(self) -> F32x4 { - F32x4([self[0], self[1], self[0], self[0]]) - } - - /// Constructs a new vector from the second, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyxx(self) -> F32x4 { - F32x4([self[1], self[1], self[0], self[0]]) - } - - /// Constructs a new vector from the third, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyxx(self) -> F32x4 { - F32x4([self[2], self[1], self[0], self[0]]) - } - - /// Constructs a new vector from the fourth, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyxx(self) -> F32x4 { - F32x4([self[3], self[1], self[0], self[0]]) - } - - /// Constructs a new vector from the first, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzxx(self) -> F32x4 { - F32x4([self[0], self[2], self[0], self[0]]) - } - - /// Constructs a new vector from the second, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzxx(self) -> F32x4 { - F32x4([self[1], self[2], self[0], self[0]]) - } - - /// Constructs a new vector from the third, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzxx(self) -> F32x4 { - F32x4([self[2], self[2], self[0], self[0]]) - } - - /// Constructs a new vector from the fourth, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzxx(self) -> F32x4 { - F32x4([self[3], self[2], self[0], self[0]]) - } - - /// Constructs a new vector from the first, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwxx(self) -> F32x4 { - F32x4([self[0], self[3], self[0], self[0]]) - } - - /// Constructs a new vector from the second, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywxx(self) -> F32x4 { - F32x4([self[1], self[3], self[0], self[0]]) - } - - /// Constructs a new vector from the third, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwxx(self) -> F32x4 { - F32x4([self[2], self[3], self[0], self[0]]) - } - - /// Constructs a new vector from the fourth, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwxx(self) -> F32x4 { - F32x4([self[3], self[3], self[0], self[0]]) - } - - /// Constructs a new vector from the first, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxyx(self) -> F32x4 { - F32x4([self[0], self[0], self[1], self[0]]) - } - - /// Constructs a new vector from the second, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxyx(self) -> F32x4 { - F32x4([self[1], self[0], self[1], self[0]]) - } - - /// Constructs a new vector from the third, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxyx(self) -> F32x4 { - F32x4([self[2], self[0], self[1], self[0]]) - } - - /// Constructs a new vector from the fourth, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxyx(self) -> F32x4 { - F32x4([self[3], self[0], self[1], self[0]]) - } - - /// Constructs a new vector from the first, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyyx(self) -> F32x4 { - F32x4([self[0], self[1], self[1], self[0]]) - } - - /// Constructs a new vector from the second, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyyx(self) -> F32x4 { - F32x4([self[1], self[1], self[1], self[0]]) - } - - /// Constructs a new vector from the third, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyyx(self) -> F32x4 { - F32x4([self[2], self[1], self[1], self[0]]) - } - - /// Constructs a new vector from the fourth, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyyx(self) -> F32x4 { - F32x4([self[3], self[1], self[1], self[0]]) - } - - /// Constructs a new vector from the first, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzyx(self) -> F32x4 { - F32x4([self[0], self[2], self[1], self[0]]) - } - - /// Constructs a new vector from the second, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzyx(self) -> F32x4 { - F32x4([self[1], self[2], self[1], self[0]]) - } - - /// Constructs a new vector from the third, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzyx(self) -> F32x4 { - F32x4([self[2], self[2], self[1], self[0]]) - } - - /// Constructs a new vector from the fourth, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzyx(self) -> F32x4 { - F32x4([self[3], self[2], self[1], self[0]]) - } - - /// Constructs a new vector from the first, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwyx(self) -> F32x4 { - F32x4([self[0], self[3], self[1], self[0]]) - } - - /// Constructs a new vector from the second, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywyx(self) -> F32x4 { - F32x4([self[1], self[3], self[1], self[0]]) - } - - /// Constructs a new vector from the third, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwyx(self) -> F32x4 { - F32x4([self[2], self[3], self[1], self[0]]) - } - - /// Constructs a new vector from the fourth, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwyx(self) -> F32x4 { - F32x4([self[3], self[3], self[1], self[0]]) - } - - /// Constructs a new vector from the first, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxzx(self) -> F32x4 { - F32x4([self[0], self[0], self[2], self[0]]) - } - - /// Constructs a new vector from the second, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxzx(self) -> F32x4 { - F32x4([self[1], self[0], self[2], self[0]]) - } - - /// Constructs a new vector from the third, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxzx(self) -> F32x4 { - F32x4([self[2], self[0], self[2], self[0]]) - } - - /// Constructs a new vector from the fourth, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxzx(self) -> F32x4 { - F32x4([self[3], self[0], self[2], self[0]]) - } - - /// Constructs a new vector from the first, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyzx(self) -> F32x4 { - F32x4([self[0], self[1], self[2], self[0]]) - } - - /// Constructs a new vector from the second, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyzx(self) -> F32x4 { - F32x4([self[1], self[1], self[2], self[0]]) - } - - /// Constructs a new vector from the third, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyzx(self) -> F32x4 { - F32x4([self[2], self[1], self[2], self[0]]) - } - - /// Constructs a new vector from the fourth, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyzx(self) -> F32x4 { - F32x4([self[3], self[1], self[2], self[0]]) - } - - /// Constructs a new vector from the first, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzzx(self) -> F32x4 { - F32x4([self[0], self[2], self[2], self[0]]) - } - - /// Constructs a new vector from the second, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzzx(self) -> F32x4 { - F32x4([self[1], self[2], self[2], self[0]]) - } - - /// Constructs a new vector from the third, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzzx(self) -> F32x4 { - F32x4([self[2], self[2], self[2], self[0]]) - } - - /// Constructs a new vector from the fourth, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzzx(self) -> F32x4 { - F32x4([self[3], self[2], self[2], self[0]]) - } - - /// Constructs a new vector from the first, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwzx(self) -> F32x4 { - F32x4([self[0], self[3], self[2], self[0]]) - } - - /// Constructs a new vector from the second, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywzx(self) -> F32x4 { - F32x4([self[1], self[3], self[2], self[0]]) - } - - /// Constructs a new vector from the third, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwzx(self) -> F32x4 { - F32x4([self[2], self[3], self[2], self[0]]) - } - - /// Constructs a new vector from the fourth, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwzx(self) -> F32x4 { - F32x4([self[3], self[3], self[2], self[0]]) - } - - /// Constructs a new vector from the first, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxwx(self) -> F32x4 { - F32x4([self[0], self[0], self[3], self[0]]) - } - - /// Constructs a new vector from the second, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxwx(self) -> F32x4 { - F32x4([self[1], self[0], self[3], self[0]]) - } - - /// Constructs a new vector from the third, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxwx(self) -> F32x4 { - F32x4([self[2], self[0], self[3], self[0]]) - } - - /// Constructs a new vector from the fourth, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxwx(self) -> F32x4 { - F32x4([self[3], self[0], self[3], self[0]]) - } - - /// Constructs a new vector from the first, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xywx(self) -> F32x4 { - F32x4([self[0], self[1], self[3], self[0]]) - } - - /// Constructs a new vector from the second, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yywx(self) -> F32x4 { - F32x4([self[1], self[1], self[3], self[0]]) - } - - /// Constructs a new vector from the third, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zywx(self) -> F32x4 { - F32x4([self[2], self[1], self[3], self[0]]) - } - - /// Constructs a new vector from the fourth, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wywx(self) -> F32x4 { - F32x4([self[3], self[1], self[3], self[0]]) - } - - /// Constructs a new vector from the first, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzwx(self) -> F32x4 { - F32x4([self[0], self[2], self[3], self[0]]) - } - - /// Constructs a new vector from the second, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzwx(self) -> F32x4 { - F32x4([self[1], self[2], self[3], self[0]]) - } - - /// Constructs a new vector from the third, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzwx(self) -> F32x4 { - F32x4([self[2], self[2], self[3], self[0]]) - } - - /// Constructs a new vector from the fourth, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzwx(self) -> F32x4 { - F32x4([self[3], self[2], self[3], self[0]]) - } - - /// Constructs a new vector from the first, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwwx(self) -> F32x4 { - F32x4([self[0], self[3], self[3], self[0]]) - } - - /// Constructs a new vector from the second, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywwx(self) -> F32x4 { - F32x4([self[1], self[3], self[3], self[0]]) - } - - /// Constructs a new vector from the third, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwwx(self) -> F32x4 { - F32x4([self[2], self[3], self[3], self[0]]) - } - - /// Constructs a new vector from the fourth, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwwx(self) -> F32x4 { - F32x4([self[3], self[3], self[3], self[0]]) - } - - /// Constructs a new vector from the first, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxxy(self) -> F32x4 { - F32x4([self[0], self[0], self[0], self[1]]) - } - - /// Constructs a new vector from the second, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxxy(self) -> F32x4 { - F32x4([self[1], self[0], self[0], self[1]]) - } - - /// Constructs a new vector from the third, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxxy(self) -> F32x4 { - F32x4([self[2], self[0], self[0], self[1]]) - } - - /// Constructs a new vector from the fourth, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxxy(self) -> F32x4 { - F32x4([self[3], self[0], self[0], self[1]]) - } - - /// Constructs a new vector from the first, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyxy(self) -> F32x4 { - F32x4([self[0], self[1], self[0], self[1]]) - } - - /// Constructs a new vector from the second, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyxy(self) -> F32x4 { - F32x4([self[1], self[1], self[0], self[1]]) - } - - /// Constructs a new vector from the third, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyxy(self) -> F32x4 { - F32x4([self[2], self[1], self[0], self[1]]) - } - - /// Constructs a new vector from the fourth, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyxy(self) -> F32x4 { - F32x4([self[3], self[1], self[0], self[1]]) - } - - /// Constructs a new vector from the first, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzxy(self) -> F32x4 { - F32x4([self[0], self[2], self[0], self[1]]) - } - - /// Constructs a new vector from the second, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzxy(self) -> F32x4 { - F32x4([self[1], self[2], self[0], self[1]]) - } - - /// Constructs a new vector from the third, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzxy(self) -> F32x4 { - F32x4([self[2], self[2], self[0], self[1]]) - } - - /// Constructs a new vector from the fourth, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzxy(self) -> F32x4 { - F32x4([self[3], self[2], self[0], self[1]]) - } - - /// Constructs a new vector from the first, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwxy(self) -> F32x4 { - F32x4([self[0], self[3], self[0], self[1]]) - } - - /// Constructs a new vector from the second, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywxy(self) -> F32x4 { - F32x4([self[1], self[3], self[0], self[1]]) - } - - /// Constructs a new vector from the third, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwxy(self) -> F32x4 { - F32x4([self[2], self[3], self[0], self[1]]) - } - - /// Constructs a new vector from the fourth, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwxy(self) -> F32x4 { - F32x4([self[3], self[3], self[0], self[1]]) - } - - /// Constructs a new vector from the first, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxyy(self) -> F32x4 { - F32x4([self[0], self[0], self[1], self[1]]) - } - - /// Constructs a new vector from the second, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxyy(self) -> F32x4 { - F32x4([self[1], self[0], self[1], self[1]]) - } - - /// Constructs a new vector from the third, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxyy(self) -> F32x4 { - F32x4([self[2], self[0], self[1], self[1]]) - } - - /// Constructs a new vector from the fourth, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxyy(self) -> F32x4 { - F32x4([self[3], self[0], self[1], self[1]]) - } - - /// Constructs a new vector from the first, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyyy(self) -> F32x4 { - F32x4([self[0], self[1], self[1], self[1]]) - } - - /// Constructs a new vector from the second, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyyy(self) -> F32x4 { - F32x4([self[1], self[1], self[1], self[1]]) - } - - /// Constructs a new vector from the third, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyyy(self) -> F32x4 { - F32x4([self[2], self[1], self[1], self[1]]) - } - - /// Constructs a new vector from the fourth, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyyy(self) -> F32x4 { - F32x4([self[3], self[1], self[1], self[1]]) - } - - /// Constructs a new vector from the first, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzyy(self) -> F32x4 { - F32x4([self[0], self[2], self[1], self[1]]) - } - - /// Constructs a new vector from the second, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzyy(self) -> F32x4 { - F32x4([self[1], self[2], self[1], self[1]]) - } - - /// Constructs a new vector from the third, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzyy(self) -> F32x4 { - F32x4([self[2], self[2], self[1], self[1]]) - } - - /// Constructs a new vector from the fourth, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzyy(self) -> F32x4 { - F32x4([self[3], self[2], self[1], self[1]]) - } - - /// Constructs a new vector from the first, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwyy(self) -> F32x4 { - F32x4([self[0], self[3], self[1], self[1]]) - } - - /// Constructs a new vector from the second, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywyy(self) -> F32x4 { - F32x4([self[1], self[3], self[1], self[1]]) - } - - /// Constructs a new vector from the third, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwyy(self) -> F32x4 { - F32x4([self[2], self[3], self[1], self[1]]) - } - - /// Constructs a new vector from the fourth, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwyy(self) -> F32x4 { - F32x4([self[3], self[3], self[1], self[1]]) - } - - /// Constructs a new vector from the first, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxzy(self) -> F32x4 { - F32x4([self[0], self[0], self[2], self[1]]) - } - - /// Constructs a new vector from the second, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxzy(self) -> F32x4 { - F32x4([self[1], self[0], self[2], self[1]]) - } - - /// Constructs a new vector from the third, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxzy(self) -> F32x4 { - F32x4([self[2], self[0], self[2], self[1]]) - } - - /// Constructs a new vector from the fourth, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxzy(self) -> F32x4 { - F32x4([self[3], self[0], self[2], self[1]]) - } - - /// Constructs a new vector from the first, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyzy(self) -> F32x4 { - F32x4([self[0], self[1], self[2], self[1]]) - } - - /// Constructs a new vector from the second, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyzy(self) -> F32x4 { - F32x4([self[1], self[1], self[2], self[1]]) - } - - /// Constructs a new vector from the third, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyzy(self) -> F32x4 { - F32x4([self[2], self[1], self[2], self[1]]) - } - - /// Constructs a new vector from the fourth, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyzy(self) -> F32x4 { - F32x4([self[3], self[1], self[2], self[1]]) - } - - /// Constructs a new vector from the first, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzzy(self) -> F32x4 { - F32x4([self[0], self[2], self[2], self[1]]) - } - - /// Constructs a new vector from the second, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzzy(self) -> F32x4 { - F32x4([self[1], self[2], self[2], self[1]]) - } - - /// Constructs a new vector from the third, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzzy(self) -> F32x4 { - F32x4([self[2], self[2], self[2], self[1]]) - } - - /// Constructs a new vector from the fourth, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzzy(self) -> F32x4 { - F32x4([self[3], self[2], self[2], self[1]]) - } - - /// Constructs a new vector from the first, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwzy(self) -> F32x4 { - F32x4([self[0], self[3], self[2], self[1]]) - } - - /// Constructs a new vector from the second, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywzy(self) -> F32x4 { - F32x4([self[1], self[3], self[2], self[1]]) - } - - /// Constructs a new vector from the third, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwzy(self) -> F32x4 { - F32x4([self[2], self[3], self[2], self[1]]) - } - - /// Constructs a new vector from the fourth, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwzy(self) -> F32x4 { - F32x4([self[3], self[3], self[2], self[1]]) - } - - /// Constructs a new vector from the first, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxwy(self) -> F32x4 { - F32x4([self[0], self[0], self[3], self[1]]) - } - - /// Constructs a new vector from the second, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxwy(self) -> F32x4 { - F32x4([self[1], self[0], self[3], self[1]]) - } - - /// Constructs a new vector from the third, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxwy(self) -> F32x4 { - F32x4([self[2], self[0], self[3], self[1]]) - } - - /// Constructs a new vector from the fourth, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxwy(self) -> F32x4 { - F32x4([self[3], self[0], self[3], self[1]]) - } - - /// Constructs a new vector from the first, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xywy(self) -> F32x4 { - F32x4([self[0], self[1], self[3], self[1]]) - } - - /// Constructs a new vector from the second, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yywy(self) -> F32x4 { - F32x4([self[1], self[1], self[3], self[1]]) - } - - /// Constructs a new vector from the third, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zywy(self) -> F32x4 { - F32x4([self[2], self[1], self[3], self[1]]) - } - - /// Constructs a new vector from the fourth, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wywy(self) -> F32x4 { - F32x4([self[3], self[1], self[3], self[1]]) - } - - /// Constructs a new vector from the first, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzwy(self) -> F32x4 { - F32x4([self[0], self[2], self[3], self[1]]) - } - - /// Constructs a new vector from the second, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzwy(self) -> F32x4 { - F32x4([self[1], self[2], self[3], self[1]]) - } - - /// Constructs a new vector from the third, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzwy(self) -> F32x4 { - F32x4([self[2], self[2], self[3], self[1]]) - } - - /// Constructs a new vector from the fourth, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzwy(self) -> F32x4 { - F32x4([self[3], self[2], self[3], self[1]]) - } - - /// Constructs a new vector from the first, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwwy(self) -> F32x4 { - F32x4([self[0], self[3], self[3], self[1]]) - } - - /// Constructs a new vector from the second, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywwy(self) -> F32x4 { - F32x4([self[1], self[3], self[3], self[1]]) - } - - /// Constructs a new vector from the third, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwwy(self) -> F32x4 { - F32x4([self[2], self[3], self[3], self[1]]) - } - - /// Constructs a new vector from the fourth, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwwy(self) -> F32x4 { - F32x4([self[3], self[3], self[3], self[1]]) - } - - /// Constructs a new vector from the first, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxxz(self) -> F32x4 { - F32x4([self[0], self[0], self[0], self[2]]) - } - - /// Constructs a new vector from the second, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxxz(self) -> F32x4 { - F32x4([self[1], self[0], self[0], self[2]]) - } - - /// Constructs a new vector from the third, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxxz(self) -> F32x4 { - F32x4([self[2], self[0], self[0], self[2]]) - } - - /// Constructs a new vector from the fourth, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxxz(self) -> F32x4 { - F32x4([self[3], self[0], self[0], self[2]]) - } - - /// Constructs a new vector from the first, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyxz(self) -> F32x4 { - F32x4([self[0], self[1], self[0], self[2]]) - } - - /// Constructs a new vector from the second, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyxz(self) -> F32x4 { - F32x4([self[1], self[1], self[0], self[2]]) - } - - /// Constructs a new vector from the third, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyxz(self) -> F32x4 { - F32x4([self[2], self[1], self[0], self[2]]) - } - - /// Constructs a new vector from the fourth, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyxz(self) -> F32x4 { - F32x4([self[3], self[1], self[0], self[2]]) - } - - /// Constructs a new vector from the first, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzxz(self) -> F32x4 { - F32x4([self[0], self[2], self[0], self[2]]) - } - - /// Constructs a new vector from the second, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzxz(self) -> F32x4 { - F32x4([self[1], self[2], self[0], self[2]]) - } - - /// Constructs a new vector from the third, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzxz(self) -> F32x4 { - F32x4([self[2], self[2], self[0], self[2]]) - } - - /// Constructs a new vector from the fourth, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzxz(self) -> F32x4 { - F32x4([self[3], self[2], self[0], self[2]]) - } - - /// Constructs a new vector from the first, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwxz(self) -> F32x4 { - F32x4([self[0], self[3], self[0], self[2]]) - } - - /// Constructs a new vector from the second, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywxz(self) -> F32x4 { - F32x4([self[1], self[3], self[0], self[2]]) - } - - /// Constructs a new vector from the third, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwxz(self) -> F32x4 { - F32x4([self[2], self[3], self[0], self[2]]) - } - - /// Constructs a new vector from the fourth, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwxz(self) -> F32x4 { - F32x4([self[3], self[3], self[0], self[2]]) - } - - /// Constructs a new vector from the first, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxyz(self) -> F32x4 { - F32x4([self[0], self[0], self[1], self[2]]) - } - - /// Constructs a new vector from the second, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxyz(self) -> F32x4 { - F32x4([self[1], self[0], self[1], self[2]]) - } - - /// Constructs a new vector from the third, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxyz(self) -> F32x4 { - F32x4([self[2], self[0], self[1], self[2]]) - } - - /// Constructs a new vector from the fourth, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxyz(self) -> F32x4 { - F32x4([self[3], self[0], self[1], self[2]]) - } - - /// Constructs a new vector from the first, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyyz(self) -> F32x4 { - F32x4([self[0], self[1], self[1], self[2]]) - } - - /// Constructs a new vector from the second, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyyz(self) -> F32x4 { - F32x4([self[1], self[1], self[1], self[2]]) - } - - /// Constructs a new vector from the third, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyyz(self) -> F32x4 { - F32x4([self[2], self[1], self[1], self[2]]) - } - - /// Constructs a new vector from the fourth, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyyz(self) -> F32x4 { - F32x4([self[3], self[1], self[1], self[2]]) - } - - /// Constructs a new vector from the first, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzyz(self) -> F32x4 { - F32x4([self[0], self[2], self[1], self[2]]) - } - - /// Constructs a new vector from the second, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzyz(self) -> F32x4 { - F32x4([self[1], self[2], self[1], self[2]]) - } - - /// Constructs a new vector from the third, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzyz(self) -> F32x4 { - F32x4([self[2], self[2], self[1], self[2]]) - } - - /// Constructs a new vector from the fourth, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzyz(self) -> F32x4 { - F32x4([self[3], self[2], self[1], self[2]]) - } - - /// Constructs a new vector from the first, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwyz(self) -> F32x4 { - F32x4([self[0], self[3], self[1], self[2]]) - } - - /// Constructs a new vector from the second, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywyz(self) -> F32x4 { - F32x4([self[1], self[3], self[1], self[2]]) - } - - /// Constructs a new vector from the third, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwyz(self) -> F32x4 { - F32x4([self[2], self[3], self[1], self[2]]) - } - - /// Constructs a new vector from the fourth, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwyz(self) -> F32x4 { - F32x4([self[3], self[3], self[1], self[2]]) - } - - /// Constructs a new vector from the first, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxzz(self) -> F32x4 { - F32x4([self[0], self[0], self[2], self[2]]) - } - - /// Constructs a new vector from the second, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxzz(self) -> F32x4 { - F32x4([self[1], self[0], self[2], self[2]]) - } - - /// Constructs a new vector from the third, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxzz(self) -> F32x4 { - F32x4([self[2], self[0], self[2], self[2]]) - } - - /// Constructs a new vector from the fourth, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxzz(self) -> F32x4 { - F32x4([self[3], self[0], self[2], self[2]]) - } - - /// Constructs a new vector from the first, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyzz(self) -> F32x4 { - F32x4([self[0], self[1], self[2], self[2]]) - } - - /// Constructs a new vector from the second, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyzz(self) -> F32x4 { - F32x4([self[1], self[1], self[2], self[2]]) - } - - /// Constructs a new vector from the third, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyzz(self) -> F32x4 { - F32x4([self[2], self[1], self[2], self[2]]) - } - - /// Constructs a new vector from the fourth, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyzz(self) -> F32x4 { - F32x4([self[3], self[1], self[2], self[2]]) - } - - /// Constructs a new vector from the first, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzzz(self) -> F32x4 { - F32x4([self[0], self[2], self[2], self[2]]) - } - - /// Constructs a new vector from the second, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzzz(self) -> F32x4 { - F32x4([self[1], self[2], self[2], self[2]]) - } - - /// Constructs a new vector from the third, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzzz(self) -> F32x4 { - F32x4([self[2], self[2], self[2], self[2]]) - } - - /// Constructs a new vector from the fourth, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzzz(self) -> F32x4 { - F32x4([self[3], self[2], self[2], self[2]]) - } - - /// Constructs a new vector from the first, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwzz(self) -> F32x4 { - F32x4([self[0], self[3], self[2], self[2]]) - } - - /// Constructs a new vector from the second, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywzz(self) -> F32x4 { - F32x4([self[1], self[3], self[2], self[2]]) - } - - /// Constructs a new vector from the third, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwzz(self) -> F32x4 { - F32x4([self[2], self[3], self[2], self[2]]) - } - - /// Constructs a new vector from the fourth, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwzz(self) -> F32x4 { - F32x4([self[3], self[3], self[2], self[2]]) - } - - /// Constructs a new vector from the first, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxwz(self) -> F32x4 { - F32x4([self[0], self[0], self[3], self[2]]) - } - - /// Constructs a new vector from the second, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxwz(self) -> F32x4 { - F32x4([self[1], self[0], self[3], self[2]]) - } - - /// Constructs a new vector from the third, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxwz(self) -> F32x4 { - F32x4([self[2], self[0], self[3], self[2]]) - } - - /// Constructs a new vector from the fourth, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxwz(self) -> F32x4 { - F32x4([self[3], self[0], self[3], self[2]]) - } - - /// Constructs a new vector from the first, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xywz(self) -> F32x4 { - F32x4([self[0], self[1], self[3], self[2]]) - } - - /// Constructs a new vector from the second, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yywz(self) -> F32x4 { - F32x4([self[1], self[1], self[3], self[2]]) - } - - /// Constructs a new vector from the third, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zywz(self) -> F32x4 { - F32x4([self[2], self[1], self[3], self[2]]) - } - - /// Constructs a new vector from the fourth, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wywz(self) -> F32x4 { - F32x4([self[3], self[1], self[3], self[2]]) - } - - /// Constructs a new vector from the first, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzwz(self) -> F32x4 { - F32x4([self[0], self[2], self[3], self[2]]) - } - - /// Constructs a new vector from the second, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzwz(self) -> F32x4 { - F32x4([self[1], self[2], self[3], self[2]]) - } - - /// Constructs a new vector from the third, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzwz(self) -> F32x4 { - F32x4([self[2], self[2], self[3], self[2]]) - } - - /// Constructs a new vector from the fourth, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzwz(self) -> F32x4 { - F32x4([self[3], self[2], self[3], self[2]]) - } - - /// Constructs a new vector from the first, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwwz(self) -> F32x4 { - F32x4([self[0], self[3], self[3], self[2]]) - } - - /// Constructs a new vector from the second, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywwz(self) -> F32x4 { - F32x4([self[1], self[3], self[3], self[2]]) - } - - /// Constructs a new vector from the third, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwwz(self) -> F32x4 { - F32x4([self[2], self[3], self[3], self[2]]) - } - - /// Constructs a new vector from the fourth, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwwz(self) -> F32x4 { - F32x4([self[3], self[3], self[3], self[2]]) - } - - /// Constructs a new vector from the first, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxxw(self) -> F32x4 { - F32x4([self[0], self[0], self[0], self[3]]) - } - - /// Constructs a new vector from the second, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxxw(self) -> F32x4 { - F32x4([self[1], self[0], self[0], self[3]]) - } - - /// Constructs a new vector from the third, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxxw(self) -> F32x4 { - F32x4([self[2], self[0], self[0], self[3]]) - } - - /// Constructs a new vector from the fourth, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxxw(self) -> F32x4 { - F32x4([self[3], self[0], self[0], self[3]]) - } - - /// Constructs a new vector from the first, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyxw(self) -> F32x4 { - F32x4([self[0], self[1], self[0], self[3]]) - } - - /// Constructs a new vector from the second, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyxw(self) -> F32x4 { - F32x4([self[1], self[1], self[0], self[3]]) - } - - /// Constructs a new vector from the third, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyxw(self) -> F32x4 { - F32x4([self[2], self[1], self[0], self[3]]) - } - - /// Constructs a new vector from the fourth, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyxw(self) -> F32x4 { - F32x4([self[3], self[1], self[0], self[3]]) - } - - /// Constructs a new vector from the first, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzxw(self) -> F32x4 { - F32x4([self[0], self[2], self[0], self[3]]) - } - - /// Constructs a new vector from the second, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzxw(self) -> F32x4 { - F32x4([self[1], self[2], self[0], self[3]]) - } - - /// Constructs a new vector from the third, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzxw(self) -> F32x4 { - F32x4([self[2], self[2], self[0], self[3]]) - } - - /// Constructs a new vector from the fourth, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzxw(self) -> F32x4 { - F32x4([self[3], self[2], self[0], self[3]]) - } - - /// Constructs a new vector from the first, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwxw(self) -> F32x4 { - F32x4([self[0], self[3], self[0], self[3]]) - } - - /// Constructs a new vector from the second, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywxw(self) -> F32x4 { - F32x4([self[1], self[3], self[0], self[3]]) - } - - /// Constructs a new vector from the third, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwxw(self) -> F32x4 { - F32x4([self[2], self[3], self[0], self[3]]) - } - - /// Constructs a new vector from the fourth, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwxw(self) -> F32x4 { - F32x4([self[3], self[3], self[0], self[3]]) - } - - /// Constructs a new vector from the first, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxyw(self) -> F32x4 { - F32x4([self[0], self[0], self[1], self[3]]) - } - - /// Constructs a new vector from the second, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxyw(self) -> F32x4 { - F32x4([self[1], self[0], self[1], self[3]]) - } - - /// Constructs a new vector from the third, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxyw(self) -> F32x4 { - F32x4([self[2], self[0], self[1], self[3]]) - } - - /// Constructs a new vector from the fourth, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxyw(self) -> F32x4 { - F32x4([self[3], self[0], self[1], self[3]]) - } - - /// Constructs a new vector from the first, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyyw(self) -> F32x4 { - F32x4([self[0], self[1], self[1], self[3]]) - } - - /// Constructs a new vector from the second, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyyw(self) -> F32x4 { - F32x4([self[1], self[1], self[1], self[3]]) - } - - /// Constructs a new vector from the third, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyyw(self) -> F32x4 { - F32x4([self[2], self[1], self[1], self[3]]) - } - - /// Constructs a new vector from the fourth, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyyw(self) -> F32x4 { - F32x4([self[3], self[1], self[1], self[3]]) - } - - /// Constructs a new vector from the first, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzyw(self) -> F32x4 { - F32x4([self[0], self[2], self[1], self[3]]) - } - - /// Constructs a new vector from the second, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzyw(self) -> F32x4 { - F32x4([self[1], self[2], self[1], self[3]]) - } - - /// Constructs a new vector from the third, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzyw(self) -> F32x4 { - F32x4([self[2], self[2], self[1], self[3]]) - } - - /// Constructs a new vector from the fourth, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzyw(self) -> F32x4 { - F32x4([self[3], self[2], self[1], self[3]]) - } - - /// Constructs a new vector from the first, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwyw(self) -> F32x4 { - F32x4([self[0], self[3], self[1], self[3]]) - } - - /// Constructs a new vector from the second, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywyw(self) -> F32x4 { - F32x4([self[1], self[3], self[1], self[3]]) - } - - /// Constructs a new vector from the third, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwyw(self) -> F32x4 { - F32x4([self[2], self[3], self[1], self[3]]) - } - - /// Constructs a new vector from the fourth, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwyw(self) -> F32x4 { - F32x4([self[3], self[3], self[1], self[3]]) - } - - /// Constructs a new vector from the first, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxzw(self) -> F32x4 { - F32x4([self[0], self[0], self[2], self[3]]) - } - - /// Constructs a new vector from the second, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxzw(self) -> F32x4 { - F32x4([self[1], self[0], self[2], self[3]]) - } - - /// Constructs a new vector from the third, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxzw(self) -> F32x4 { - F32x4([self[2], self[0], self[2], self[3]]) - } - - /// Constructs a new vector from the fourth, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxzw(self) -> F32x4 { - F32x4([self[3], self[0], self[2], self[3]]) - } - - /// Constructs a new vector from the first, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyzw(self) -> F32x4 { - F32x4([self[0], self[1], self[2], self[3]]) - } - - /// Constructs a new vector from the second, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyzw(self) -> F32x4 { - F32x4([self[1], self[1], self[2], self[3]]) - } - - /// Constructs a new vector from the third, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyzw(self) -> F32x4 { - F32x4([self[2], self[1], self[2], self[3]]) - } - - /// Constructs a new vector from the fourth, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyzw(self) -> F32x4 { - F32x4([self[3], self[1], self[2], self[3]]) - } - - /// Constructs a new vector from the first, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzzw(self) -> F32x4 { - F32x4([self[0], self[2], self[2], self[3]]) - } - - /// Constructs a new vector from the second, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzzw(self) -> F32x4 { - F32x4([self[1], self[2], self[2], self[3]]) - } - - /// Constructs a new vector from the third, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzzw(self) -> F32x4 { - F32x4([self[2], self[2], self[2], self[3]]) - } - - /// Constructs a new vector from the fourth, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzzw(self) -> F32x4 { - F32x4([self[3], self[2], self[2], self[3]]) - } - - /// Constructs a new vector from the first, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwzw(self) -> F32x4 { - F32x4([self[0], self[3], self[2], self[3]]) - } - - /// Constructs a new vector from the second, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywzw(self) -> F32x4 { - F32x4([self[1], self[3], self[2], self[3]]) - } - - /// Constructs a new vector from the third, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwzw(self) -> F32x4 { - F32x4([self[2], self[3], self[2], self[3]]) - } - - /// Constructs a new vector from the fourth, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwzw(self) -> F32x4 { - F32x4([self[3], self[3], self[2], self[3]]) - } - - /// Constructs a new vector from the first, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxww(self) -> F32x4 { - F32x4([self[0], self[0], self[3], self[3]]) - } - - /// Constructs a new vector from the second, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxww(self) -> F32x4 { - F32x4([self[1], self[0], self[3], self[3]]) - } - - /// Constructs a new vector from the third, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxww(self) -> F32x4 { - F32x4([self[2], self[0], self[3], self[3]]) - } - - /// Constructs a new vector from the fourth, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxww(self) -> F32x4 { - F32x4([self[3], self[0], self[3], self[3]]) - } - - /// Constructs a new vector from the first, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyww(self) -> F32x4 { - F32x4([self[0], self[1], self[3], self[3]]) - } - - /// Constructs a new vector from the second, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyww(self) -> F32x4 { - F32x4([self[1], self[1], self[3], self[3]]) - } - - /// Constructs a new vector from the third, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyww(self) -> F32x4 { - F32x4([self[2], self[1], self[3], self[3]]) - } - - /// Constructs a new vector from the fourth, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyww(self) -> F32x4 { - F32x4([self[3], self[1], self[3], self[3]]) - } - - /// Constructs a new vector from the first, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzww(self) -> F32x4 { - F32x4([self[0], self[2], self[3], self[3]]) - } - - /// Constructs a new vector from the second, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzww(self) -> F32x4 { - F32x4([self[1], self[2], self[3], self[3]]) - } - - /// Constructs a new vector from the third, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzww(self) -> F32x4 { - F32x4([self[2], self[2], self[3], self[3]]) - } - - /// Constructs a new vector from the fourth, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzww(self) -> F32x4 { - F32x4([self[3], self[2], self[3], self[3]]) - } - - /// Constructs a new vector from the first, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwww(self) -> F32x4 { - F32x4([self[0], self[3], self[3], self[3]]) - } - - /// Constructs a new vector from the second, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywww(self) -> F32x4 { - F32x4([self[1], self[3], self[3], self[3]]) - } - - /// Constructs a new vector from the third, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwww(self) -> F32x4 { - F32x4([self[2], self[3], self[3], self[3]]) - } - - /// Constructs a new vector from the fourth, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwww(self) -> F32x4 { - F32x4([self[3], self[3], self[3], self[3]]) - } -} diff --git a/crates/pathfinder/simd/src/scalar/swizzle_i32x4.rs b/crates/pathfinder/simd/src/scalar/swizzle_i32x4.rs deleted file mode 100644 index f46f7c5ebd..0000000000 --- a/crates/pathfinder/simd/src/scalar/swizzle_i32x4.rs +++ /dev/null @@ -1,1805 +0,0 @@ -// pathfinder/simd/src/scalar/swizzle_i32x4.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::scalar::I32x4; - -impl I32x4 { - /// Constructs a new vector from the first, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxxx(self) -> I32x4 { - I32x4([self[0], self[0], self[0], self[0]]) - } - - /// Constructs a new vector from the second, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxxx(self) -> I32x4 { - I32x4([self[1], self[0], self[0], self[0]]) - } - - /// Constructs a new vector from the third, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxxx(self) -> I32x4 { - I32x4([self[2], self[0], self[0], self[0]]) - } - - /// Constructs a new vector from the fourth, first, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxxx(self) -> I32x4 { - I32x4([self[3], self[0], self[0], self[0]]) - } - - /// Constructs a new vector from the first, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyxx(self) -> I32x4 { - I32x4([self[0], self[1], self[0], self[0]]) - } - - /// Constructs a new vector from the second, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyxx(self) -> I32x4 { - I32x4([self[1], self[1], self[0], self[0]]) - } - - /// Constructs a new vector from the third, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyxx(self) -> I32x4 { - I32x4([self[2], self[1], self[0], self[0]]) - } - - /// Constructs a new vector from the fourth, second, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyxx(self) -> I32x4 { - I32x4([self[3], self[1], self[0], self[0]]) - } - - /// Constructs a new vector from the first, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzxx(self) -> I32x4 { - I32x4([self[0], self[2], self[0], self[0]]) - } - - /// Constructs a new vector from the second, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzxx(self) -> I32x4 { - I32x4([self[1], self[2], self[0], self[0]]) - } - - /// Constructs a new vector from the third, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzxx(self) -> I32x4 { - I32x4([self[2], self[2], self[0], self[0]]) - } - - /// Constructs a new vector from the fourth, third, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzxx(self) -> I32x4 { - I32x4([self[3], self[2], self[0], self[0]]) - } - - /// Constructs a new vector from the first, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwxx(self) -> I32x4 { - I32x4([self[0], self[3], self[0], self[0]]) - } - - /// Constructs a new vector from the second, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywxx(self) -> I32x4 { - I32x4([self[1], self[3], self[0], self[0]]) - } - - /// Constructs a new vector from the third, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwxx(self) -> I32x4 { - I32x4([self[2], self[3], self[0], self[0]]) - } - - /// Constructs a new vector from the fourth, fourth, first, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwxx(self) -> I32x4 { - I32x4([self[3], self[3], self[0], self[0]]) - } - - /// Constructs a new vector from the first, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxyx(self) -> I32x4 { - I32x4([self[0], self[0], self[1], self[0]]) - } - - /// Constructs a new vector from the second, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxyx(self) -> I32x4 { - I32x4([self[1], self[0], self[1], self[0]]) - } - - /// Constructs a new vector from the third, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxyx(self) -> I32x4 { - I32x4([self[2], self[0], self[1], self[0]]) - } - - /// Constructs a new vector from the fourth, first, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxyx(self) -> I32x4 { - I32x4([self[3], self[0], self[1], self[0]]) - } - - /// Constructs a new vector from the first, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyyx(self) -> I32x4 { - I32x4([self[0], self[1], self[1], self[0]]) - } - - /// Constructs a new vector from the second, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyyx(self) -> I32x4 { - I32x4([self[1], self[1], self[1], self[0]]) - } - - /// Constructs a new vector from the third, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyyx(self) -> I32x4 { - I32x4([self[2], self[1], self[1], self[0]]) - } - - /// Constructs a new vector from the fourth, second, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyyx(self) -> I32x4 { - I32x4([self[3], self[1], self[1], self[0]]) - } - - /// Constructs a new vector from the first, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzyx(self) -> I32x4 { - I32x4([self[0], self[2], self[1], self[0]]) - } - - /// Constructs a new vector from the second, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzyx(self) -> I32x4 { - I32x4([self[1], self[2], self[1], self[0]]) - } - - /// Constructs a new vector from the third, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzyx(self) -> I32x4 { - I32x4([self[2], self[2], self[1], self[0]]) - } - - /// Constructs a new vector from the fourth, third, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzyx(self) -> I32x4 { - I32x4([self[3], self[2], self[1], self[0]]) - } - - /// Constructs a new vector from the first, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwyx(self) -> I32x4 { - I32x4([self[0], self[3], self[1], self[0]]) - } - - /// Constructs a new vector from the second, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywyx(self) -> I32x4 { - I32x4([self[1], self[3], self[1], self[0]]) - } - - /// Constructs a new vector from the third, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwyx(self) -> I32x4 { - I32x4([self[2], self[3], self[1], self[0]]) - } - - /// Constructs a new vector from the fourth, fourth, second, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwyx(self) -> I32x4 { - I32x4([self[3], self[3], self[1], self[0]]) - } - - /// Constructs a new vector from the first, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxzx(self) -> I32x4 { - I32x4([self[0], self[0], self[2], self[0]]) - } - - /// Constructs a new vector from the second, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxzx(self) -> I32x4 { - I32x4([self[1], self[0], self[2], self[0]]) - } - - /// Constructs a new vector from the third, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxzx(self) -> I32x4 { - I32x4([self[2], self[0], self[2], self[0]]) - } - - /// Constructs a new vector from the fourth, first, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxzx(self) -> I32x4 { - I32x4([self[3], self[0], self[2], self[0]]) - } - - /// Constructs a new vector from the first, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xyzx(self) -> I32x4 { - I32x4([self[0], self[1], self[2], self[0]]) - } - - /// Constructs a new vector from the second, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yyzx(self) -> I32x4 { - I32x4([self[1], self[1], self[2], self[0]]) - } - - /// Constructs a new vector from the third, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zyzx(self) -> I32x4 { - I32x4([self[2], self[1], self[2], self[0]]) - } - - /// Constructs a new vector from the fourth, second, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wyzx(self) -> I32x4 { - I32x4([self[3], self[1], self[2], self[0]]) - } - - /// Constructs a new vector from the first, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzzx(self) -> I32x4 { - I32x4([self[0], self[2], self[2], self[0]]) - } - - /// Constructs a new vector from the second, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzzx(self) -> I32x4 { - I32x4([self[1], self[2], self[2], self[0]]) - } - - /// Constructs a new vector from the third, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzzx(self) -> I32x4 { - I32x4([self[2], self[2], self[2], self[0]]) - } - - /// Constructs a new vector from the fourth, third, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzzx(self) -> I32x4 { - I32x4([self[3], self[2], self[2], self[0]]) - } - - /// Constructs a new vector from the first, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwzx(self) -> I32x4 { - I32x4([self[0], self[3], self[2], self[0]]) - } - - /// Constructs a new vector from the second, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywzx(self) -> I32x4 { - I32x4([self[1], self[3], self[2], self[0]]) - } - - /// Constructs a new vector from the third, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwzx(self) -> I32x4 { - I32x4([self[2], self[3], self[2], self[0]]) - } - - /// Constructs a new vector from the fourth, fourth, third, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwzx(self) -> I32x4 { - I32x4([self[3], self[3], self[2], self[0]]) - } - - /// Constructs a new vector from the first, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xxwx(self) -> I32x4 { - I32x4([self[0], self[0], self[3], self[0]]) - } - - /// Constructs a new vector from the second, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yxwx(self) -> I32x4 { - I32x4([self[1], self[0], self[3], self[0]]) - } - - /// Constructs a new vector from the third, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zxwx(self) -> I32x4 { - I32x4([self[2], self[0], self[3], self[0]]) - } - - /// Constructs a new vector from the fourth, first, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wxwx(self) -> I32x4 { - I32x4([self[3], self[0], self[3], self[0]]) - } - - /// Constructs a new vector from the first, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xywx(self) -> I32x4 { - I32x4([self[0], self[1], self[3], self[0]]) - } - - /// Constructs a new vector from the second, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yywx(self) -> I32x4 { - I32x4([self[1], self[1], self[3], self[0]]) - } - - /// Constructs a new vector from the third, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zywx(self) -> I32x4 { - I32x4([self[2], self[1], self[3], self[0]]) - } - - /// Constructs a new vector from the fourth, second, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wywx(self) -> I32x4 { - I32x4([self[3], self[1], self[3], self[0]]) - } - - /// Constructs a new vector from the first, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xzwx(self) -> I32x4 { - I32x4([self[0], self[2], self[3], self[0]]) - } - - /// Constructs a new vector from the second, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn yzwx(self) -> I32x4 { - I32x4([self[1], self[2], self[3], self[0]]) - } - - /// Constructs a new vector from the third, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zzwx(self) -> I32x4 { - I32x4([self[2], self[2], self[3], self[0]]) - } - - /// Constructs a new vector from the fourth, third, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wzwx(self) -> I32x4 { - I32x4([self[3], self[2], self[3], self[0]]) - } - - /// Constructs a new vector from the first, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn xwwx(self) -> I32x4 { - I32x4([self[0], self[3], self[3], self[0]]) - } - - /// Constructs a new vector from the second, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn ywwx(self) -> I32x4 { - I32x4([self[1], self[3], self[3], self[0]]) - } - - /// Constructs a new vector from the third, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn zwwx(self) -> I32x4 { - I32x4([self[2], self[3], self[3], self[0]]) - } - - /// Constructs a new vector from the fourth, fourth, fourth, and first - /// lanes in this vector, respectively. - #[inline] - pub fn wwwx(self) -> I32x4 { - I32x4([self[3], self[3], self[3], self[0]]) - } - - /// Constructs a new vector from the first, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxxy(self) -> I32x4 { - I32x4([self[0], self[0], self[0], self[1]]) - } - - /// Constructs a new vector from the second, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxxy(self) -> I32x4 { - I32x4([self[1], self[0], self[0], self[1]]) - } - - /// Constructs a new vector from the third, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxxy(self) -> I32x4 { - I32x4([self[2], self[0], self[0], self[1]]) - } - - /// Constructs a new vector from the fourth, first, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxxy(self) -> I32x4 { - I32x4([self[3], self[0], self[0], self[1]]) - } - - /// Constructs a new vector from the first, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyxy(self) -> I32x4 { - I32x4([self[0], self[1], self[0], self[1]]) - } - - /// Constructs a new vector from the second, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyxy(self) -> I32x4 { - I32x4([self[1], self[1], self[0], self[1]]) - } - - /// Constructs a new vector from the third, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyxy(self) -> I32x4 { - I32x4([self[2], self[1], self[0], self[1]]) - } - - /// Constructs a new vector from the fourth, second, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyxy(self) -> I32x4 { - I32x4([self[3], self[1], self[0], self[1]]) - } - - /// Constructs a new vector from the first, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzxy(self) -> I32x4 { - I32x4([self[0], self[2], self[0], self[1]]) - } - - /// Constructs a new vector from the second, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzxy(self) -> I32x4 { - I32x4([self[1], self[2], self[0], self[1]]) - } - - /// Constructs a new vector from the third, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzxy(self) -> I32x4 { - I32x4([self[2], self[2], self[0], self[1]]) - } - - /// Constructs a new vector from the fourth, third, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzxy(self) -> I32x4 { - I32x4([self[3], self[2], self[0], self[1]]) - } - - /// Constructs a new vector from the first, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwxy(self) -> I32x4 { - I32x4([self[0], self[3], self[0], self[1]]) - } - - /// Constructs a new vector from the second, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywxy(self) -> I32x4 { - I32x4([self[1], self[3], self[0], self[1]]) - } - - /// Constructs a new vector from the third, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwxy(self) -> I32x4 { - I32x4([self[2], self[3], self[0], self[1]]) - } - - /// Constructs a new vector from the fourth, fourth, first, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwxy(self) -> I32x4 { - I32x4([self[3], self[3], self[0], self[1]]) - } - - /// Constructs a new vector from the first, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxyy(self) -> I32x4 { - I32x4([self[0], self[0], self[1], self[1]]) - } - - /// Constructs a new vector from the second, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxyy(self) -> I32x4 { - I32x4([self[1], self[0], self[1], self[1]]) - } - - /// Constructs a new vector from the third, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxyy(self) -> I32x4 { - I32x4([self[2], self[0], self[1], self[1]]) - } - - /// Constructs a new vector from the fourth, first, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxyy(self) -> I32x4 { - I32x4([self[3], self[0], self[1], self[1]]) - } - - /// Constructs a new vector from the first, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyyy(self) -> I32x4 { - I32x4([self[0], self[1], self[1], self[1]]) - } - - /// Constructs a new vector from the second, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyyy(self) -> I32x4 { - I32x4([self[1], self[1], self[1], self[1]]) - } - - /// Constructs a new vector from the third, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyyy(self) -> I32x4 { - I32x4([self[2], self[1], self[1], self[1]]) - } - - /// Constructs a new vector from the fourth, second, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyyy(self) -> I32x4 { - I32x4([self[3], self[1], self[1], self[1]]) - } - - /// Constructs a new vector from the first, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzyy(self) -> I32x4 { - I32x4([self[0], self[2], self[1], self[1]]) - } - - /// Constructs a new vector from the second, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzyy(self) -> I32x4 { - I32x4([self[1], self[2], self[1], self[1]]) - } - - /// Constructs a new vector from the third, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzyy(self) -> I32x4 { - I32x4([self[2], self[2], self[1], self[1]]) - } - - /// Constructs a new vector from the fourth, third, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzyy(self) -> I32x4 { - I32x4([self[3], self[2], self[1], self[1]]) - } - - /// Constructs a new vector from the first, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwyy(self) -> I32x4 { - I32x4([self[0], self[3], self[1], self[1]]) - } - - /// Constructs a new vector from the second, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywyy(self) -> I32x4 { - I32x4([self[1], self[3], self[1], self[1]]) - } - - /// Constructs a new vector from the third, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwyy(self) -> I32x4 { - I32x4([self[2], self[3], self[1], self[1]]) - } - - /// Constructs a new vector from the fourth, fourth, second, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwyy(self) -> I32x4 { - I32x4([self[3], self[3], self[1], self[1]]) - } - - /// Constructs a new vector from the first, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxzy(self) -> I32x4 { - I32x4([self[0], self[0], self[2], self[1]]) - } - - /// Constructs a new vector from the second, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxzy(self) -> I32x4 { - I32x4([self[1], self[0], self[2], self[1]]) - } - - /// Constructs a new vector from the third, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxzy(self) -> I32x4 { - I32x4([self[2], self[0], self[2], self[1]]) - } - - /// Constructs a new vector from the fourth, first, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxzy(self) -> I32x4 { - I32x4([self[3], self[0], self[2], self[1]]) - } - - /// Constructs a new vector from the first, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xyzy(self) -> I32x4 { - I32x4([self[0], self[1], self[2], self[1]]) - } - - /// Constructs a new vector from the second, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yyzy(self) -> I32x4 { - I32x4([self[1], self[1], self[2], self[1]]) - } - - /// Constructs a new vector from the third, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zyzy(self) -> I32x4 { - I32x4([self[2], self[1], self[2], self[1]]) - } - - /// Constructs a new vector from the fourth, second, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wyzy(self) -> I32x4 { - I32x4([self[3], self[1], self[2], self[1]]) - } - - /// Constructs a new vector from the first, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzzy(self) -> I32x4 { - I32x4([self[0], self[2], self[2], self[1]]) - } - - /// Constructs a new vector from the second, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzzy(self) -> I32x4 { - I32x4([self[1], self[2], self[2], self[1]]) - } - - /// Constructs a new vector from the third, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzzy(self) -> I32x4 { - I32x4([self[2], self[2], self[2], self[1]]) - } - - /// Constructs a new vector from the fourth, third, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzzy(self) -> I32x4 { - I32x4([self[3], self[2], self[2], self[1]]) - } - - /// Constructs a new vector from the first, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwzy(self) -> I32x4 { - I32x4([self[0], self[3], self[2], self[1]]) - } - - /// Constructs a new vector from the second, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywzy(self) -> I32x4 { - I32x4([self[1], self[3], self[2], self[1]]) - } - - /// Constructs a new vector from the third, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwzy(self) -> I32x4 { - I32x4([self[2], self[3], self[2], self[1]]) - } - - /// Constructs a new vector from the fourth, fourth, third, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwzy(self) -> I32x4 { - I32x4([self[3], self[3], self[2], self[1]]) - } - - /// Constructs a new vector from the first, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xxwy(self) -> I32x4 { - I32x4([self[0], self[0], self[3], self[1]]) - } - - /// Constructs a new vector from the second, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yxwy(self) -> I32x4 { - I32x4([self[1], self[0], self[3], self[1]]) - } - - /// Constructs a new vector from the third, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zxwy(self) -> I32x4 { - I32x4([self[2], self[0], self[3], self[1]]) - } - - /// Constructs a new vector from the fourth, first, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wxwy(self) -> I32x4 { - I32x4([self[3], self[0], self[3], self[1]]) - } - - /// Constructs a new vector from the first, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xywy(self) -> I32x4 { - I32x4([self[0], self[1], self[3], self[1]]) - } - - /// Constructs a new vector from the second, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yywy(self) -> I32x4 { - I32x4([self[1], self[1], self[3], self[1]]) - } - - /// Constructs a new vector from the third, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zywy(self) -> I32x4 { - I32x4([self[2], self[1], self[3], self[1]]) - } - - /// Constructs a new vector from the fourth, second, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wywy(self) -> I32x4 { - I32x4([self[3], self[1], self[3], self[1]]) - } - - /// Constructs a new vector from the first, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xzwy(self) -> I32x4 { - I32x4([self[0], self[2], self[3], self[1]]) - } - - /// Constructs a new vector from the second, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn yzwy(self) -> I32x4 { - I32x4([self[1], self[2], self[3], self[1]]) - } - - /// Constructs a new vector from the third, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zzwy(self) -> I32x4 { - I32x4([self[2], self[2], self[3], self[1]]) - } - - /// Constructs a new vector from the fourth, third, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wzwy(self) -> I32x4 { - I32x4([self[3], self[2], self[3], self[1]]) - } - - /// Constructs a new vector from the first, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn xwwy(self) -> I32x4 { - I32x4([self[0], self[3], self[3], self[1]]) - } - - /// Constructs a new vector from the second, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn ywwy(self) -> I32x4 { - I32x4([self[1], self[3], self[3], self[1]]) - } - - /// Constructs a new vector from the third, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn zwwy(self) -> I32x4 { - I32x4([self[2], self[3], self[3], self[1]]) - } - - /// Constructs a new vector from the fourth, fourth, fourth, and second - /// lanes in this vector, respectively. - #[inline] - pub fn wwwy(self) -> I32x4 { - I32x4([self[3], self[3], self[3], self[1]]) - } - - /// Constructs a new vector from the first, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxxz(self) -> I32x4 { - I32x4([self[0], self[0], self[0], self[2]]) - } - - /// Constructs a new vector from the second, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxxz(self) -> I32x4 { - I32x4([self[1], self[0], self[0], self[2]]) - } - - /// Constructs a new vector from the third, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxxz(self) -> I32x4 { - I32x4([self[2], self[0], self[0], self[2]]) - } - - /// Constructs a new vector from the fourth, first, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxxz(self) -> I32x4 { - I32x4([self[3], self[0], self[0], self[2]]) - } - - /// Constructs a new vector from the first, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyxz(self) -> I32x4 { - I32x4([self[0], self[1], self[0], self[2]]) - } - - /// Constructs a new vector from the second, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyxz(self) -> I32x4 { - I32x4([self[1], self[1], self[0], self[2]]) - } - - /// Constructs a new vector from the third, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyxz(self) -> I32x4 { - I32x4([self[2], self[1], self[0], self[2]]) - } - - /// Constructs a new vector from the fourth, second, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyxz(self) -> I32x4 { - I32x4([self[3], self[1], self[0], self[2]]) - } - - /// Constructs a new vector from the first, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzxz(self) -> I32x4 { - I32x4([self[0], self[2], self[0], self[2]]) - } - - /// Constructs a new vector from the second, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzxz(self) -> I32x4 { - I32x4([self[1], self[2], self[0], self[2]]) - } - - /// Constructs a new vector from the third, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzxz(self) -> I32x4 { - I32x4([self[2], self[2], self[0], self[2]]) - } - - /// Constructs a new vector from the fourth, third, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzxz(self) -> I32x4 { - I32x4([self[3], self[2], self[0], self[2]]) - } - - /// Constructs a new vector from the first, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwxz(self) -> I32x4 { - I32x4([self[0], self[3], self[0], self[2]]) - } - - /// Constructs a new vector from the second, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywxz(self) -> I32x4 { - I32x4([self[1], self[3], self[0], self[2]]) - } - - /// Constructs a new vector from the third, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwxz(self) -> I32x4 { - I32x4([self[2], self[3], self[0], self[2]]) - } - - /// Constructs a new vector from the fourth, fourth, first, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwxz(self) -> I32x4 { - I32x4([self[3], self[3], self[0], self[2]]) - } - - /// Constructs a new vector from the first, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxyz(self) -> I32x4 { - I32x4([self[0], self[0], self[1], self[2]]) - } - - /// Constructs a new vector from the second, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxyz(self) -> I32x4 { - I32x4([self[1], self[0], self[1], self[2]]) - } - - /// Constructs a new vector from the third, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxyz(self) -> I32x4 { - I32x4([self[2], self[0], self[1], self[2]]) - } - - /// Constructs a new vector from the fourth, first, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxyz(self) -> I32x4 { - I32x4([self[3], self[0], self[1], self[2]]) - } - - /// Constructs a new vector from the first, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyyz(self) -> I32x4 { - I32x4([self[0], self[1], self[1], self[2]]) - } - - /// Constructs a new vector from the second, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyyz(self) -> I32x4 { - I32x4([self[1], self[1], self[1], self[2]]) - } - - /// Constructs a new vector from the third, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyyz(self) -> I32x4 { - I32x4([self[2], self[1], self[1], self[2]]) - } - - /// Constructs a new vector from the fourth, second, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyyz(self) -> I32x4 { - I32x4([self[3], self[1], self[1], self[2]]) - } - - /// Constructs a new vector from the first, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzyz(self) -> I32x4 { - I32x4([self[0], self[2], self[1], self[2]]) - } - - /// Constructs a new vector from the second, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzyz(self) -> I32x4 { - I32x4([self[1], self[2], self[1], self[2]]) - } - - /// Constructs a new vector from the third, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzyz(self) -> I32x4 { - I32x4([self[2], self[2], self[1], self[2]]) - } - - /// Constructs a new vector from the fourth, third, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzyz(self) -> I32x4 { - I32x4([self[3], self[2], self[1], self[2]]) - } - - /// Constructs a new vector from the first, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwyz(self) -> I32x4 { - I32x4([self[0], self[3], self[1], self[2]]) - } - - /// Constructs a new vector from the second, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywyz(self) -> I32x4 { - I32x4([self[1], self[3], self[1], self[2]]) - } - - /// Constructs a new vector from the third, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwyz(self) -> I32x4 { - I32x4([self[2], self[3], self[1], self[2]]) - } - - /// Constructs a new vector from the fourth, fourth, second, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwyz(self) -> I32x4 { - I32x4([self[3], self[3], self[1], self[2]]) - } - - /// Constructs a new vector from the first, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxzz(self) -> I32x4 { - I32x4([self[0], self[0], self[2], self[2]]) - } - - /// Constructs a new vector from the second, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxzz(self) -> I32x4 { - I32x4([self[1], self[0], self[2], self[2]]) - } - - /// Constructs a new vector from the third, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxzz(self) -> I32x4 { - I32x4([self[2], self[0], self[2], self[2]]) - } - - /// Constructs a new vector from the fourth, first, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxzz(self) -> I32x4 { - I32x4([self[3], self[0], self[2], self[2]]) - } - - /// Constructs a new vector from the first, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xyzz(self) -> I32x4 { - I32x4([self[0], self[1], self[2], self[2]]) - } - - /// Constructs a new vector from the second, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yyzz(self) -> I32x4 { - I32x4([self[1], self[1], self[2], self[2]]) - } - - /// Constructs a new vector from the third, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zyzz(self) -> I32x4 { - I32x4([self[2], self[1], self[2], self[2]]) - } - - /// Constructs a new vector from the fourth, second, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wyzz(self) -> I32x4 { - I32x4([self[3], self[1], self[2], self[2]]) - } - - /// Constructs a new vector from the first, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzzz(self) -> I32x4 { - I32x4([self[0], self[2], self[2], self[2]]) - } - - /// Constructs a new vector from the second, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzzz(self) -> I32x4 { - I32x4([self[1], self[2], self[2], self[2]]) - } - - /// Constructs a new vector from the third, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzzz(self) -> I32x4 { - I32x4([self[2], self[2], self[2], self[2]]) - } - - /// Constructs a new vector from the fourth, third, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzzz(self) -> I32x4 { - I32x4([self[3], self[2], self[2], self[2]]) - } - - /// Constructs a new vector from the first, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwzz(self) -> I32x4 { - I32x4([self[0], self[3], self[2], self[2]]) - } - - /// Constructs a new vector from the second, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywzz(self) -> I32x4 { - I32x4([self[1], self[3], self[2], self[2]]) - } - - /// Constructs a new vector from the third, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwzz(self) -> I32x4 { - I32x4([self[2], self[3], self[2], self[2]]) - } - - /// Constructs a new vector from the fourth, fourth, third, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwzz(self) -> I32x4 { - I32x4([self[3], self[3], self[2], self[2]]) - } - - /// Constructs a new vector from the first, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xxwz(self) -> I32x4 { - I32x4([self[0], self[0], self[3], self[2]]) - } - - /// Constructs a new vector from the second, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yxwz(self) -> I32x4 { - I32x4([self[1], self[0], self[3], self[2]]) - } - - /// Constructs a new vector from the third, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zxwz(self) -> I32x4 { - I32x4([self[2], self[0], self[3], self[2]]) - } - - /// Constructs a new vector from the fourth, first, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wxwz(self) -> I32x4 { - I32x4([self[3], self[0], self[3], self[2]]) - } - - /// Constructs a new vector from the first, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xywz(self) -> I32x4 { - I32x4([self[0], self[1], self[3], self[2]]) - } - - /// Constructs a new vector from the second, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yywz(self) -> I32x4 { - I32x4([self[1], self[1], self[3], self[2]]) - } - - /// Constructs a new vector from the third, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zywz(self) -> I32x4 { - I32x4([self[2], self[1], self[3], self[2]]) - } - - /// Constructs a new vector from the fourth, second, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wywz(self) -> I32x4 { - I32x4([self[3], self[1], self[3], self[2]]) - } - - /// Constructs a new vector from the first, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xzwz(self) -> I32x4 { - I32x4([self[0], self[2], self[3], self[2]]) - } - - /// Constructs a new vector from the second, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn yzwz(self) -> I32x4 { - I32x4([self[1], self[2], self[3], self[2]]) - } - - /// Constructs a new vector from the third, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zzwz(self) -> I32x4 { - I32x4([self[2], self[2], self[3], self[2]]) - } - - /// Constructs a new vector from the fourth, third, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wzwz(self) -> I32x4 { - I32x4([self[3], self[2], self[3], self[2]]) - } - - /// Constructs a new vector from the first, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn xwwz(self) -> I32x4 { - I32x4([self[0], self[3], self[3], self[2]]) - } - - /// Constructs a new vector from the second, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn ywwz(self) -> I32x4 { - I32x4([self[1], self[3], self[3], self[2]]) - } - - /// Constructs a new vector from the third, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn zwwz(self) -> I32x4 { - I32x4([self[2], self[3], self[3], self[2]]) - } - - /// Constructs a new vector from the fourth, fourth, fourth, and third - /// lanes in this vector, respectively. - #[inline] - pub fn wwwz(self) -> I32x4 { - I32x4([self[3], self[3], self[3], self[2]]) - } - - /// Constructs a new vector from the first, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxxw(self) -> I32x4 { - I32x4([self[0], self[0], self[0], self[3]]) - } - - /// Constructs a new vector from the second, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxxw(self) -> I32x4 { - I32x4([self[1], self[0], self[0], self[3]]) - } - - /// Constructs a new vector from the third, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxxw(self) -> I32x4 { - I32x4([self[2], self[0], self[0], self[3]]) - } - - /// Constructs a new vector from the fourth, first, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxxw(self) -> I32x4 { - I32x4([self[3], self[0], self[0], self[3]]) - } - - /// Constructs a new vector from the first, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyxw(self) -> I32x4 { - I32x4([self[0], self[1], self[0], self[3]]) - } - - /// Constructs a new vector from the second, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyxw(self) -> I32x4 { - I32x4([self[1], self[1], self[0], self[3]]) - } - - /// Constructs a new vector from the third, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyxw(self) -> I32x4 { - I32x4([self[2], self[1], self[0], self[3]]) - } - - /// Constructs a new vector from the fourth, second, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyxw(self) -> I32x4 { - I32x4([self[3], self[1], self[0], self[3]]) - } - - /// Constructs a new vector from the first, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzxw(self) -> I32x4 { - I32x4([self[0], self[2], self[0], self[3]]) - } - - /// Constructs a new vector from the second, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzxw(self) -> I32x4 { - I32x4([self[1], self[2], self[0], self[3]]) - } - - /// Constructs a new vector from the third, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzxw(self) -> I32x4 { - I32x4([self[2], self[2], self[0], self[3]]) - } - - /// Constructs a new vector from the fourth, third, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzxw(self) -> I32x4 { - I32x4([self[3], self[2], self[0], self[3]]) - } - - /// Constructs a new vector from the first, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwxw(self) -> I32x4 { - I32x4([self[0], self[3], self[0], self[3]]) - } - - /// Constructs a new vector from the second, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywxw(self) -> I32x4 { - I32x4([self[1], self[3], self[0], self[3]]) - } - - /// Constructs a new vector from the third, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwxw(self) -> I32x4 { - I32x4([self[2], self[3], self[0], self[3]]) - } - - /// Constructs a new vector from the fourth, fourth, first, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwxw(self) -> I32x4 { - I32x4([self[3], self[3], self[0], self[3]]) - } - - /// Constructs a new vector from the first, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxyw(self) -> I32x4 { - I32x4([self[0], self[0], self[1], self[3]]) - } - - /// Constructs a new vector from the second, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxyw(self) -> I32x4 { - I32x4([self[1], self[0], self[1], self[3]]) - } - - /// Constructs a new vector from the third, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxyw(self) -> I32x4 { - I32x4([self[2], self[0], self[1], self[3]]) - } - - /// Constructs a new vector from the fourth, first, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxyw(self) -> I32x4 { - I32x4([self[3], self[0], self[1], self[3]]) - } - - /// Constructs a new vector from the first, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyyw(self) -> I32x4 { - I32x4([self[0], self[1], self[1], self[3]]) - } - - /// Constructs a new vector from the second, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyyw(self) -> I32x4 { - I32x4([self[1], self[1], self[1], self[3]]) - } - - /// Constructs a new vector from the third, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyyw(self) -> I32x4 { - I32x4([self[2], self[1], self[1], self[3]]) - } - - /// Constructs a new vector from the fourth, second, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyyw(self) -> I32x4 { - I32x4([self[3], self[1], self[1], self[3]]) - } - - /// Constructs a new vector from the first, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzyw(self) -> I32x4 { - I32x4([self[0], self[2], self[1], self[3]]) - } - - /// Constructs a new vector from the second, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzyw(self) -> I32x4 { - I32x4([self[1], self[2], self[1], self[3]]) - } - - /// Constructs a new vector from the third, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzyw(self) -> I32x4 { - I32x4([self[2], self[2], self[1], self[3]]) - } - - /// Constructs a new vector from the fourth, third, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzyw(self) -> I32x4 { - I32x4([self[3], self[2], self[1], self[3]]) - } - - /// Constructs a new vector from the first, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwyw(self) -> I32x4 { - I32x4([self[0], self[3], self[1], self[3]]) - } - - /// Constructs a new vector from the second, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywyw(self) -> I32x4 { - I32x4([self[1], self[3], self[1], self[3]]) - } - - /// Constructs a new vector from the third, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwyw(self) -> I32x4 { - I32x4([self[2], self[3], self[1], self[3]]) - } - - /// Constructs a new vector from the fourth, fourth, second, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwyw(self) -> I32x4 { - I32x4([self[3], self[3], self[1], self[3]]) - } - - /// Constructs a new vector from the first, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxzw(self) -> I32x4 { - I32x4([self[0], self[0], self[2], self[3]]) - } - - /// Constructs a new vector from the second, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxzw(self) -> I32x4 { - I32x4([self[1], self[0], self[2], self[3]]) - } - - /// Constructs a new vector from the third, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxzw(self) -> I32x4 { - I32x4([self[2], self[0], self[2], self[3]]) - } - - /// Constructs a new vector from the fourth, first, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxzw(self) -> I32x4 { - I32x4([self[3], self[0], self[2], self[3]]) - } - - /// Constructs a new vector from the first, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyzw(self) -> I32x4 { - I32x4([self[0], self[1], self[2], self[3]]) - } - - /// Constructs a new vector from the second, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyzw(self) -> I32x4 { - I32x4([self[1], self[1], self[2], self[3]]) - } - - /// Constructs a new vector from the third, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyzw(self) -> I32x4 { - I32x4([self[2], self[1], self[2], self[3]]) - } - - /// Constructs a new vector from the fourth, second, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyzw(self) -> I32x4 { - I32x4([self[3], self[1], self[2], self[3]]) - } - - /// Constructs a new vector from the first, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzzw(self) -> I32x4 { - I32x4([self[0], self[2], self[2], self[3]]) - } - - /// Constructs a new vector from the second, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzzw(self) -> I32x4 { - I32x4([self[1], self[2], self[2], self[3]]) - } - - /// Constructs a new vector from the third, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzzw(self) -> I32x4 { - I32x4([self[2], self[2], self[2], self[3]]) - } - - /// Constructs a new vector from the fourth, third, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzzw(self) -> I32x4 { - I32x4([self[3], self[2], self[2], self[3]]) - } - - /// Constructs a new vector from the first, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwzw(self) -> I32x4 { - I32x4([self[0], self[3], self[2], self[3]]) - } - - /// Constructs a new vector from the second, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywzw(self) -> I32x4 { - I32x4([self[1], self[3], self[2], self[3]]) - } - - /// Constructs a new vector from the third, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwzw(self) -> I32x4 { - I32x4([self[2], self[3], self[2], self[3]]) - } - - /// Constructs a new vector from the fourth, fourth, third, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwzw(self) -> I32x4 { - I32x4([self[3], self[3], self[2], self[3]]) - } - - /// Constructs a new vector from the first, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xxww(self) -> I32x4 { - I32x4([self[0], self[0], self[3], self[3]]) - } - - /// Constructs a new vector from the second, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yxww(self) -> I32x4 { - I32x4([self[1], self[0], self[3], self[3]]) - } - - /// Constructs a new vector from the third, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zxww(self) -> I32x4 { - I32x4([self[2], self[0], self[3], self[3]]) - } - - /// Constructs a new vector from the fourth, first, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wxww(self) -> I32x4 { - I32x4([self[3], self[0], self[3], self[3]]) - } - - /// Constructs a new vector from the first, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xyww(self) -> I32x4 { - I32x4([self[0], self[1], self[3], self[3]]) - } - - /// Constructs a new vector from the second, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yyww(self) -> I32x4 { - I32x4([self[1], self[1], self[3], self[3]]) - } - - /// Constructs a new vector from the third, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zyww(self) -> I32x4 { - I32x4([self[2], self[1], self[3], self[3]]) - } - - /// Constructs a new vector from the fourth, second, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wyww(self) -> I32x4 { - I32x4([self[3], self[1], self[3], self[3]]) - } - - /// Constructs a new vector from the first, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xzww(self) -> I32x4 { - I32x4([self[0], self[2], self[3], self[3]]) - } - - /// Constructs a new vector from the second, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn yzww(self) -> I32x4 { - I32x4([self[1], self[2], self[3], self[3]]) - } - - /// Constructs a new vector from the third, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zzww(self) -> I32x4 { - I32x4([self[2], self[2], self[3], self[3]]) - } - - /// Constructs a new vector from the fourth, third, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wzww(self) -> I32x4 { - I32x4([self[3], self[2], self[3], self[3]]) - } - - /// Constructs a new vector from the first, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn xwww(self) -> I32x4 { - I32x4([self[0], self[3], self[3], self[3]]) - } - - /// Constructs a new vector from the second, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn ywww(self) -> I32x4 { - I32x4([self[1], self[3], self[3], self[3]]) - } - - /// Constructs a new vector from the third, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn zwww(self) -> I32x4 { - I32x4([self[2], self[3], self[3], self[3]]) - } - - /// Constructs a new vector from the fourth, fourth, fourth, and fourth - /// lanes in this vector, respectively. - #[inline] - pub fn wwww(self) -> I32x4 { - I32x4([self[3], self[3], self[3], self[3]]) - } -} diff --git a/crates/pathfinder/simd/src/test.rs b/crates/pathfinder/simd/src/test.rs deleted file mode 100644 index 629127ccf2..0000000000 --- a/crates/pathfinder/simd/src/test.rs +++ /dev/null @@ -1,691 +0,0 @@ -// pathfinder/simd/src/test.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::default::{F32x4, I32x4, U32x4}; -use crate::scalar::F32x4 as F32x4S; - -// F32x4 - -#[test] -fn test_f32x4_constructors() { - let a = F32x4::new(1.0, 2.0, 3.0, 4.0); - assert_eq!((a[0], a[1], a[2], a[3]), (1.0, 2.0, 3.0, 4.0)); - let b = F32x4::splat(10.0); - assert_eq!(b, F32x4::new(10.0, 10.0, 10.0, 10.0)); -} - -#[test] -fn test_f32x4_accessors_and_mutators() { - let a = F32x4::new(5.0, 6.0, 7.0, 8.0); - assert_eq!((a.x(), a.y(), a.z(), a.w()), (5.0, 6.0, 7.0, 8.0)); - let mut b = F32x4::new(10.0, 11.0, 12.0, 13.0); - b.set_x(20.0); - b.set_y(30.0); - b.set_z(40.0); - b.set_w(50.0); - assert_eq!(b, F32x4::new(20.0, 30.0, 40.0, 50.0)); -} - -#[test] -fn test_f32x4_basic_ops() { - let a = F32x4::new(1.0, 3.0, 5.0, 7.0); - let b = F32x4::new(2.0, 2.0, 6.0, 6.0); - assert_eq!(a.approx_recip(), F32x4::new(0.99975586, 0.33325195, 0.19995117, 0.14282227)); - assert_eq!(a.min(b), F32x4::new(1.0, 2.0, 5.0, 6.0)); - assert_eq!(a.max(b), F32x4::new(2.0, 3.0, 6.0, 7.0)); - let c = F32x4::new(-1.0, 1.3, -20.0, 3.6); - assert_eq!(c.clamp(a, b), F32x4::new(1.0, 2.0, 5.0, 6.0)); - assert_eq!(c.abs(), F32x4::new(1.0, 1.3, 20.0, 3.6)); - assert_eq!(c.floor(), F32x4::new(-1.0, 1.0, -20.0, 3.0)); - assert_eq!(c.ceil(), F32x4::new(-1.0, 2.0, -20.0, 4.0)); - assert_eq!(c.to_i32x4().to_f32x4(), F32x4::new(-1.0, 1.0, -20.0, 4.0)); - let d = F32x4::new(1.0, 2.0, 3.0, 4.0); - assert_eq!(d.sqrt(), F32x4::new(1.0, 1.4142135, 1.7320508, 2.0)); -} - -#[test] -fn test_f32x4_packed_comparisons() { - let a = F32x4::new(7.0, 3.0, 6.0, -2.0); - let b = F32x4::new(10.0, 3.0, 5.0, -2.0); - assert_eq!(a.packed_eq(b), U32x4::new(0, !0, 0, !0)); - assert_eq!(a.packed_gt(b), U32x4::new(0, 0, !0, 0)); - assert_eq!(a.packed_le(b), U32x4::new(!0, !0, 0, !0)); -} - -#[test] -fn test_f32x4_swizzles() { - let a = F32x4::new(1.0, 2.0, 3.0, 4.0); - assert_eq!(a.xxxx(), F32x4::splat(1.0)); - assert_eq!(a.yyyy(), F32x4::splat(2.0)); - assert_eq!(a.zzzz(), F32x4::splat(3.0)); - assert_eq!(a.wwww(), F32x4::splat(4.0)); - - assert_eq!(a.yxxx(), F32x4::new(2.0, 1.0, 1.0, 1.0)); - assert_eq!(a.zxxx(), F32x4::new(3.0, 1.0, 1.0, 1.0)); - assert_eq!(a.wxxx(), F32x4::new(4.0, 1.0, 1.0, 1.0)); - assert_eq!(a.xyxx(), F32x4::new(1.0, 2.0, 1.0, 1.0)); - assert_eq!(a.yyxx(), F32x4::new(2.0, 2.0, 1.0, 1.0)); - assert_eq!(a.zyxx(), F32x4::new(3.0, 2.0, 1.0, 1.0)); - assert_eq!(a.wyxx(), F32x4::new(4.0, 2.0, 1.0, 1.0)); - assert_eq!(a.xzxx(), F32x4::new(1.0, 3.0, 1.0, 1.0)); - assert_eq!(a.yzxx(), F32x4::new(2.0, 3.0, 1.0, 1.0)); - assert_eq!(a.zzxx(), F32x4::new(3.0, 3.0, 1.0, 1.0)); - assert_eq!(a.wzxx(), F32x4::new(4.0, 3.0, 1.0, 1.0)); - assert_eq!(a.xwxx(), F32x4::new(1.0, 4.0, 1.0, 1.0)); - assert_eq!(a.ywxx(), F32x4::new(2.0, 4.0, 1.0, 1.0)); - assert_eq!(a.zwxx(), F32x4::new(3.0, 4.0, 1.0, 1.0)); - assert_eq!(a.wwxx(), F32x4::new(4.0, 4.0, 1.0, 1.0)); - assert_eq!(a.xxyx(), F32x4::new(1.0, 1.0, 2.0, 1.0)); - assert_eq!(a.yxyx(), F32x4::new(2.0, 1.0, 2.0, 1.0)); - assert_eq!(a.zxyx(), F32x4::new(3.0, 1.0, 2.0, 1.0)); - assert_eq!(a.wxyx(), F32x4::new(4.0, 1.0, 2.0, 1.0)); - assert_eq!(a.xyyx(), F32x4::new(1.0, 2.0, 2.0, 1.0)); - assert_eq!(a.yyyx(), F32x4::new(2.0, 2.0, 2.0, 1.0)); - assert_eq!(a.zyyx(), F32x4::new(3.0, 2.0, 2.0, 1.0)); - assert_eq!(a.wyyx(), F32x4::new(4.0, 2.0, 2.0, 1.0)); - assert_eq!(a.xzyx(), F32x4::new(1.0, 3.0, 2.0, 1.0)); - assert_eq!(a.yzyx(), F32x4::new(2.0, 3.0, 2.0, 1.0)); - assert_eq!(a.zzyx(), F32x4::new(3.0, 3.0, 2.0, 1.0)); - assert_eq!(a.wzyx(), F32x4::new(4.0, 3.0, 2.0, 1.0)); - assert_eq!(a.xwyx(), F32x4::new(1.0, 4.0, 2.0, 1.0)); - assert_eq!(a.ywyx(), F32x4::new(2.0, 4.0, 2.0, 1.0)); - assert_eq!(a.zwyx(), F32x4::new(3.0, 4.0, 2.0, 1.0)); - assert_eq!(a.wwyx(), F32x4::new(4.0, 4.0, 2.0, 1.0)); - assert_eq!(a.xxzx(), F32x4::new(1.0, 1.0, 3.0, 1.0)); - assert_eq!(a.yxzx(), F32x4::new(2.0, 1.0, 3.0, 1.0)); - assert_eq!(a.zxzx(), F32x4::new(3.0, 1.0, 3.0, 1.0)); - assert_eq!(a.wxzx(), F32x4::new(4.0, 1.0, 3.0, 1.0)); - assert_eq!(a.xyzx(), F32x4::new(1.0, 2.0, 3.0, 1.0)); - assert_eq!(a.yyzx(), F32x4::new(2.0, 2.0, 3.0, 1.0)); - assert_eq!(a.zyzx(), F32x4::new(3.0, 2.0, 3.0, 1.0)); - assert_eq!(a.wyzx(), F32x4::new(4.0, 2.0, 3.0, 1.0)); - assert_eq!(a.xzzx(), F32x4::new(1.0, 3.0, 3.0, 1.0)); - assert_eq!(a.yzzx(), F32x4::new(2.0, 3.0, 3.0, 1.0)); - assert_eq!(a.zzzx(), F32x4::new(3.0, 3.0, 3.0, 1.0)); - assert_eq!(a.wzzx(), F32x4::new(4.0, 3.0, 3.0, 1.0)); - assert_eq!(a.xwzx(), F32x4::new(1.0, 4.0, 3.0, 1.0)); - assert_eq!(a.ywzx(), F32x4::new(2.0, 4.0, 3.0, 1.0)); - assert_eq!(a.zwzx(), F32x4::new(3.0, 4.0, 3.0, 1.0)); - assert_eq!(a.wwzx(), F32x4::new(4.0, 4.0, 3.0, 1.0)); - assert_eq!(a.xxwx(), F32x4::new(1.0, 1.0, 4.0, 1.0)); - assert_eq!(a.yxwx(), F32x4::new(2.0, 1.0, 4.0, 1.0)); - assert_eq!(a.zxwx(), F32x4::new(3.0, 1.0, 4.0, 1.0)); - assert_eq!(a.wxwx(), F32x4::new(4.0, 1.0, 4.0, 1.0)); - assert_eq!(a.xywx(), F32x4::new(1.0, 2.0, 4.0, 1.0)); - assert_eq!(a.yywx(), F32x4::new(2.0, 2.0, 4.0, 1.0)); - assert_eq!(a.zywx(), F32x4::new(3.0, 2.0, 4.0, 1.0)); - assert_eq!(a.wywx(), F32x4::new(4.0, 2.0, 4.0, 1.0)); - assert_eq!(a.xzwx(), F32x4::new(1.0, 3.0, 4.0, 1.0)); - assert_eq!(a.yzwx(), F32x4::new(2.0, 3.0, 4.0, 1.0)); - assert_eq!(a.zzwx(), F32x4::new(3.0, 3.0, 4.0, 1.0)); - assert_eq!(a.wzwx(), F32x4::new(4.0, 3.0, 4.0, 1.0)); - assert_eq!(a.xwwx(), F32x4::new(1.0, 4.0, 4.0, 1.0)); - assert_eq!(a.ywwx(), F32x4::new(2.0, 4.0, 4.0, 1.0)); - assert_eq!(a.zwwx(), F32x4::new(3.0, 4.0, 4.0, 1.0)); - assert_eq!(a.wwwx(), F32x4::new(4.0, 4.0, 4.0, 1.0)); - - assert_eq!(a.xxxy(), F32x4::new(1.0, 1.0, 1.0, 2.0)); - assert_eq!(a.yxxy(), F32x4::new(2.0, 1.0, 1.0, 2.0)); - assert_eq!(a.zxxy(), F32x4::new(3.0, 1.0, 1.0, 2.0)); - assert_eq!(a.wxxy(), F32x4::new(4.0, 1.0, 1.0, 2.0)); - assert_eq!(a.xyxy(), F32x4::new(1.0, 2.0, 1.0, 2.0)); - assert_eq!(a.yyxy(), F32x4::new(2.0, 2.0, 1.0, 2.0)); - assert_eq!(a.zyxy(), F32x4::new(3.0, 2.0, 1.0, 2.0)); - assert_eq!(a.wyxy(), F32x4::new(4.0, 2.0, 1.0, 2.0)); - assert_eq!(a.xzxy(), F32x4::new(1.0, 3.0, 1.0, 2.0)); - assert_eq!(a.yzxy(), F32x4::new(2.0, 3.0, 1.0, 2.0)); - assert_eq!(a.zzxy(), F32x4::new(3.0, 3.0, 1.0, 2.0)); - assert_eq!(a.wzxy(), F32x4::new(4.0, 3.0, 1.0, 2.0)); - assert_eq!(a.xwxy(), F32x4::new(1.0, 4.0, 1.0, 2.0)); - assert_eq!(a.ywxy(), F32x4::new(2.0, 4.0, 1.0, 2.0)); - assert_eq!(a.zwxy(), F32x4::new(3.0, 4.0, 1.0, 2.0)); - assert_eq!(a.wwxy(), F32x4::new(4.0, 4.0, 1.0, 2.0)); - assert_eq!(a.xxyy(), F32x4::new(1.0, 1.0, 2.0, 2.0)); - assert_eq!(a.yxyy(), F32x4::new(2.0, 1.0, 2.0, 2.0)); - assert_eq!(a.zxyy(), F32x4::new(3.0, 1.0, 2.0, 2.0)); - assert_eq!(a.wxyy(), F32x4::new(4.0, 1.0, 2.0, 2.0)); - assert_eq!(a.xyyy(), F32x4::new(1.0, 2.0, 2.0, 2.0)); - assert_eq!(a.zyyy(), F32x4::new(3.0, 2.0, 2.0, 2.0)); - assert_eq!(a.wyyy(), F32x4::new(4.0, 2.0, 2.0, 2.0)); - assert_eq!(a.xzyy(), F32x4::new(1.0, 3.0, 2.0, 2.0)); - assert_eq!(a.yzyy(), F32x4::new(2.0, 3.0, 2.0, 2.0)); - assert_eq!(a.zzyy(), F32x4::new(3.0, 3.0, 2.0, 2.0)); - assert_eq!(a.wzyy(), F32x4::new(4.0, 3.0, 2.0, 2.0)); - assert_eq!(a.xwyy(), F32x4::new(1.0, 4.0, 2.0, 2.0)); - assert_eq!(a.ywyy(), F32x4::new(2.0, 4.0, 2.0, 2.0)); - assert_eq!(a.zwyy(), F32x4::new(3.0, 4.0, 2.0, 2.0)); - assert_eq!(a.wwyy(), F32x4::new(4.0, 4.0, 2.0, 2.0)); - assert_eq!(a.xxzy(), F32x4::new(1.0, 1.0, 3.0, 2.0)); - assert_eq!(a.yxzy(), F32x4::new(2.0, 1.0, 3.0, 2.0)); - assert_eq!(a.zxzy(), F32x4::new(3.0, 1.0, 3.0, 2.0)); - assert_eq!(a.wxzy(), F32x4::new(4.0, 1.0, 3.0, 2.0)); - assert_eq!(a.xyzy(), F32x4::new(1.0, 2.0, 3.0, 2.0)); - assert_eq!(a.yyzy(), F32x4::new(2.0, 2.0, 3.0, 2.0)); - assert_eq!(a.zyzy(), F32x4::new(3.0, 2.0, 3.0, 2.0)); - assert_eq!(a.wyzy(), F32x4::new(4.0, 2.0, 3.0, 2.0)); - assert_eq!(a.xzzy(), F32x4::new(1.0, 3.0, 3.0, 2.0)); - assert_eq!(a.yzzy(), F32x4::new(2.0, 3.0, 3.0, 2.0)); - assert_eq!(a.zzzy(), F32x4::new(3.0, 3.0, 3.0, 2.0)); - assert_eq!(a.wzzy(), F32x4::new(4.0, 3.0, 3.0, 2.0)); - assert_eq!(a.xwzy(), F32x4::new(1.0, 4.0, 3.0, 2.0)); - assert_eq!(a.ywzy(), F32x4::new(2.0, 4.0, 3.0, 2.0)); - assert_eq!(a.zwzy(), F32x4::new(3.0, 4.0, 3.0, 2.0)); - assert_eq!(a.wwzy(), F32x4::new(4.0, 4.0, 3.0, 2.0)); - assert_eq!(a.xxwy(), F32x4::new(1.0, 1.0, 4.0, 2.0)); - assert_eq!(a.yxwy(), F32x4::new(2.0, 1.0, 4.0, 2.0)); - assert_eq!(a.zxwy(), F32x4::new(3.0, 1.0, 4.0, 2.0)); - assert_eq!(a.wxwy(), F32x4::new(4.0, 1.0, 4.0, 2.0)); - assert_eq!(a.xywy(), F32x4::new(1.0, 2.0, 4.0, 2.0)); - assert_eq!(a.yywy(), F32x4::new(2.0, 2.0, 4.0, 2.0)); - assert_eq!(a.zywy(), F32x4::new(3.0, 2.0, 4.0, 2.0)); - assert_eq!(a.wywy(), F32x4::new(4.0, 2.0, 4.0, 2.0)); - assert_eq!(a.xzwy(), F32x4::new(1.0, 3.0, 4.0, 2.0)); - assert_eq!(a.yzwy(), F32x4::new(2.0, 3.0, 4.0, 2.0)); - assert_eq!(a.zzwy(), F32x4::new(3.0, 3.0, 4.0, 2.0)); - assert_eq!(a.wzwy(), F32x4::new(4.0, 3.0, 4.0, 2.0)); - assert_eq!(a.xwwy(), F32x4::new(1.0, 4.0, 4.0, 2.0)); - assert_eq!(a.ywwy(), F32x4::new(2.0, 4.0, 4.0, 2.0)); - assert_eq!(a.zwwy(), F32x4::new(3.0, 4.0, 4.0, 2.0)); - assert_eq!(a.wwwy(), F32x4::new(4.0, 4.0, 4.0, 2.0)); - - assert_eq!(a.xxxw(), F32x4::new(1.0, 1.0, 1.0, 4.0)); - assert_eq!(a.yxxw(), F32x4::new(2.0, 1.0, 1.0, 4.0)); - assert_eq!(a.zxxw(), F32x4::new(3.0, 1.0, 1.0, 4.0)); - assert_eq!(a.wxxw(), F32x4::new(4.0, 1.0, 1.0, 4.0)); - assert_eq!(a.xyxw(), F32x4::new(1.0, 2.0, 1.0, 4.0)); - assert_eq!(a.yyxw(), F32x4::new(2.0, 2.0, 1.0, 4.0)); - assert_eq!(a.zyxw(), F32x4::new(3.0, 2.0, 1.0, 4.0)); - assert_eq!(a.wyxw(), F32x4::new(4.0, 2.0, 1.0, 4.0)); - assert_eq!(a.xzxw(), F32x4::new(1.0, 3.0, 1.0, 4.0)); - assert_eq!(a.yzxw(), F32x4::new(2.0, 3.0, 1.0, 4.0)); - assert_eq!(a.zzxw(), F32x4::new(3.0, 3.0, 1.0, 4.0)); - assert_eq!(a.wzxw(), F32x4::new(4.0, 3.0, 1.0, 4.0)); - assert_eq!(a.xwxw(), F32x4::new(1.0, 4.0, 1.0, 4.0)); - assert_eq!(a.ywxw(), F32x4::new(2.0, 4.0, 1.0, 4.0)); - assert_eq!(a.zwxw(), F32x4::new(3.0, 4.0, 1.0, 4.0)); - assert_eq!(a.wwxw(), F32x4::new(4.0, 4.0, 1.0, 4.0)); - assert_eq!(a.xxyw(), F32x4::new(1.0, 1.0, 2.0, 4.0)); - assert_eq!(a.yxyw(), F32x4::new(2.0, 1.0, 2.0, 4.0)); - assert_eq!(a.zxyw(), F32x4::new(3.0, 1.0, 2.0, 4.0)); - assert_eq!(a.wxyw(), F32x4::new(4.0, 1.0, 2.0, 4.0)); - assert_eq!(a.xyyw(), F32x4::new(1.0, 2.0, 2.0, 4.0)); - assert_eq!(a.yyyw(), F32x4::new(2.0, 2.0, 2.0, 4.0)); - assert_eq!(a.zyyw(), F32x4::new(3.0, 2.0, 2.0, 4.0)); - assert_eq!(a.wyyw(), F32x4::new(4.0, 2.0, 2.0, 4.0)); - assert_eq!(a.xzyw(), F32x4::new(1.0, 3.0, 2.0, 4.0)); - assert_eq!(a.yzyw(), F32x4::new(2.0, 3.0, 2.0, 4.0)); - assert_eq!(a.zzyw(), F32x4::new(3.0, 3.0, 2.0, 4.0)); - assert_eq!(a.wzyw(), F32x4::new(4.0, 3.0, 2.0, 4.0)); - assert_eq!(a.xwyw(), F32x4::new(1.0, 4.0, 2.0, 4.0)); - assert_eq!(a.ywyw(), F32x4::new(2.0, 4.0, 2.0, 4.0)); - assert_eq!(a.zwyw(), F32x4::new(3.0, 4.0, 2.0, 4.0)); - assert_eq!(a.wwyw(), F32x4::new(4.0, 4.0, 2.0, 4.0)); - assert_eq!(a.xxzw(), F32x4::new(1.0, 1.0, 3.0, 4.0)); - assert_eq!(a.yxzw(), F32x4::new(2.0, 1.0, 3.0, 4.0)); - assert_eq!(a.zxzw(), F32x4::new(3.0, 1.0, 3.0, 4.0)); - assert_eq!(a.wxzw(), F32x4::new(4.0, 1.0, 3.0, 4.0)); - assert_eq!(a.xyzw(), F32x4::new(1.0, 2.0, 3.0, 4.0)); - assert_eq!(a.yyzw(), F32x4::new(2.0, 2.0, 3.0, 4.0)); - assert_eq!(a.zyzw(), F32x4::new(3.0, 2.0, 3.0, 4.0)); - assert_eq!(a.wyzw(), F32x4::new(4.0, 2.0, 3.0, 4.0)); - assert_eq!(a.xzzw(), F32x4::new(1.0, 3.0, 3.0, 4.0)); - assert_eq!(a.yzzw(), F32x4::new(2.0, 3.0, 3.0, 4.0)); - assert_eq!(a.zzzw(), F32x4::new(3.0, 3.0, 3.0, 4.0)); - assert_eq!(a.wzzw(), F32x4::new(4.0, 3.0, 3.0, 4.0)); - assert_eq!(a.xwzw(), F32x4::new(1.0, 4.0, 3.0, 4.0)); - assert_eq!(a.ywzw(), F32x4::new(2.0, 4.0, 3.0, 4.0)); - assert_eq!(a.zwzw(), F32x4::new(3.0, 4.0, 3.0, 4.0)); - assert_eq!(a.wwzw(), F32x4::new(4.0, 4.0, 3.0, 4.0)); - assert_eq!(a.xxww(), F32x4::new(1.0, 1.0, 4.0, 4.0)); - assert_eq!(a.yxww(), F32x4::new(2.0, 1.0, 4.0, 4.0)); - assert_eq!(a.zxww(), F32x4::new(3.0, 1.0, 4.0, 4.0)); - assert_eq!(a.wxww(), F32x4::new(4.0, 1.0, 4.0, 4.0)); - assert_eq!(a.xyww(), F32x4::new(1.0, 2.0, 4.0, 4.0)); - assert_eq!(a.yyww(), F32x4::new(2.0, 2.0, 4.0, 4.0)); - assert_eq!(a.zyww(), F32x4::new(3.0, 2.0, 4.0, 4.0)); - assert_eq!(a.wzww(), F32x4::new(4.0, 3.0, 4.0, 4.0)); - assert_eq!(a.xzww(), F32x4::new(1.0, 3.0, 4.0, 4.0)); - assert_eq!(a.yzww(), F32x4::new(2.0, 3.0, 4.0, 4.0)); - assert_eq!(a.zzww(), F32x4::new(3.0, 3.0, 4.0, 4.0)); - assert_eq!(a.wzww(), F32x4::new(4.0, 3.0, 4.0, 4.0)); - assert_eq!(a.xwww(), F32x4::new(1.0, 4.0, 4.0, 4.0)); - assert_eq!(a.ywww(), F32x4::new(2.0, 4.0, 4.0, 4.0)); - assert_eq!(a.zwww(), F32x4::new(3.0, 4.0, 4.0, 4.0)); - - assert_eq!(a.xxxz(), F32x4::new(1.0, 1.0, 1.0, 3.0)); - assert_eq!(a.yxxz(), F32x4::new(2.0, 1.0, 1.0, 3.0)); - assert_eq!(a.zxxz(), F32x4::new(3.0, 1.0, 1.0, 3.0)); - assert_eq!(a.wxxz(), F32x4::new(4.0, 1.0, 1.0, 3.0)); - assert_eq!(a.xyxz(), F32x4::new(1.0, 2.0, 1.0, 3.0)); - assert_eq!(a.yyxz(), F32x4::new(2.0, 2.0, 1.0, 3.0)); - assert_eq!(a.zyxz(), F32x4::new(3.0, 2.0, 1.0, 3.0)); - assert_eq!(a.wyxz(), F32x4::new(4.0, 2.0, 1.0, 3.0)); - assert_eq!(a.xzxz(), F32x4::new(1.0, 3.0, 1.0, 3.0)); - assert_eq!(a.yzxz(), F32x4::new(2.0, 3.0, 1.0, 3.0)); - assert_eq!(a.zzxz(), F32x4::new(3.0, 3.0, 1.0, 3.0)); - assert_eq!(a.wzxz(), F32x4::new(4.0, 3.0, 1.0, 3.0)); - assert_eq!(a.xwxz(), F32x4::new(1.0, 4.0, 1.0, 3.0)); - assert_eq!(a.ywxz(), F32x4::new(2.0, 4.0, 1.0, 3.0)); - assert_eq!(a.zwxz(), F32x4::new(3.0, 4.0, 1.0, 3.0)); - assert_eq!(a.wwxz(), F32x4::new(4.0, 4.0, 1.0, 3.0)); - assert_eq!(a.xxyz(), F32x4::new(1.0, 1.0, 2.0, 3.0)); - assert_eq!(a.yxyz(), F32x4::new(2.0, 1.0, 2.0, 3.0)); - assert_eq!(a.zxyz(), F32x4::new(3.0, 1.0, 2.0, 3.0)); - assert_eq!(a.wxyz(), F32x4::new(4.0, 1.0, 2.0, 3.0)); - assert_eq!(a.xyyz(), F32x4::new(1.0, 2.0, 2.0, 3.0)); - assert_eq!(a.yyyz(), F32x4::new(2.0, 2.0, 2.0, 3.0)); - assert_eq!(a.zyyz(), F32x4::new(3.0, 2.0, 2.0, 3.0)); - assert_eq!(a.wyyz(), F32x4::new(4.0, 2.0, 2.0, 3.0)); - assert_eq!(a.xzyz(), F32x4::new(1.0, 3.0, 2.0, 3.0)); - assert_eq!(a.yzyz(), F32x4::new(2.0, 3.0, 2.0, 3.0)); - assert_eq!(a.zzyz(), F32x4::new(3.0, 3.0, 2.0, 3.0)); - assert_eq!(a.wzyz(), F32x4::new(4.0, 3.0, 2.0, 3.0)); - assert_eq!(a.xwyz(), F32x4::new(1.0, 4.0, 2.0, 3.0)); - assert_eq!(a.ywyz(), F32x4::new(2.0, 4.0, 2.0, 3.0)); - assert_eq!(a.zwyz(), F32x4::new(3.0, 4.0, 2.0, 3.0)); - assert_eq!(a.wwyz(), F32x4::new(4.0, 4.0, 2.0, 3.0)); - assert_eq!(a.xxzz(), F32x4::new(1.0, 1.0, 3.0, 3.0)); - assert_eq!(a.yxzz(), F32x4::new(2.0, 1.0, 3.0, 3.0)); - assert_eq!(a.zxzz(), F32x4::new(3.0, 1.0, 3.0, 3.0)); - assert_eq!(a.wxzz(), F32x4::new(4.0, 1.0, 3.0, 3.0)); - assert_eq!(a.xyzz(), F32x4::new(1.0, 2.0, 3.0, 3.0)); - assert_eq!(a.yyzz(), F32x4::new(2.0, 2.0, 3.0, 3.0)); - assert_eq!(a.zyzz(), F32x4::new(3.0, 2.0, 3.0, 3.0)); - assert_eq!(a.wyzz(), F32x4::new(4.0, 2.0, 3.0, 3.0)); - assert_eq!(a.xzzz(), F32x4::new(1.0, 3.0, 3.0, 3.0)); - assert_eq!(a.yzzz(), F32x4::new(2.0, 3.0, 3.0, 3.0)); - assert_eq!(a.wzzz(), F32x4::new(4.0, 3.0, 3.0, 3.0)); - assert_eq!(a.xwzz(), F32x4::new(1.0, 4.0, 3.0, 3.0)); - assert_eq!(a.ywzz(), F32x4::new(2.0, 4.0, 3.0, 3.0)); - assert_eq!(a.zwzz(), F32x4::new(3.0, 4.0, 3.0, 3.0)); - assert_eq!(a.wwzz(), F32x4::new(4.0, 4.0, 3.0, 3.0)); - assert_eq!(a.xxwz(), F32x4::new(1.0, 1.0, 4.0, 3.0)); - assert_eq!(a.yxwz(), F32x4::new(2.0, 1.0, 4.0, 3.0)); - assert_eq!(a.zxwz(), F32x4::new(3.0, 1.0, 4.0, 3.0)); - assert_eq!(a.wxwz(), F32x4::new(4.0, 1.0, 4.0, 3.0)); - assert_eq!(a.xywz(), F32x4::new(1.0, 2.0, 4.0, 3.0)); - assert_eq!(a.yywz(), F32x4::new(2.0, 2.0, 4.0, 3.0)); - assert_eq!(a.zywz(), F32x4::new(3.0, 2.0, 4.0, 3.0)); - assert_eq!(a.wywz(), F32x4::new(4.0, 2.0, 4.0, 3.0)); - assert_eq!(a.xzwz(), F32x4::new(1.0, 3.0, 4.0, 3.0)); - assert_eq!(a.yzwz(), F32x4::new(2.0, 3.0, 4.0, 3.0)); - assert_eq!(a.zzwz(), F32x4::new(3.0, 3.0, 4.0, 3.0)); - assert_eq!(a.wzwz(), F32x4::new(4.0, 3.0, 4.0, 3.0)); - assert_eq!(a.xwwz(), F32x4::new(1.0, 4.0, 4.0, 3.0)); - assert_eq!(a.ywwz(), F32x4::new(2.0, 4.0, 4.0, 3.0)); - assert_eq!(a.zwwz(), F32x4::new(3.0, 4.0, 4.0, 3.0)); - assert_eq!(a.wwwz(), F32x4::new(4.0, 4.0, 4.0, 3.0)); -} - -#[test] -fn test_f32x4_concatenations() { - let a = F32x4::new(4.0, 2.0, 6.0, -1.0); - let b = F32x4::new(10.0, -3.0, 15.0, 41.0); - assert_eq!(a.concat_xy_xy(b), F32x4::new(4.0, 2.0, 10.0, -3.0)); - assert_eq!(a.concat_xy_zw(b), F32x4::new(4.0, 2.0, 15.0, 41.0)); - assert_eq!(a.concat_zw_zw(b), F32x4::new(6.0, -1.0, 15.0, 41.0)); - assert_eq!(a.concat_wz_yx(b), F32x4::new(-1.0, 6.0, -3.0, 10.0)); -} - -#[test] -fn test_f32x4_arithmetic_overloads() { - let a = F32x4::new(4.0, -1.0, 6.0, -32.0); - let b = F32x4::new(0.5, 0.5, 10.0, 3.0); - let a_plus_b = F32x4::new(4.5, -0.5, 16.0, -29.0); - let a_minus_b = F32x4::new(3.5, -1.5, -4.0, -35.0); - let a_times_b = F32x4::new(2.0, -0.5, 60.0, -96.0); - assert_eq!(a + b, a_plus_b); - assert_eq!(a - b, a_minus_b); - assert_eq!(a * b, a_times_b); - let mut c = a; - c += b; - assert_eq!(c, a_plus_b); - c = a; - c -= b; - assert_eq!(c, a_minus_b); - c = a; - c *= b; - assert_eq!(c, a_times_b); - assert_eq!(-a, F32x4::new(-4.0, 1.0, -6.0, 32.0)); -} - -#[test] -fn test_f32x4_index_overloads() { - let mut a = F32x4::new(4.0, 1.0, -32.5, 75.0); - assert_eq!(a[2], -32.5); - a[3] = 300.0; - assert_eq!(a[3], 300.0); - a[0] *= 0.5; - assert_eq!(a[0], 2.0); -} - -#[test] -fn test_f32x4_conversions() { - let a = F32x4::new(48.0, -4.0, 200.0, 7.0); - assert_eq!(a.to_i32x4(), I32x4::new(48, -4, 200, 7)); -} - -#[test] -fn test_f32x4_debug() { - let a = F32x4::new(48.0, -4.0, 200.0, 7.0); - assert_eq!("<48, -4, 200, 7>", format!("{:?}", a)); -} - -// I32x4 - -#[test] -fn test_i32x4_constructors() { - let a = I32x4::new(3, 58, 10, 4); - assert_eq!((a[0], a[1], a[2], a[3]), (3, 58, 10, 4)); - let b = I32x4::splat(39); - assert_eq!(b, I32x4::new(39, 39, 39, 39)); -} - -#[test] -fn test_i32x4_basic_ops() { - let a = I32x4::new(6, 29, -40, 2); - let b = I32x4::new(10, -5, 10, 46); - assert_eq!(a.min(b), I32x4::new(6, -5, -40, 2)); -} - -#[test] -fn test_i32x4_packed_comparisons() { - let a = I32x4::new(59, 1, 5, 63); - let b = I32x4::new(-59, 1, 5, 104); - assert_eq!(a.packed_eq(b), U32x4::new(0, !0, !0, 0)); -} - -#[test] -fn test_i32x4_swizzles() { - let a = I32x4::new(1, 2, 3, 4); - assert_eq!(a.xxxx(), I32x4::splat(1)); - assert_eq!(a.yyyy(), I32x4::splat(2)); - assert_eq!(a.zzzz(), I32x4::splat(3)); - assert_eq!(a.wwww(), I32x4::splat(4)); - - assert_eq!(a.yxxx(), I32x4::new(2, 1, 1, 1)); - assert_eq!(a.zxxx(), I32x4::new(3, 1, 1, 1)); - assert_eq!(a.wxxx(), I32x4::new(4, 1, 1, 1)); - assert_eq!(a.xyxx(), I32x4::new(1, 2, 1, 1)); - assert_eq!(a.yyxx(), I32x4::new(2, 2, 1, 1)); - assert_eq!(a.zyxx(), I32x4::new(3, 2, 1, 1)); - assert_eq!(a.wyxx(), I32x4::new(4, 2, 1, 1)); - assert_eq!(a.xzxx(), I32x4::new(1, 3, 1, 1)); - assert_eq!(a.yzxx(), I32x4::new(2, 3, 1, 1)); - assert_eq!(a.zzxx(), I32x4::new(3, 3, 1, 1)); - assert_eq!(a.wzxx(), I32x4::new(4, 3, 1, 1)); - assert_eq!(a.xwxx(), I32x4::new(1, 4, 1, 1)); - assert_eq!(a.ywxx(), I32x4::new(2, 4, 1, 1)); - assert_eq!(a.zwxx(), I32x4::new(3, 4, 1, 1)); - assert_eq!(a.wwxx(), I32x4::new(4, 4, 1, 1)); - assert_eq!(a.xxyx(), I32x4::new(1, 1, 2, 1)); - assert_eq!(a.yxyx(), I32x4::new(2, 1, 2, 1)); - assert_eq!(a.zxyx(), I32x4::new(3, 1, 2, 1)); - assert_eq!(a.wxyx(), I32x4::new(4, 1, 2, 1)); - assert_eq!(a.xyyx(), I32x4::new(1, 2, 2, 1)); - assert_eq!(a.yyyx(), I32x4::new(2, 2, 2, 1)); - assert_eq!(a.zyyx(), I32x4::new(3, 2, 2, 1)); - assert_eq!(a.wyyx(), I32x4::new(4, 2, 2, 1)); - assert_eq!(a.xzyx(), I32x4::new(1, 3, 2, 1)); - assert_eq!(a.yzyx(), I32x4::new(2, 3, 2, 1)); - assert_eq!(a.zzyx(), I32x4::new(3, 3, 2, 1)); - assert_eq!(a.wzyx(), I32x4::new(4, 3, 2, 1)); - assert_eq!(a.xwyx(), I32x4::new(1, 4, 2, 1)); - assert_eq!(a.ywyx(), I32x4::new(2, 4, 2, 1)); - assert_eq!(a.zwyx(), I32x4::new(3, 4, 2, 1)); - assert_eq!(a.wwyx(), I32x4::new(4, 4, 2, 1)); - assert_eq!(a.xxzx(), I32x4::new(1, 1, 3, 1)); - assert_eq!(a.yxzx(), I32x4::new(2, 1, 3, 1)); - assert_eq!(a.zxzx(), I32x4::new(3, 1, 3, 1)); - assert_eq!(a.wxzx(), I32x4::new(4, 1, 3, 1)); - assert_eq!(a.xyzx(), I32x4::new(1, 2, 3, 1)); - assert_eq!(a.yyzx(), I32x4::new(2, 2, 3, 1)); - assert_eq!(a.zyzx(), I32x4::new(3, 2, 3, 1)); - assert_eq!(a.wyzx(), I32x4::new(4, 2, 3, 1)); - assert_eq!(a.xzzx(), I32x4::new(1, 3, 3, 1)); - assert_eq!(a.yzzx(), I32x4::new(2, 3, 3, 1)); - assert_eq!(a.zzzx(), I32x4::new(3, 3, 3, 1)); - assert_eq!(a.wzzx(), I32x4::new(4, 3, 3, 1)); - assert_eq!(a.xwzx(), I32x4::new(1, 4, 3, 1)); - assert_eq!(a.ywzx(), I32x4::new(2, 4, 3, 1)); - assert_eq!(a.zwzx(), I32x4::new(3, 4, 3, 1)); - assert_eq!(a.wwzx(), I32x4::new(4, 4, 3, 1)); - assert_eq!(a.xxwx(), I32x4::new(1, 1, 4, 1)); - assert_eq!(a.yxwx(), I32x4::new(2, 1, 4, 1)); - assert_eq!(a.zxwx(), I32x4::new(3, 1, 4, 1)); - assert_eq!(a.wxwx(), I32x4::new(4, 1, 4, 1)); - assert_eq!(a.xywx(), I32x4::new(1, 2, 4, 1)); - assert_eq!(a.yywx(), I32x4::new(2, 2, 4, 1)); - assert_eq!(a.zywx(), I32x4::new(3, 2, 4, 1)); - assert_eq!(a.wywx(), I32x4::new(4, 2, 4, 1)); - assert_eq!(a.xzwx(), I32x4::new(1, 3, 4, 1)); - assert_eq!(a.yzwx(), I32x4::new(2, 3, 4, 1)); - assert_eq!(a.zzwx(), I32x4::new(3, 3, 4, 1)); - assert_eq!(a.wzwx(), I32x4::new(4, 3, 4, 1)); - assert_eq!(a.xwwx(), I32x4::new(1, 4, 4, 1)); - assert_eq!(a.ywwx(), I32x4::new(2, 4, 4, 1)); - assert_eq!(a.zwwx(), I32x4::new(3, 4, 4, 1)); - assert_eq!(a.wwwx(), I32x4::new(4, 4, 4, 1)); - - assert_eq!(a.xxxy(), I32x4::new(1, 1, 1, 2)); - assert_eq!(a.yxxy(), I32x4::new(2, 1, 1, 2)); - assert_eq!(a.zxxy(), I32x4::new(3, 1, 1, 2)); - assert_eq!(a.wxxy(), I32x4::new(4, 1, 1, 2)); - assert_eq!(a.xyxy(), I32x4::new(1, 2, 1, 2)); - assert_eq!(a.yyxy(), I32x4::new(2, 2, 1, 2)); - assert_eq!(a.zyxy(), I32x4::new(3, 2, 1, 2)); - assert_eq!(a.wyxy(), I32x4::new(4, 2, 1, 2)); - assert_eq!(a.xzxy(), I32x4::new(1, 3, 1, 2)); - assert_eq!(a.yzxy(), I32x4::new(2, 3, 1, 2)); - assert_eq!(a.zzxy(), I32x4::new(3, 3, 1, 2)); - assert_eq!(a.wzxy(), I32x4::new(4, 3, 1, 2)); - assert_eq!(a.xwxy(), I32x4::new(1, 4, 1, 2)); - assert_eq!(a.ywxy(), I32x4::new(2, 4, 1, 2)); - assert_eq!(a.zwxy(), I32x4::new(3, 4, 1, 2)); - assert_eq!(a.wwxy(), I32x4::new(4, 4, 1, 2)); - assert_eq!(a.xxyy(), I32x4::new(1, 1, 2, 2)); - assert_eq!(a.yxyy(), I32x4::new(2, 1, 2, 2)); - assert_eq!(a.zxyy(), I32x4::new(3, 1, 2, 2)); - assert_eq!(a.wxyy(), I32x4::new(4, 1, 2, 2)); - assert_eq!(a.xyyy(), I32x4::new(1, 2, 2, 2)); - assert_eq!(a.zyyy(), I32x4::new(3, 2, 2, 2)); - assert_eq!(a.wyyy(), I32x4::new(4, 2, 2, 2)); - assert_eq!(a.xzyy(), I32x4::new(1, 3, 2, 2)); - assert_eq!(a.yzyy(), I32x4::new(2, 3, 2, 2)); - assert_eq!(a.zzyy(), I32x4::new(3, 3, 2, 2)); - assert_eq!(a.wzyy(), I32x4::new(4, 3, 2, 2)); - assert_eq!(a.xwyy(), I32x4::new(1, 4, 2, 2)); - assert_eq!(a.ywyy(), I32x4::new(2, 4, 2, 2)); - assert_eq!(a.zwyy(), I32x4::new(3, 4, 2, 2)); - assert_eq!(a.wwyy(), I32x4::new(4, 4, 2, 2)); - assert_eq!(a.xxzy(), I32x4::new(1, 1, 3, 2)); - assert_eq!(a.yxzy(), I32x4::new(2, 1, 3, 2)); - assert_eq!(a.zxzy(), I32x4::new(3, 1, 3, 2)); - assert_eq!(a.wxzy(), I32x4::new(4, 1, 3, 2)); - assert_eq!(a.xyzy(), I32x4::new(1, 2, 3, 2)); - assert_eq!(a.yyzy(), I32x4::new(2, 2, 3, 2)); - assert_eq!(a.zyzy(), I32x4::new(3, 2, 3, 2)); - assert_eq!(a.wyzy(), I32x4::new(4, 2, 3, 2)); - assert_eq!(a.xzzy(), I32x4::new(1, 3, 3, 2)); - assert_eq!(a.yzzy(), I32x4::new(2, 3, 3, 2)); - assert_eq!(a.zzzy(), I32x4::new(3, 3, 3, 2)); - assert_eq!(a.wzzy(), I32x4::new(4, 3, 3, 2)); - assert_eq!(a.xwzy(), I32x4::new(1, 4, 3, 2)); - assert_eq!(a.ywzy(), I32x4::new(2, 4, 3, 2)); - assert_eq!(a.zwzy(), I32x4::new(3, 4, 3, 2)); - assert_eq!(a.wwzy(), I32x4::new(4, 4, 3, 2)); - assert_eq!(a.xxwy(), I32x4::new(1, 1, 4, 2)); - assert_eq!(a.yxwy(), I32x4::new(2, 1, 4, 2)); - assert_eq!(a.zxwy(), I32x4::new(3, 1, 4, 2)); - assert_eq!(a.wxwy(), I32x4::new(4, 1, 4, 2)); - assert_eq!(a.xywy(), I32x4::new(1, 2, 4, 2)); - assert_eq!(a.yywy(), I32x4::new(2, 2, 4, 2)); - assert_eq!(a.zywy(), I32x4::new(3, 2, 4, 2)); - assert_eq!(a.wywy(), I32x4::new(4, 2, 4, 2)); - assert_eq!(a.xzwy(), I32x4::new(1, 3, 4, 2)); - assert_eq!(a.yzwy(), I32x4::new(2, 3, 4, 2)); - assert_eq!(a.zzwy(), I32x4::new(3, 3, 4, 2)); - assert_eq!(a.wzwy(), I32x4::new(4, 3, 4, 2)); - assert_eq!(a.xwwy(), I32x4::new(1, 4, 4, 2)); - assert_eq!(a.ywwy(), I32x4::new(2, 4, 4, 2)); - assert_eq!(a.zwwy(), I32x4::new(3, 4, 4, 2)); - assert_eq!(a.wwwy(), I32x4::new(4, 4, 4, 2)); - - assert_eq!(a.xxxz(), I32x4::new(1, 1, 1, 3)); - assert_eq!(a.yxxz(), I32x4::new(2, 1, 1, 3)); - assert_eq!(a.zxxz(), I32x4::new(3, 1, 1, 3)); - assert_eq!(a.wxxz(), I32x4::new(4, 1, 1, 3)); - assert_eq!(a.xyxz(), I32x4::new(1, 2, 1, 3)); - assert_eq!(a.yyxz(), I32x4::new(2, 2, 1, 3)); - assert_eq!(a.zyxz(), I32x4::new(3, 2, 1, 3)); - assert_eq!(a.wyxz(), I32x4::new(4, 2, 1, 3)); - assert_eq!(a.xzxz(), I32x4::new(1, 3, 1, 3)); - assert_eq!(a.yzxz(), I32x4::new(2, 3, 1, 3)); - assert_eq!(a.zzxz(), I32x4::new(3, 3, 1, 3)); - assert_eq!(a.wzxz(), I32x4::new(4, 3, 1, 3)); - assert_eq!(a.xwxz(), I32x4::new(1, 4, 1, 3)); - assert_eq!(a.ywxz(), I32x4::new(2, 4, 1, 3)); - assert_eq!(a.zwxz(), I32x4::new(3, 4, 1, 3)); - assert_eq!(a.wwxz(), I32x4::new(4, 4, 1, 3)); - assert_eq!(a.xxyz(), I32x4::new(1, 1, 2, 3)); - assert_eq!(a.yxyz(), I32x4::new(2, 1, 2, 3)); - assert_eq!(a.zxyz(), I32x4::new(3, 1, 2, 3)); - assert_eq!(a.wxyz(), I32x4::new(4, 1, 2, 3)); - assert_eq!(a.xyyz(), I32x4::new(1, 2, 2, 3)); - assert_eq!(a.yyyz(), I32x4::new(2, 2, 2, 3)); - assert_eq!(a.zyyz(), I32x4::new(3, 2, 2, 3)); - assert_eq!(a.wyyz(), I32x4::new(4, 2, 2, 3)); - assert_eq!(a.xzyz(), I32x4::new(1, 3, 2, 3)); - assert_eq!(a.yzyz(), I32x4::new(2, 3, 2, 3)); - assert_eq!(a.zzyz(), I32x4::new(3, 3, 2, 3)); - assert_eq!(a.wzyz(), I32x4::new(4, 3, 2, 3)); - assert_eq!(a.xwyz(), I32x4::new(1, 4, 2, 3)); - assert_eq!(a.ywyz(), I32x4::new(2, 4, 2, 3)); - assert_eq!(a.zwyz(), I32x4::new(3, 4, 2, 3)); - assert_eq!(a.wwyz(), I32x4::new(4, 4, 2, 3)); - assert_eq!(a.xxzz(), I32x4::new(1, 1, 3, 3)); - assert_eq!(a.yxzz(), I32x4::new(2, 1, 3, 3)); - assert_eq!(a.zxzz(), I32x4::new(3, 1, 3, 3)); - assert_eq!(a.wxzz(), I32x4::new(4, 1, 3, 3)); - assert_eq!(a.xyzz(), I32x4::new(1, 2, 3, 3)); - assert_eq!(a.yyzz(), I32x4::new(2, 2, 3, 3)); - assert_eq!(a.zyzz(), I32x4::new(3, 2, 3, 3)); - assert_eq!(a.wyzz(), I32x4::new(4, 2, 3, 3)); - assert_eq!(a.xzzz(), I32x4::new(1, 3, 3, 3)); - assert_eq!(a.yzzz(), I32x4::new(2, 3, 3, 3)); - assert_eq!(a.wzzz(), I32x4::new(4, 3, 3, 3)); - assert_eq!(a.xwzz(), I32x4::new(1, 4, 3, 3)); - assert_eq!(a.ywzz(), I32x4::new(2, 4, 3, 3)); - assert_eq!(a.zwzz(), I32x4::new(3, 4, 3, 3)); - assert_eq!(a.wwzz(), I32x4::new(4, 4, 3, 3)); - assert_eq!(a.xxwz(), I32x4::new(1, 1, 4, 3)); - assert_eq!(a.yxwz(), I32x4::new(2, 1, 4, 3)); - assert_eq!(a.zxwz(), I32x4::new(3, 1, 4, 3)); - assert_eq!(a.wxwz(), I32x4::new(4, 1, 4, 3)); - assert_eq!(a.xywz(), I32x4::new(1, 2, 4, 3)); - assert_eq!(a.yywz(), I32x4::new(2, 2, 4, 3)); - assert_eq!(a.zywz(), I32x4::new(3, 2, 4, 3)); - assert_eq!(a.wywz(), I32x4::new(4, 2, 4, 3)); - assert_eq!(a.xzwz(), I32x4::new(1, 3, 4, 3)); - assert_eq!(a.yzwz(), I32x4::new(2, 3, 4, 3)); - assert_eq!(a.zzwz(), I32x4::new(3, 3, 4, 3)); - assert_eq!(a.wzwz(), I32x4::new(4, 3, 4, 3)); - assert_eq!(a.xwwz(), I32x4::new(1, 4, 4, 3)); - assert_eq!(a.ywwz(), I32x4::new(2, 4, 4, 3)); - assert_eq!(a.zwwz(), I32x4::new(3, 4, 4, 3)); - assert_eq!(a.wwwz(), I32x4::new(4, 4, 4, 3)); - - assert_eq!(a.xxxw(), I32x4::new(1, 1, 1, 4)); - assert_eq!(a.yxxw(), I32x4::new(2, 1, 1, 4)); - assert_eq!(a.zxxw(), I32x4::new(3, 1, 1, 4)); - assert_eq!(a.wxxw(), I32x4::new(4, 1, 1, 4)); - assert_eq!(a.xyxw(), I32x4::new(1, 2, 1, 4)); - assert_eq!(a.yyxw(), I32x4::new(2, 2, 1, 4)); - assert_eq!(a.zyxw(), I32x4::new(3, 2, 1, 4)); - assert_eq!(a.wyxw(), I32x4::new(4, 2, 1, 4)); - assert_eq!(a.xzxw(), I32x4::new(1, 3, 1, 4)); - assert_eq!(a.yzxw(), I32x4::new(2, 3, 1, 4)); - assert_eq!(a.zzxw(), I32x4::new(3, 3, 1, 4)); - assert_eq!(a.wzxw(), I32x4::new(4, 3, 1, 4)); - assert_eq!(a.xwxw(), I32x4::new(1, 4, 1, 4)); - assert_eq!(a.ywxw(), I32x4::new(2, 4, 1, 4)); - assert_eq!(a.zwxw(), I32x4::new(3, 4, 1, 4)); - assert_eq!(a.wwxw(), I32x4::new(4, 4, 1, 4)); - assert_eq!(a.xxyw(), I32x4::new(1, 1, 2, 4)); - assert_eq!(a.yxyw(), I32x4::new(2, 1, 2, 4)); - assert_eq!(a.zxyw(), I32x4::new(3, 1, 2, 4)); - assert_eq!(a.wxyw(), I32x4::new(4, 1, 2, 4)); - assert_eq!(a.xyyw(), I32x4::new(1, 2, 2, 4)); - assert_eq!(a.yyyw(), I32x4::new(2, 2, 2, 4)); - assert_eq!(a.zyyw(), I32x4::new(3, 2, 2, 4)); - assert_eq!(a.wyyw(), I32x4::new(4, 2, 2, 4)); - assert_eq!(a.xzyw(), I32x4::new(1, 3, 2, 4)); - assert_eq!(a.yzyw(), I32x4::new(2, 3, 2, 4)); - assert_eq!(a.zzyw(), I32x4::new(3, 3, 2, 4)); - assert_eq!(a.wzyw(), I32x4::new(4, 3, 2, 4)); - assert_eq!(a.xwyw(), I32x4::new(1, 4, 2, 4)); - assert_eq!(a.ywyw(), I32x4::new(2, 4, 2, 4)); - assert_eq!(a.zwyw(), I32x4::new(3, 4, 2, 4)); - assert_eq!(a.wwyw(), I32x4::new(4, 4, 2, 4)); - assert_eq!(a.xxzw(), I32x4::new(1, 1, 3, 4)); - assert_eq!(a.yxzw(), I32x4::new(2, 1, 3, 4)); - assert_eq!(a.zxzw(), I32x4::new(3, 1, 3, 4)); - assert_eq!(a.wxzw(), I32x4::new(4, 1, 3, 4)); - assert_eq!(a.xyzw(), I32x4::new(1, 2, 3, 4)); - assert_eq!(a.yyzw(), I32x4::new(2, 2, 3, 4)); - assert_eq!(a.zyzw(), I32x4::new(3, 2, 3, 4)); - assert_eq!(a.wyzw(), I32x4::new(4, 2, 3, 4)); - assert_eq!(a.xzzw(), I32x4::new(1, 3, 3, 4)); - assert_eq!(a.yzzw(), I32x4::new(2, 3, 3, 4)); - assert_eq!(a.zzzw(), I32x4::new(3, 3, 3, 4)); - assert_eq!(a.wzzw(), I32x4::new(4, 3, 3, 4)); - assert_eq!(a.xwzw(), I32x4::new(1, 4, 3, 4)); - assert_eq!(a.ywzw(), I32x4::new(2, 4, 3, 4)); - assert_eq!(a.zwzw(), I32x4::new(3, 4, 3, 4)); - assert_eq!(a.wwzw(), I32x4::new(4, 4, 3, 4)); - assert_eq!(a.xxww(), I32x4::new(1, 1, 4, 4)); - assert_eq!(a.yxww(), I32x4::new(2, 1, 4, 4)); - assert_eq!(a.zxww(), I32x4::new(3, 1, 4, 4)); - assert_eq!(a.wxww(), I32x4::new(4, 1, 4, 4)); - assert_eq!(a.xyww(), I32x4::new(1, 2, 4, 4)); - assert_eq!(a.yyww(), I32x4::new(2, 2, 4, 4)); - assert_eq!(a.zyww(), I32x4::new(3, 2, 4, 4)); - assert_eq!(a.wzww(), I32x4::new(4, 3, 4, 4)); - assert_eq!(a.xzww(), I32x4::new(1, 3, 4, 4)); - assert_eq!(a.yzww(), I32x4::new(2, 3, 4, 4)); - assert_eq!(a.zzww(), I32x4::new(3, 3, 4, 4)); - assert_eq!(a.wzww(), I32x4::new(4, 3, 4, 4)); - assert_eq!(a.xwww(), I32x4::new(1, 4, 4, 4)); - assert_eq!(a.ywww(), I32x4::new(2, 4, 4, 4)); - assert_eq!(a.zwww(), I32x4::new(3, 4, 4, 4)); -} - -// Scalar F32x4 - -#[test] -fn test_f32x4s_constructors() { - let a = F32x4S::new(1.0, 2.0, 3.0, 4.0); - assert_eq!((a[0], a[1], a[2], a[3]), (1.0, 2.0, 3.0, 4.0)); - let b = F32x4S::splat(10.0); - assert_eq!(b, F32x4S::new(10.0, 10.0, 10.0, 10.0)); -} - -#[test] -fn test_f32x4s_basic_ops() { - let a = F32x4S::new(1.0, 3.0, 5.0, 7.0); - let b = F32x4S::new(2.0, 2.0, 6.0, 6.0); - assert_eq!(a.min(b), F32x4S::new(1.0, 2.0, 5.0, 6.0)); - assert_eq!(a.max(b), F32x4S::new(2.0, 3.0, 6.0, 7.0)); - let c = F32x4S::new(-1.0, 1.3, -20.0, 3.6); - assert_eq!(c.abs(), F32x4S::new(1.0, 1.3, 20.0, 3.6)); - assert_eq!(c.floor(), F32x4S::new(-1.0, 1.0, -20.0, 3.0)); - assert_eq!(c.ceil(), F32x4S::new(-1.0, 2.0, -20.0, 4.0)); - assert_eq!(c.to_i32x4().to_f32x4(), F32x4S::new(-1.0, 1.0, -20.0, 4.0)); -} diff --git a/crates/pathfinder/simd/src/x86/mod.rs b/crates/pathfinder/simd/src/x86/mod.rs deleted file mode 100644 index 23a52686ab..0000000000 --- a/crates/pathfinder/simd/src/x86/mod.rs +++ /dev/null @@ -1,952 +0,0 @@ -// pathfinder/simd/src/x86.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::cmp::PartialEq; -use std::fmt::{self, Debug, Formatter}; -use std::mem; -use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Index, IndexMut, Mul, Not, Shr, Sub}; - -#[cfg(target_pointer_width = "32")] -use std::arch::x86::{__m128, __m128i}; -#[cfg(target_pointer_width = "32")] -use std::arch::x86; -#[cfg(target_pointer_width = "64")] -use std::arch::x86_64::{__m128, __m128i}; -#[cfg(target_pointer_width = "64")] -use std::arch::x86_64 as x86; - -mod swizzle_f32x4; -mod swizzle_i32x4; - -// Two 32-bit floats - -#[derive(Clone, Copy)] -pub struct F32x2(pub u64); - -impl F32x2 { - // Constructors - - #[inline] - pub fn new(a: f32, b: f32) -> F32x2 { - unsafe { - let a = mem::transmute::<*const f32, *const u32>(&a); - let b = mem::transmute::<*const f32, *const u32>(&b); - F32x2((*a as u64) | ((*b as u64) << 32)) - } - } - - #[inline] - pub fn splat(x: f32) -> F32x2 { - F32x2::new(x, x) - } - - // Basic operations - - #[inline] - pub fn approx_recip(self) -> F32x2 { - self.to_f32x4().approx_recip().xy() - } - - #[inline] - pub fn min(self, other: F32x2) -> F32x2 { - self.to_f32x4().min(other.to_f32x4()).xy() - } - - #[inline] - pub fn max(self, other: F32x2) -> F32x2 { - self.to_f32x4().max(other.to_f32x4()).xy() - } - - #[inline] - pub fn clamp(self, min: F32x2, max: F32x2) -> F32x2 { - self.to_f32x4().clamp(min.to_f32x4(), max.to_f32x4()).xy() - } - - #[inline] - pub fn abs(self) -> F32x2 { - self.to_f32x4().abs().xy() - } - - #[inline] - pub fn floor(self) -> F32x2 { - self.to_f32x4().floor().xy() - } - - #[inline] - pub fn ceil(self) -> F32x2 { - self.to_f32x4().ceil().xy() - } - - #[inline] - pub fn sqrt(self) -> F32x2 { - self.to_f32x4().sqrt().xy() - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: F32x2) -> U32x2 { - self.to_f32x4().packed_eq(other.to_f32x4()).xy() - } - - #[inline] - pub fn packed_gt(self, other: F32x2) -> U32x2 { - self.to_f32x4().packed_gt(other.to_f32x4()).xy() - } - - #[inline] - pub fn packed_lt(self, other: F32x2) -> U32x2 { - self.to_f32x4().packed_lt(other.to_f32x4()).xy() - } - - #[inline] - pub fn packed_le(self, other: F32x2) -> U32x2 { - self.to_f32x4().packed_le(other.to_f32x4()).xy() - } - - // Conversions - - #[inline] - pub fn to_f32x4(self) -> F32x4 { - unsafe { - let mut result = F32x4::default(); - *mem::transmute::<&mut __m128, &mut u64>(&mut result.0) = self.0; - result - } - } - - #[inline] - pub fn to_i32x2(self) -> I32x2 { - self.to_i32x4().xy() - } - - #[inline] - pub fn to_i32x4(self) -> I32x4 { - self.to_f32x4().to_i32x4() - } - - // Swizzle - - #[inline] - pub fn yx(self) -> F32x2 { - self.to_f32x4().yx() - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: F32x2) -> F32x4 { - self.to_f32x4().concat_xy_xy(other.to_f32x4()) - } -} - -impl Default for F32x2 { - #[inline] - fn default() -> F32x2 { - F32x2(0) - } -} - -impl Index for F32x2 { - type Output = f32; - #[inline] - fn index(&self, index: usize) -> &f32 { - unsafe { &mem::transmute::<&u64, &[f32; 2]>(&self.0)[index] } - } -} - -impl IndexMut for F32x2 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut f32 { - unsafe { &mut mem::transmute::<&mut u64, &mut [f32; 2]>(&mut self.0)[index] } - } -} - -impl Debug for F32x2 { - #[inline] - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "<{}, {}>", self[0], self[1]) - } -} - -impl PartialEq for F32x2 { - #[inline] - fn eq(&self, other: &F32x2) -> bool { - self.packed_eq(*other).all_true() - } -} - -impl Add for F32x2 { - type Output = F32x2; - #[inline] - fn add(self, other: F32x2) -> F32x2 { - (self.to_f32x4() + other.to_f32x4()).xy() - } -} - -impl Div for F32x2 { - type Output = F32x2; - #[inline] - fn div(self, other: F32x2) -> F32x2 { - (self.to_f32x4() / other.to_f32x4()).xy() - } -} - -impl Mul for F32x2 { - type Output = F32x2; - #[inline] - fn mul(self, other: F32x2) -> F32x2 { - (self.to_f32x4() * other.to_f32x4()).xy() - } -} - -impl Sub for F32x2 { - type Output = F32x2; - #[inline] - fn sub(self, other: F32x2) -> F32x2 { - (self.to_f32x4() - other.to_f32x4()).xy() - } -} - -// Four 32-bit floats - -#[derive(Clone, Copy)] -pub struct F32x4(pub __m128); - -impl F32x4 { - // Constructors - - #[inline] - pub fn new(a: f32, b: f32, c: f32, d: f32) -> F32x4 { - unsafe { - let vector = [a, b, c, d]; - F32x4(x86::_mm_loadu_ps(vector.as_ptr())) - } - } - - #[inline] - pub fn splat(x: f32) -> F32x4 { - unsafe { F32x4(x86::_mm_set1_ps(x)) } - } - - // Basic operations - - #[inline] - pub fn approx_recip(self) -> F32x4 { - unsafe { F32x4(x86::_mm_rcp_ps(self.0)) } - } - - #[inline] - pub fn min(self, other: F32x4) -> F32x4 { - unsafe { F32x4(x86::_mm_min_ps(self.0, other.0)) } - } - - #[inline] - pub fn max(self, other: F32x4) -> F32x4 { - unsafe { F32x4(x86::_mm_max_ps(self.0, other.0)) } - } - - #[inline] - pub fn clamp(self, min: F32x4, max: F32x4) -> F32x4 { - self.max(min).min(max) - } - - #[inline] - pub fn abs(self) -> F32x4 { - unsafe { - let tmp = x86::_mm_srli_epi32(I32x4::splat(-1).0, 1); - F32x4(x86::_mm_and_ps(x86::_mm_castsi128_ps(tmp), self.0)) - } - } - - #[inline] - pub fn floor(self) -> F32x4 { - unsafe { F32x4(x86::_mm_floor_ps(self.0)) } - } - - #[inline] - pub fn ceil(self) -> F32x4 { - unsafe { F32x4(x86::_mm_ceil_ps(self.0)) } - } - - #[inline] - pub fn sqrt(self) -> F32x4 { - unsafe { F32x4(x86::_mm_sqrt_ps(self.0)) } - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: F32x4) -> U32x4 { - unsafe { - U32x4(x86::_mm_castps_si128(x86::_mm_cmpeq_ps( - self.0, other.0, - ))) - } - } - - #[inline] - pub fn packed_gt(self, other: F32x4) -> U32x4 { - unsafe { - U32x4(x86::_mm_castps_si128(x86::_mm_cmpgt_ps( - self.0, other.0, - ))) - } - } - - #[inline] - pub fn packed_lt(self, other: F32x4) -> U32x4 { - other.packed_gt(self) - } - - #[inline] - pub fn packed_le(self, other: F32x4) -> U32x4 { - !self.packed_gt(other) - } - - // Conversions - - /// Converts these packed floats to integers via rounding. - #[inline] - pub fn to_i32x4(self) -> I32x4 { - unsafe { I32x4(x86::_mm_cvtps_epi32(self.0)) } - } - - // Extraction - - #[inline] - pub fn xy(self) -> F32x2 { - unsafe { - let swizzled = self.0; - F32x2(*mem::transmute::<&__m128, &u64>(&swizzled)) - } - } - - #[inline] - pub fn xw(self) -> F32x2 { - self.xwyz().xy() - } - - #[inline] - pub fn yx(self) -> F32x2 { - self.yxwz().xy() - } - - #[inline] - pub fn zy(self) -> F32x2 { - self.zyxw().xy() - } - - #[inline] - pub fn zw(self) -> F32x2 { - self.zwxy().xy() - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: F32x4) -> F32x4 { - unsafe { - let this = x86::_mm_castps_pd(self.0); - let other = x86::_mm_castps_pd(other.0); - let result = x86::_mm_unpacklo_pd(this, other); - F32x4(x86::_mm_castpd_ps(result)) - } - } - - #[inline] - pub fn concat_xy_zw(self, other: F32x4) -> F32x4 { - unsafe { - let this = x86::_mm_castps_pd(self.0); - let other = x86::_mm_castps_pd(other.0); - let result = x86::_mm_shuffle_pd(this, other, 0b10); - F32x4(x86::_mm_castpd_ps(result)) - } - } - - #[inline] - pub fn concat_zw_zw(self, other: F32x4) -> F32x4 { - unsafe { - let this = x86::_mm_castps_pd(self.0); - let other = x86::_mm_castps_pd(other.0); - let result = x86::_mm_unpackhi_pd(this, other); - F32x4(x86::_mm_castpd_ps(result)) - } - } - - #[inline] - pub fn concat_wz_yx(self, other: F32x4) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, other.0, 0b0001_1011)) } - } -} - -impl Default for F32x4 { - #[inline] - fn default() -> F32x4 { - unsafe { F32x4(x86::_mm_setzero_ps()) } - } -} - -impl Index for F32x4 { - type Output = f32; - #[inline] - fn index(&self, index: usize) -> &f32 { - unsafe { &mem::transmute::<&__m128, &[f32; 4]>(&self.0)[index] } - } -} - -impl IndexMut for F32x4 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut f32 { - unsafe { &mut mem::transmute::<&mut __m128, &mut [f32; 4]>(&mut self.0)[index] } - } -} - -impl Debug for F32x4 { - #[inline] - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "<{}, {}, {}, {}>", self[0], self[1], self[2], self[3]) - } -} - -impl PartialEq for F32x4 { - #[inline] - fn eq(&self, other: &F32x4) -> bool { - self.packed_eq(*other).all_true() - } -} - -impl Add for F32x4 { - type Output = F32x4; - #[inline] - fn add(self, other: F32x4) -> F32x4 { - unsafe { F32x4(x86::_mm_add_ps(self.0, other.0)) } - } -} - -impl Div for F32x4 { - type Output = F32x4; - #[inline] - fn div(self, other: F32x4) -> F32x4 { - unsafe { F32x4(x86::_mm_div_ps(self.0, other.0)) } - } -} - -impl Mul for F32x4 { - type Output = F32x4; - #[inline] - fn mul(self, other: F32x4) -> F32x4 { - unsafe { F32x4(x86::_mm_mul_ps(self.0, other.0)) } - } -} - -impl Sub for F32x4 { - type Output = F32x4; - #[inline] - fn sub(self, other: F32x4) -> F32x4 { - unsafe { F32x4(x86::_mm_sub_ps(self.0, other.0)) } - } -} - -// Two 32-bit signed integers - -#[derive(Clone, Copy)] -pub struct I32x2(pub u64); - -impl I32x2 { - // Constructors - - #[inline] - pub fn new(a: i32, b: i32) -> I32x2 { - unsafe { - let a = mem::transmute::<*const i32, *const u32>(&a); - let b = mem::transmute::<*const i32, *const u32>(&b); - I32x2((*a as u64) | ((*b as u64) << 32)) - } - } - - #[inline] - pub fn splat(x: i32) -> I32x2 { - I32x2::new(x, x) - } - - // Accessors - - #[inline] - pub fn x(self) -> i32 { - self[0] - } - - #[inline] - pub fn y(self) -> i32 { - self[1] - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: I32x2) -> I32x4 { - self.to_i32x4().concat_xy_xy(other.to_i32x4()) - } - - // Conversions - - #[inline] - pub fn to_i32x4(self) -> I32x4 { - unsafe { - let mut result = I32x4::default(); - *mem::transmute::<&mut __m128i, &mut u64>(&mut result.0) = self.0; - result - } - } - - #[inline] - pub fn to_f32x4(self) -> F32x4 { - self.to_i32x4().to_f32x4() - } - - /// Converts these packed integers to floats. - #[inline] - pub fn to_f32x2(self) -> F32x2 { - self.to_f32x4().xy() - } - - // Basic operations - - #[inline] - pub fn max(self, other: I32x2) -> I32x2 { - self.to_i32x4().max(other.to_i32x4()).xy() - } - - #[inline] - pub fn min(self, other: I32x2) -> I32x2 { - self.to_i32x4().min(other.to_i32x4()).xy() - } - - // Comparisons - - // TODO(pcwalton): Use the `U32x2` type! - #[inline] - pub fn packed_eq(self, other: I32x2) -> U32x4 { - self.to_i32x4().packed_eq(other.to_i32x4()) - } - - #[inline] - pub fn packed_gt(self, other: I32x2) -> U32x4 { - self.to_i32x4().packed_gt(other.to_i32x4()) - } - - #[inline] - pub fn packed_le(self, other: I32x2) -> U32x4 { - self.to_i32x4().packed_le(other.to_i32x4()) - } -} - -impl Default for I32x2 { - #[inline] - fn default() -> I32x2 { - I32x2(0) - } -} - -impl Index for I32x2 { - type Output = i32; - #[inline] - fn index(&self, index: usize) -> &i32 { - unsafe { &mem::transmute::<&u64, &[i32; 2]>(&self.0)[index] } - } -} - -impl IndexMut for I32x2 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut i32 { - unsafe { &mut mem::transmute::<&mut u64, &mut [i32; 2]>(&mut self.0)[index] } - } -} - -impl Add for I32x2 { - type Output = I32x2; - #[inline] - fn add(self, other: I32x2) -> I32x2 { - (self.to_i32x4() + other.to_i32x4()).xy() - } -} - -impl Sub for I32x2 { - type Output = I32x2; - #[inline] - fn sub(self, other: I32x2) -> I32x2 { - (self.to_i32x4() - other.to_i32x4()).xy() - } -} - -impl Mul for I32x2 { - type Output = I32x2; - #[inline] - fn mul(self, other: I32x2) -> I32x2 { - (self.to_i32x4() * other.to_i32x4()).xy() - } -} - -impl Debug for I32x2 { - #[inline] - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "<{}, {}>", self[0], self[1]) - } -} - -impl PartialEq for I32x2 { - #[inline] - fn eq(&self, other: &I32x2) -> bool { - self.packed_eq(*other).all_true() - } -} - -// Four 32-bit signed integers - -#[derive(Clone, Copy)] -pub struct I32x4(pub __m128i); - -impl I32x4 { - // Constructors - - #[inline] - pub fn new(a: i32, b: i32, c: i32, d: i32) -> I32x4 { - unsafe { - let vector = [a, b, c, d]; - I32x4(x86::_mm_loadu_si128(vector.as_ptr() as *const __m128i)) - } - } - - #[inline] - pub fn splat(x: i32) -> I32x4 { - unsafe { I32x4(x86::_mm_set1_epi32(x)) } - } - - // Extraction - - #[inline] - pub fn xy(self) -> I32x2 { - unsafe { - let swizzled = self.0; - I32x2(*mem::transmute::<&__m128i, &u64>(&swizzled)) - } - } - - #[inline] - pub fn xw(self) -> I32x2 { - self.xwyz().xy() - } - - #[inline] - pub fn yx(self) -> I32x2 { - self.yxwz().xy() - } - - #[inline] - pub fn zy(self) -> I32x2 { - self.zyxw().xy() - } - - #[inline] - pub fn zw(self) -> I32x2 { - self.zwxy().xy() - } - - // Concatenations - - #[inline] - pub fn concat_xy_xy(self, other: I32x4) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_pd(self.0); - let other = x86::_mm_castsi128_pd(other.0); - let result = x86::_mm_unpacklo_pd(this, other); - I32x4(x86::_mm_castpd_si128(result)) - } - } - - #[inline] - pub fn concat_zw_zw(self, other: I32x4) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_pd(self.0); - let other = x86::_mm_castsi128_pd(other.0); - let result = x86::_mm_unpackhi_pd(this, other); - I32x4(x86::_mm_castpd_si128(result)) - } - } - - // Conversions - - /// Converts these packed integers to floats. - #[inline] - pub fn to_f32x4(self) -> F32x4 { - unsafe { F32x4(x86::_mm_cvtepi32_ps(self.0)) } - } - - /// Converts these packed signed integers to unsigned integers. - /// - /// Overflowing values will wrap around. - #[inline] - pub fn to_u32x4(self) -> U32x4 { - U32x4(self.0) - } - - // Basic operations - - #[inline] - pub fn max(self, other: I32x4) -> I32x4 { - unsafe { I32x4(x86::_mm_max_epi32(self.0, other.0)) } - } - - #[inline] - pub fn min(self, other: I32x4) -> I32x4 { - unsafe { I32x4(x86::_mm_min_epi32(self.0, other.0)) } - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: I32x4) -> U32x4 { - unsafe { U32x4(x86::_mm_cmpeq_epi32(self.0, other.0)) } - } - - // Comparisons - - #[inline] - pub fn packed_gt(self, other: I32x4) -> U32x4 { - unsafe { U32x4(x86::_mm_cmpgt_epi32(self.0, other.0)) } - } - - #[inline] - pub fn packed_lt(self, other: I32x4) -> U32x4 { - other.packed_gt(self) - } - - #[inline] - pub fn packed_le(self, other: I32x4) -> U32x4 { - !self.packed_gt(other) - } -} - -impl Default for I32x4 { - #[inline] - fn default() -> I32x4 { - unsafe { I32x4(x86::_mm_setzero_si128()) } - } -} - -impl Index for I32x4 { - type Output = i32; - #[inline] - fn index(&self, index: usize) -> &i32 { - unsafe { &mem::transmute::<&__m128i, &[i32; 4]>(&self.0)[index] } - } -} - -impl IndexMut for I32x4 { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut i32 { - unsafe { &mut mem::transmute::<&mut __m128i, &mut [i32; 4]>(&mut self.0)[index] } - } -} - -impl Add for I32x4 { - type Output = I32x4; - #[inline] - fn add(self, other: I32x4) -> I32x4 { - unsafe { I32x4(x86::_mm_add_epi32(self.0, other.0)) } - } -} - -impl Sub for I32x4 { - type Output = I32x4; - #[inline] - fn sub(self, other: I32x4) -> I32x4 { - unsafe { I32x4(x86::_mm_sub_epi32(self.0, other.0)) } - } -} - -impl Mul for I32x4 { - type Output = I32x4; - #[inline] - fn mul(self, other: I32x4) -> I32x4 { - unsafe { I32x4(x86::_mm_mullo_epi32(self.0, other.0)) } - } -} - -impl BitAnd for I32x4 { - type Output = I32x4; - #[inline] - fn bitand(self, other: I32x4) -> I32x4 { - unsafe { I32x4(x86::_mm_and_si128(self.0, other.0)) } - } -} - -impl BitOr for I32x4 { - type Output = I32x4; - #[inline] - fn bitor(self, other: I32x4) -> I32x4 { - unsafe { I32x4(x86::_mm_or_si128(self.0, other.0)) } - } -} - -impl Debug for I32x4 { - #[inline] - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "<{}, {}, {}, {}>", self[0], self[1], self[2], self[3]) - } -} - -impl PartialEq for I32x4 { - #[inline] - fn eq(&self, other: &I32x4) -> bool { - self.packed_eq(*other).all_true() - } -} - -// Two 32-bit unsigned integers - -#[derive(Clone, Copy)] -pub struct U32x2(pub u64); - -impl U32x2 { - /// Returns true if both booleans in this vector are true. - /// - /// The result is *undefined* if both values in this vector are not booleans. A boolean is a - /// value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_true(self) -> bool { - self.0 == !0 - } - - /// Returns true if both booleans in this vector are false. - /// - /// The result is *undefined* if both values in this vector are not booleans. A boolean is a - /// value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_false(self) -> bool { - self.0 == 0 - } -} - -// Four 32-bit unsigned integers - -#[derive(Clone, Copy)] -pub struct U32x4(pub __m128i); - -impl U32x4 { - // Constructors - - #[inline] - pub fn new(a: u32, b: u32, c: u32, d: u32) -> U32x4 { - unsafe { - let vector = [a, b, c, d]; - U32x4(x86::_mm_loadu_si128(vector.as_ptr() as *const __m128i)) - } - } - - #[inline] - pub fn splat(x: u32) -> U32x4 { - unsafe { U32x4(x86::_mm_set1_epi32(x as i32)) } - } - - // Conversions - - /// Converts these packed unsigned integers to signed integers. - /// - /// Overflowing values will wrap around. - #[inline] - pub fn to_i32x4(self) -> I32x4 { - I32x4(self.0) - } - - // Basic operations - - /// Returns true if all four booleans in this vector are true. - /// - /// The result is *undefined* if all four values in this vector are not booleans. A boolean is - /// a value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_true(self) -> bool { - unsafe { x86::_mm_movemask_ps(x86::_mm_castsi128_ps(self.0)) == 0x0f } - } - - /// Returns true if all four booleans in this vector are false. - /// - /// The result is *undefined* if all four values in this vector are not booleans. A boolean is - /// a value with all bits set or all bits clear (i.e. !0 or 0). - #[inline] - pub fn all_false(self) -> bool { - unsafe { x86::_mm_movemask_ps(x86::_mm_castsi128_ps(self.0)) == 0x00 } - } - - // Extraction - - #[inline] - pub fn xy(self) -> U32x2 { - unsafe { - let swizzled = self.0; - U32x2(*mem::transmute::<&__m128i, &u64>(&swizzled)) - } - } - - // Packed comparisons - - #[inline] - pub fn packed_eq(self, other: U32x4) -> U32x4 { - unsafe { U32x4(x86::_mm_cmpeq_epi32(self.0, other.0)) } - } -} - -impl Debug for U32x4 { - #[inline] - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "<{}, {}, {}, {}>", self[0], self[1], self[2], self[3]) - } -} - -impl Index for U32x4 { - type Output = u32; - #[inline] - fn index(&self, index: usize) -> &u32 { - unsafe { &mem::transmute::<&__m128i, &[u32; 4]>(&self.0)[index] } - } -} - -impl PartialEq for U32x4 { - #[inline] - fn eq(&self, other: &U32x4) -> bool { - self.packed_eq(*other).all_true() - } -} - -impl Not for U32x4 { - type Output = U32x4; - #[inline] - fn not(self) -> U32x4 { - self ^ U32x4::splat(!0) - } -} - -impl BitXor for U32x4 { - type Output = U32x4; - #[inline] - fn bitxor(self, other: U32x4) -> U32x4 { - unsafe { U32x4(x86::_mm_xor_si128(self.0, other.0)) } - } -} - -impl Shr for U32x4 { - type Output = U32x4; - #[inline] - fn shr(self, amount: u32) -> U32x4 { - unsafe { U32x4(x86::_mm_srl_epi32(self.0, U32x4::new(amount, 0, 0, 0).0)) } - } -} diff --git a/crates/pathfinder/simd/src/x86/swizzle_f32x4.rs b/crates/pathfinder/simd/src/x86/swizzle_f32x4.rs deleted file mode 100644 index e6c829c49d..0000000000 --- a/crates/pathfinder/simd/src/x86/swizzle_f32x4.rs +++ /dev/null @@ -1,1298 +0,0 @@ -// pathfinder/simd/src/x86/swizzle_f32x4.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::x86::F32x4; - -#[cfg(target_pointer_width = "32")] -use std::arch::x86; -#[cfg(target_pointer_width = "64")] -use std::arch::x86_64 as x86; - -impl F32x4 { - #[inline] - pub fn xxxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 0)) } - } - - #[inline] - pub fn yxxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 1)) } - } - - #[inline] - pub fn zxxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 2)) } - } - - #[inline] - pub fn wxxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 3)) } - } - - #[inline] - pub fn xyxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 4)) } - } - - #[inline] - pub fn yyxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 5)) } - } - - #[inline] - pub fn zyxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 6)) } - } - - #[inline] - pub fn wyxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 7)) } - } - - #[inline] - pub fn xzxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 8)) } - } - - #[inline] - pub fn yzxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 9)) } - } - - #[inline] - pub fn zzxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 10)) } - } - - #[inline] - pub fn wzxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 11)) } - } - - #[inline] - pub fn xwxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 12)) } - } - - #[inline] - pub fn ywxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 13)) } - } - - #[inline] - pub fn zwxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 14)) } - } - - #[inline] - pub fn wwxx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 15)) } - } - - #[inline] - pub fn xxyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 16)) } - } - - #[inline] - pub fn yxyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 17)) } - } - - #[inline] - pub fn zxyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 18)) } - } - - #[inline] - pub fn wxyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 19)) } - } - - #[inline] - pub fn xyyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 20)) } - } - - #[inline] - pub fn yyyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 21)) } - } - - #[inline] - pub fn zyyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 22)) } - } - - #[inline] - pub fn wyyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 23)) } - } - - #[inline] - pub fn xzyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 24)) } - } - - #[inline] - pub fn yzyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 25)) } - } - - #[inline] - pub fn zzyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 26)) } - } - - #[inline] - pub fn wzyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 27)) } - } - - #[inline] - pub fn xwyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 28)) } - } - - #[inline] - pub fn ywyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 29)) } - } - - #[inline] - pub fn zwyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 30)) } - } - - #[inline] - pub fn wwyx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 31)) } - } - - #[inline] - pub fn xxzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 32)) } - } - - #[inline] - pub fn yxzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 33)) } - } - - #[inline] - pub fn zxzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 34)) } - } - - #[inline] - pub fn wxzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 35)) } - } - - #[inline] - pub fn xyzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 36)) } - } - - #[inline] - pub fn yyzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 37)) } - } - - #[inline] - pub fn zyzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 38)) } - } - - #[inline] - pub fn wyzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 39)) } - } - - #[inline] - pub fn xzzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 40)) } - } - - #[inline] - pub fn yzzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 41)) } - } - - #[inline] - pub fn zzzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 42)) } - } - - #[inline] - pub fn wzzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 43)) } - } - - #[inline] - pub fn xwzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 44)) } - } - - #[inline] - pub fn ywzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 45)) } - } - - #[inline] - pub fn zwzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 46)) } - } - - #[inline] - pub fn wwzx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 47)) } - } - - #[inline] - pub fn xxwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 48)) } - } - - #[inline] - pub fn yxwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 49)) } - } - - #[inline] - pub fn zxwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 50)) } - } - - #[inline] - pub fn wxwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 51)) } - } - - #[inline] - pub fn xywx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 52)) } - } - - #[inline] - pub fn yywx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 53)) } - } - - #[inline] - pub fn zywx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 54)) } - } - - #[inline] - pub fn wywx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 55)) } - } - - #[inline] - pub fn xzwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 56)) } - } - - #[inline] - pub fn yzwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 57)) } - } - - #[inline] - pub fn zzwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 58)) } - } - - #[inline] - pub fn wzwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 59)) } - } - - #[inline] - pub fn xwwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 60)) } - } - - #[inline] - pub fn ywwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 61)) } - } - - #[inline] - pub fn zwwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 62)) } - } - - #[inline] - pub fn wwwx(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 63)) } - } - - #[inline] - pub fn xxxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 64)) } - } - - #[inline] - pub fn yxxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 65)) } - } - - #[inline] - pub fn zxxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 66)) } - } - - #[inline] - pub fn wxxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 67)) } - } - - #[inline] - pub fn xyxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 68)) } - } - - #[inline] - pub fn yyxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 69)) } - } - - #[inline] - pub fn zyxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 70)) } - } - - #[inline] - pub fn wyxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 71)) } - } - - #[inline] - pub fn xzxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 72)) } - } - - #[inline] - pub fn yzxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 73)) } - } - - #[inline] - pub fn zzxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 74)) } - } - - #[inline] - pub fn wzxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 75)) } - } - - #[inline] - pub fn xwxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 76)) } - } - - #[inline] - pub fn ywxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 77)) } - } - - #[inline] - pub fn zwxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 78)) } - } - - #[inline] - pub fn wwxy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 79)) } - } - - #[inline] - pub fn xxyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 80)) } - } - - #[inline] - pub fn yxyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 81)) } - } - - #[inline] - pub fn zxyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 82)) } - } - - #[inline] - pub fn wxyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 83)) } - } - - #[inline] - pub fn xyyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 84)) } - } - - #[inline] - pub fn yyyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 85)) } - } - - #[inline] - pub fn zyyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 86)) } - } - - #[inline] - pub fn wyyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 87)) } - } - - #[inline] - pub fn xzyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 88)) } - } - - #[inline] - pub fn yzyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 89)) } - } - - #[inline] - pub fn zzyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 90)) } - } - - #[inline] - pub fn wzyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 91)) } - } - - #[inline] - pub fn xwyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 92)) } - } - - #[inline] - pub fn ywyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 93)) } - } - - #[inline] - pub fn zwyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 94)) } - } - - #[inline] - pub fn wwyy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 95)) } - } - - #[inline] - pub fn xxzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 96)) } - } - - #[inline] - pub fn yxzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 97)) } - } - - #[inline] - pub fn zxzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 98)) } - } - - #[inline] - pub fn wxzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 99)) } - } - - #[inline] - pub fn xyzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 100)) } - } - - #[inline] - pub fn yyzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 101)) } - } - - #[inline] - pub fn zyzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 102)) } - } - - #[inline] - pub fn wyzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 103)) } - } - - #[inline] - pub fn xzzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 104)) } - } - - #[inline] - pub fn yzzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 105)) } - } - - #[inline] - pub fn zzzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 106)) } - } - - #[inline] - pub fn wzzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 107)) } - } - - #[inline] - pub fn xwzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 108)) } - } - - #[inline] - pub fn ywzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 109)) } - } - - #[inline] - pub fn zwzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 110)) } - } - - #[inline] - pub fn wwzy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 111)) } - } - - #[inline] - pub fn xxwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 112)) } - } - - #[inline] - pub fn yxwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 113)) } - } - - #[inline] - pub fn zxwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 114)) } - } - - #[inline] - pub fn wxwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 115)) } - } - - #[inline] - pub fn xywy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 116)) } - } - - #[inline] - pub fn yywy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 117)) } - } - - #[inline] - pub fn zywy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 118)) } - } - - #[inline] - pub fn wywy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 119)) } - } - - #[inline] - pub fn xzwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 120)) } - } - - #[inline] - pub fn yzwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 121)) } - } - - #[inline] - pub fn zzwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 122)) } - } - - #[inline] - pub fn wzwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 123)) } - } - - #[inline] - pub fn xwwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 124)) } - } - - #[inline] - pub fn ywwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 125)) } - } - - #[inline] - pub fn zwwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 126)) } - } - - #[inline] - pub fn wwwy(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 127)) } - } - - #[inline] - pub fn xxxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 128)) } - } - - #[inline] - pub fn yxxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 129)) } - } - - #[inline] - pub fn zxxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 130)) } - } - - #[inline] - pub fn wxxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 131)) } - } - - #[inline] - pub fn xyxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 132)) } - } - - #[inline] - pub fn yyxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 133)) } - } - - #[inline] - pub fn zyxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 134)) } - } - - #[inline] - pub fn wyxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 135)) } - } - - #[inline] - pub fn xzxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 136)) } - } - - #[inline] - pub fn yzxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 137)) } - } - - #[inline] - pub fn zzxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 138)) } - } - - #[inline] - pub fn wzxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 139)) } - } - - #[inline] - pub fn xwxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 140)) } - } - - #[inline] - pub fn ywxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 141)) } - } - - #[inline] - pub fn zwxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 142)) } - } - - #[inline] - pub fn wwxz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 143)) } - } - - #[inline] - pub fn xxyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 144)) } - } - - #[inline] - pub fn yxyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 145)) } - } - - #[inline] - pub fn zxyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 146)) } - } - - #[inline] - pub fn wxyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 147)) } - } - - #[inline] - pub fn xyyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 148)) } - } - - #[inline] - pub fn yyyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 149)) } - } - - #[inline] - pub fn zyyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 150)) } - } - - #[inline] - pub fn wyyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 151)) } - } - - #[inline] - pub fn xzyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 152)) } - } - - #[inline] - pub fn yzyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 153)) } - } - - #[inline] - pub fn zzyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 154)) } - } - - #[inline] - pub fn wzyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 155)) } - } - - #[inline] - pub fn xwyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 156)) } - } - - #[inline] - pub fn ywyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 157)) } - } - - #[inline] - pub fn zwyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 158)) } - } - - #[inline] - pub fn wwyz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 159)) } - } - - #[inline] - pub fn xxzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 160)) } - } - - #[inline] - pub fn yxzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 161)) } - } - - #[inline] - pub fn zxzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 162)) } - } - - #[inline] - pub fn wxzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 163)) } - } - - #[inline] - pub fn xyzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 164)) } - } - - #[inline] - pub fn yyzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 165)) } - } - - #[inline] - pub fn zyzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 166)) } - } - - #[inline] - pub fn wyzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 167)) } - } - - #[inline] - pub fn xzzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 168)) } - } - - #[inline] - pub fn yzzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 169)) } - } - - #[inline] - pub fn zzzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 170)) } - } - - #[inline] - pub fn wzzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 171)) } - } - - #[inline] - pub fn xwzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 172)) } - } - - #[inline] - pub fn ywzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 173)) } - } - - #[inline] - pub fn zwzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 174)) } - } - - #[inline] - pub fn wwzz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 175)) } - } - - #[inline] - pub fn xxwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 176)) } - } - - #[inline] - pub fn yxwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 177)) } - } - - #[inline] - pub fn zxwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 178)) } - } - - #[inline] - pub fn wxwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 179)) } - } - - #[inline] - pub fn xywz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 180)) } - } - - #[inline] - pub fn yywz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 181)) } - } - - #[inline] - pub fn zywz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 182)) } - } - - #[inline] - pub fn wywz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 183)) } - } - - #[inline] - pub fn xzwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 184)) } - } - - #[inline] - pub fn yzwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 185)) } - } - - #[inline] - pub fn zzwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 186)) } - } - - #[inline] - pub fn wzwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 187)) } - } - - #[inline] - pub fn xwwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 188)) } - } - - #[inline] - pub fn ywwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 189)) } - } - - #[inline] - pub fn zwwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 190)) } - } - - #[inline] - pub fn wwwz(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 191)) } - } - - #[inline] - pub fn xxxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 192)) } - } - - #[inline] - pub fn yxxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 193)) } - } - - #[inline] - pub fn zxxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 194)) } - } - - #[inline] - pub fn wxxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 195)) } - } - - #[inline] - pub fn xyxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 196)) } - } - - #[inline] - pub fn yyxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 197)) } - } - - #[inline] - pub fn zyxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 198)) } - } - - #[inline] - pub fn wyxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 199)) } - } - - #[inline] - pub fn xzxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 200)) } - } - - #[inline] - pub fn yzxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 201)) } - } - - #[inline] - pub fn zzxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 202)) } - } - - #[inline] - pub fn wzxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 203)) } - } - - #[inline] - pub fn xwxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 204)) } - } - - #[inline] - pub fn ywxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 205)) } - } - - #[inline] - pub fn zwxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 206)) } - } - - #[inline] - pub fn wwxw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 207)) } - } - - #[inline] - pub fn xxyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 208)) } - } - - #[inline] - pub fn yxyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 209)) } - } - - #[inline] - pub fn zxyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 210)) } - } - - #[inline] - pub fn wxyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 211)) } - } - - #[inline] - pub fn xyyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 212)) } - } - - #[inline] - pub fn yyyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 213)) } - } - - #[inline] - pub fn zyyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 214)) } - } - - #[inline] - pub fn wyyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 215)) } - } - - #[inline] - pub fn xzyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 216)) } - } - - #[inline] - pub fn yzyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 217)) } - } - - #[inline] - pub fn zzyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 218)) } - } - - #[inline] - pub fn wzyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 219)) } - } - - #[inline] - pub fn xwyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 220)) } - } - - #[inline] - pub fn ywyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 221)) } - } - - #[inline] - pub fn zwyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 222)) } - } - - #[inline] - pub fn wwyw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 223)) } - } - - #[inline] - pub fn xxzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 224)) } - } - - #[inline] - pub fn yxzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 225)) } - } - - #[inline] - pub fn zxzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 226)) } - } - - #[inline] - pub fn wxzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 227)) } - } - - #[inline] - pub fn xyzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 228)) } - } - - #[inline] - pub fn yyzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 229)) } - } - - #[inline] - pub fn zyzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 230)) } - } - - #[inline] - pub fn wyzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 231)) } - } - - #[inline] - pub fn xzzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 232)) } - } - - #[inline] - pub fn yzzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 233)) } - } - - #[inline] - pub fn zzzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 234)) } - } - - #[inline] - pub fn wzzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 235)) } - } - - #[inline] - pub fn xwzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 236)) } - } - - #[inline] - pub fn ywzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 237)) } - } - - #[inline] - pub fn zwzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 238)) } - } - - #[inline] - pub fn wwzw(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 239)) } - } - - #[inline] - pub fn xxww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 240)) } - } - - #[inline] - pub fn yxww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 241)) } - } - - #[inline] - pub fn zxww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 242)) } - } - - #[inline] - pub fn wxww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 243)) } - } - - #[inline] - pub fn xyww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 244)) } - } - - #[inline] - pub fn yyww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 245)) } - } - - #[inline] - pub fn zyww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 246)) } - } - - #[inline] - pub fn wyww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 247)) } - } - - #[inline] - pub fn xzww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 248)) } - } - - #[inline] - pub fn yzww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 249)) } - } - - #[inline] - pub fn zzww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 250)) } - } - - #[inline] - pub fn wzww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 251)) } - } - - #[inline] - pub fn xwww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 252)) } - } - - #[inline] - pub fn ywww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 253)) } - } - - #[inline] - pub fn zwww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 254)) } - } - - #[inline] - pub fn wwww(self) -> F32x4 { - unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 255)) } - } -} diff --git a/crates/pathfinder/simd/src/x86/swizzle_i32x4.rs b/crates/pathfinder/simd/src/x86/swizzle_i32x4.rs deleted file mode 100644 index 0743d2e1ae..0000000000 --- a/crates/pathfinder/simd/src/x86/swizzle_i32x4.rs +++ /dev/null @@ -1,2578 +0,0 @@ -// pathfinder/simd/src/x86/swizzle_i32x4.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::x86::I32x4; - -#[cfg(target_pointer_width = "32")] -use std::arch::x86; -#[cfg(target_pointer_width = "64")] -use std::arch::x86_64 as x86; - -impl I32x4 { - #[inline] - pub fn xxxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 0, - ))) - } - } - - #[inline] - pub fn yxxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 1, - ))) - } - } - - #[inline] - pub fn zxxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 2, - ))) - } - } - - #[inline] - pub fn wxxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 3, - ))) - } - } - - #[inline] - pub fn xyxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 4, - ))) - } - } - - #[inline] - pub fn yyxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 5, - ))) - } - } - - #[inline] - pub fn zyxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 6, - ))) - } - } - - #[inline] - pub fn wyxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 7, - ))) - } - } - - #[inline] - pub fn xzxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 8, - ))) - } - } - - #[inline] - pub fn yzxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 9, - ))) - } - } - - #[inline] - pub fn zzxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 10, - ))) - } - } - - #[inline] - pub fn wzxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 11, - ))) - } - } - - #[inline] - pub fn xwxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 12, - ))) - } - } - - #[inline] - pub fn ywxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 13, - ))) - } - } - - #[inline] - pub fn zwxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 14, - ))) - } - } - - #[inline] - pub fn wwxx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 15, - ))) - } - } - - #[inline] - pub fn xxyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 16, - ))) - } - } - - #[inline] - pub fn yxyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 17, - ))) - } - } - - #[inline] - pub fn zxyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 18, - ))) - } - } - - #[inline] - pub fn wxyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 19, - ))) - } - } - - #[inline] - pub fn xyyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 20, - ))) - } - } - - #[inline] - pub fn yyyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 21, - ))) - } - } - - #[inline] - pub fn zyyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 22, - ))) - } - } - - #[inline] - pub fn wyyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 23, - ))) - } - } - - #[inline] - pub fn xzyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 24, - ))) - } - } - - #[inline] - pub fn yzyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 25, - ))) - } - } - - #[inline] - pub fn zzyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 26, - ))) - } - } - - #[inline] - pub fn wzyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 27, - ))) - } - } - - #[inline] - pub fn xwyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 28, - ))) - } - } - - #[inline] - pub fn ywyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 29, - ))) - } - } - - #[inline] - pub fn zwyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 30, - ))) - } - } - - #[inline] - pub fn wwyx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 31, - ))) - } - } - - #[inline] - pub fn xxzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 32, - ))) - } - } - - #[inline] - pub fn yxzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 33, - ))) - } - } - - #[inline] - pub fn zxzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 34, - ))) - } - } - - #[inline] - pub fn wxzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 35, - ))) - } - } - - #[inline] - pub fn xyzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 36, - ))) - } - } - - #[inline] - pub fn yyzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 37, - ))) - } - } - - #[inline] - pub fn zyzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 38, - ))) - } - } - - #[inline] - pub fn wyzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 39, - ))) - } - } - - #[inline] - pub fn xzzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 40, - ))) - } - } - - #[inline] - pub fn yzzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 41, - ))) - } - } - - #[inline] - pub fn zzzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 42, - ))) - } - } - - #[inline] - pub fn wzzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 43, - ))) - } - } - - #[inline] - pub fn xwzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 44, - ))) - } - } - - #[inline] - pub fn ywzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 45, - ))) - } - } - - #[inline] - pub fn zwzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 46, - ))) - } - } - - #[inline] - pub fn wwzx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 47, - ))) - } - } - - #[inline] - pub fn xxwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 48, - ))) - } - } - - #[inline] - pub fn yxwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 49, - ))) - } - } - - #[inline] - pub fn zxwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 50, - ))) - } - } - - #[inline] - pub fn wxwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 51, - ))) - } - } - - #[inline] - pub fn xywx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 52, - ))) - } - } - - #[inline] - pub fn yywx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 53, - ))) - } - } - - #[inline] - pub fn zywx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 54, - ))) - } - } - - #[inline] - pub fn wywx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 55, - ))) - } - } - - #[inline] - pub fn xzwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 56, - ))) - } - } - - #[inline] - pub fn yzwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 57, - ))) - } - } - - #[inline] - pub fn zzwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 58, - ))) - } - } - - #[inline] - pub fn wzwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 59, - ))) - } - } - - #[inline] - pub fn xwwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 60, - ))) - } - } - - #[inline] - pub fn ywwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 61, - ))) - } - } - - #[inline] - pub fn zwwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 62, - ))) - } - } - - #[inline] - pub fn wwwx(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 63, - ))) - } - } - - #[inline] - pub fn xxxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 64, - ))) - } - } - - #[inline] - pub fn yxxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 65, - ))) - } - } - - #[inline] - pub fn zxxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 66, - ))) - } - } - - #[inline] - pub fn wxxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 67, - ))) - } - } - - #[inline] - pub fn xyxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 68, - ))) - } - } - - #[inline] - pub fn yyxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 69, - ))) - } - } - - #[inline] - pub fn zyxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 70, - ))) - } - } - - #[inline] - pub fn wyxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 71, - ))) - } - } - - #[inline] - pub fn xzxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 72, - ))) - } - } - - #[inline] - pub fn yzxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 73, - ))) - } - } - - #[inline] - pub fn zzxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 74, - ))) - } - } - - #[inline] - pub fn wzxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 75, - ))) - } - } - - #[inline] - pub fn xwxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 76, - ))) - } - } - - #[inline] - pub fn ywxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 77, - ))) - } - } - - #[inline] - pub fn zwxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 78, - ))) - } - } - - #[inline] - pub fn wwxy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 79, - ))) - } - } - - #[inline] - pub fn xxyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 80, - ))) - } - } - - #[inline] - pub fn yxyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 81, - ))) - } - } - - #[inline] - pub fn zxyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 82, - ))) - } - } - - #[inline] - pub fn wxyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 83, - ))) - } - } - - #[inline] - pub fn xyyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 84, - ))) - } - } - - #[inline] - pub fn yyyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 85, - ))) - } - } - - #[inline] - pub fn zyyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 86, - ))) - } - } - - #[inline] - pub fn wyyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 87, - ))) - } - } - - #[inline] - pub fn xzyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 88, - ))) - } - } - - #[inline] - pub fn yzyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 89, - ))) - } - } - - #[inline] - pub fn zzyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 90, - ))) - } - } - - #[inline] - pub fn wzyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 91, - ))) - } - } - - #[inline] - pub fn xwyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 92, - ))) - } - } - - #[inline] - pub fn ywyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 93, - ))) - } - } - - #[inline] - pub fn zwyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 94, - ))) - } - } - - #[inline] - pub fn wwyy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 95, - ))) - } - } - - #[inline] - pub fn xxzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 96, - ))) - } - } - - #[inline] - pub fn yxzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 97, - ))) - } - } - - #[inline] - pub fn zxzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 98, - ))) - } - } - - #[inline] - pub fn wxzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 99, - ))) - } - } - - #[inline] - pub fn xyzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 100, - ))) - } - } - - #[inline] - pub fn yyzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 101, - ))) - } - } - - #[inline] - pub fn zyzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 102, - ))) - } - } - - #[inline] - pub fn wyzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 103, - ))) - } - } - - #[inline] - pub fn xzzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 104, - ))) - } - } - - #[inline] - pub fn yzzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 105, - ))) - } - } - - #[inline] - pub fn zzzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 106, - ))) - } - } - - #[inline] - pub fn wzzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 107, - ))) - } - } - - #[inline] - pub fn xwzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 108, - ))) - } - } - - #[inline] - pub fn ywzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 109, - ))) - } - } - - #[inline] - pub fn zwzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 110, - ))) - } - } - - #[inline] - pub fn wwzy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 111, - ))) - } - } - - #[inline] - pub fn xxwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 112, - ))) - } - } - - #[inline] - pub fn yxwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 113, - ))) - } - } - - #[inline] - pub fn zxwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 114, - ))) - } - } - - #[inline] - pub fn wxwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 115, - ))) - } - } - - #[inline] - pub fn xywy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 116, - ))) - } - } - - #[inline] - pub fn yywy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 117, - ))) - } - } - - #[inline] - pub fn zywy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 118, - ))) - } - } - - #[inline] - pub fn wywy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 119, - ))) - } - } - - #[inline] - pub fn xzwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 120, - ))) - } - } - - #[inline] - pub fn yzwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 121, - ))) - } - } - - #[inline] - pub fn zzwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 122, - ))) - } - } - - #[inline] - pub fn wzwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 123, - ))) - } - } - - #[inline] - pub fn xwwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 124, - ))) - } - } - - #[inline] - pub fn ywwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 125, - ))) - } - } - - #[inline] - pub fn zwwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 126, - ))) - } - } - - #[inline] - pub fn wwwy(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 127, - ))) - } - } - - #[inline] - pub fn xxxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 128, - ))) - } - } - - #[inline] - pub fn yxxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 129, - ))) - } - } - - #[inline] - pub fn zxxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 130, - ))) - } - } - - #[inline] - pub fn wxxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 131, - ))) - } - } - - #[inline] - pub fn xyxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 132, - ))) - } - } - - #[inline] - pub fn yyxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 133, - ))) - } - } - - #[inline] - pub fn zyxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 134, - ))) - } - } - - #[inline] - pub fn wyxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 135, - ))) - } - } - - #[inline] - pub fn xzxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 136, - ))) - } - } - - #[inline] - pub fn yzxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 137, - ))) - } - } - - #[inline] - pub fn zzxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 138, - ))) - } - } - - #[inline] - pub fn wzxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 139, - ))) - } - } - - #[inline] - pub fn xwxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 140, - ))) - } - } - - #[inline] - pub fn ywxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 141, - ))) - } - } - - #[inline] - pub fn zwxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 142, - ))) - } - } - - #[inline] - pub fn wwxz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 143, - ))) - } - } - - #[inline] - pub fn xxyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 144, - ))) - } - } - - #[inline] - pub fn yxyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 145, - ))) - } - } - - #[inline] - pub fn zxyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 146, - ))) - } - } - - #[inline] - pub fn wxyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 147, - ))) - } - } - - #[inline] - pub fn xyyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 148, - ))) - } - } - - #[inline] - pub fn yyyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 149, - ))) - } - } - - #[inline] - pub fn zyyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 150, - ))) - } - } - - #[inline] - pub fn wyyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 151, - ))) - } - } - - #[inline] - pub fn xzyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 152, - ))) - } - } - - #[inline] - pub fn yzyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 153, - ))) - } - } - - #[inline] - pub fn zzyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 154, - ))) - } - } - - #[inline] - pub fn wzyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 155, - ))) - } - } - - #[inline] - pub fn xwyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 156, - ))) - } - } - - #[inline] - pub fn ywyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 157, - ))) - } - } - - #[inline] - pub fn zwyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 158, - ))) - } - } - - #[inline] - pub fn wwyz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 159, - ))) - } - } - - #[inline] - pub fn xxzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 160, - ))) - } - } - - #[inline] - pub fn yxzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 161, - ))) - } - } - - #[inline] - pub fn zxzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 162, - ))) - } - } - - #[inline] - pub fn wxzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 163, - ))) - } - } - - #[inline] - pub fn xyzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 164, - ))) - } - } - - #[inline] - pub fn yyzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 165, - ))) - } - } - - #[inline] - pub fn zyzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 166, - ))) - } - } - - #[inline] - pub fn wyzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 167, - ))) - } - } - - #[inline] - pub fn xzzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 168, - ))) - } - } - - #[inline] - pub fn yzzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 169, - ))) - } - } - - #[inline] - pub fn zzzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 170, - ))) - } - } - - #[inline] - pub fn wzzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 171, - ))) - } - } - - #[inline] - pub fn xwzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 172, - ))) - } - } - - #[inline] - pub fn ywzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 173, - ))) - } - } - - #[inline] - pub fn zwzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 174, - ))) - } - } - - #[inline] - pub fn wwzz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 175, - ))) - } - } - - #[inline] - pub fn xxwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 176, - ))) - } - } - - #[inline] - pub fn yxwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 177, - ))) - } - } - - #[inline] - pub fn zxwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 178, - ))) - } - } - - #[inline] - pub fn wxwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 179, - ))) - } - } - - #[inline] - pub fn xywz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 180, - ))) - } - } - - #[inline] - pub fn yywz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 181, - ))) - } - } - - #[inline] - pub fn zywz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 182, - ))) - } - } - - #[inline] - pub fn wywz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 183, - ))) - } - } - - #[inline] - pub fn xzwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 184, - ))) - } - } - - #[inline] - pub fn yzwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 185, - ))) - } - } - - #[inline] - pub fn zzwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 186, - ))) - } - } - - #[inline] - pub fn wzwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 187, - ))) - } - } - - #[inline] - pub fn xwwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 188, - ))) - } - } - - #[inline] - pub fn ywwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 189, - ))) - } - } - - #[inline] - pub fn zwwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 190, - ))) - } - } - - #[inline] - pub fn wwwz(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 191, - ))) - } - } - - #[inline] - pub fn xxxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 192, - ))) - } - } - - #[inline] - pub fn yxxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 193, - ))) - } - } - - #[inline] - pub fn zxxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 194, - ))) - } - } - - #[inline] - pub fn wxxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 195, - ))) - } - } - - #[inline] - pub fn xyxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 196, - ))) - } - } - - #[inline] - pub fn yyxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 197, - ))) - } - } - - #[inline] - pub fn zyxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 198, - ))) - } - } - - #[inline] - pub fn wyxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 199, - ))) - } - } - - #[inline] - pub fn xzxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 200, - ))) - } - } - - #[inline] - pub fn yzxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 201, - ))) - } - } - - #[inline] - pub fn zzxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 202, - ))) - } - } - - #[inline] - pub fn wzxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 203, - ))) - } - } - - #[inline] - pub fn xwxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 204, - ))) - } - } - - #[inline] - pub fn ywxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 205, - ))) - } - } - - #[inline] - pub fn zwxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 206, - ))) - } - } - - #[inline] - pub fn wwxw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 207, - ))) - } - } - - #[inline] - pub fn xxyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 208, - ))) - } - } - - #[inline] - pub fn yxyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 209, - ))) - } - } - - #[inline] - pub fn zxyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 210, - ))) - } - } - - #[inline] - pub fn wxyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 211, - ))) - } - } - - #[inline] - pub fn xyyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 212, - ))) - } - } - - #[inline] - pub fn yyyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 213, - ))) - } - } - - #[inline] - pub fn zyyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 214, - ))) - } - } - - #[inline] - pub fn wyyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 215, - ))) - } - } - - #[inline] - pub fn xzyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 216, - ))) - } - } - - #[inline] - pub fn yzyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 217, - ))) - } - } - - #[inline] - pub fn zzyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 218, - ))) - } - } - - #[inline] - pub fn wzyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 219, - ))) - } - } - - #[inline] - pub fn xwyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 220, - ))) - } - } - - #[inline] - pub fn ywyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 221, - ))) - } - } - - #[inline] - pub fn zwyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 222, - ))) - } - } - - #[inline] - pub fn wwyw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 223, - ))) - } - } - - #[inline] - pub fn xxzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 224, - ))) - } - } - - #[inline] - pub fn yxzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 225, - ))) - } - } - - #[inline] - pub fn zxzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 226, - ))) - } - } - - #[inline] - pub fn wxzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 227, - ))) - } - } - - #[inline] - pub fn xyzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 228, - ))) - } - } - - #[inline] - pub fn yyzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 229, - ))) - } - } - - #[inline] - pub fn zyzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 230, - ))) - } - } - - #[inline] - pub fn wyzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 231, - ))) - } - } - - #[inline] - pub fn xzzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 232, - ))) - } - } - - #[inline] - pub fn yzzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 233, - ))) - } - } - - #[inline] - pub fn zzzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 234, - ))) - } - } - - #[inline] - pub fn wzzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 235, - ))) - } - } - - #[inline] - pub fn xwzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 236, - ))) - } - } - - #[inline] - pub fn ywzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 237, - ))) - } - } - - #[inline] - pub fn zwzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 238, - ))) - } - } - - #[inline] - pub fn wwzw(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 239, - ))) - } - } - - #[inline] - pub fn xxww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 240, - ))) - } - } - - #[inline] - pub fn yxww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 241, - ))) - } - } - - #[inline] - pub fn zxww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 242, - ))) - } - } - - #[inline] - pub fn wxww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 243, - ))) - } - } - - #[inline] - pub fn xyww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 244, - ))) - } - } - - #[inline] - pub fn yyww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 245, - ))) - } - } - - #[inline] - pub fn zyww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 246, - ))) - } - } - - #[inline] - pub fn wyww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 247, - ))) - } - } - - #[inline] - pub fn xzww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 248, - ))) - } - } - - #[inline] - pub fn yzww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 249, - ))) - } - } - - #[inline] - pub fn zzww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 250, - ))) - } - } - - #[inline] - pub fn wzww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 251, - ))) - } - } - - #[inline] - pub fn xwww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 252, - ))) - } - } - - #[inline] - pub fn ywww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 253, - ))) - } - } - - #[inline] - pub fn zwww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 254, - ))) - } - } - - #[inline] - pub fn wwww(self) -> I32x4 { - unsafe { - let this = x86::_mm_castsi128_ps(self.0); - I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps( - this, this, 255, - ))) - } - } -} diff --git a/crates/pathfinder/site/assets/fonts/D-DIN-Bold.woff2 b/crates/pathfinder/site/assets/fonts/D-DIN-Bold.woff2 deleted file mode 100644 index a49aef3d85..0000000000 Binary files a/crates/pathfinder/site/assets/fonts/D-DIN-Bold.woff2 and /dev/null differ diff --git a/crates/pathfinder/site/assets/fonts/D-DIN-Italic.woff2 b/crates/pathfinder/site/assets/fonts/D-DIN-Italic.woff2 deleted file mode 100644 index be6b460011..0000000000 Binary files a/crates/pathfinder/site/assets/fonts/D-DIN-Italic.woff2 and /dev/null differ diff --git a/crates/pathfinder/site/assets/fonts/D-DIN.woff2 b/crates/pathfinder/site/assets/fonts/D-DIN.woff2 deleted file mode 100644 index e7c87be6fc..0000000000 Binary files a/crates/pathfinder/site/assets/fonts/D-DIN.woff2 and /dev/null differ diff --git a/crates/pathfinder/site/assets/fonts/SIL Open Font License.txt b/crates/pathfinder/site/assets/fonts/SIL Open Font License.txt deleted file mode 100644 index 5edcc5e8e0..0000000000 --- a/crates/pathfinder/site/assets/fonts/SIL Open Font License.txt +++ /dev/null @@ -1,51 +0,0 @@ -Copyright (C) 2017 Datto Inc. https://www.datto.com/fonts/d-din, -with Reserved Font Names "D-DIN". - -Copyright (C) 2017 Datto Inc. https://www.datto.com/fonts/d-din, -with Reserved Font Names "D-DIN Condensed". - -Copyright (C) 2017 Datto Inc. https://www.datto.com/fonts/d-din, -with Reserved Font Names "D-DIN Expanded". - - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. - -The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the copyright statement(s). - -"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. - -"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. - -5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/crates/pathfinder/site/assets/svg/pathfinder_logo_bw.svg b/crates/pathfinder/site/assets/svg/pathfinder_logo_bw.svg deleted file mode 100644 index b6f61af14c..0000000000 --- a/crates/pathfinder/site/assets/svg/pathfinder_logo_bw.svg +++ /dev/null @@ -1,192 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/crates/pathfinder/site/index.html b/crates/pathfinder/site/index.html deleted file mode 100644 index d5b19643cc..0000000000 --- a/crates/pathfinder/site/index.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - Pathfinder 3 - - - - - -
-
-

Pathfinder 3

-

Fast GPU text and vector graphics rendering for your OpenGL app.

-
-
-
-

Built on Rust

-
- Pathfinder is written in Rust, with only the minimum unsafe code necessary to - use SIMD and render with OpenGL. You can use it to render untrusted content - without worrying about security problems or segfaults. -
-
-
-

Works everywhere

-
- Pathfinder runs on any desktop or mobile GPU supporting OpenGL or OpenGL ES 3.0 - (roughly, any GPU manufactured after 2002). There's no need for fancy features - like compute, geometry shaders, and tessellation shaders. -
-
-
-

Easy to use

-
- Thanks to the inclusion of the resvg library, a subset of SVG is supported - out-of-the-box. Rendering SVG content to the screen is just a few lines of - code. -
-
-
-
- Pathfinder is an open-source Mozilla Research project under the Servo umbrella. - It's also a component of WebRender, the new Web renderer for Firefox. We welcome - contributions from anyone. -
-
- - diff --git a/crates/pathfinder/site/package.json b/crates/pathfinder/site/package.json deleted file mode 100644 index d6c75d9ad4..0000000000 --- a/crates/pathfinder/site/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "bootstrap": "^4.3.1" - } -} diff --git a/crates/pathfinder/svg/Cargo.toml b/crates/pathfinder/svg/Cargo.toml deleted file mode 100644 index 1842c81dd0..0000000000 --- a/crates/pathfinder/svg/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "pathfinder_svg" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -description = "A GPU-accelerated SVG renderer" -license = "MIT/Apache-2.0" -repository = "https://github.com/servo/pathfinder" -homepage = "https://github.com/servo/pathfinder" -keywords = ["pathfinder", "svg", "vector", "graphics", "gpu"] - -[dependencies] -bitflags = "1.0" -hashbrown = "0.7" -usvg = "0.9" - -[dependencies.pathfinder_color] -path = "../color" -version = "0.5" - -[dependencies.pathfinder_content] -path = "../content" -version = "0.5" - -[dependencies.pathfinder_geometry] -path = "../geometry" -version = "0.5" - -[dependencies.pathfinder_renderer] -path = "../renderer" -version = "0.5" - -[dependencies.pathfinder_simd] -path = "../simd" -version = "0.5" diff --git a/crates/pathfinder/svg/src/lib.rs b/crates/pathfinder/svg/src/lib.rs deleted file mode 100644 index 7f7de16362..0000000000 --- a/crates/pathfinder/svg/src/lib.rs +++ /dev/null @@ -1,557 +0,0 @@ -// pathfinder/svg/src/lib.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Converts a subset of SVG to a Pathfinder scene. - -#[macro_use] -extern crate bitflags; - -use hashbrown::HashMap; -use pathfinder_color::ColorU; -use pathfinder_content::dash::OutlineDash; -use pathfinder_content::fill::FillRule; -use pathfinder_content::gradient::{ColorStop, Gradient}; -use pathfinder_content::outline::Outline; -use pathfinder_content::segment::{Segment, SegmentFlags}; -use pathfinder_content::stroke::{LineCap, LineJoin, OutlineStrokeToFill, StrokeStyle}; -use pathfinder_content::transform::Transform2FPathIter; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::rect::RectF; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::vector::{Vector2F, vec2f}; -use pathfinder_renderer::paint::Paint; -use pathfinder_renderer::scene::{ClipPath, ClipPathId, DrawPath, Scene}; -use pathfinder_simd::default::F32x2; -use std::fmt::{Display, Formatter, Result as FormatResult}; -use usvg::{BaseGradient, Color as SvgColor, FillRule as UsvgFillRule, LineCap as UsvgLineCap}; -use usvg::{LineJoin as UsvgLineJoin, Node, NodeExt, NodeKind, Opacity, Paint as UsvgPaint}; -use usvg::{PathSegment as UsvgPathSegment, Rect as UsvgRect, SpreadMethod, Stop}; -use usvg::{Transform as UsvgTransform, Tree, Visibility}; - -const HAIRLINE_STROKE_WIDTH: f32 = 0.0333; - -pub struct BuiltSVG { - pub scene: Scene, - pub result_flags: BuildResultFlags, - pub clip_paths: HashMap, - gradients: HashMap, -} - -bitflags! { - // NB: If you change this, make sure to update the `Display` - // implementation as well. - pub struct BuildResultFlags: u16 { - const UNSUPPORTED_FILTER_NODE = 0x0001; - const UNSUPPORTED_IMAGE_NODE = 0x0002; - const UNSUPPORTED_MASK_NODE = 0x0004; - const UNSUPPORTED_PATTERN_NODE = 0x0008; - const UNSUPPORTED_NESTED_SVG_NODE = 0x0010; - const UNSUPPORTED_MULTIPLE_CLIP_PATHS = 0x0020; - const UNSUPPORTED_LINK_PAINT = 0x0040; - const UNSUPPORTED_FILTER_ATTR = 0x0080; - const UNSUPPORTED_MASK_ATTR = 0x0100; - const UNSUPPORTED_GRADIENT_SPREAD_METHOD = 0x0200; - } -} - -impl BuiltSVG { - // TODO(pcwalton): Allow a global transform to be set. - #[inline] - pub fn from_tree(tree: &Tree) -> BuiltSVG { - BuiltSVG::from_tree_and_scene(tree, Scene::new()) - } - - // TODO(pcwalton): Allow a global transform to be set. - pub fn from_tree_and_scene(tree: &Tree, scene: Scene) -> BuiltSVG { - // TODO(pcwalton): Maybe have a `SVGBuilder` type to hold the clip path IDs and other - // transient data separate from `BuiltSVG`? - let mut built_svg = BuiltSVG { - scene, - result_flags: BuildResultFlags::empty(), - clip_paths: HashMap::new(), - gradients: HashMap::new(), - }; - - let root = &tree.root(); - match *root.borrow() { - NodeKind::Svg(ref svg) => { - built_svg.scene.set_view_box(usvg_rect_to_euclid_rect(&svg.view_box.rect)); - for kid in root.children() { - built_svg.process_node(&kid, &State::new(), &mut None); - } - } - _ => unreachable!(), - } - - built_svg - } - - fn process_node(&mut self, - node: &Node, - state: &State, - clip_outline: &mut Option) { - let mut state = (*state).clone(); - let node_transform = usvg_transform_to_transform_2d(&node.transform()); - state.transform = node_transform * state.transform; - - match *node.borrow() { - NodeKind::Group(ref group) => { - if group.filter.is_some() { - self.result_flags.insert(BuildResultFlags::UNSUPPORTED_FILTER_ATTR); - } - if group.mask.is_some() { - self.result_flags.insert(BuildResultFlags::UNSUPPORTED_MASK_ATTR); - } - - if let Some(ref clip_path_name) = group.clip_path { - if let Some(clip_path_id) = self.clip_paths.get(clip_path_name) { - // TODO(pcwalton): Combine multiple clip paths if there's already one. - if state.clip_path.is_some() { - self.result_flags - .insert(BuildResultFlags::UNSUPPORTED_MULTIPLE_CLIP_PATHS); - } - state.clip_path = Some(*clip_path_id); - } - } - - for kid in node.children() { - self.process_node(&kid, &state, clip_outline) - } - } - NodeKind::Path(ref path) if state.path_destination == PathDestination::Clip => { - // TODO(pcwalton): Multiple clip paths. - let path = UsvgPathToSegments::new(path.data.iter().cloned()); - let path = Transform2FPathIter::new(path, &state.transform); - if clip_outline.is_some() { - self.result_flags.insert(BuildResultFlags::UNSUPPORTED_MULTIPLE_CLIP_PATHS); - } - *clip_outline = Some(Outline::from_segments(path)); - } - NodeKind::Path(ref path) if state.path_destination == PathDestination::Draw && - path.visibility == Visibility::Visible => { - if let Some(ref fill) = path.fill { - let path = UsvgPathToSegments::new(path.data.iter().cloned()); - let outline = Outline::from_segments(path); - - let name = format!("Fill({})", node.id()); - self.push_draw_path(outline, - name, - &state, - &fill.paint, - fill.opacity, - fill.rule); - } - - if let Some(ref stroke) = path.stroke { - let stroke_style = StrokeStyle { - line_width: f32::max(stroke.width.value() as f32, HAIRLINE_STROKE_WIDTH), - line_cap: LineCap::from_usvg_line_cap(stroke.linecap), - line_join: LineJoin::from_usvg_line_join(stroke.linejoin, - stroke.miterlimit.value() as f32), - }; - - let path = UsvgPathToSegments::new(path.data.iter().cloned()); - let mut outline = Outline::from_segments(path); - - if let Some(ref dash_array) = stroke.dasharray { - let dash_array: Vec = dash_array.iter().map(|&x| x as f32).collect(); - let mut dash = OutlineDash::new(&outline, &dash_array, stroke.dashoffset); - dash.dash(); - outline = dash.into_outline(); - } - - let mut stroke_to_fill = OutlineStrokeToFill::new(&outline, stroke_style); - stroke_to_fill.offset(); - let outline = stroke_to_fill.into_outline(); - - let name = format!("Stroke({})", node.id()); - self.push_draw_path(outline, - name, - &state, - &stroke.paint, - stroke.opacity, - UsvgFillRule::NonZero); - } - } - NodeKind::Path(..) => {} - NodeKind::ClipPath(_) => { - let mut clip_outline = None; - state.path_destination = PathDestination::Clip; - for kid in node.children() { - self.process_node(&kid, &state, &mut clip_outline); - } - - if let Some(clip_outline) = clip_outline { - // FIXME(pcwalton): Is the winding fill rule correct to use? - let mut clip_path = ClipPath::new(clip_outline); - clip_path.set_name(format!("ClipPath({})", node.id())); - let clip_path_id = self.scene.push_clip_path(clip_path); - self.clip_paths.insert(node.id().to_owned(), clip_path_id); - } - } - NodeKind::Defs => { - // FIXME(pcwalton): This is wrong. - state.path_destination = PathDestination::Defs; - for kid in node.children() { - self.process_node(&kid, &state, clip_outline); - } - } - NodeKind::LinearGradient(ref svg_linear_gradient) => { - let from = vec2f(svg_linear_gradient.x1 as f32, svg_linear_gradient.y1 as f32); - let to = vec2f(svg_linear_gradient.x2 as f32, svg_linear_gradient.y2 as f32); - let gradient = Gradient::linear_from_points(from, to); - self.add_gradient(gradient, - svg_linear_gradient.id.clone(), - &svg_linear_gradient.base) - } - NodeKind::RadialGradient(ref svg_radial_gradient) => { - let from = vec2f(svg_radial_gradient.fx as f32, svg_radial_gradient.fy as f32); - let to = vec2f(svg_radial_gradient.cx as f32, svg_radial_gradient.cy as f32); - let radii = F32x2::new(0.0, svg_radial_gradient.r.value() as f32); - let gradient = Gradient::radial(LineSegment2F::new(from, to), radii); - self.add_gradient(gradient, - svg_radial_gradient.id.clone(), - &svg_radial_gradient.base) - } - NodeKind::Filter(..) => { - self.result_flags - .insert(BuildResultFlags::UNSUPPORTED_FILTER_NODE); - } - NodeKind::Image(..) => { - self.result_flags - .insert(BuildResultFlags::UNSUPPORTED_IMAGE_NODE); - } - NodeKind::Mask(..) => { - self.result_flags - .insert(BuildResultFlags::UNSUPPORTED_MASK_NODE); - } - NodeKind::Pattern(..) => { - self.result_flags - .insert(BuildResultFlags::UNSUPPORTED_PATTERN_NODE); - } - NodeKind::Svg(..) => { - self.result_flags - .insert(BuildResultFlags::UNSUPPORTED_NESTED_SVG_NODE); - } - } - } - - fn add_gradient(&mut self, - mut gradient: Gradient, - id: String, - usvg_base_gradient: &BaseGradient) { - for stop in &usvg_base_gradient.stops { - gradient.add(ColorStop::from_usvg_stop(stop)); - } - - if usvg_base_gradient.spread_method != SpreadMethod::Pad { - self.result_flags.insert(BuildResultFlags::UNSUPPORTED_GRADIENT_SPREAD_METHOD); - } - - let transform = usvg_transform_to_transform_2d(&usvg_base_gradient.transform); - - // TODO(pcwalton): What should we do with `gradientUnits`? - self.gradients.insert(id, GradientInfo { gradient, transform }); - } - - fn push_draw_path(&mut self, - mut outline: Outline, - name: String, - state: &State, - paint: &UsvgPaint, - opacity: Opacity, - fill_rule: UsvgFillRule) { - outline.transform(&state.transform); - let paint = Paint::from_svg_paint(paint, - &state.transform, - opacity, - &self.gradients, - &mut self.result_flags); - let style = self.scene.push_paint(&paint); - let fill_rule = FillRule::from_usvg_fill_rule(fill_rule); - let mut path = DrawPath::new(outline, style); - path.set_clip_path(state.clip_path); - path.set_fill_rule(fill_rule); - path.set_name(name); - self.scene.push_path(path); - } -} - -impl Display for BuildResultFlags { - fn fmt(&self, formatter: &mut Formatter) -> FormatResult { - if self.is_empty() { - return Ok(()); - } - - let mut first = true; - for (bit, name) in NAMES.iter().enumerate() { - if (self.bits() >> bit) & 1 == 0 { - continue; - } - if !first { - formatter.write_str(", ")?; - } else { - first = false; - } - formatter.write_str(name)?; - } - - return Ok(()); - - // Must match the order in `BuildResultFlags`. - static NAMES: &'static [&'static str] = &[ - "", - "", - "", - "", - "nested ", - "multiple clip paths", - "non-color paint", - "filter attribute", - "mask attribute", - "gradient spread method", - ]; - } -} - -trait PaintExt { - fn from_svg_paint(svg_paint: &UsvgPaint, - transform: &Transform2F, - opacity: Opacity, - gradients: &HashMap, - result_flags: &mut BuildResultFlags) - -> Self; -} - -impl PaintExt for Paint { - #[inline] - fn from_svg_paint(svg_paint: &UsvgPaint, - transform: &Transform2F, - opacity: Opacity, - gradients: &HashMap, - result_flags: &mut BuildResultFlags) - -> Paint { - let mut paint; - match *svg_paint { - UsvgPaint::Color(color) => paint = Paint::from_color(ColorU::from_svg_color(color)), - UsvgPaint::Link(ref id) => { - match gradients.get(id) { - Some(ref gradient_info) => { - paint = Paint::from_gradient(gradient_info.gradient.clone()); - paint.apply_transform(&(*transform * gradient_info.transform)); - } - None => { - // TODO(pcwalton) - result_flags.insert(BuildResultFlags::UNSUPPORTED_LINK_PAINT); - paint = Paint::from_color(ColorU::black()); - } - } - } - } - - let mut base_color = paint.base_color().to_f32(); - base_color.set_a(base_color.a() * opacity.value() as f32); - paint.set_base_color(base_color.to_u8()); - - paint - } -} - -fn usvg_rect_to_euclid_rect(rect: &UsvgRect) -> RectF { - RectF::new(vec2f(rect.x() as f32, rect.y() as f32), - vec2f(rect.width() as f32, rect.height() as f32)) -} - -fn usvg_transform_to_transform_2d(transform: &UsvgTransform) -> Transform2F { - Transform2F::row_major(transform.a as f32, transform.c as f32, transform.e as f32, - transform.b as f32, transform.d as f32, transform.f as f32) -} - -struct UsvgPathToSegments -where - I: Iterator, -{ - iter: I, - first_subpath_point: Vector2F, - last_subpath_point: Vector2F, - just_moved: bool, -} - -impl UsvgPathToSegments -where - I: Iterator, -{ - fn new(iter: I) -> UsvgPathToSegments { - UsvgPathToSegments { - iter, - first_subpath_point: Vector2F::zero(), - last_subpath_point: Vector2F::zero(), - just_moved: false, - } - } -} - -impl Iterator for UsvgPathToSegments -where - I: Iterator, -{ - type Item = Segment; - - fn next(&mut self) -> Option { - match self.iter.next()? { - UsvgPathSegment::MoveTo { x, y } => { - let to = vec2f(x as f32, y as f32); - self.first_subpath_point = to; - self.last_subpath_point = to; - self.just_moved = true; - self.next() - } - UsvgPathSegment::LineTo { x, y } => { - let to = vec2f(x as f32, y as f32); - let mut segment = Segment::line(LineSegment2F::new(self.last_subpath_point, to)); - if self.just_moved { - segment.flags.insert(SegmentFlags::FIRST_IN_SUBPATH); - } - self.last_subpath_point = to; - self.just_moved = false; - Some(segment) - } - UsvgPathSegment::CurveTo { - x1, - y1, - x2, - y2, - x, - y, - } => { - let ctrl0 = vec2f(x1 as f32, y1 as f32); - let ctrl1 = vec2f(x2 as f32, y2 as f32); - let to = vec2f(x as f32, y as f32); - let mut segment = Segment::cubic(LineSegment2F::new(self.last_subpath_point, to), - LineSegment2F::new(ctrl0, ctrl1)); - if self.just_moved { - segment.flags.insert(SegmentFlags::FIRST_IN_SUBPATH); - } - self.last_subpath_point = to; - self.just_moved = false; - Some(segment) - } - UsvgPathSegment::ClosePath => { - let mut segment = Segment::line(LineSegment2F::new( - self.last_subpath_point, - self.first_subpath_point, - )); - segment.flags.insert(SegmentFlags::CLOSES_SUBPATH); - self.just_moved = false; - self.last_subpath_point = self.first_subpath_point; - Some(segment) - } - } - } -} - -trait ColorUExt { - fn from_svg_color(svg_color: SvgColor) -> Self; -} - -impl ColorUExt for ColorU { - #[inline] - fn from_svg_color(svg_color: SvgColor) -> ColorU { - ColorU { r: svg_color.red, g: svg_color.green, b: svg_color.blue, a: !0 } - } -} - -trait LineCapExt { - fn from_usvg_line_cap(usvg_line_cap: UsvgLineCap) -> Self; -} - -impl LineCapExt for LineCap { - #[inline] - fn from_usvg_line_cap(usvg_line_cap: UsvgLineCap) -> LineCap { - match usvg_line_cap { - UsvgLineCap::Butt => LineCap::Butt, - UsvgLineCap::Round => LineCap::Round, - UsvgLineCap::Square => LineCap::Square, - } - } -} - -trait LineJoinExt { - fn from_usvg_line_join(usvg_line_join: UsvgLineJoin, miter_limit: f32) -> Self; -} - -impl LineJoinExt for LineJoin { - #[inline] - fn from_usvg_line_join(usvg_line_join: UsvgLineJoin, miter_limit: f32) -> LineJoin { - match usvg_line_join { - UsvgLineJoin::Miter => LineJoin::Miter(miter_limit), - UsvgLineJoin::Round => LineJoin::Round, - UsvgLineJoin::Bevel => LineJoin::Bevel, - } - } -} - -trait FillRuleExt { - fn from_usvg_fill_rule(usvg_fill_rule: UsvgFillRule) -> Self; -} - -impl FillRuleExt for FillRule { - #[inline] - fn from_usvg_fill_rule(usvg_fill_rule: UsvgFillRule) -> FillRule { - match usvg_fill_rule { - UsvgFillRule::NonZero => FillRule::Winding, - UsvgFillRule::EvenOdd => FillRule::EvenOdd, - } - } -} - -trait ColorStopExt { - fn from_usvg_stop(usvg_stop: &Stop) -> Self; -} - -impl ColorStopExt for ColorStop { - fn from_usvg_stop(usvg_stop: &Stop) -> ColorStop { - let mut color = ColorU::from_svg_color(usvg_stop.color); - color.a = (usvg_stop.opacity.value() * 255.0) as u8; - ColorStop::new(color, usvg_stop.offset.value() as f32) - } -} - -#[derive(Clone)] -struct State { - // Where paths are being appended to. - path_destination: PathDestination, - // The current transform. - transform: Transform2F, - // The current clip path in effect. - clip_path: Option, -} - -impl State { - fn new() -> State { - State { - path_destination: PathDestination::Draw, - transform: Transform2F::default(), - clip_path: None, - } - } -} - -#[derive(Clone, Copy, PartialEq, Debug)] -enum PathDestination { - Draw, - Defs, - Clip, -} - -struct GradientInfo { - gradient: Gradient, - transform: Transform2F, -} diff --git a/crates/pathfinder/swf/Cargo.toml b/crates/pathfinder/swf/Cargo.toml deleted file mode 100644 index b079a8e3df..0000000000 --- a/crates/pathfinder/swf/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "pathfinder_swf" -version = "0.1.0" -authors = ["Jon Hardie "] -edition = "2018" - -[dependencies] -swf-parser = "0.10" -swf-types = "0.10" - -[dependencies.pathfinder_color] -path = "../color" - -[dependencies.pathfinder_content] -path = "../content" - -[dependencies.pathfinder_geometry] -path = "../geometry" - -[dependencies.pathfinder_renderer] -path = "../renderer" - -[dependencies.pathfinder_gl] -path = "../gl" - -[dependencies.pathfinder_gpu] -path = "../gpu" diff --git a/crates/pathfinder/swf/src/lib.rs b/crates/pathfinder/swf/src/lib.rs deleted file mode 100644 index 911181fc15..0000000000 --- a/crates/pathfinder/swf/src/lib.rs +++ /dev/null @@ -1,201 +0,0 @@ -// pathfinder/swf/src/lib.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::ops::Add; -use pathfinder_color::{ColorF, ColorU}; -use pathfinder_content::fill::FillRule; -use pathfinder_content::outline::{Outline, Contour}; -use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle}; -use pathfinder_geometry::vector::vec2f; -use pathfinder_renderer::scene::{DrawPath, Scene}; - -use swf_types::tags::SetBackgroundColor; -use swf_types::{Tag, SRgb8, Movie}; - -use crate::shapes::{GraphicLayers, PaintOrLine}; - -mod shapes; - -type SymbolId = u16; - -// In swf, most values are specified in a fixed point format known as "twips" or twentieths of -// a pixel. We store twips in their integer form, as if we were to convert them to floating point -// at the beginning of the pipeline it's easy to start running into precision errors when we add -// coordinate deltas and then try and compare coords for equality. - -#[derive(Copy, Clone, Debug, PartialEq)] -struct Twips(i32); - -impl Twips { - // Divide twips by 20 to get the f32 value, just to be used once all processing - // of the swf coords is completed and we want to output. - fn as_f32(&self) -> f32 { - self.0 as f32 / 20.0 - } -} - -impl Add for Twips { - type Output = Twips; - fn add(self, rhs: Twips) -> Self { - Twips(self.0 + rhs.0) - } -} - -#[derive(Copy, Clone, Debug, PartialEq)] -struct Point2 { - x: T, - y: T -} - -impl Point2 { - fn as_f32(self: Point2) -> Point2 { - Point2 { - x: self.x.as_f32(), - y: self.y.as_f32(), - } - } -} - -impl Add for Point2 { - type Output = Self; - fn add(self, rhs: Self) -> Self { - Point2 { x: self.x + rhs.x, y: self.y + rhs.y } - } -} - -enum Symbol { - Graphic(GraphicLayers), - // Timeline, // TODO(jon) -} - -pub struct Stage { - // TODO(jon): Support some kind of lazy frames iterator. - // frames: Timeline, - background_color: SRgb8, - width: i32, - height: i32, -} - -impl Stage { - pub fn width(&self) -> i32 { - self.width - } - - pub fn height(&self) -> i32 { - self.height - } - - pub fn background_color(&self) -> ColorF { - ColorU { - r: self.background_color.r, - g: self.background_color.g, - b: self.background_color.b, - a: 255, - }.to_f32() - } -} - - -pub struct SymbolLibrary(Vec); - -impl SymbolLibrary { - fn add_symbol(&mut self, symbol: Symbol) { - self.0.push(symbol); - } - - fn symbols(&self) -> &Vec { - &self.0 - } -} - -pub fn process_swf_tags(movie: &Movie) -> (SymbolLibrary, Stage) { - let mut symbol_library = SymbolLibrary(Vec::new()); - let stage_width = Twips(movie.header.frame_size.x_max); - let stage_height = Twips(movie.header.frame_size.y_max); - // let num_frames = movie.header.frame_count; - - let mut stage = Stage { - // frames: Timeline(Vec::new()), // TODO(jon) - background_color: SRgb8 { - r: 255, - g: 255, - b: 255 - }, - width: stage_width.as_f32() as i32, - height: stage_height.as_f32() as i32, - }; - - for tag in &movie.tags { - match tag { - Tag::SetBackgroundColor(SetBackgroundColor { color }) => { - stage.background_color = *color; - }, - Tag::DefineShape(shape) => { - symbol_library.add_symbol(Symbol::Graphic(shapes::decode_shape(shape))); - // We will assume that symbol ids just go up, and are 1 based. - let symbol_id: SymbolId = shape.id; - debug_assert!(symbol_id as usize == symbol_library.0.len()); - } - _ => () - } - } - (symbol_library, stage) -} - -#[allow(irrefutable_let_patterns)] -pub fn draw_paths_into_scene(library: &SymbolLibrary, scene: &mut Scene) { - for symbol in library.symbols() { - // NOTE: Right now symbols only contain graphics. - if let Symbol::Graphic(graphic) = symbol { - for style_layer in graphic.layers() { - let mut path = Outline::new(); - let paint_id = scene.push_paint(&style_layer.fill()); - - for shape in style_layer.shapes() { - let mut contour = Contour::new(); - let Point2 { x, y } = shape.outline.first().unwrap().from.as_f32(); - contour.push_endpoint(vec2f(x, y)); - for segment in &shape.outline { - let Point2 { x, y } = segment.to.as_f32(); - match segment.ctrl { - Some(ctrl) => { - let Point2 { x: ctrl_x, y: ctrl_y } = ctrl.as_f32(); - contour.push_quadratic(vec2f(ctrl_x, ctrl_y), vec2f(x, y)); - } - None => { - contour.push_endpoint(vec2f(x, y)); - }, - } - } - if shape.is_closed() { - // NOTE: I'm not sure if this really does anything in this context, - // since all our closed shapes already have coincident start and end points. - contour.close(); - } - path.push_contour(contour); - } - - if let PaintOrLine::Line(line) = style_layer.kind() { - let mut stroke_to_fill = OutlineStrokeToFill::new(&path, StrokeStyle { - line_width: line.width.as_f32(), - line_cap: line.cap, - line_join: line.join, - }); - stroke_to_fill.offset(); - path = stroke_to_fill.into_outline(); - } - - let mut path = DrawPath::new(path, paint_id); - path.set_fill_rule(FillRule::EvenOdd); - scene.push_path(path); - } - } - } -} diff --git a/crates/pathfinder/swf/src/shapes.rs b/crates/pathfinder/swf/src/shapes.rs deleted file mode 100644 index 88b451782c..0000000000 --- a/crates/pathfinder/swf/src/shapes.rs +++ /dev/null @@ -1,609 +0,0 @@ -// pathfinder/swf/src/shapes.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::{Twips, Point2}; - -use pathfinder_color::ColorU; -use pathfinder_content::stroke::{LineJoin, LineCap}; -use pathfinder_renderer::paint::Paint; -use std::cmp::Ordering; -use std::mem; -use swf_types::tags::DefineShape; -use swf_types::{CapStyle, FillStyle, JoinStyle, LineStyle, ShapeRecord, StraightSRgba8, Vector2D}; -use swf_types::{fill_styles, join_styles, shape_records}; - -#[derive(Clone, Copy, Debug)] -pub(crate) struct LineSegment { - pub(crate) from: Point2, - pub(crate) to: Point2, - pub(crate) ctrl: Option>, -} - -impl LineSegment { - fn reverse(&mut self) { - let tmp = self.from; - self.from = self.to; - self.to = tmp; - } -} - -#[derive(Copy, Clone, PartialEq, Debug)] -pub(crate) enum LineDirection { - Left, - Right, -} - -impl LineDirection { - fn reverse(&mut self) { - *self = match self { - LineDirection::Right => LineDirection::Left, - LineDirection::Left => LineDirection::Right - }; - } -} - -#[derive(Clone, Debug)] -pub(crate) struct Shape { - pub(crate) outline: Vec, // Could be Vec<(start, end)> - direction: LineDirection, - reversed: bool, -} - -impl Shape { - pub fn new_with_direction(direction: LineDirection) -> Shape { - Shape { - direction, - outline: Vec::new(), - reversed: false, - } - } - - fn prepend_shape(&mut self, shape: &mut Shape) { - shape.append_shape(&self); - mem::swap(&mut self.outline, &mut shape.outline); - } - - fn append_shape(&mut self, shape: &Shape) { - self.outline.extend_from_slice(&shape.outline); - } - - fn add_line_segment(&mut self, segment: LineSegment) { - self.outline.push(segment); - } - - #[inline] - fn len(&self) -> usize { - self.outline.len() - } - - #[inline] - fn first(&self) -> LineSegment { - *self.outline.first().unwrap() - } - - #[inline] - fn last(&self) -> LineSegment { - *self.outline.last().unwrap() - } - - #[inline] - fn comes_before(&self, other: &Shape) -> bool { - self.last().to == other.first().from - } - - #[inline] - fn comes_after(&self, other: &Shape) -> bool { - self.first().from == other.last().to - } - - #[inline] - pub(crate) fn is_closed(&self) -> bool { - self.len() > 1 && self.comes_after(self) - } - - fn reverse(&mut self) { - self.reversed = !self.reversed; - self.direction.reverse(); - for segment in &mut self.outline { - segment.reverse(); - } - self.outline.reverse(); - } -} - -pub(crate) struct SwfLineStyle { - color: Paint, - pub(crate) width: Twips, - pub(crate) join: LineJoin, - pub(crate) cap: LineCap, -} - -pub(crate) enum PaintOrLine { - Paint(Paint), - Line(SwfLineStyle), -} - -pub(crate) struct StyleLayer { - fill: PaintOrLine, - // TODO(jon): Maybe shapes are actually slices into a single buffer, then we don't - // need to realloc anything, we're just shuffling shapes around? - shapes: Vec, -} - -impl StyleLayer { - pub(crate) fn kind(&self) -> &PaintOrLine { - &self.fill - } - - fn is_fill(&self) -> bool { - match &self.fill { - PaintOrLine::Paint(_) => true, - PaintOrLine::Line(_) => false, - } - } - - pub(crate) fn fill(&self) -> &Paint { - match &self.fill { - PaintOrLine::Paint(ref paint) => paint, - PaintOrLine::Line(line) => &line.color, - } - } - - fn push_new_shape(&mut self, direction: LineDirection) { - if let Some(prev_shape) = self.shapes.last_mut() { - // Check that the previous shape was actually used, otherwise reuse it. - if prev_shape.len() != 0 { - self.shapes.push(Shape::new_with_direction(direction)) - } else { - prev_shape.direction = direction; - } - } else { - self.shapes.push(Shape::new_with_direction(direction)) - } - } - - pub(crate) fn shapes(&self) -> &Vec { - &self.shapes - } - - fn shapes_mut(&mut self) -> &mut Vec { - &mut self.shapes - } - - fn current_shape_mut(&mut self) -> &mut Shape { - self.shapes.last_mut().unwrap() - } - - fn consolidate_edges(&mut self) { - // Reverse left fill shape fragments in place. - { - self.shapes - .iter_mut() - .filter(|frag| frag.direction == LineDirection::Left) - .for_each(|frag| frag.reverse()); - } - - // Sort shapes into [closed...open] - if self.is_fill() { - // I think sorting is only necessary when we want to have closed shapes, - // lines don't really need this? - self.shapes.sort_unstable_by(|a, b| { - match (a.is_closed(), b.is_closed()) { - (true, true) | (false, false) => Ordering::Equal, - (true, false) => Ordering::Less, - (false, true) => Ordering::Greater, - } - }); - } - - // A cursor at the index of the first unclosed shape, if any. - let first_open_index = self.shapes - .iter() - .position(|frag| !frag.is_closed()); - - if let Some(first_open_index) = first_open_index { - if self.shapes.len() - first_open_index >= 2 { - // TODO(jon): This might be sped up by doing it in a way that we don't have - // to allocate more vecs? - // Also, maybe avoid path reversal, and just flag the path as reversed and iterate it - // backwards. - let unmatched_pieces = find_matches(first_open_index, &mut self.shapes, false); - if let Some(mut unmatched_pieces) = unmatched_pieces { - if self.is_fill() { - // If they didn't match before, they're probably parts of inner shapes - // and should be reversed again so they have correct winding - let unclosed = find_matches(0, &mut unmatched_pieces, true); - // If it's a shape we should always be able to close it. - debug_assert!(unclosed.is_none()); - } - for dropped in &mut unmatched_pieces { - dropped.reverse(); - } - self.shapes.extend_from_slice(&unmatched_pieces); - } - // FIXME(jon): Sometimes we don't get the correct winding of internal closed shapes, - // need to figure out why this happens. - } - } - } -} - - -fn get_new_styles<'a>( - fills: &'a Vec, - lines: &'a Vec -) -> impl Iterator + 'a { - // This enforces the order that fills and line groupings are added in. - // Fills always come first. - fills.iter().filter_map(|fill_style| { - match fill_style { - FillStyle::Solid( - fill_styles::Solid { - color: StraightSRgba8 { - r, - g, - b, - a - } - } - ) => { - Some(PaintOrLine::Paint(Paint::from_color(ColorU { r: *r, g: *g, b: *b, a: *a }))) - } - _ => unimplemented!("Unimplemented fill style") - } - }).chain( - lines.iter().filter_map(|LineStyle { - width, - fill, - join, - start_cap, - end_cap: _, - /* - TODO(jon): Handle these cases? - pub no_h_scale: bool, - pub no_v_scale: bool, - pub no_close: bool, - pub pixel_hinting: bool, - */ - .. - }| { - if let FillStyle::Solid(fill_styles::Solid { - color: StraightSRgba8 { - r, - g, - b, - a - } - }) = fill { - // NOTE: PathFinder doesn't support different cap styles for start and end of - // strokes, so lets assume that they're always the same for the inputs we care about. - // Alternately, we split a line in two with a diff cap style for each. - // assert_eq!(start_cap, end_cap); - Some(PaintOrLine::Line(SwfLineStyle { - width: Twips(*width as i32), - color: Paint::from_color(ColorU { r: *r, g: *g, b: *b, a: *a }), - join: match join { - JoinStyle::Bevel => LineJoin::Bevel, - JoinStyle::Round => LineJoin::Round, - JoinStyle::Miter(join_styles::Miter { limit }) => { - LineJoin::Miter(*limit as f32) - }, - }, - cap: match start_cap { - CapStyle::None => LineCap::Butt, - CapStyle::Square => LineCap::Square, - CapStyle::Round => LineCap::Round, - }, - })) - } else { - unimplemented!("unimplemented line fill style"); - } - }) - ) -} - -pub(crate) fn decode_shape(shape: &DefineShape) -> GraphicLayers { - let DefineShape { - shape, - // id, - // has_fill_winding, NOTE(jon): Could be important for some inputs? - // has_non_scaling_strokes, - // has_scaling_strokes, - .. - } = shape; - let mut graphic = GraphicLayers::new(); - let mut current_line_style = None; - let mut current_left_fill = None; - let mut current_right_fill = None; - let mut prev_pos = None; - - let mut some_fill_set = false; - let mut both_fills_set; - let mut both_fills_same = false; - let mut both_fills_set_and_same = false; - - // Create style groups for initially specified fills and lines. - for fills_or_line in get_new_styles(&shape.initial_styles.fill, &shape.initial_styles.line) { - match fills_or_line { - PaintOrLine::Paint(fill) => graphic.begin_fill_style(fill), - PaintOrLine::Line(line) => graphic.begin_line_style(line), - } - } - - for record in &shape.records { - match record { - ShapeRecord::StyleChange( - shape_records::StyleChange { - move_to, - new_styles, - line_style, - left_fill, - right_fill, - } - ) => { - // Start a whole new style grouping. - if let Some(new_style) = new_styles { - // Consolidate current style grouping and begin a new one. - graphic.end_style_group(); - graphic.begin_style_group(); - for fills_or_line in get_new_styles(&new_style.fill, &new_style.line) { - match fills_or_line { - PaintOrLine::Paint(fill) => graphic.begin_fill_style(fill), - PaintOrLine::Line(line) => graphic.begin_line_style(line), - } - } - } - - // If there's a change in right fill - if let Some(fill_id) = right_fill { - if *fill_id == 0 { - current_right_fill = None; - } else { - current_right_fill = Some(*fill_id); - graphic - .with_fill_style_mut(*fill_id) - .unwrap() - .push_new_shape(LineDirection::Right); - } - } - // If there's a change in left fill - if let Some(fill_id) = left_fill { - if *fill_id == 0 { - current_left_fill = None; - } else { - current_left_fill = Some(*fill_id); - graphic - .with_fill_style_mut(*fill_id) - .unwrap() - .push_new_shape(LineDirection::Left); - } - } - - some_fill_set = current_left_fill.is_some() || current_right_fill.is_some(); - both_fills_set = current_left_fill.is_some() && current_right_fill.is_some(); - both_fills_same = current_left_fill == current_right_fill; - both_fills_set_and_same = both_fills_set && both_fills_same; - - // If there's a change in line style - if let Some(style_id) = line_style { - if *style_id == 0 { - current_line_style = None; - } else { - current_line_style = Some(*style_id); - graphic - .with_line_style_mut(*style_id) - .unwrap() - .push_new_shape(LineDirection::Right); - } - } - - // Move to, start new shape fragments with the current styles. - if let Some(Vector2D { x, y }) = move_to { - let to: Point2 = Point2 { x: Twips(*x), y: Twips(*y) }; - prev_pos = Some(to); - - // If we didn't start a new shape for the current fill due to a fill - // style change earlier, we definitely want to start a new shape now, - // since each move_to command indicates a new shape fragment. - if let Some(current_right_fill) = current_right_fill { - graphic - .with_fill_style_mut(current_right_fill) - .unwrap() - .push_new_shape(LineDirection::Right); - } - if let Some(current_left_fill) = current_left_fill { - graphic - .with_fill_style_mut(current_left_fill) - .unwrap() - .push_new_shape(LineDirection::Left); - } - if let Some(current_line_style) = current_line_style { - // TODO(jon): Does the direction of this line depend on the current - // fill directions? - graphic - .with_line_style_mut(current_line_style) - .unwrap() - .push_new_shape(LineDirection::Right); - } - } - }, - ShapeRecord::Edge( - shape_records::Edge { - delta, - control_delta, - } - ) => { - let from = prev_pos.unwrap(); - let to = Point2 { - x: from.x + Twips(delta.x), - y: from.y + Twips(delta.y) - }; - prev_pos = Some(to); - let new_segment = LineSegment { - from, - to, - ctrl: control_delta.map(|Vector2D { x, y }| { - Point2 { - x: from.x + Twips(x), - y: from.y + Twips(y), - } - }), - }; - if some_fill_set && !both_fills_same { - for fill_id in [ - current_right_fill, - current_left_fill - ].iter() { - if let Some(fill_id) = fill_id { - graphic - .with_fill_style_mut(*fill_id) - .unwrap() - .current_shape_mut() - .add_line_segment(new_segment); - } - } - } else if both_fills_set_and_same { - for (fill_id, direction) in [ - (current_right_fill, LineDirection::Right), - (current_left_fill, LineDirection::Left) - ].iter() { - // NOTE: If both left and right fill are set the same, - // then we don't record the edge as part of the current shape; - // it's will just be an internal stroke inside an otherwise solid - // shape, and recording these edges as part of the shape means that - // we can't determine the closed shape outline later. - if let Some(fill_id) = fill_id { - graphic - .with_fill_style_mut(*fill_id) - .unwrap() - .push_new_shape(*direction); - } - } - } - if let Some(current_line_style) = current_line_style { - graphic - .with_line_style_mut(current_line_style) - .unwrap() - .current_shape_mut() - .add_line_segment(new_segment); - } - } - } - } - // NOTE: Consolidate current group of styles, joining edges of shapes/strokes where - // possible and forming closed shapes. In swf, all filled shapes should always be closed, - // so there will always be a solution for joining shape line segments together so that - // the start point and end point are coincident. - graphic.end_style_group(); - graphic -} - -fn find_matches( - mut first_open_index: usize, - shapes: &mut Vec, - reverse: bool -) -> Option> { - let mut dropped_pieces = None; - while first_open_index < shapes.len() { - // Take the last unclosed value, and try to join it onto - // one of the other unclosed values. - let mut last = shapes.pop().unwrap(); - if reverse { - last.reverse(); - } - let mut found_match = false; - for i in first_open_index..shapes.len() { - let fragment = &mut shapes[i]; - if last.comes_after(fragment) { - // NOTE(jon): We do realloc quite a bit here, I wonder if it's worth trying - // to avoid that? Could do it with another level of indirection, where an outline - // is a list of fragments. - - // println!("app ({}, {})", last.reversed, fragment.reversed); - fragment.append_shape(&last); - found_match = true; - } else if last.comes_before(fragment) { - // println!("pre ({}, {})", last.reversed, fragment.reversed); - fragment.prepend_shape(&mut last); - found_match = true; - } - if found_match { - if fragment.is_closed() { - // Move the shape that was just closed to the left side of the current slice, - // and advance the cursor. - shapes.swap(first_open_index, i); - first_open_index += 1; - } - break; - } - } - if !found_match { - // Have we tried matching a reversed version of this segment? - // move last back onto the array, it will never be closed, presumably because - // it's a set of line segments rather than a shape that needs to be closed. - let dropped_pieces: &mut Vec = dropped_pieces.get_or_insert(Vec::new()); - dropped_pieces.push(last); - } - } - dropped_pieces -} - -pub(crate) struct GraphicLayers { - style_layers: Vec, - base_layer_offset: usize, - stroke_layer_offset: Option, -} - -impl GraphicLayers { - fn new() -> GraphicLayers { - GraphicLayers { style_layers: Vec::new(), stroke_layer_offset: None, base_layer_offset: 0 } - } - - fn begin_style_group(&mut self) { - self.stroke_layer_offset = None; - self.base_layer_offset = self.style_layers.len(); - } - - fn begin_fill_style(&mut self, fill: Paint) { - self.style_layers.push(StyleLayer { fill: PaintOrLine::Paint(fill), shapes: Vec::new() }) - } - - fn begin_line_style(&mut self, line: SwfLineStyle) { - if self.stroke_layer_offset.is_none() { - self.stroke_layer_offset = Some(self.style_layers.len()); - } - self.style_layers.push(StyleLayer { fill: PaintOrLine::Line(line), shapes: Vec::new() }) - } - - fn with_fill_style_mut(&mut self, fill_id: usize) -> Option<&mut StyleLayer> { - self.style_layers.get_mut(self.base_layer_offset + fill_id - 1) - } - - fn with_line_style_mut(&mut self, line_id: usize) -> Option<&mut StyleLayer> { - self.style_layers.get_mut((self.stroke_layer_offset.unwrap() + line_id) - 1) - } - - pub(crate) fn layers(&self) -> &Vec { - &self.style_layers - } - - fn end_style_group(&mut self) { - for style_layer in &mut self.style_layers[self.base_layer_offset..] { - // There can be an unused style group at the end of each layer, which we should remove. - if let Some(last) = style_layer.shapes().last() { - if last.len() == 0 { - style_layer.shapes_mut().pop(); - } - } - style_layer.consolidate_edges(); - } - } -} - diff --git a/crates/pathfinder/swf/src/timeline.rs b/crates/pathfinder/swf/src/timeline.rs deleted file mode 100644 index e3f684b32a..0000000000 --- a/crates/pathfinder/swf/src/timeline.rs +++ /dev/null @@ -1,42 +0,0 @@ -// pathfinder/swf/src/timeline.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct PlacementInfo { - symbol_id: u32, - translate_x: Twips, - translate_y: Twips, -} - -struct Timeline(Vec); - -impl Timeline { - fn first(&self) -> &Frame { - &self.0[0] - } - - fn last(&self) -> &Frame { - &self.0[self.0.len() - 1] - } - - fn first_mut(&mut self) -> &mut Frame { - &mut self.0[0] - } - - fn last_mut(&mut self) -> &mut Frame { - let last = self.0.len() - 1; - &mut self.0[last] - } -} - -struct Frame { - duration_frames_initial: u16, - duration_remaining_frames: u16, - placements: Vec -} diff --git a/crates/pathfinder/text/Cargo.toml b/crates/pathfinder/text/Cargo.toml deleted file mode 100644 index adcdfb8421..0000000000 --- a/crates/pathfinder/text/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "pathfinder_text" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -description = "Text layout for the Pathfinder vector graphics renderer" -license = "MIT/Apache-2.0" -repository = "https://github.com/servo/pathfinder" -homepage = "https://github.com/servo/pathfinder" - -[dependencies] -font-kit = "0.6" - -[dependencies.pathfinder_content] -path = "../content" -version = "0.5" - -[dependencies.pathfinder_geometry] -path = "../geometry" -version = "0.5" - -[dependencies.pathfinder_renderer] -path = "../renderer" -version = "0.5" - -[dependencies.skribo] -version = "0.1" diff --git a/crates/pathfinder/text/src/lib.rs b/crates/pathfinder/text/src/lib.rs deleted file mode 100644 index 575e7f4cc9..0000000000 --- a/crates/pathfinder/text/src/lib.rs +++ /dev/null @@ -1,249 +0,0 @@ -// pathfinder/text/src/lib.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use font_kit::error::GlyphLoadingError; -use font_kit::hinting::HintingOptions; -use font_kit::loader::Loader; -use font_kit::loaders::default::Font as DefaultLoader; -use font_kit::outline::OutlineSink; -use pathfinder_content::effects::BlendMode; -use pathfinder_content::outline::{Contour, Outline}; -use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle}; -use pathfinder_geometry::line_segment::LineSegment2F; -use pathfinder_geometry::transform2d::Transform2F; -use pathfinder_geometry::vector::{Vector2F, vec2f}; -use pathfinder_renderer::paint::PaintId; -use pathfinder_renderer::scene::{ClipPathId, DrawPath, Scene}; -use skribo::{FontCollection, Layout, TextStyle}; -use std::collections::HashMap; -use std::mem; - -#[derive(Clone)] -pub struct FontContext where F: Loader { - font_info: HashMap>, -} - -#[derive(Clone)] -struct FontInfo where F: Loader { - font: F, - outline_cache: HashMap, -} - -#[derive(Clone, Copy)] -pub struct FontRenderOptions { - pub transform: Transform2F, - pub render_mode: TextRenderMode, - pub hinting_options: HintingOptions, - pub clip_path: Option, - pub blend_mode: BlendMode, - pub paint_id: PaintId, -} - -impl Default for FontRenderOptions { - #[inline] - fn default() -> FontRenderOptions { - FontRenderOptions { - transform: Transform2F::default(), - render_mode: TextRenderMode::Fill, - hinting_options: HintingOptions::None, - clip_path: None, - blend_mode: BlendMode::SrcOver, - paint_id: PaintId(0), - } - } -} - -#[derive(Clone, Copy, PartialEq, Debug, Eq, Hash)] -pub struct GlyphId(pub u32); - -impl FontContext where F: Loader { - #[inline] - pub fn new() -> FontContext { - FontContext { font_info: HashMap::new() } - } - - pub fn push_glyph(&mut self, - scene: &mut Scene, - font: &F, - glyph_id: GlyphId, - render_options: &FontRenderOptions) - -> Result<(), GlyphLoadingError> { - let font_key = font.postscript_name(); - let metrics = font.metrics(); - - // Insert the font into the cache if needed. - if let Some(ref font_key) = font_key { - if !self.font_info.contains_key(&*font_key) { - self.font_info.insert((*font_key).clone(), FontInfo::new((*font).clone())); - } - } - - // See if we have a cached outline. - // - // TODO(pcwalton): Cache hinted outlines too. - let mut cached_outline = None; - let can_cache_outline = font_key.is_some() && - render_options.hinting_options == HintingOptions::None; - if can_cache_outline { - if let Some(ref font_info) = self.font_info.get(&*font_key.as_ref().unwrap()) { - if let Some(ref outline) = font_info.outline_cache.get(&glyph_id) { - cached_outline = Some((*outline).clone()); - } - } - } - - let mut outline = match cached_outline { - Some(mut cached_outline) => { - let scale = 1.0 / metrics.units_per_em as f32; - cached_outline.transform(&(render_options.transform * - Transform2F::from_scale(scale))); - cached_outline - } - None => { - let transform = if can_cache_outline { - Transform2F::from_scale(metrics.units_per_em as f32) - } else { - render_options.transform - }; - let mut outline_builder = OutlinePathBuilder::new(&transform); - font.outline(glyph_id.0, render_options.hinting_options, &mut outline_builder)?; - let mut outline = outline_builder.build(); - if can_cache_outline { - let font_key = font_key.as_ref().unwrap(); - let font_info = self.font_info.get_mut(&*font_key).unwrap(); - font_info.outline_cache.insert(glyph_id, outline.clone()); - let scale = 1.0 / metrics.units_per_em as f32; - outline.transform(&(render_options.transform * - Transform2F::from_scale(scale))); - } - outline - } - }; - - if let TextRenderMode::Stroke(stroke_style) = render_options.render_mode { - let mut stroke_to_fill = OutlineStrokeToFill::new(&outline, stroke_style); - stroke_to_fill.offset(); - outline = stroke_to_fill.into_outline(); - } - - let mut path = DrawPath::new(outline, render_options.paint_id); - path.set_clip_path(render_options.clip_path); - path.set_blend_mode(render_options.blend_mode); - - scene.push_path(path); - Ok(()) - } - - /// Attempts to look up a font in the font cache. - #[inline] - pub fn get_cached_font(&self, postscript_name: &str) -> Option<&F> { - self.font_info.get(postscript_name).map(|font_info| &font_info.font) - } -} - -impl FontContext { - pub fn push_layout(&mut self, - scene: &mut Scene, - layout: &Layout, - style: &TextStyle, - render_options: &FontRenderOptions) - -> Result<(), GlyphLoadingError> { - for glyph in &layout.glyphs { - let offset = glyph.offset; - let font = &*glyph.font.font; - // FIXME(pcwalton): Cache this! - let scale = style.size / (font.metrics().units_per_em as f32); - let scale = vec2f(scale, -scale); - let render_options = FontRenderOptions { - transform: render_options.transform * - Transform2F::from_scale(scale).translate(offset), - ..*render_options - }; - self.push_glyph(scene, font, GlyphId(glyph.glyph_id), &render_options)?; - } - Ok(()) - } - - #[inline] - pub fn push_text(&mut self, - scene: &mut Scene, - text: &str, - style: &TextStyle, - collection: &FontCollection, - render_options: &FontRenderOptions) - -> Result<(), GlyphLoadingError> { - let layout = skribo::layout(style, collection, text); - self.push_layout(scene, &layout, style, render_options) - } -} - -impl FontInfo where F: Loader { - fn new(font: F) -> FontInfo { - FontInfo { font, outline_cache: HashMap::new() } - } -} - -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum TextRenderMode { - Fill, - Stroke(StrokeStyle), -} - -struct OutlinePathBuilder { - outline: Outline, - current_contour: Contour, - transform: Transform2F, -} - -impl OutlinePathBuilder { - fn new(transform: &Transform2F) -> OutlinePathBuilder { - OutlinePathBuilder { - outline: Outline::new(), - current_contour: Contour::new(), - transform: *transform, - } - } - - fn flush_current_contour(&mut self) { - if !self.current_contour.is_empty() { - self.outline.push_contour(mem::replace(&mut self.current_contour, Contour::new())); - } - } - - fn build(mut self) -> Outline { - self.flush_current_contour(); - self.outline - } -} - -impl OutlineSink for OutlinePathBuilder { - fn move_to(&mut self, to: Vector2F) { - self.flush_current_contour(); - self.current_contour.push_endpoint(self.transform * to); - } - - fn line_to(&mut self, to: Vector2F) { - self.current_contour.push_endpoint(self.transform * to); - } - - fn quadratic_curve_to(&mut self, ctrl: Vector2F, to: Vector2F) { - self.current_contour.push_quadratic(self.transform * ctrl, self.transform * to); - } - - fn cubic_curve_to(&mut self, ctrl: LineSegment2F, to: Vector2F) { - self.current_contour.push_cubic(self.transform * ctrl.from(), - self.transform * ctrl.to(), - self.transform * to); - } - - fn close(&mut self) { - self.current_contour.close(); - } -} diff --git a/crates/pathfinder/ui/Cargo.toml b/crates/pathfinder/ui/Cargo.toml deleted file mode 100644 index 9064fb5c5e..0000000000 --- a/crates/pathfinder/ui/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "pathfinder_ui" -version = "0.5.0" -edition = "2018" -authors = ["Patrick Walton "] -description = "A minimal immediate mode UI library for debugging overlays" -license = "MIT/Apache-2.0" -repository = "https://github.com/servo/pathfinder" -homepage = "https://github.com/servo/pathfinder" - -[dependencies] -serde = "1.0" -serde_derive = "1.0" -serde_json = "1.0" - -[dependencies.hashbrown] -version = "0.7" -features = ["serde"] - -[dependencies.pathfinder_color] -path = "../color" -version = "0.5" - -[dependencies.pathfinder_geometry] -path = "../geometry" -version = "0.5" - -[dependencies.pathfinder_gpu] -path = "../gpu" -version = "0.5" - -[dependencies.pathfinder_resources] -path = "../resources" -version = "0.5" - -[dependencies.pathfinder_simd] -path = "../simd" -version = "0.5" diff --git a/crates/pathfinder/ui/src/lib.rs b/crates/pathfinder/ui/src/lib.rs deleted file mode 100644 index 21e747a959..0000000000 --- a/crates/pathfinder/ui/src/lib.rs +++ /dev/null @@ -1,837 +0,0 @@ -// pathfinder/ui/src/lib.rs -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A minimal immediate mode UI, for debugging. -//! -//! This can be used in your own applications as an ultra-minimal lightweight -//! alternative to dear imgui, Conrod, etc. - -#[macro_use] -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}; -use pathfinder_gpu::{UniformData, VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; -use pathfinder_resources::ResourceLoader; -use pathfinder_simd::default::F32x4; -use serde_json; -use std::mem; - -pub const PADDING: i32 = 12; - -pub const LINE_HEIGHT: i32 = 42; -pub const FONT_ASCENT: i32 = 28; - -pub const BUTTON_WIDTH: i32 = PADDING * 2 + ICON_SIZE; -pub const BUTTON_HEIGHT: i32 = PADDING * 2 + ICON_SIZE; -pub const BUTTON_TEXT_OFFSET: i32 = PADDING + 36; - -pub const TOOLTIP_HEIGHT: i32 = FONT_ASCENT + PADDING * 2; - -const DEBUG_TEXTURE_VERTEX_SIZE: usize = 8; -const DEBUG_SOLID_VERTEX_SIZE: usize = 4; - -const ICON_SIZE: i32 = 48; - -const SEGMENT_SIZE: i32 = 96; - -pub static TEXT_COLOR: ColorU = ColorU { r: 255, g: 255, b: 255, a: 255 }; -pub static WINDOW_COLOR: ColorU = ColorU { r: 0, g: 0, b: 0, a: 255 - 90 }; - -static BUTTON_ICON_COLOR: ColorU = ColorU { r: 255, g: 255, b: 255, a: 255 }; -static OUTLINE_COLOR: ColorU = ColorU { r: 255, g: 255, b: 255, a: 192 }; - -static INVERTED_TEXT_COLOR: ColorU = ColorU { r: 0, g: 0, b: 0, a: 255 }; - -static FONT_JSON_VIRTUAL_PATH: &'static str = "debug-fonts/regular.json"; -static FONT_PNG_NAME: &'static str = "debug-font"; - -static CORNER_FILL_PNG_NAME: &'static str = "debug-corner-fill"; -static CORNER_OUTLINE_PNG_NAME: &'static str = "debug-corner-outline"; - -static QUAD_INDICES: [u32; 6] = [0, 1, 3, 1, 2, 3]; -static RECT_LINE_INDICES: [u32; 8] = [0, 1, 1, 2, 2, 3, 3, 0]; -static OUTLINE_RECT_LINE_INDICES: [u32; 8] = [0, 1, 2, 3, 4, 5, 6, 7]; - -pub struct UIPresenter where D: Device { - pub event_queue: UIEventQueue, - pub mouse_position: Vector2F, - - framebuffer_size: Vector2I, - - texture_program: DebugTextureProgram, - texture_vertex_array: DebugTextureVertexArray, - solid_program: DebugSolidProgram, - solid_vertex_array: DebugSolidVertexArray, - font: DebugFont, - - font_texture: D::Texture, - corner_fill_texture: D::Texture, - corner_outline_texture: D::Texture, -} - -impl UIPresenter where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader, framebuffer_size: Vector2I) - -> UIPresenter { - let texture_program = DebugTextureProgram::new(device, resources); - let texture_vertex_array = DebugTextureVertexArray::new(device, &texture_program); - let font = DebugFont::load(resources); - - let solid_program = DebugSolidProgram::new(device, resources); - let solid_vertex_array = DebugSolidVertexArray::new(device, &solid_program); - - let font_texture = device.create_texture_from_png(resources, - FONT_PNG_NAME, - TextureFormat::R8); - let corner_fill_texture = device.create_texture_from_png(resources, - CORNER_FILL_PNG_NAME, - TextureFormat::R8); - let corner_outline_texture = device.create_texture_from_png(resources, - CORNER_OUTLINE_PNG_NAME, - TextureFormat::R8); - - UIPresenter { - event_queue: UIEventQueue::new(), - mouse_position: Vector2F::zero(), - - framebuffer_size, - - texture_program, - texture_vertex_array, - font, - solid_program, - solid_vertex_array, - - font_texture, - corner_fill_texture, - corner_outline_texture, - } - } - - pub fn framebuffer_size(&self) -> Vector2I { - self.framebuffer_size - } - - pub fn set_framebuffer_size(&mut self, window_size: Vector2I) { - self.framebuffer_size = window_size; - } - - - pub fn draw_solid_rect(&self, device: &D, rect: RectI, color: ColorU) { - self.draw_rect(device, rect, color, true); - } - - pub fn draw_rect_outline(&self, device: &D, rect: RectI, color: ColorU) { - self.draw_rect(device, rect, color, false); - } - - fn draw_rect(&self, - device: &D, - rect: RectI, - color: ColorU, - filled: bool) { - let vertex_data = [ - DebugSolidVertex::new(rect.origin()), - DebugSolidVertex::new(rect.upper_right()), - DebugSolidVertex::new(rect.lower_right()), - DebugSolidVertex::new(rect.lower_left()), - ]; - - if filled { - self.draw_solid_rects_with_vertex_data(device, - &vertex_data, - &QUAD_INDICES, - color, - true); - } else { - self.draw_solid_rects_with_vertex_data(device, - &vertex_data, - &RECT_LINE_INDICES, - color, - false); - } - } - - fn draw_solid_rects_with_vertex_data(&self, - device: &D, - vertex_data: &[DebugSolidVertex], - index_data: &[u32], - color: ColorU, - filled: bool) { - device.allocate_buffer(&self.solid_vertex_array.vertex_buffer, - BufferData::Memory(vertex_data), - BufferTarget::Vertex); - device.allocate_buffer(&self.solid_vertex_array.index_buffer, - BufferData::Memory(index_data), - BufferTarget::Index); - - let primitive = if filled { Primitive::Triangles } else { Primitive::Lines }; - device.draw_elements(index_data.len() as u32, &RenderState { - target: &RenderTarget::Default, - program: &self.solid_program.program, - vertex_array: &self.solid_vertex_array.vertex_array, - primitive, - uniforms: &[ - (&self.solid_program.framebuffer_size_uniform, - UniformData::Vec2(self.framebuffer_size.0.to_f32x2())), - (&self.solid_program.color_uniform, get_color_uniform(color)), - ], - textures: &[], - images: &[], - viewport: RectI::new(Vector2I::default(), self.framebuffer_size), - options: RenderOptions { - blend: Some(alpha_blend_state()), - ..RenderOptions::default() - }, - }); - } - - pub fn draw_text(&self, device: &D, string: &str, origin: Vector2I, invert: bool) { - let mut next = origin; - let char_count = string.chars().count(); - let mut vertex_data = Vec::with_capacity(char_count * 4); - let mut index_data = Vec::with_capacity(char_count * 6); - for mut character in string.chars() { - if !self.font.characters.contains_key(&character) { - character = '?'; - } - - let info = &self.font.characters[&character]; - let position_rect = - RectI::new(vec2i(next.x() - info.origin_x, next.y() - info.origin_y), - vec2i(info.width as i32, info.height as i32)); - let tex_coord_rect = RectI::new(vec2i(info.x, info.y), vec2i(info.width, info.height)); - let first_vertex_index = vertex_data.len(); - vertex_data.extend_from_slice(&[ - DebugTextureVertex::new(position_rect.origin(), tex_coord_rect.origin()), - DebugTextureVertex::new(position_rect.upper_right(), tex_coord_rect.upper_right()), - DebugTextureVertex::new(position_rect.lower_right(), tex_coord_rect.lower_right()), - DebugTextureVertex::new(position_rect.lower_left(), tex_coord_rect.lower_left()), - ]); - index_data.extend(QUAD_INDICES.iter().map(|&i| i + first_vertex_index as u32)); - - let next_x = next.x() + info.advance; - next.set_x(next_x); - } - - let color = if invert { INVERTED_TEXT_COLOR } else { TEXT_COLOR }; - self.draw_texture_with_vertex_data(device, - &vertex_data, - &index_data, - &self.font_texture, - color); - } - - pub fn draw_texture(&self, - device: &D, - origin: Vector2I, - texture: &D::Texture, - color: ColorU) { - let position_rect = RectI::new(origin, device.texture_size(&texture)); - let tex_coord_rect = RectI::new(Vector2I::default(), position_rect.size()); - let vertex_data = [ - DebugTextureVertex::new(position_rect.origin(), tex_coord_rect.origin()), - DebugTextureVertex::new(position_rect.upper_right(), tex_coord_rect.upper_right()), - DebugTextureVertex::new(position_rect.lower_right(), tex_coord_rect.lower_right()), - DebugTextureVertex::new(position_rect.lower_left(), tex_coord_rect.lower_left()), - ]; - - self.draw_texture_with_vertex_data(device, &vertex_data, &QUAD_INDICES, texture, color); - } - - pub fn measure_text(&self, string: &str) -> i32 { - let mut next = 0; - for mut character in string.chars() { - if !self.font.characters.contains_key(&character) { - character = '?'; - } - - let info = &self.font.characters[&character]; - next += info.advance; - } - next - } - - #[inline] - pub fn measure_segmented_control(&self, segment_count: u8) -> i32 { - SEGMENT_SIZE * segment_count as i32 + (segment_count - 1) as i32 - } - - pub fn draw_solid_rounded_rect(&self, device: &D, rect: RectI, color: ColorU) { - let corner_texture = self.corner_texture(true); - let corner_rects = CornerRects::new(device, rect, corner_texture); - self.draw_rounded_rect_corners(device, color, corner_texture, &corner_rects); - - let solid_rect_mid = RectI::from_points(corner_rects.upper_left.upper_right(), - corner_rects.lower_right.lower_left()); - let solid_rect_left = RectI::from_points(corner_rects.upper_left.lower_left(), - corner_rects.lower_left.upper_right()); - let solid_rect_right = RectI::from_points(corner_rects.upper_right.lower_left(), - corner_rects.lower_right.upper_right()); - let vertex_data = vec![ - DebugSolidVertex::new(solid_rect_mid.origin()), - DebugSolidVertex::new(solid_rect_mid.upper_right()), - DebugSolidVertex::new(solid_rect_mid.lower_right()), - DebugSolidVertex::new(solid_rect_mid.lower_left()), - - DebugSolidVertex::new(solid_rect_left.origin()), - DebugSolidVertex::new(solid_rect_left.upper_right()), - DebugSolidVertex::new(solid_rect_left.lower_right()), - DebugSolidVertex::new(solid_rect_left.lower_left()), - - DebugSolidVertex::new(solid_rect_right.origin()), - DebugSolidVertex::new(solid_rect_right.upper_right()), - DebugSolidVertex::new(solid_rect_right.lower_right()), - DebugSolidVertex::new(solid_rect_right.lower_left()), - ]; - - let mut index_data = Vec::with_capacity(18); - index_data.extend(QUAD_INDICES.iter().map(|&index| index + 0)); - index_data.extend(QUAD_INDICES.iter().map(|&index| index + 4)); - index_data.extend(QUAD_INDICES.iter().map(|&index| index + 8)); - - self.draw_solid_rects_with_vertex_data(device, - &vertex_data, - &index_data[0..18], - color, - true); - } - - pub fn draw_rounded_rect_outline(&self, device: &D, rect: RectI, color: ColorU) { - let corner_texture = self.corner_texture(false); - let corner_rects = CornerRects::new(device, rect, corner_texture); - self.draw_rounded_rect_corners(device, color, corner_texture, &corner_rects); - - let vertex_data = vec![ - DebugSolidVertex::new(corner_rects.upper_left.upper_right()), - DebugSolidVertex::new(corner_rects.upper_right.origin()), - DebugSolidVertex::new(corner_rects.upper_right.lower_right()), - DebugSolidVertex::new(corner_rects.lower_right.upper_right()), - DebugSolidVertex::new(corner_rects.lower_left.lower_right()), - DebugSolidVertex::new(corner_rects.lower_right.lower_left()), - DebugSolidVertex::new(corner_rects.upper_left.lower_left()), - DebugSolidVertex::new(corner_rects.lower_left.origin()), - ]; - - let index_data = &OUTLINE_RECT_LINE_INDICES; - self.draw_solid_rects_with_vertex_data(device, &vertex_data, index_data, color, false); - } - - // TODO(pcwalton): `LineSegment2I`. - fn draw_line(&self, device: &D, from: Vector2I, to: Vector2I, color: ColorU) { - let vertex_data = vec![DebugSolidVertex::new(from), DebugSolidVertex::new(to)]; - self.draw_solid_rects_with_vertex_data(device, &vertex_data, &[0, 1], color, false); - - } - - fn draw_rounded_rect_corners(&self, - device: &D, - color: ColorU, - texture: &D::Texture, - corner_rects: &CornerRects) { - let corner_size = device.texture_size(&texture); - let tex_coord_rect = RectI::new(Vector2I::default(), corner_size); - - let vertex_data = vec![ - DebugTextureVertex::new( - corner_rects.upper_left.origin(), tex_coord_rect.origin()), - DebugTextureVertex::new( - corner_rects.upper_left.upper_right(), tex_coord_rect.upper_right()), - DebugTextureVertex::new( - corner_rects.upper_left.lower_right(), tex_coord_rect.lower_right()), - DebugTextureVertex::new( - corner_rects.upper_left.lower_left(), tex_coord_rect.lower_left()), - - DebugTextureVertex::new( - corner_rects.upper_right.origin(), tex_coord_rect.lower_left()), - DebugTextureVertex::new( - corner_rects.upper_right.upper_right(), tex_coord_rect.origin()), - DebugTextureVertex::new( - corner_rects.upper_right.lower_right(), tex_coord_rect.upper_right()), - DebugTextureVertex::new( - corner_rects.upper_right.lower_left(), tex_coord_rect.lower_right()), - - DebugTextureVertex::new( - corner_rects.lower_left.origin(), tex_coord_rect.upper_right()), - DebugTextureVertex::new( - corner_rects.lower_left.upper_right(), tex_coord_rect.lower_right()), - DebugTextureVertex::new( - corner_rects.lower_left.lower_right(), tex_coord_rect.lower_left()), - DebugTextureVertex::new( - corner_rects.lower_left.lower_left(), tex_coord_rect.origin()), - - DebugTextureVertex::new( - corner_rects.lower_right.origin(), tex_coord_rect.lower_right()), - DebugTextureVertex::new( - corner_rects.lower_right.upper_right(), tex_coord_rect.lower_left()), - DebugTextureVertex::new( - corner_rects.lower_right.lower_right(), tex_coord_rect.origin()), - DebugTextureVertex::new( - corner_rects.lower_right.lower_left(), tex_coord_rect.upper_right()), - ]; - - let mut index_data = Vec::with_capacity(24); - index_data.extend(QUAD_INDICES.iter().map(|&index| index + 0)); - index_data.extend(QUAD_INDICES.iter().map(|&index| index + 4)); - index_data.extend(QUAD_INDICES.iter().map(|&index| index + 8)); - index_data.extend(QUAD_INDICES.iter().map(|&index| index + 12)); - - self.draw_texture_with_vertex_data(device, &vertex_data, &index_data, texture, color); - } - - fn corner_texture(&self, filled: bool) -> &D::Texture { - if filled { &self.corner_fill_texture } else { &self.corner_outline_texture } - } - - fn draw_texture_with_vertex_data(&self, - device: &D, - vertex_data: &[DebugTextureVertex], - index_data: &[u32], - texture: &D::Texture, - color: ColorU) { - device.allocate_buffer(&self.texture_vertex_array.vertex_buffer, - BufferData::Memory(vertex_data), - BufferTarget::Vertex); - device.allocate_buffer(&self.texture_vertex_array.index_buffer, - BufferData::Memory(index_data), - BufferTarget::Index); - - device.draw_elements(index_data.len() as u32, &RenderState { - target: &RenderTarget::Default, - program: &self.texture_program.program, - vertex_array: &self.texture_vertex_array.vertex_array, - primitive: Primitive::Triangles, - textures: &[&texture], - images: &[], - uniforms: &[ - (&self.texture_program.framebuffer_size_uniform, - UniformData::Vec2(self.framebuffer_size.0.to_f32x2())), - (&self.texture_program.color_uniform, get_color_uniform(color)), - (&self.texture_program.texture_uniform, UniformData::TextureUnit(0)), - (&self.texture_program.texture_size_uniform, - UniformData::Vec2(device.texture_size(&texture).0.to_f32x2())) - ], - viewport: RectI::new(Vector2I::default(), self.framebuffer_size), - options: RenderOptions { - blend: Some(alpha_blend_state()), - ..RenderOptions::default() - }, - }); - } - - pub fn draw_button(&mut self, device: &D, origin: Vector2I, texture: &D::Texture) -> bool { - let button_rect = RectI::new(origin, vec2i(BUTTON_WIDTH, BUTTON_HEIGHT)); - self.draw_solid_rounded_rect(device, button_rect, WINDOW_COLOR); - self.draw_rounded_rect_outline(device, button_rect, OUTLINE_COLOR); - self.draw_texture(device, - origin + vec2i(PADDING, PADDING), - texture, - BUTTON_ICON_COLOR); - self.event_queue.handle_mouse_down_in_rect(button_rect).is_some() - } - - pub fn draw_text_switch(&mut self, - device: &D, - mut origin: Vector2I, - segment_labels: &[&str], - mut value: u8) - -> u8 { - if let Some(new_value) = self.draw_segmented_control(device, - origin, - Some(value), - segment_labels.len() as u8) { - value = new_value; - } - - origin = origin + vec2i(0, BUTTON_TEXT_OFFSET); - for (segment_index, segment_label) in segment_labels.iter().enumerate() { - let label_width = self.measure_text(segment_label); - let offset = SEGMENT_SIZE / 2 - label_width / 2; - self.draw_text(device, - segment_label, - origin + vec2i(offset, 0), - segment_index as u8 == value); - origin += vec2i(SEGMENT_SIZE + 1, 0); - } - - value - } - - pub fn draw_image_segmented_control(&mut self, - device: &D, - mut origin: Vector2I, - segment_textures: &[&D::Texture], - mut value: Option) - -> Option { - let mut clicked_segment = None; - if let Some(segment_index) = self.draw_segmented_control(device, - origin, - value, - segment_textures.len() as u8) { - if let Some(ref mut value) = value { - *value = segment_index; - } - clicked_segment = Some(segment_index); - } - - for (segment_index, segment_texture) in segment_textures.iter().enumerate() { - let texture_width = device.texture_size(segment_texture).x(); - let offset = vec2i(SEGMENT_SIZE / 2 - texture_width / 2, PADDING); - let color = if Some(segment_index as u8) == value { - WINDOW_COLOR - } else { - TEXT_COLOR - }; - - self.draw_texture(device, origin + offset, segment_texture, color); - origin += vec2i(SEGMENT_SIZE + 1, 0); - } - - clicked_segment - } - - fn draw_segmented_control(&mut self, - device: &D, - origin: Vector2I, - mut value: Option, - segment_count: u8) - -> Option { - let widget_width = self.measure_segmented_control(segment_count); - let widget_rect = RectI::new(origin, vec2i(widget_width, BUTTON_HEIGHT)); - - let mut clicked_segment = None; - if let Some(position) = self.event_queue.handle_mouse_down_in_rect(widget_rect) { - let segment = ((position.x() / (SEGMENT_SIZE + 1)) as u8).min(segment_count - 1); - if let Some(ref mut value) = value { - *value = segment; - } - clicked_segment = Some(segment); - } - - self.draw_solid_rounded_rect(device, widget_rect, WINDOW_COLOR); - self.draw_rounded_rect_outline(device, widget_rect, OUTLINE_COLOR); - - if let Some(value) = value { - let highlight_size = vec2i(SEGMENT_SIZE, BUTTON_HEIGHT); - let x_offset = value as i32 * SEGMENT_SIZE + (value as i32 - 1); - self.draw_solid_rounded_rect(device, - RectI::new(origin + vec2i(x_offset, 0), highlight_size), - TEXT_COLOR); - } - - let mut segment_origin = origin + vec2i(SEGMENT_SIZE + 1, 0); - for next_segment_index in 1..segment_count { - let prev_segment_index = next_segment_index - 1; - match value { - Some(value) if value == prev_segment_index || value == next_segment_index => {} - _ => { - self.draw_line(device, - segment_origin, - segment_origin + vec2i(0, BUTTON_HEIGHT), - TEXT_COLOR); - } - } - segment_origin += vec2i(SEGMENT_SIZE + 1, 0); - } - - clicked_segment - } - - pub fn draw_tooltip(&self, device: &D, string: &str, rect: RectI) { - if !rect.to_f32().contains_point(self.mouse_position) { - return; - } - - let text_size = self.measure_text(string); - let window_size = vec2i(text_size + PADDING * 2, TOOLTIP_HEIGHT); - let origin = rect.origin() - vec2i(0, window_size.y() + PADDING); - - self.draw_solid_rounded_rect(device, RectI::new(origin, window_size), WINDOW_COLOR); - self.draw_text(device, string, origin + vec2i(PADDING, PADDING + FONT_ASCENT), false); - } -} - -struct DebugTextureProgram where D: Device { - program: D::Program, - framebuffer_size_uniform: D::Uniform, - texture_size_uniform: D::Uniform, - texture_uniform: D::Uniform, - color_uniform: D::Uniform, -} - -impl DebugTextureProgram where D: Device { - fn new(device: &D, resources: &dyn ResourceLoader) -> DebugTextureProgram { - let program = device.create_raster_program(resources, "debug_texture"); - let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - let texture_size_uniform = device.get_uniform(&program, "TextureSize"); - let texture_uniform = device.get_uniform(&program, "Texture"); - let color_uniform = device.get_uniform(&program, "Color"); - DebugTextureProgram { - program, - framebuffer_size_uniform, - texture_size_uniform, - texture_uniform, - color_uniform, - } - } -} - -struct DebugTextureVertexArray where D: Device { - vertex_array: D::VertexArray, - vertex_buffer: D::Buffer, - index_buffer: D::Buffer, -} - -impl DebugTextureVertexArray where D: Device { - fn new(device: &D, debug_texture_program: &DebugTextureProgram) - -> DebugTextureVertexArray { - let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic); - let index_buffer = device.create_buffer(BufferUploadMode::Dynamic); - let vertex_array = device.create_vertex_array(); - - let position_attr = device.get_vertex_attr(&debug_texture_program.program, "Position") - .unwrap(); - let tex_coord_attr = device.get_vertex_attr(&debug_texture_program.program, "TexCoord") - .unwrap(); - - device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: DEBUG_TEXTURE_VERTEX_SIZE, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.configure_vertex_attr(&vertex_array, &tex_coord_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: DEBUG_TEXTURE_VERTEX_SIZE, - offset: 4, - divisor: 0, - buffer_index: 0, - }); - - DebugTextureVertexArray { vertex_array, vertex_buffer, index_buffer } - } -} - -struct DebugSolidVertexArray where D: Device { - vertex_array: D::VertexArray, - vertex_buffer: D::Buffer, - index_buffer: D::Buffer, -} - -impl DebugSolidVertexArray where D: Device { - fn new(device: &D, debug_solid_program: &DebugSolidProgram) -> DebugSolidVertexArray { - let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic); - let index_buffer = device.create_buffer(BufferUploadMode::Dynamic); - let vertex_array = device.create_vertex_array(); - - let position_attr = - device.get_vertex_attr(&debug_solid_program.program, "Position").unwrap(); - device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index); - device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: DEBUG_SOLID_VERTEX_SIZE, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - - DebugSolidVertexArray { vertex_array, vertex_buffer, index_buffer } - } -} - -struct DebugSolidProgram where D: Device { - program: D::Program, - framebuffer_size_uniform: D::Uniform, - color_uniform: D::Uniform, -} - -impl DebugSolidProgram where D: Device { - fn new(device: &D, resources: &dyn ResourceLoader) -> DebugSolidProgram { - let program = device.create_raster_program(resources, "debug_solid"); - let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - let color_uniform = device.get_uniform(&program, "Color"); - DebugSolidProgram { program, framebuffer_size_uniform, color_uniform } - } -} - -#[derive(Clone, Copy, Debug)] -#[allow(dead_code)] -#[repr(C)] -struct DebugTextureVertex { - 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 AlignedI16, - position_y: position.y() as AlignedI16, - tex_coord_x: tex_coord.x() as AlignedU16, - tex_coord_y: tex_coord.y() as AlignedU16, - } - } -} - -#[derive(Clone, Copy)] -#[allow(dead_code)] -#[repr(C)] -struct DebugSolidVertex { - position_x: AlignedI16, - position_y: AlignedI16, -} - -impl DebugSolidVertex { - fn new(position: Vector2I) -> DebugSolidVertex { - DebugSolidVertex { position_x: position.x() as AlignedI16, position_y: position.y() as AlignedI16 } - } -} - -struct CornerRects { - upper_left: RectI, - upper_right: RectI, - lower_left: RectI, - lower_right: RectI, -} - -impl CornerRects { - fn new(device: &D, rect: RectI, texture: &D::Texture) -> CornerRects where D: Device { - let size = device.texture_size(texture); - CornerRects { - upper_left: RectI::new(rect.origin(), size), - upper_right: RectI::new(rect.upper_right() - vec2i(size.x(), 0), size), - lower_left: RectI::new(rect.lower_left() - vec2i(0, size.y()), size), - lower_right: RectI::new(rect.lower_right() - size, size), - } - } -} - -fn get_color_uniform(color: ColorU) -> UniformData { - let color = F32x4::new(color.r as f32, color.g as f32, color.b as f32, color.a as f32); - UniformData::Vec4(color * F32x4::splat(1.0 / 255.0)) -} - -#[derive(Clone, Copy)] -pub enum UIEvent { - MouseDown(MousePosition), - MouseDragged(MousePosition), -} - -pub struct UIEventQueue { - events: Vec, -} - -impl UIEventQueue { - fn new() -> UIEventQueue { - UIEventQueue { events: vec![] } - } - - pub fn push(&mut self, event: UIEvent) { - self.events.push(event); - } - - pub fn drain(&mut self) -> Vec { - mem::replace(&mut self.events, vec![]) - } - - pub fn handle_mouse_down_in_rect(&mut self, rect: RectI) -> Option { - let (mut remaining_events, mut result) = (vec![], None); - for event in self.events.drain(..) { - match event { - UIEvent::MouseDown(position) if rect.contains_point(position.absolute) => { - result = Some(position.absolute - rect.origin()); - } - event => remaining_events.push(event), - } - } - self.events = remaining_events; - result - } - - pub fn handle_mouse_down_or_dragged_in_rect(&mut self, rect: RectI) -> Option { - let (mut remaining_events, mut result) = (vec![], None); - for event in self.events.drain(..) { - match event { - UIEvent::MouseDown(position) | UIEvent::MouseDragged(position) if - rect.contains_point(position.absolute) => { - result = Some(position.absolute - rect.origin()); - } - event => remaining_events.push(event), - } - } - self.events = remaining_events; - result - } -} - -#[derive(Clone, Copy)] -pub struct MousePosition { - pub absolute: Vector2I, - pub relative: Vector2I, -} - -#[derive(Deserialize)] -#[allow(dead_code)] -pub struct DebugFont { - name: String, - size: i32, - bold: bool, - italic: bool, - width: u32, - height: u32, - characters: HashMap, -} - -#[derive(Deserialize)] -struct DebugCharacter { - x: i32, - y: i32, - width: i32, - height: i32, - #[serde(rename = "originX")] - origin_x: i32, - #[serde(rename = "originY")] - origin_y: i32, - advance: i32, -} - -impl DebugFont { - #[inline] - fn load(resources: &dyn ResourceLoader) -> DebugFont { - serde_json::from_slice(&resources.slurp(FONT_JSON_VIRTUAL_PATH).unwrap()).unwrap() - } -} - -fn alpha_blend_state() -> BlendState { - BlendState { - src_rgb_factor: BlendFactor::One, - dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, - src_alpha_factor: BlendFactor::One, - dest_alpha_factor: BlendFactor::One, - ..BlendState::default() - } -} diff --git a/crates/pathfinder/utils/area-lut/Cargo.toml b/crates/pathfinder/utils/area-lut/Cargo.toml deleted file mode 100644 index 66959aba37..0000000000 --- a/crates/pathfinder/utils/area-lut/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "area-lut" -version = "0.2.0" -authors = ["Patrick Walton "] - -[dependencies] -clap = "2.30" -euclid = "0.20" -image = "0.23" diff --git a/crates/pathfinder/utils/area-lut/src/main.rs b/crates/pathfinder/utils/area-lut/src/main.rs deleted file mode 100644 index 09110b3dcb..0000000000 --- a/crates/pathfinder/utils/area-lut/src/main.rs +++ /dev/null @@ -1,102 +0,0 @@ -// pathfinder/area-lut/src/main.rs - -extern crate clap; -extern crate euclid; -extern crate image; - -use clap::{App, Arg}; -use euclid::default::Point2D; -use image::{ImageBuffer, Rgba}; -use std::f32; -use std::path::Path; - -const WIDTH: u32 = 256; -const HEIGHT: u32 = 256; - -fn solve_line_y(p0: &Point2D, p1: &Point2D, y: f32) -> Point2D { - let m = (p1.y - p0.y) / (p1.x - p0.x); - Point2D::new(p0.x - (p0.y - y) / m, y) -} - -fn area_tri(p0: Point2D, p1: Point2D) -> f32 { - 0.5 * (p1.x - p0.x) * (p0.y - p1.y) -} - -fn area_rect(p0: Point2D, p1: Point2D) -> f32 { - (p1.x - p0.x) * (p0.y - p1.y) -} - -fn area(y: f32, dydx: f32) -> f32 { - let (x_left, x_right) = (-0.5, 0.5); - let (y_left, y_right) = (dydx * x_left + y, dydx * x_right + y); - - let (p0, p1) = (Point2D::new(x_left, y_left), Point2D::new(x_right, y_right)); - let p2 = solve_line_y(&p0, &p1, -0.5); - let p3 = Point2D::new(p1.x, -0.5); - let p4 = solve_line_y(&p0, &p1, 0.5); - let p7 = Point2D::new(p1.x, 0.5); - - let alpha; - if p0.y > 0.5 { - if p1.y < -0.5 { - // Case 0 - alpha = area_tri(p0, p1) - area_tri(p2, p1) - area_rect(p0, p7) + area_tri(p0, p4); - } else if p1.y < 0.5 { - // Case 6 - alpha = area_tri(p0, p1) - area_rect(p0, p7) + area_tri(p0, p4); - } else { - // Case 3 - alpha = 0.0; - } - } else if p0.y > -0.5 { - if p1.y < -0.5 { - // Case 1 - alpha = area_tri(p0, p1) - area_tri(p2, p1) - area_rect(p0, p7); - } else { - // Case 4 - alpha = area_tri(p0, p1) - area_rect(p0, p7); - } - } else { - // Case 2 - alpha = -area_rect(p0, p7) + area_rect(p0, p3); - } - - alpha -} - -fn main() { - let app = App::new("Pathfinder Area LUT Generator") - .version("0.1") - .author("The Pathfinder Project Developers") - .about("Generates area lookup tables for use with Pathfinder") - .arg(Arg::with_name("OUTPUT-PATH").help("The `.png` image to produce") - .required(true) - .index(1)); - - let matches = app.get_matches(); - let image = ImageBuffer::from_fn(WIDTH, HEIGHT, |u, v| { - if u == 0 { - return Rgba([255, 255, 255, 255]) - } - if u == WIDTH - 1 { - return Rgba([0, 0, 0, 0]) - } - - let y = ((u as f32) - (WIDTH / 2) as f32) / 16.0; - let dydx = -(v as f32) / 16.0; - - let alphas = [ - (area(y - 0.0, dydx) * 255.0).round() as u8, - (area(y - 1.0, dydx) * 255.0).round() as u8, - (area(y - 2.0, dydx) * 255.0).round() as u8, - (area(y - 3.0, dydx) * 255.0).round() as u8, - ]; - - Rgba([alphas[0], alphas[1], alphas[2], alphas[3]]) - }); - - let output_path = matches.value_of("OUTPUT-PATH").unwrap(); - let output_path = Path::new(output_path); - - image.save(&output_path).unwrap(); -} diff --git a/crates/pathfinder/utils/convert/Cargo.toml b/crates/pathfinder/utils/convert/Cargo.toml deleted file mode 100644 index 4f88c522c1..0000000000 --- a/crates/pathfinder/utils/convert/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "convert" -version = "0.1.0" -authors = ["Sebastian Köln "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -pathfinder_export = { path = "../../export" } -pathfinder_svg = { path = "../../svg" } -usvg = "0.9" diff --git a/crates/pathfinder/utils/convert/src/main.rs b/crates/pathfinder/utils/convert/src/main.rs deleted file mode 100644 index f7923f69d2..0000000000 --- a/crates/pathfinder/utils/convert/src/main.rs +++ /dev/null @@ -1,27 +0,0 @@ -use std::fs::File; -use std::io::{Read, BufWriter}; -use std::error::Error; -use std::path::PathBuf; -use pathfinder_svg::BuiltSVG; -use pathfinder_export::{Export, FileFormat}; -use usvg::{Tree, Options}; - -fn main() -> Result<(), Box> { - let mut args = std::env::args_os().skip(1); - let input = PathBuf::from(args.next().expect("no input given")); - let output = PathBuf::from(args.next().expect("no output given")); - - let mut data = Vec::new(); - File::open(input)?.read_to_end(&mut data)?; - let svg = BuiltSVG::from_tree(&Tree::from_data(&data, &Options::default()).unwrap()); - - let scene = &svg.scene; - let mut writer = BufWriter::new(File::create(&output)?); - let format = match output.extension().and_then(|s| s.to_str()) { - Some("pdf") => FileFormat::PDF, - Some("ps") => FileFormat::PS, - _ => return Err("output filename must have .ps or .pdf extension".into()) - }; - scene.export(&mut writer, format).unwrap(); - Ok(()) -} diff --git a/crates/pathfinder/utils/gamma-lut/Cargo.toml b/crates/pathfinder/utils/gamma-lut/Cargo.toml deleted file mode 100644 index e216a8c04b..0000000000 --- a/crates/pathfinder/utils/gamma-lut/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "generate-gamma-lut" -version = "0.1.0" -authors = ["Patrick Walton "] - -[dependencies] -clap = "2.27" -log = "0.4" -image = "0.23" diff --git a/crates/pathfinder/utils/gamma-lut/src/gamma_lut.rs b/crates/pathfinder/utils/gamma-lut/src/gamma_lut.rs deleted file mode 100644 index eba7f810a4..0000000000 --- a/crates/pathfinder/utils/gamma-lut/src/gamma_lut.rs +++ /dev/null @@ -1,355 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*! -Gamma correction lookup tables. - -This is a port of Skia gamma LUT logic into Rust, used by WebRender. -*/ -//#![warn(missing_docs)] //TODO -#![allow(dead_code)] - -use std::cmp::max; - -use ColorU; - -/// Color space responsible for converting between lumas and luminances. -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum LuminanceColorSpace { - /// Linear space - no conversion involved. - Linear, - /// Simple gamma space - uses the `luminance ^ gamma` function. - Gamma(f32), - /// Srgb space. - Srgb, -} - -impl LuminanceColorSpace { - pub fn new(gamma: f32) -> LuminanceColorSpace { - if gamma == 1.0 { - LuminanceColorSpace::Linear - } else if gamma == 0.0 { - LuminanceColorSpace::Srgb - } else { - LuminanceColorSpace::Gamma(gamma) - } - } - - pub fn to_luma(&self, luminance: f32) -> f32 { - match *self { - LuminanceColorSpace::Linear => luminance, - LuminanceColorSpace::Gamma(gamma) => luminance.powf(gamma), - LuminanceColorSpace::Srgb => { - //The magic numbers are derived from the sRGB specification. - //See http://www.color.org/chardata/rgb/srgb.xalter . - if luminance <= 0.04045 { - luminance / 12.92 - } else { - ((luminance + 0.055) / 1.055).powf(2.4) - } - } - } - } - - pub fn from_luma(&self, luma: f32) -> f32 { - match *self { - LuminanceColorSpace::Linear => luma, - LuminanceColorSpace::Gamma(gamma) => luma.powf(1. / gamma), - LuminanceColorSpace::Srgb => { - //The magic numbers are derived from the sRGB specification. - //See http://www.color.org/chardata/rgb/srgb.xalter . - if luma <= 0.0031308 { - luma * 12.92 - } else { - 1.055 * luma.powf(1./2.4) - 0.055 - } - } - } - } -} - -//TODO: tests -fn round_to_u8(x : f32) -> u8 { - let v = (x + 0.5).floor() as i32; - assert!(0 <= v && v < 0x100); - v as u8 -} - -//TODO: tests -/* - * Scales base <= 2^N-1 to 2^8-1 - * @param N [1, 8] the number of bits used by base. - * @param base the number to be scaled to [0, 255]. - */ -fn scale255(n: u8, mut base: u8) -> u8 { - base <<= 8 - n; - let mut lum = base; - let mut i = n; - - while i < 8 { - lum |= base >> i; - i += n; - } - - lum -} - -// Computes the luminance from the given r, g, and b in accordance with -// SK_LUM_COEFF_X. For correct results, r, g, and b should be in linear space. -fn compute_luminance(r: u8, g: u8, b: u8) -> u8 { - // The following is - // r * SK_LUM_COEFF_R + g * SK_LUM_COEFF_G + b * SK_LUM_COEFF_B - // with SK_LUM_COEFF_X in 1.8 fixed point (rounding adjusted to sum to 256). - let val: u32 = r as u32 * 54 + g as u32 * 183 + b as u32 * 19; - assert!(val < 0x10000); - (val >> 8) as u8 -} - -// Skia uses 3 bits per channel for luminance. -const LUM_BITS: u8 = 3; -// Mask of the highest used bits. -const LUM_MASK: u8 = ((1 << LUM_BITS) - 1) << (8 - LUM_BITS); - -pub trait ColorLut { - fn quantize(&self) -> ColorU; - fn quantized_floor(&self) -> ColorU; - fn quantized_ceil(&self) -> ColorU; - fn luminance(&self) -> u8; - fn luminance_color(&self) -> ColorU; -} - -impl ColorLut for ColorU { - // Compute a canonical color that is equivalent to the input color - // for preblend table lookups. The alpha channel is never used for - // preblending, so overwrite it with opaque. - fn quantize(&self) -> ColorU { - ColorU::new( - scale255(LUM_BITS, self.r >> (8 - LUM_BITS)), - scale255(LUM_BITS, self.g >> (8 - LUM_BITS)), - scale255(LUM_BITS, self.b >> (8 - LUM_BITS)), - 255, - ) - } - - // Quantize to the smallest value that yields the same table index. - fn quantized_floor(&self) -> ColorU { - ColorU::new( - self.r & LUM_MASK, - self.g & LUM_MASK, - self.b & LUM_MASK, - 255, - ) - } - - // Quantize to the largest value that yields the same table index. - fn quantized_ceil(&self) -> ColorU { - ColorU::new( - self.r | !LUM_MASK, - self.g | !LUM_MASK, - self.b | !LUM_MASK, - 255, - ) - } - - // Compute a luminance value suitable for grayscale preblend table - // lookups. - fn luminance(&self) -> u8 { - compute_luminance(self.r, self.g, self.b) - } - - // Make a grayscale color from the computed luminance. - fn luminance_color(&self) -> ColorU { - let lum = self.luminance(); - ColorU::new(lum, lum, lum, self.a) - } -} - -// A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise. -// With lower values small text appears washed out (though correctly so). -// With higher values lcd fringing is worse and the smoothing effect of -// partial coverage is diminished. -fn apply_contrast(srca: f32, contrast: f32) -> f32 { - srca + ((1.0 - srca) * contrast * srca) -} - -// The approach here is not necessarily the one with the lowest error -// See https://bel.fi/alankila/lcd/alpcor.html for a similar kind of thing -// that just search for the adjusted alpha value -pub fn build_gamma_correcting_lut(table: &mut [u8; 256], src: u8, contrast: f32, - src_space: LuminanceColorSpace, - dst_convert: LuminanceColorSpace) { - - let src = src as f32 / 255.0; - let lin_src = src_space.to_luma(src); - // Guess at the dst. The perceptual inverse provides smaller visual - // discontinuities when slight changes to desaturated colors cause a channel - // to map to a different correcting lut with neighboring srcI. - // See https://code.google.com/p/chromium/issues/detail?id=141425#c59 . - let dst = 1.0 - src; - let lin_dst = dst_convert.to_luma(dst); - - // Contrast value tapers off to 0 as the src luminance becomes white - let adjusted_contrast = contrast * lin_dst; - - // Remove discontinuity and instability when src is close to dst. - // The value 1/256 is arbitrary and appears to contain the instability. - if (src - dst).abs() < (1.0 / 256.0) { - let mut ii : f32 = 0.0; - for v in table.iter_mut() { - let raw_srca = ii / 255.0; - let srca = apply_contrast(raw_srca, adjusted_contrast); - - *v = round_to_u8(255.0 * srca); - ii += 1.0; - } - } else { - // Avoid slow int to float conversion. - let mut ii : f32 = 0.0; - for v in table.iter_mut() { - // 'raw_srca += 1.0f / 255.0f' and even - // 'raw_srca = i * (1.0f / 255.0f)' can add up to more than 1.0f. - // When this happens the table[255] == 0x0 instead of 0xff. - // See http://code.google.com/p/chromium/issues/detail?id=146466 - let raw_srca = ii / 255.0; - let srca = apply_contrast(raw_srca, adjusted_contrast); - assert!(srca <= 1.0); - let dsta = 1.0 - srca; - - // Calculate the output we want. - let lin_out = lin_src * srca + dsta * lin_dst; - assert!(lin_out <= 1.0); - let out = dst_convert.from_luma(lin_out); - - // Undo what the blit blend will do. - // i.e. given the formula for OVER: out = src * result + (1 - result) * dst - // solving for result gives: - let result = (out - dst) / (src - dst); - - *v = round_to_u8(255.0 * result); - debug!("Setting {:?} to {:?}", ii as u8, *v); - - ii += 1.0; - } - } -} - -pub struct GammaLut { - pub tables: [[u8; 256]; 1 << LUM_BITS], -} - -impl GammaLut { - // Skia actually makes 9 gamma tables, then based on the luminance color, - // fetches the RGB gamma table for that color. - fn generate_tables(&mut self, contrast: f32, paint_gamma: f32, device_gamma: f32) { - let paint_color_space = LuminanceColorSpace::new(paint_gamma); - let device_color_space = LuminanceColorSpace::new(device_gamma); - - for (i, entry) in self.tables.iter_mut().enumerate() { - let luminance = scale255(LUM_BITS, i as u8); - build_gamma_correcting_lut(entry, - luminance, - contrast, - paint_color_space, - device_color_space); - } - } - - pub fn table_count(&self) -> usize { - self.tables.len() - } - - pub fn get_table(&self, color: u8) -> &[u8; 256] { - &self.tables[(color >> (8 - LUM_BITS)) as usize] - } - - pub fn new(contrast: f32, paint_gamma: f32, device_gamma: f32) -> GammaLut { - let mut table = GammaLut { - tables: [[0; 256]; 1 << LUM_BITS], - }; - - table.generate_tables(contrast, paint_gamma, device_gamma); - - table - } - - // Assumes pixels are in BGRA format. Assumes pixel values are in linear space already. - pub fn preblend(&self, pixels: &mut [u8], color: ColorU) { - let table_r = self.get_table(color.r); - let table_g = self.get_table(color.g); - let table_b = self.get_table(color.b); - - for pixel in pixels.chunks_mut(4) { - let (b, g, r) = (table_b[pixel[0] as usize], table_g[pixel[1] as usize], table_r[pixel[2] as usize]); - pixel[0] = b; - pixel[1] = g; - pixel[2] = r; - pixel[3] = max(max(b, g), r); - } - } - - // Assumes pixels are in BGRA format. Assumes pixel values are in linear space already. - pub fn preblend_grayscale(&self, pixels: &mut [u8], color: ColorU) { - let table_g = self.get_table(color.g); - - for pixel in pixels.chunks_mut(4) { - let luminance = compute_luminance(pixel[2], pixel[1], pixel[0]); - let alpha = table_g[luminance as usize]; - pixel[0] = alpha; - pixel[1] = alpha; - pixel[2] = alpha; - pixel[3] = alpha; - } - } - -} // end impl GammaLut - -#[cfg(test)] -mod tests { - use super::*; - - fn over(dst: u32, src: u32, alpha: u32) -> u32 { - (src * alpha + dst * (255 - alpha))/255 - } - - fn overf(dst: f32, src: f32, alpha: f32) -> f32 { - ((src * alpha + dst * (255. - alpha))/255.) as f32 - } - - - fn absdiff(a: u32, b: u32) -> u32 { - if a < b { b - a } else { a - b } - } - - #[test] - fn gamma() { - let mut table = [0u8; 256]; - let g = 2.0; - let space = LuminanceColorSpace::Gamma(g); - let mut src : u32 = 131; - while src < 256 { - build_gamma_correcting_lut(&mut table, src as u8, 0., space, space); - let mut max_diff = 0; - let mut dst = 0; - while dst < 256 { - for alpha in 0u32..256 { - let preblend = table[alpha as usize]; - let lin_dst = (dst as f32 / 255.).powf(g) * 255.; - let lin_src = (src as f32 / 255.).powf(g) * 255.; - - let preblend_result = over(dst, src, preblend as u32); - let true_result = ((overf(lin_dst, lin_src, alpha as f32) / 255.).powf(1. / g) * 255.) as u32; - let diff = absdiff(preblend_result, true_result); - //println!("{} -- {} {} = {}", alpha, preblend_result, true_result, diff); - max_diff = max(max_diff, diff); - } - - //println!("{} {} max {}", src, dst, max_diff); - assert!(max_diff <= 33); - dst += 1; - - } - src += 1; - } - } -} // end mod diff --git a/crates/pathfinder/utils/gamma-lut/src/main.rs b/crates/pathfinder/utils/gamma-lut/src/main.rs deleted file mode 100644 index d2db1069a4..0000000000 --- a/crates/pathfinder/utils/gamma-lut/src/main.rs +++ /dev/null @@ -1,61 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -extern crate clap; -extern crate image; - -#[macro_use] -extern crate log; - -mod gamma_lut; - -use clap::{App, Arg}; -use gamma_lut::GammaLut; -use image::{DynamicImage, ImageBuffer, Luma}; - -const CONTRAST: f32 = 0.0; -const GAMMA: f32 = 0.0; - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct ColorU { - pub r: u8, - pub g: u8, - pub b: u8, - pub a: u8, -} - -impl ColorU { - #[inline] - pub fn new(r: u8, g: u8, b: u8, a: u8) -> ColorU { - ColorU { - r: r, - g: g, - b: b, - a: a, - } - } -} - -pub fn main() { - let app = App::new("Pathfinder Gamma LUT Generator") - .version("0.1") - .author("The Pathfinder Project Developers") - .about("Generates gamma lookup tables for use with Pathfinder") - .arg(Arg::with_name("OUTPUT-PATH").help("The `.png` image to produce") - .required(true) - .index(1)); - let matches = app.get_matches(); - - let gamma_lut = GammaLut::new(CONTRAST, GAMMA, GAMMA); - let mut image = ImageBuffer::new(256, gamma_lut.tables.len() as u32); - for (table_index, table) in gamma_lut.tables.iter().enumerate() { - for (color_index, &color) in table.iter().enumerate() { - image.put_pixel(color_index as u32, table_index as u32, Luma([color])) - } - } - - let output_path = matches.value_of("OUTPUT-PATH").unwrap(); - - DynamicImage::ImageLuma8(image).save(output_path).unwrap(); -} diff --git a/crates/pathfinder/utils/svg-to-skia/Cargo.toml b/crates/pathfinder/utils/svg-to-skia/Cargo.toml deleted file mode 100644 index 06af2c75d6..0000000000 --- a/crates/pathfinder/utils/svg-to-skia/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "svg-to-skia" -version = "0.1.0" -authors = ["Patrick Walton "] -edition = "2018" - -[dependencies] -usvg = "0.9" diff --git a/crates/pathfinder/utils/svg-to-skia/src/main.rs b/crates/pathfinder/utils/svg-to-skia/src/main.rs deleted file mode 100644 index 8a9714218e..0000000000 --- a/crates/pathfinder/utils/svg-to-skia/src/main.rs +++ /dev/null @@ -1,87 +0,0 @@ -// pathfinder/utils/svg-to-skia/src/main.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::env; -use usvg::{Node, NodeKind, Options, Paint, PathSegment, Tree}; - -fn main() { - let input_path = env::args().skip(1).next().unwrap(); - let tree = Tree::from_file(&input_path, &Options::default()).unwrap(); - - println!("#ifndef PAINT_H"); - println!("#define PAINT_H"); - println!("static void paint(SkCanvas *canvas) {{"); - println!(" SkPaint paint;"); - println!(" SkPath path;"); - println!(" paint.setAntiAlias(true);"); - println!(" canvas->clear(SK_ColorWHITE);"); - - let root = &tree.root(); - match *root.borrow() { - NodeKind::Svg(_) => { - for kid in root.children() { - process_node(&kid); - } - } - _ => unreachable!(), - } - - println!("}}"); - println!("#endif"); -} - -fn process_node(node: &Node) { - match *node.borrow() { - NodeKind::Group(_) => { - for kid in node.children() { - process_node(&kid) - } - } - NodeKind::Path(ref path) => { - for segment in path.data.iter() { - match segment { - PathSegment::MoveTo { x, y } => println!(" path.moveTo({}, {});", x, y), - PathSegment::LineTo { x, y } => println!(" path.lineTo({}, {});", x, y), - PathSegment::CurveTo { x1, y1, x2, y2, x, y } => { - println!(" path.cubicTo({}, {}, {}, {}, {}, {});", - x1, y1, x2, y2, x, y); - } - PathSegment::ClosePath => println!(" path.close();"), - } - } - - if let Some(ref fill) = path.fill { - set_color(&fill.paint); - println!(" paint.setStyle(SkPaint::kFill_Style);"); - println!(" canvas->drawPath(path, paint);"); - } - - if let Some(ref stroke) = path.stroke { - set_color(&stroke.paint); - println!(" paint.setStrokeWidth({});", stroke.width.value()); - println!(" paint.setStyle(SkPaint::kStroke_Style);"); - println!(" canvas->drawPath(path, paint);"); - } - - println!(" path.reset();"); - } - _ => {} - } -} - -fn set_color(paint: &Paint) { - if let Paint::Color(color) = *paint { - println!(" paint.setColor(0x{:x});", - ((color.red as u32) << 16) | - ((color.green as u32) << 8) | - ((color.blue as u32) << 0) | - (0xff << 24)); - } -} diff --git a/examples/2d/pathfinder.rs b/examples/2d/pathfinder.rs deleted file mode 100644 index e677999387..0000000000 --- a/examples/2d/pathfinder.rs +++ /dev/null @@ -1,29 +0,0 @@ -use bevy::prelude::*; -use bevy::render::base_render_graph::BaseRenderGraphConfig; -use bevy_diagnostic::{PrintDiagnosticsPlugin, FrameTimeDiagnosticsPlugin}; -use bevy_wgpu::diagnostic::WgpuResourceDiagnosticsPlugin; - -fn main() { - App::build() - .add_plugin(bevy::core::CorePlugin::default()) - .add_plugin(bevy::diagnostic::DiagnosticsPlugin::default()) - .add_plugin(bevy::input::InputPlugin::default()) - .add_plugin(bevy::window::WindowPlugin::default()) - .add_plugin(bevy::render::RenderPlugin { - base_render_graph_config: Some(BaseRenderGraphConfig { - add_2d_camera: true, - add_3d_camera: false, - add_main_pass: false, - add_main_depth_texture:true, - connect_main_pass_to_swapchain: false, - connect_main_pass_to_main_depth_texture: false, - }) - }) - .add_plugin(bevy::pathfinder::PathfinderPlugin::default()) - .add_plugin(bevy::winit::WinitPlugin::default()) - .add_plugin(bevy::wgpu::WgpuPlugin::default()) - .add_plugin(FrameTimeDiagnosticsPlugin::default()) - .add_plugin(WgpuResourceDiagnosticsPlugin::default()) - .add_plugin(PrintDiagnosticsPlugin::default()) - .run(); -} diff --git a/src/add_default_plugins.rs b/src/add_default_plugins.rs index 6c30016844..56056457fc 100644 --- a/src/add_default_plugins.rs +++ b/src/add_default_plugins.rs @@ -21,9 +21,6 @@ impl AddDefaultPlugins for AppBuilder { #[cfg(feature = "render")] self.add_plugin(bevy_render::RenderPlugin::default()); - // #[cfg(feature = "pathfinder")] - // self.add_plugin(bevy_pathfinder::PathfinderPlugin::default()); - #[cfg(feature = "pbr")] self.add_plugin(bevy_pbr::PbrPlugin::default()); diff --git a/src/lib.rs b/src/lib.rs index adceb838ae..4b0fef87d7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,8 +59,6 @@ pub use bevy_diagnostic as diagnostic; pub use bevy_gltf as gltf; #[cfg(feature = "input")] pub use bevy_input as input; -#[cfg(feature = "pathfinder")] -pub use bevy_pathfinder as pathfinder; #[cfg(feature = "pbr")] pub use bevy_pbr as pbr; #[cfg(feature = "render")]